This commit is contained in:
11 files changed
+175
-73
No files matched your search
@@ -16,6 +16,9 @@ import org.junit.Assert.fail
|
||||
import org.junit.Test
|
||||
|
||||
class PluginManageRepositoryTest {
|
||||
private fun pluginRepo(handler: suspend (String, Map<String, Any>) -> Any?) =
|
||||
PluginManageRepository(fakeCaller(handler))
|
||||
|
||||
// CONTRACT: `listPlugins(profile)` calls WsMethods.PLUGINS_MANAGE with {"action": "list"} (and profile if set) and decodes plugins list.
|
||||
@Test
|
||||
fun `listPlugins without profile calls PLUGINS_MANAGE action list and decodes plugins list`() =
|
||||
@@ -44,7 +47,7 @@ class PluginManageRepositoryTest {
|
||||
)
|
||||
|
||||
val repository =
|
||||
PluginManageRepository { method, params ->
|
||||
pluginRepo { method, params ->
|
||||
capturedMethod = method
|
||||
capturedParams = params
|
||||
mockPayload
|
||||
@@ -80,7 +83,7 @@ class PluginManageRepositoryTest {
|
||||
)
|
||||
|
||||
val repository =
|
||||
PluginManageRepository { method, params ->
|
||||
pluginRepo { method, params ->
|
||||
capturedMethod = method
|
||||
capturedParams = params
|
||||
mockPayload
|
||||
@@ -98,19 +101,19 @@ class PluginManageRepositoryTest {
|
||||
fun `listPlugins returns empty list when plugins key is missing or response is not a JsonObject`() =
|
||||
runTest {
|
||||
val emptyObjRepo =
|
||||
PluginManageRepository { _, _ ->
|
||||
pluginRepo { _, _ ->
|
||||
OkHttpProvider.json.parseToJsonElement("{}")
|
||||
}
|
||||
assertTrue(emptyObjRepo.listPlugins().isEmpty())
|
||||
|
||||
val nonObjRepo =
|
||||
PluginManageRepository { _, _ ->
|
||||
pluginRepo { _, _ ->
|
||||
OkHttpProvider.json.parseToJsonElement("[]")
|
||||
}
|
||||
assertTrue(nonObjRepo.listPlugins().isEmpty())
|
||||
|
||||
val nullRepo =
|
||||
PluginManageRepository { _, _ ->
|
||||
pluginRepo { _, _ ->
|
||||
null
|
||||
}
|
||||
assertTrue(nullRepo.listPlugins().isEmpty())
|
||||
@@ -139,7 +142,7 @@ class PluginManageRepositoryTest {
|
||||
)
|
||||
|
||||
val repository =
|
||||
PluginManageRepository { method, params ->
|
||||
pluginRepo { method, params ->
|
||||
capturedMethod = method
|
||||
capturedParams = params
|
||||
mockResponse
|
||||
@@ -156,7 +159,7 @@ class PluginManageRepositoryTest {
|
||||
assertEquals(WsMethods.PLUGINS_MANAGE, capturedMethod)
|
||||
assertEquals("settings", capturedParams["action"])
|
||||
assertEquals("camofox", capturedParams["key"])
|
||||
assertEquals(JsonObject(valuesToSave), capturedParams["values"])
|
||||
assertEquals(mapOf("port" to 9222, "headless" to true), capturedParams["values"])
|
||||
assertFalse(capturedParams.containsKey("profile"))
|
||||
|
||||
assertTrue(result.ok)
|
||||
@@ -186,7 +189,7 @@ class PluginManageRepositoryTest {
|
||||
)
|
||||
|
||||
val repository =
|
||||
PluginManageRepository { method, params ->
|
||||
pluginRepo { method, params ->
|
||||
capturedMethod = method
|
||||
capturedParams = params
|
||||
mockResponse
|
||||
@@ -204,7 +207,7 @@ class PluginManageRepositoryTest {
|
||||
mapOf(
|
||||
"action" to "settings",
|
||||
"key" to "camofox",
|
||||
"values" to JsonObject(valuesToSave),
|
||||
"values" to mapOf("port" to 8080),
|
||||
"profile" to "staging",
|
||||
),
|
||||
capturedParams,
|
||||
@@ -222,7 +225,7 @@ class PluginManageRepositoryTest {
|
||||
fun `saveSettings throws SerializationException when response is malformed`() =
|
||||
runTest {
|
||||
val repository =
|
||||
PluginManageRepository { _, _ ->
|
||||
pluginRepo { _, _ ->
|
||||
OkHttpProvider.json.parseToJsonElement("{\"ok\": \"not-a-boolean\"}")
|
||||
}
|
||||
|
||||
|
||||
@@ -9,13 +9,16 @@ import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class PluginRemovalRepositoryTest {
|
||||
private fun removalRepo(handler: suspend (String, Map<String, Any>) -> Any?) =
|
||||
PluginRemovalRepository(fakeCaller(handler))
|
||||
|
||||
@Test
|
||||
fun `remove sends scoped gateway action and decodes success`() =
|
||||
runTest {
|
||||
var method = ""
|
||||
var params: Map<String, Any> = emptyMap()
|
||||
val repository =
|
||||
PluginRemovalRepository { requestedMethod, requestedParams ->
|
||||
removalRepo { requestedMethod, requestedParams ->
|
||||
method = requestedMethod
|
||||
params = requestedParams
|
||||
Json.parseToJsonElement("""{"ok":true,"name":"demo"}""")
|
||||
@@ -33,11 +36,11 @@ class PluginRemovalRepositoryTest {
|
||||
@Test
|
||||
fun `refusal is a typed failure and missing ok cannot masquerade as success`() =
|
||||
runTest {
|
||||
val refused = PluginRemovalRepository { _, _ -> mapOf("ok" to false, "error" to "bundled plugin") }
|
||||
val refused = removalRepo { _, _ -> mapOf("ok" to false, "error" to "bundled plugin") }
|
||||
assertFalse(refused.remove("builtin").ok)
|
||||
assertEquals("bundled plugin", refused.remove("builtin").error)
|
||||
|
||||
val malformed = PluginRemovalRepository { _, _ -> mapOf("name" to "demo") }
|
||||
val malformed = removalRepo { _, _ -> mapOf("name" to "demo") }
|
||||
try {
|
||||
malformed.remove("demo")
|
||||
throw AssertionError("Missing ok must fail decoding")
|
||||
|
||||
@@ -8,12 +8,17 @@ import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class ProjectsSourceTest {
|
||||
private fun projectsSource(
|
||||
connected: Boolean = true,
|
||||
handler: suspend (String, Map<String, Any>) -> Any?,
|
||||
) = HermesProjectsSource(isConnected = { connected }, caller = fakeCaller(handler))
|
||||
|
||||
@Test
|
||||
fun `decodes the untyped rpc map`() =
|
||||
runTest {
|
||||
var calledMethod: String? = null
|
||||
val source =
|
||||
HermesProjectsSource(isConnected = { true }) { method, _ ->
|
||||
projectsSource { method, _ ->
|
||||
calledMethod = method
|
||||
mapOf(
|
||||
"projects" to
|
||||
@@ -49,13 +54,10 @@ class ProjectsSourceTest {
|
||||
runTest {
|
||||
var calls = 0
|
||||
val source =
|
||||
HermesProjectsSource(
|
||||
rpcRequest = { _, _ ->
|
||||
calls++
|
||||
mapOf("projects" to emptyList<Any>())
|
||||
},
|
||||
isConnected = { false },
|
||||
)
|
||||
projectsSource(connected = false) { _, _ ->
|
||||
calls++
|
||||
mapOf("projects" to emptyList<Any>())
|
||||
}
|
||||
|
||||
assertNull(source.fetchProjects())
|
||||
assertEquals("a disconnected fetch must not queue an RPC", 0, calls)
|
||||
@@ -65,10 +67,10 @@ class ProjectsSourceTest {
|
||||
fun `rpc failure or unexpected payload yields null`() =
|
||||
runTest {
|
||||
assertNull(
|
||||
HermesProjectsSource(isConnected = { true }) { _, _ -> error("method not found") }.fetchProjects(),
|
||||
projectsSource { _, _ -> error("method not found") }.fetchProjects(),
|
||||
)
|
||||
assertNull(HermesProjectsSource(isConnected = { true }) { _, _ -> "nope" }.fetchProjects())
|
||||
assertNull(HermesProjectsSource(isConnected = { true }) { _, _ -> null }.fetchProjects())
|
||||
assertNull(projectsSource { _, _ -> "nope" }.fetchProjects())
|
||||
assertNull(projectsSource { _, _ -> null }.fetchProjects())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,9 +78,7 @@ class ProjectsSourceTest {
|
||||
runTest {
|
||||
val thrown =
|
||||
runCatching {
|
||||
HermesProjectsSource(
|
||||
isConnected = { true },
|
||||
) { _, _ -> throw CancellationException("gone") }.fetchProjects()
|
||||
projectsSource { _, _ -> throw CancellationException("gone") }.fetchProjects()
|
||||
}.exceptionOrNull()
|
||||
assertTrue(thrown is CancellationException)
|
||||
}
|
||||
|
||||
@@ -318,10 +318,6 @@ class RawRpcParamsRatchetTest {
|
||||
listOf(
|
||||
"data/ws/HermesWsClient.kt::CLIENT_CAPABILITIES",
|
||||
"data/ws/ModelOptionsRepository.kt::MODEL_OPTIONS",
|
||||
"data/ws/PluginManageRepository.kt::PLUGINS_MANAGE",
|
||||
"data/ws/PluginManageRepository.kt::PLUGINS_MANAGE",
|
||||
"data/ws/PluginRemovalRepository.kt::PLUGINS_MANAGE",
|
||||
"data/ws/ProjectsSource.kt::PROJECTS_LIST",
|
||||
"ui/bots/BotsViewModel.kt::PROFILES_CONFIGURE",
|
||||
"ui/bots/BotsViewModel.kt::PROFILES_CONFIGURE",
|
||||
"ui/bots/BotsViewModel.kt::PROFILES_CONFIGURE",
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.m57.hermescontrol.data.ws.contract
|
||||
|
||||
import com.m57.hermescontrol.data.remote.OkHttpProvider
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
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 PluginsProjectsTypesTest {
|
||||
private fun encode(params: PluginsManageParams) =
|
||||
OkHttpProvider.json.encodeToJsonElement(PluginsManageParams.serializer(), params)
|
||||
|
||||
@Test
|
||||
fun listEncodesOnlyAction() {
|
||||
assertEquals(buildJsonObject { put("action", "list") }, encode(PluginsManageParams(action = "list")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun removeEncodesActionAndName() {
|
||||
assertEquals(
|
||||
buildJsonObject {
|
||||
put("action", "remove")
|
||||
put("name", "demo")
|
||||
},
|
||||
encode(PluginsManageParams(action = "remove", name = "demo")),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun settingsEncodesKeyValuesAndExplicitProfile() {
|
||||
val values = buildJsonObject { put("port", JsonPrimitive(8080)) }
|
||||
assertEquals(
|
||||
buildJsonObject {
|
||||
put("action", "settings")
|
||||
put("profile", "staging")
|
||||
put("key", "camofox")
|
||||
put("values", values)
|
||||
},
|
||||
encode(PluginsManageParams(action = "settings", key = "camofox", values = values, profile = "staging")),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun projectsListEncodesAsEmptyObject() {
|
||||
assertEquals(
|
||||
buildJsonObject { },
|
||||
OkHttpProvider.json.encodeToJsonElement(ProjectsListParams.serializer(), ProjectsListParams),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun descriptorsAreRegisteredWithContractNames() {
|
||||
assertTrue(RpcMethods.PLUGINS_MANAGE in RpcMethods.all)
|
||||
assertTrue(RpcMethods.PROJECTS_LIST in RpcMethods.all)
|
||||
assertEquals("plugins.manage", RpcMethods.PLUGINS_MANAGE.name)
|
||||
assertEquals("projects.list", RpcMethods.PROJECTS_LIST.name)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user