This commit is contained in:
7 files changed
+164
-82
No files matched your search
@@ -0,0 +1,16 @@
|
|||||||
|
package com.m57.hermescontrol.data.ws.contract
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `profiles.configure` params for the sections the app writes: `ui_meta` and the bot `soul`.
|
||||||
|
* `profile` is not a field: WsProfileParams injects it when the method is profile scoped.
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class ProfilesConfigureParams(
|
||||||
|
@SerialName("name") val name: String? = null,
|
||||||
|
@SerialName("ui_meta") val uiMeta: JsonObject? = null,
|
||||||
|
@SerialName("soul") val soul: String? = null,
|
||||||
|
)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.m57.hermescontrol.data.ws.contract
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
/** `profiles.list` takes no explicit params here; the active profile is injected by WsProfileParams. */
|
||||||
|
@Serializable
|
||||||
|
data object ProfilesListParams
|
||||||
@@ -379,6 +379,22 @@ object RpcMethods {
|
|||||||
JsonElement.serializer(),
|
JsonElement.serializer(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Passthrough JsonElement results: callers keep their existing legacy decoders.
|
||||||
|
val PROFILES_LIST: RpcMethod<ProfilesListParams, JsonElement> =
|
||||||
|
RpcMethod(
|
||||||
|
WsMethods.PROFILES_LIST,
|
||||||
|
ProfilesListParams.serializer(),
|
||||||
|
JsonElement.serializer(),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Passthrough JsonElement results: callers keep their existing legacy decoders.
|
||||||
|
val PROFILES_CONFIGURE: RpcMethod<ProfilesConfigureParams, JsonElement> =
|
||||||
|
RpcMethod(
|
||||||
|
WsMethods.PROFILES_CONFIGURE,
|
||||||
|
ProfilesConfigureParams.serializer(),
|
||||||
|
JsonElement.serializer(),
|
||||||
|
)
|
||||||
|
|
||||||
/** Every typed method. GatewayContractTest iterates this; future migrations append here. */
|
/** Every typed method. GatewayContractTest iterates this; future migrations append here. */
|
||||||
val all: List<RpcMethod<*, *>> =
|
val all: List<RpcMethod<*, *>> =
|
||||||
listOf(
|
listOf(
|
||||||
@@ -428,5 +444,7 @@ object RpcMethods {
|
|||||||
PROCESS_KILL,
|
PROCESS_KILL,
|
||||||
PLUGINS_MANAGE,
|
PLUGINS_MANAGE,
|
||||||
PROJECTS_LIST,
|
PROJECTS_LIST,
|
||||||
|
PROFILES_LIST,
|
||||||
|
PROFILES_CONFIGURE,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,9 @@ import com.m57.hermescontrol.data.remote.OkHttpProvider
|
|||||||
import com.m57.hermescontrol.data.remote.safeApiCall
|
import com.m57.hermescontrol.data.remote.safeApiCall
|
||||||
import com.m57.hermescontrol.data.session.ProfileSwitchCoordinator
|
import com.m57.hermescontrol.data.session.ProfileSwitchCoordinator
|
||||||
import com.m57.hermescontrol.data.ws.HermesWsClient
|
import com.m57.hermescontrol.data.ws.HermesWsClient
|
||||||
import com.m57.hermescontrol.data.ws.WsMethods
|
import com.m57.hermescontrol.data.ws.contract.ProfilesConfigureParams
|
||||||
|
import com.m57.hermescontrol.data.ws.contract.ProfilesListParams
|
||||||
|
import com.m57.hermescontrol.data.ws.contract.RpcMethods
|
||||||
import com.m57.hermescontrol.data.ws.toJsonElement
|
import com.m57.hermescontrol.data.ws.toJsonElement
|
||||||
import com.m57.hermescontrol.ui.common.ToastHost
|
import com.m57.hermescontrol.ui.common.ToastHost
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
@@ -29,6 +31,8 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
|
import kotlinx.serialization.json.JsonNull
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
import kotlinx.serialization.json.decodeFromJsonElement
|
import kotlinx.serialization.json.decodeFromJsonElement
|
||||||
|
|
||||||
@@ -243,14 +247,8 @@ class BotsViewModel(
|
|||||||
// First try fetching profiles via WebSocket RPC (profiles.list) which includes ui_meta (groups, custom avatars).
|
// First try fetching profiles via WebSocket RPC (profiles.list) which includes ui_meta (groups, custom avatars).
|
||||||
var profilesWithMeta: List<ProfileInfo>? = null
|
var profilesWithMeta: List<ProfileInfo>? = null
|
||||||
try {
|
try {
|
||||||
val rpcResult = HermesWsClient.request(WsMethods.PROFILES_LIST).await()
|
val jsonElement = HermesWsClient.call(RpcMethods.PROFILES_LIST, ProfilesListParams)
|
||||||
val jsonElement =
|
if (jsonElement !is JsonNull) {
|
||||||
when (rpcResult) {
|
|
||||||
is JsonElement -> rpcResult
|
|
||||||
null -> null
|
|
||||||
else -> rpcResult.toJsonElement()
|
|
||||||
}
|
|
||||||
if (jsonElement != null) {
|
|
||||||
val resp = OkHttpProvider.json.decodeFromJsonElement<ProfilesResponse>(jsonElement)
|
val resp = OkHttpProvider.json.decodeFromJsonElement<ProfilesResponse>(jsonElement)
|
||||||
if (!resp.profiles.isNullOrEmpty()) {
|
if (!resp.profiles.isNullOrEmpty()) {
|
||||||
profilesWithMeta = resp.profiles
|
profilesWithMeta = resp.profiles
|
||||||
@@ -362,7 +360,13 @@ class BotsViewModel(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
val botSoul = composeBotSoul(name, title, description)
|
val botSoul = composeBotSoul(name, title, description)
|
||||||
wsClientConfigureBot(name, botMeta, soul = botSoul)
|
// Fire-and-forget as before: the metadata write never gated the reload or onSuccess.
|
||||||
|
launch {
|
||||||
|
try {
|
||||||
|
wsClientConfigureBot(name, botMeta, soul = botSoul)
|
||||||
|
} catch (_: Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
loadBots()
|
loadBots()
|
||||||
onSuccess()
|
onSuccess()
|
||||||
} else {
|
} else {
|
||||||
@@ -396,7 +400,7 @@ class BotsViewModel(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
try {
|
try {
|
||||||
wsClientConfigureBot(name, updatedMeta).await()
|
wsClientConfigureBot(name, updatedMeta)
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
}
|
}
|
||||||
loadBots()
|
loadBots()
|
||||||
@@ -440,7 +444,7 @@ class BotsViewModel(
|
|||||||
group = existingGroups.firstOrNull() ?: groupName,
|
group = existingGroups.firstOrNull() ?: groupName,
|
||||||
)
|
)
|
||||||
try {
|
try {
|
||||||
wsClientConfigureBot(name, updatedMeta).await()
|
wsClientConfigureBot(name, updatedMeta)
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -475,14 +479,13 @@ class BotsViewModel(
|
|||||||
rooms = updatedRooms,
|
rooms = updatedRooms,
|
||||||
deleted = updatedDeleted,
|
deleted = updatedDeleted,
|
||||||
)
|
)
|
||||||
HermesWsClient
|
HermesWsClient.call(
|
||||||
.request(
|
RpcMethods.PROFILES_CONFIGURE,
|
||||||
WsMethods.PROFILES_CONFIGURE,
|
ProfilesConfigureParams(
|
||||||
mapOf(
|
name = defaultProfile.name,
|
||||||
"name" to defaultProfile.name,
|
uiMeta = mapOf("hermes-bots-groups" to newSnapshot.toMap()).toJsonObject(),
|
||||||
"ui_meta" to mapOf("hermes-bots-groups" to newSnapshot.toMap()),
|
),
|
||||||
),
|
)
|
||||||
).await()
|
|
||||||
}
|
}
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
}
|
}
|
||||||
@@ -509,7 +512,7 @@ class BotsViewModel(
|
|||||||
group = filtered.firstOrNull(),
|
group = filtered.firstOrNull(),
|
||||||
)
|
)
|
||||||
try {
|
try {
|
||||||
wsClientConfigureBot(bot.name, updatedMeta).await()
|
wsClientConfigureBot(bot.name, updatedMeta)
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -540,14 +543,13 @@ class BotsViewModel(
|
|||||||
rooms = updatedRooms,
|
rooms = updatedRooms,
|
||||||
deleted = deletedMap,
|
deleted = deletedMap,
|
||||||
)
|
)
|
||||||
HermesWsClient
|
HermesWsClient.call(
|
||||||
.request(
|
RpcMethods.PROFILES_CONFIGURE,
|
||||||
WsMethods.PROFILES_CONFIGURE,
|
ProfilesConfigureParams(
|
||||||
mapOf(
|
name = defaultProfile.name,
|
||||||
"name" to defaultProfile.name,
|
uiMeta = mapOf("hermes-bots-groups" to newSnapshot.toMap()).toJsonObject(),
|
||||||
"ui_meta" to mapOf("hermes-bots-groups" to newSnapshot.toMap()),
|
),
|
||||||
),
|
)
|
||||||
).await()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
@@ -575,11 +577,11 @@ class BotsViewModel(
|
|||||||
return lines.joinToString("\n")
|
return lines.joinToString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wsClientConfigureBot(
|
private suspend fun wsClientConfigureBot(
|
||||||
name: String,
|
name: String,
|
||||||
meta: BotRosterMeta,
|
meta: BotRosterMeta,
|
||||||
soul: String? = null,
|
soul: String? = null,
|
||||||
): kotlinx.coroutines.CompletableDeferred<Any?> {
|
) {
|
||||||
val metaMap =
|
val metaMap =
|
||||||
buildMap<String, Any> {
|
buildMap<String, Any> {
|
||||||
meta.title?.let { put("title", it) }
|
meta.title?.let { put("title", it) }
|
||||||
@@ -599,16 +601,15 @@ class BotsViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val params =
|
HermesWsClient.call(
|
||||||
buildMap<String, Any> {
|
RpcMethods.PROFILES_CONFIGURE,
|
||||||
put("name", name)
|
ProfilesConfigureParams(
|
||||||
put("ui_meta", mapOf("hermes-bots" to metaMap))
|
name = name,
|
||||||
soul?.let { put("soul", it) }
|
uiMeta = mapOf("hermes-bots" to metaMap).toJsonObject(),
|
||||||
}
|
soul = soul,
|
||||||
|
),
|
||||||
return HermesWsClient.request(
|
|
||||||
WsMethods.PROFILES_CONFIGURE,
|
|
||||||
params,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Map<String, Any?>.toJsonObject(): JsonObject = toJsonElement() as JsonObject
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,8 @@ import com.m57.hermescontrol.data.remote.safeApiCall
|
|||||||
import com.m57.hermescontrol.data.session.ActiveSessionHolder
|
import com.m57.hermescontrol.data.session.ActiveSessionHolder
|
||||||
import com.m57.hermescontrol.data.ws.HermesWsClient
|
import com.m57.hermescontrol.data.ws.HermesWsClient
|
||||||
import com.m57.hermescontrol.data.ws.WsEvent
|
import com.m57.hermescontrol.data.ws.WsEvent
|
||||||
import com.m57.hermescontrol.data.ws.WsMethods
|
import com.m57.hermescontrol.data.ws.contract.ProfilesConfigureParams
|
||||||
|
import com.m57.hermescontrol.data.ws.contract.ProfilesListParams
|
||||||
import com.m57.hermescontrol.data.ws.contract.PromptSubmitParams
|
import com.m57.hermescontrol.data.ws.contract.PromptSubmitParams
|
||||||
import com.m57.hermescontrol.data.ws.contract.RpcMethods
|
import com.m57.hermescontrol.data.ws.contract.RpcMethods
|
||||||
import com.m57.hermescontrol.data.ws.contract.SessionCreateParams
|
import com.m57.hermescontrol.data.ws.contract.SessionCreateParams
|
||||||
@@ -34,6 +35,8 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
|
import kotlinx.serialization.json.JsonNull
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
import kotlinx.serialization.json.decodeFromJsonElement
|
import kotlinx.serialization.json.decodeFromJsonElement
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -327,14 +330,8 @@ class GroupChatViewModel(
|
|||||||
|
|
||||||
private suspend fun fetchProfiles(): List<ProfileInfo> {
|
private suspend fun fetchProfiles(): List<ProfileInfo> {
|
||||||
try {
|
try {
|
||||||
val rpcResult = HermesWsClient.request(WsMethods.PROFILES_LIST).await()
|
val jsonElement = HermesWsClient.call(RpcMethods.PROFILES_LIST, ProfilesListParams)
|
||||||
val jsonElement =
|
if (jsonElement !is JsonNull) {
|
||||||
when (rpcResult) {
|
|
||||||
is JsonElement -> rpcResult
|
|
||||||
null -> null
|
|
||||||
else -> rpcResult.toJsonElement()
|
|
||||||
}
|
|
||||||
if (jsonElement != null) {
|
|
||||||
val resp = json.decodeFromJsonElement<ProfilesResponse>(jsonElement)
|
val resp = json.decodeFromJsonElement<ProfilesResponse>(jsonElement)
|
||||||
if (!resp.profiles.isNullOrEmpty()) {
|
if (!resp.profiles.isNullOrEmpty()) {
|
||||||
return resp.profiles
|
return resp.profiles
|
||||||
@@ -534,14 +531,13 @@ class GroupChatViewModel(
|
|||||||
|
|
||||||
val uiMetaPayload = mapOf("hermes-bots-groups" to newSnapshot.toMap())
|
val uiMetaPayload = mapOf("hermes-bots-groups" to newSnapshot.toMap())
|
||||||
|
|
||||||
HermesWsClient
|
HermesWsClient.call(
|
||||||
.request(
|
RpcMethods.PROFILES_CONFIGURE,
|
||||||
WsMethods.PROFILES_CONFIGURE,
|
ProfilesConfigureParams(
|
||||||
mapOf(
|
name = defaultProfile.name,
|
||||||
"name" to defaultProfile.name,
|
uiMeta = uiMetaPayload.toJsonElement() as JsonObject,
|
||||||
"ui_meta" to uiMetaPayload,
|
),
|
||||||
),
|
)
|
||||||
).await()
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w("GroupChatViewModel", "updateGroupLimits failed: ${e.message}")
|
Log.w("GroupChatViewModel", "updateGroupLimits failed: ${e.message}")
|
||||||
}
|
}
|
||||||
@@ -636,14 +632,13 @@ class GroupChatViewModel(
|
|||||||
val newSnapshot = existingSnapshot.copy(version = 3, updatedAt = now, rooms = updatedRooms)
|
val newSnapshot = existingSnapshot.copy(version = 3, updatedAt = now, rooms = updatedRooms)
|
||||||
val uiMetaPayload = mapOf("hermes-bots-groups" to newSnapshot.toMap())
|
val uiMetaPayload = mapOf("hermes-bots-groups" to newSnapshot.toMap())
|
||||||
|
|
||||||
HermesWsClient
|
HermesWsClient.call(
|
||||||
.request(
|
RpcMethods.PROFILES_CONFIGURE,
|
||||||
WsMethods.PROFILES_CONFIGURE,
|
ProfilesConfigureParams(
|
||||||
mapOf(
|
name = defaultProfile.name,
|
||||||
"name" to defaultProfile.name,
|
uiMeta = uiMetaPayload.toJsonElement() as JsonObject,
|
||||||
"ui_meta" to uiMetaPayload,
|
),
|
||||||
),
|
)
|
||||||
).await()
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -1193,14 +1188,13 @@ class GroupChatViewModel(
|
|||||||
|
|
||||||
val uiMetaPayload = mapOf("hermes-bots-groups" to newSnapshot.toMap())
|
val uiMetaPayload = mapOf("hermes-bots-groups" to newSnapshot.toMap())
|
||||||
|
|
||||||
HermesWsClient
|
HermesWsClient.call(
|
||||||
.request(
|
RpcMethods.PROFILES_CONFIGURE,
|
||||||
WsMethods.PROFILES_CONFIGURE,
|
ProfilesConfigureParams(
|
||||||
mapOf(
|
name = defaultProfile.name,
|
||||||
"name" to defaultProfile.name,
|
uiMeta = uiMetaPayload.toJsonElement() as JsonObject,
|
||||||
"ui_meta" to uiMetaPayload,
|
),
|
||||||
),
|
)
|
||||||
).await()
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w("GroupChatViewModel", "persistSyncSnapshot failed: ${e.message}")
|
Log.w("GroupChatViewModel", "persistSyncSnapshot failed: ${e.message}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -318,14 +318,6 @@ class RawRpcParamsRatchetTest {
|
|||||||
listOf(
|
listOf(
|
||||||
"data/ws/HermesWsClient.kt::CLIENT_CAPABILITIES",
|
"data/ws/HermesWsClient.kt::CLIENT_CAPABILITIES",
|
||||||
"data/ws/ModelOptionsRepository.kt::MODEL_OPTIONS",
|
"data/ws/ModelOptionsRepository.kt::MODEL_OPTIONS",
|
||||||
"ui/bots/BotsViewModel.kt::PROFILES_CONFIGURE",
|
|
||||||
"ui/bots/BotsViewModel.kt::PROFILES_CONFIGURE",
|
|
||||||
"ui/bots/BotsViewModel.kt::PROFILES_CONFIGURE",
|
|
||||||
"ui/bots/BotsViewModel.kt::PROFILES_LIST",
|
|
||||||
"ui/bots/group/GroupChatViewModel.kt::PROFILES_CONFIGURE",
|
|
||||||
"ui/bots/group/GroupChatViewModel.kt::PROFILES_CONFIGURE",
|
|
||||||
"ui/bots/group/GroupChatViewModel.kt::PROFILES_CONFIGURE",
|
|
||||||
"ui/bots/group/GroupChatViewModel.kt::PROFILES_LIST",
|
|
||||||
"ui/chat/ChatModelSwitchDelegate.kt::CONFIG_SET",
|
"ui/chat/ChatModelSwitchDelegate.kt::CONFIG_SET",
|
||||||
"ui/chat/ChatModelSwitchDelegate.kt::CONFIG_SET",
|
"ui/chat/ChatModelSwitchDelegate.kt::CONFIG_SET",
|
||||||
"ui/chat/ChatModelSwitchDelegate.kt::CONFIG_SET",
|
"ui/chat/ChatModelSwitchDelegate.kt::CONFIG_SET",
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.m57.hermescontrol.data.ws.contract
|
||||||
|
|
||||||
|
import com.m57.hermescontrol.data.remote.OkHttpProvider
|
||||||
|
import kotlinx.serialization.json.buildJsonObject
|
||||||
|
import kotlinx.serialization.json.put
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class ProfilesTypesTest {
|
||||||
|
private fun encode(params: ProfilesConfigureParams) =
|
||||||
|
OkHttpProvider.json.encodeToJsonElement(ProfilesConfigureParams.serializer(), params)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun configureEncodesNameAndUiMetaOnly() {
|
||||||
|
val meta = buildJsonObject { put("hermes-bots-groups", buildJsonObject { put("version", 3) }) }
|
||||||
|
assertEquals(
|
||||||
|
buildJsonObject {
|
||||||
|
put("name", "default")
|
||||||
|
put("ui_meta", meta)
|
||||||
|
},
|
||||||
|
encode(ProfilesConfigureParams(name = "default", uiMeta = meta)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun configureIncludesSoulWhenPresent() {
|
||||||
|
val meta = buildJsonObject { put("hermes-bots", buildJsonObject { put("title", "Scout") }) }
|
||||||
|
assertEquals(
|
||||||
|
buildJsonObject {
|
||||||
|
put("name", "scout")
|
||||||
|
put("ui_meta", meta)
|
||||||
|
put("soul", "# Scout")
|
||||||
|
},
|
||||||
|
encode(ProfilesConfigureParams(name = "scout", uiMeta = meta, soul = "# Scout")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun listEncodesAsEmptyObject() {
|
||||||
|
assertEquals(
|
||||||
|
buildJsonObject { },
|
||||||
|
OkHttpProvider.json.encodeToJsonElement(ProfilesListParams.serializer(), ProfilesListParams),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun descriptorsAreRegisteredWithContractNames() {
|
||||||
|
assertTrue(RpcMethods.PROFILES_LIST in RpcMethods.all)
|
||||||
|
assertTrue(RpcMethods.PROFILES_CONFIGURE in RpcMethods.all)
|
||||||
|
assertEquals("profiles.list", RpcMethods.PROFILES_LIST.name)
|
||||||
|
assertEquals("profiles.configure", RpcMethods.PROFILES_CONFIGURE.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user