feat: add ABSDK 0630 bridge #3

Merged
KremeCN merged 3 commits from feat/absdk-bridge into main 2026-08-23 07:19:05 +08:00
2 changed files with 36 additions and 3 deletions
Showing only changes of commit 13fd18a9f3 - Show all commits
@@ -249,12 +249,19 @@ class AbsdkBridge internal constructor(
codes: List<InfraredCode>,
response: AbsdkResponse?,
): DomainResult<List<InfraredCodeDownloadResult>> {
val results = response?.data?.get(IR_RESULTS_KEY) as? List<*>
val validResponse = response?.takeIf { it.code in IR_DOWNLOAD_RESULT_CODES }
?: return DomainResult.Failure(AbsdkErrorMapper.fromResponse(response))
val results = validResponse.data[IR_RESULTS_KEY] as? List<*>
?: return DomainResult.Failure(
DomainError.OperationFailed(
externalCode = validResponse.code,
detail = "Missing infrared download results",
),
)
if (results.size != codes.size || results.any { it !is AbsdkIrResult }) {
return DomainResult.Failure(
DomainError.OperationFailed(
externalCode = response.code,
externalCode = validResponse.code,
detail = "Malformed infrared download result",
),
)
@@ -267,7 +274,7 @@ class AbsdkBridge internal constructor(
) {
return DomainResult.Failure(
DomainError.OperationFailed(
externalCode = response.code,
externalCode = validResponse.code,
detail = "Infrared download results do not match their requests",
),
)
@@ -318,6 +325,8 @@ class AbsdkBridge internal constructor(
}
private const val SUCCESS_CODE = "00000"
private const val PARTIAL_IR_DOWNLOAD_CODE = "20204"
private val IR_DOWNLOAD_RESULT_CODES = setOf(SUCCESS_CODE, PARTIAL_IR_DOWNLOAD_CODE)
private sealed interface ClientCall {
data class Completed(val response: AbsdkResponse?) : ClientCall
@@ -11,6 +11,7 @@ import com.flagship.abox.manager.domain.SocketPowerState
import com.flagship.abox.manager.domain.Username
import java.io.IOException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
@@ -114,6 +115,29 @@ class AbsdkDeviceBridgeTest {
)
}
@Test
fun infraredTokenErrorCannotBeMaskedByValidResults() = runTest {
val code = InfraredCode(DeviceName("ir-1"), "power", "code-1")
val client = ScriptedAbsdkClient().apply {
downloadResponse = AbsdkResponse(
code = "10002",
message = "expired",
data = mapOf(
"ret" to listOf(AbsdkIrResult("ir-1", "power", "1")),
),
)
}
val bridge = authenticatedBridge(client)
val result = bridge.downloadCodes(profile, listOf(code))
assertTrue((result as DomainResult.Failure).error is DomainError.TokenInvalid)
assertEquals(null, bridge.observeSession(profile).first())
val second = bridge.sendKey(profile, DeviceName("ir-1"), "power")
assertTrue((second as DomainResult.Failure).error is DomainError.TokenInvalid)
assertEquals(listOf("login:demo", "ir-download"), client.calls)
}
@Test
fun infraredMalformedResultsFailTheBatch() = runTest {
val code = InfraredCode(DeviceName("ir-1"), "power", "code-1")