feat: support 1-100 numeric infrared key slots and gateway login entry

This commit is contained in:
2026-08-25 11:40:45 +08:00
committed by KremeCN
parent aec43df775
commit 78dac5519a
10 changed files with 88 additions and 21 deletions
@@ -21,6 +21,7 @@ class InfraredKeyFactory(
profileId: ProviderProfileId,
deviceName: DeviceName,
displayName: String,
sdkKey: String? = null,
): DomainResult<SavedInfraredKey> {
val normalizedName = displayName.trim()
if (
@@ -39,6 +40,20 @@ class InfraredKeyFactory(
?: return DomainResult.Failure(
DomainError.InvalidRequest(detail = "Infrared key id is invalid"),
)
val finalSdkKey = if (sdkKey != null) {
val trimmed = sdkKey.trim()
val intVal = trimmed.toIntOrNull()
if (intVal == null || intVal !in 1..100) {
return DomainResult.Failure(
DomainError.InvalidRequest(detail = "Infrared key slot must be an integer between 1 and 100"),
)
}
intVal.toString()
} else {
"app_ir_$canonicalId"
}
val now = clock.now()
return DomainResult.Success(
SavedInfraredKey(
@@ -46,7 +61,7 @@ class InfraredKeyFactory(
profileId = profileId,
deviceName = deviceName,
displayName = normalizedName,
sdkKey = "app_ir_$canonicalId",
sdkKey = finalSdkKey,
status = InfraredKeyStatus.LEARNING,
lastErrorCode = null,
lastErrorDetail = null,
@@ -68,4 +83,4 @@ class InfraredKeyFactory(
"^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$",
)
}
}
}
@@ -16,8 +16,9 @@ class LearnInfraredKey(
profileId: ProviderProfileId,
deviceName: DeviceName,
displayName: String,
sdkKey: String? = null,
): DomainResult<InfraredKeyId> {
val key = when (val result = factory.create(profileId, deviceName, displayName)) {
val key = when (val result = factory.create(profileId, deviceName, displayName, sdkKey)) {
is DomainResult.Success -> result.value
is DomainResult.Failure -> return result
}
@@ -32,6 +32,25 @@ class InfraredKeyFactoryTest {
assertEquals(result.value.createdAtEpochMillis, result.value.updatedAtEpochMillis)
}
@Test
fun createsLearningKeyWithCustomNumericSlot() {
val result = factory.create(
ProviderProfileId("abox"),
DeviceName("ir-1"),
"空调开",
sdkKey = "1",
) as DomainResult.Success
assertEquals("1", result.value.sdkKey)
}
@Test
fun rejectsInvalidNumericSlots() {
assertTrue(factory.create(ProviderProfileId("abox"), DeviceName("ir-1"), "Power", sdkKey = "0") is DomainResult.Failure)
assertTrue(factory.create(ProviderProfileId("abox"), DeviceName("ir-1"), "Power", sdkKey = "101") is DomainResult.Failure)
assertTrue(factory.create(ProviderProfileId("abox"), DeviceName("ir-1"), "Power", sdkKey = "abc") is DomainResult.Failure)
}
@Test
fun rejectsBlankDeviceOrDisplayName() {
assertTrue(factory.create(ProviderProfileId("abox"), DeviceName(""), "Power") is DomainResult.Failure)
@@ -67,4 +86,4 @@ class InfraredKeyFactoryTest {
DeviceName("ir-1"),
"Power",
)
}
}