fix: reject invalid infrared batch responses
This commit is contained in:
@@ -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
|
||||
|
||||
+24
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user