diff --git a/android/app/src/main/kotlin/com/yubico/authenticator/device/Info.kt b/android/app/src/main/kotlin/com/yubico/authenticator/device/Info.kt index c1618571..e27e4add 100644 --- a/android/app/src/main/kotlin/com/yubico/authenticator/device/Info.kt +++ b/android/app/src/main/kotlin/com/yubico/authenticator/device/Info.kt @@ -18,10 +18,15 @@ package com.yubico.authenticator.device import com.yubico.yubikit.core.Transport import com.yubico.yubikit.management.DeviceInfo -import com.yubico.yubikit.management.FormFactor import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +private fun DeviceInfo.capabilitiesFor(transport: Transport) : Int? = + when { + hasTransport(transport) -> getSupportedCapabilities(transport) + else -> null + } + @Serializable data class Info( @SerialName("config") @@ -59,8 +64,8 @@ data class Info( isNfc = isNfc, usbPid = usbPid, supportedCapabilities = Capabilities( - nfc = deviceInfo.getSupportedCapabilities(Transport.NFC), - usb = deviceInfo.getSupportedCapabilities(Transport.USB) + nfc = deviceInfo.capabilitiesFor(Transport.NFC), + usb = deviceInfo.capabilitiesFor(Transport.USB), ) ) } diff --git a/android/app/src/test/java/com/yubico/authenticator/device/CapabilitiesTest.kt b/android/app/src/test/java/com/yubico/authenticator/device/CapabilitiesTest.kt index f6e340ef..78185f00 100644 --- a/android/app/src/test/java/com/yubico/authenticator/device/CapabilitiesTest.kt +++ b/android/app/src/test/java/com/yubico/authenticator/device/CapabilitiesTest.kt @@ -22,6 +22,7 @@ import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.decodeFromJsonElement import kotlinx.serialization.json.encodeToJsonElement +import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test @@ -46,8 +47,11 @@ class CapabilitiesTest { // test that keys are correct in serialized json assertTrue(serialize(Capabilities()).isEmpty()) assertTrue(serialize(Capabilities(0)).containsKey(TAG_USB)) + assertFalse(serialize(Capabilities(0)).containsKey(TAG_NFC)) assertTrue(serialize(Capabilities(usb = 0)).containsKey(TAG_USB)) + assertFalse(serialize(Capabilities(usb = 0)).containsKey(TAG_NFC)) assertTrue(serialize(Capabilities(nfc = 0)).containsKey(TAG_NFC)) + assertFalse(serialize(Capabilities(nfc = 0)).containsKey(TAG_USB)) assertTrue(with(serialize(Capabilities(0, 0))) { containsKey(TAG_NFC) and containsKey(TAG_USB) }) diff --git a/android/app/src/test/java/com/yubico/authenticator/device/ConfigTest.kt b/android/app/src/test/java/com/yubico/authenticator/device/ConfigTest.kt index 13f5b1f9..00dc112e 100644 --- a/android/app/src/test/java/com/yubico/authenticator/device/ConfigTest.kt +++ b/android/app/src/test/java/com/yubico/authenticator/device/ConfigTest.kt @@ -126,7 +126,7 @@ class ConfigTest { @Test fun `deviceFlags value`() { - val deviceConfig = Mockito.mock(DeviceConfig::class.java) + val deviceConfig = deviceConfigMock Mockito.`when`(deviceConfig.deviceFlags).thenReturn(null) assertEquals(Config(deviceConfig).deviceFlags, null) @@ -137,7 +137,7 @@ class ConfigTest { @Test fun `challengeResponseTimeout value`() { - val deviceConfig = Mockito.mock(DeviceConfig::class.java) + val deviceConfig = deviceConfigMock Mockito.`when`(deviceConfig.challengeResponseTimeout).thenReturn(null) assertEquals(Config(deviceConfig).challengeResponseTimeout, null) @@ -157,7 +157,7 @@ class ConfigTest { @Test fun `autoEjectTimeout value`() { - val deviceConfig = Mockito.mock(DeviceConfig::class.java) + val deviceConfig = deviceConfigMock Mockito.`when`(deviceConfig.autoEjectTimeout).thenReturn(null) assertEquals(Config(deviceConfig).autoEjectTimeout, null) diff --git a/android/app/src/test/java/com/yubico/authenticator/device/DeviceConfigMock.kt b/android/app/src/test/java/com/yubico/authenticator/device/DeviceConfigMock.kt new file mode 100644 index 00000000..2104148c --- /dev/null +++ b/android/app/src/test/java/com/yubico/authenticator/device/DeviceConfigMock.kt @@ -0,0 +1,14 @@ +package com.yubico.authenticator.device + +import com.yubico.yubikit.core.Transport +import com.yubico.yubikit.management.DeviceConfig +import org.mockito.Mockito + +val deviceConfigMock: DeviceConfig + get() = Mockito.mock(DeviceConfig::class.java).also { + Mockito.`when`(it.autoEjectTimeout).thenReturn(null) + Mockito.`when`(it.challengeResponseTimeout).thenReturn(null) + Mockito.`when`(it.deviceFlags).thenReturn(null) + Mockito.`when`(it.getEnabledCapabilities(Transport.NFC)).thenReturn(null) + Mockito.`when`(it.getEnabledCapabilities(Transport.USB)).thenReturn(null) + } \ No newline at end of file diff --git a/android/app/src/test/java/com/yubico/authenticator/device/DeviceInfoMock.kt b/android/app/src/test/java/com/yubico/authenticator/device/DeviceInfoMock.kt new file mode 100644 index 00000000..199a098a --- /dev/null +++ b/android/app/src/test/java/com/yubico/authenticator/device/DeviceInfoMock.kt @@ -0,0 +1,23 @@ +package com.yubico.authenticator.device + +import com.yubico.yubikit.core.Transport +import com.yubico.yubikit.core.Version +import com.yubico.yubikit.management.DeviceInfo +import com.yubico.yubikit.management.FormFactor +import org.mockito.Mockito + +val deviceInfoMock: DeviceInfo + get() = Mockito.mock(DeviceInfo::class.java).also { + val deviceConfig = deviceConfigMock + Mockito.`when`(it.config).thenReturn(deviceConfig) + Mockito.`when`(it.version).thenReturn(Version(0, 0, 0)) + Mockito.`when`(it.serialNumber).thenReturn(0) + Mockito.`when`(it.formFactor).thenReturn(FormFactor.USB_A_NANO) + Mockito.`when`(it.isLocked).thenReturn(false) + Mockito.`when`(it.isSky).thenReturn(false) + Mockito.`when`(it.isFips).thenReturn(false) + Mockito.`when`(it.hasTransport(Transport.NFC)).thenReturn(false) + Mockito.`when`(it.hasTransport(Transport.USB)).thenReturn(false) + Mockito.`when`(it.getSupportedCapabilities(Transport.USB)).thenReturn(0) + Mockito.`when`(it.getSupportedCapabilities(Transport.NFC)).thenReturn(0) + } \ No newline at end of file diff --git a/android/app/src/test/java/com/yubico/authenticator/device/InfoTest.kt b/android/app/src/test/java/com/yubico/authenticator/device/InfoTest.kt index 0b725d94..2adfb5a7 100644 --- a/android/app/src/test/java/com/yubico/authenticator/device/InfoTest.kt +++ b/android/app/src/test/java/com/yubico/authenticator/device/InfoTest.kt @@ -18,7 +18,6 @@ package com.yubico.authenticator.device import com.yubico.yubikit.core.Transport import com.yubico.yubikit.core.Version -import com.yubico.yubikit.management.DeviceConfig import com.yubico.yubikit.management.DeviceInfo import com.yubico.yubikit.management.FormFactor import org.junit.Assert.assertEquals @@ -26,42 +25,78 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Test -import org.mockito.Mockito.mock import org.mockito.Mockito.`when` class InfoTest { - @Test fun construction() { - val deviceInfo = mock(DeviceInfo::class.java) - val deviceConfig = mock(DeviceConfig::class.java) + val deviceInfo = deviceInfoMock - `when`(deviceInfo.config).thenReturn(deviceConfig) `when`(deviceInfo.serialNumber).thenReturn(1234) `when`(deviceInfo.version).thenReturn(Version(1, 2, 3)) - `when`(deviceInfo.formFactor).thenReturn(FormFactor.USB_A_NANO) + `when`(deviceInfo.formFactor).thenReturn(FormFactor.USB_C_KEYCHAIN) `when`(deviceInfo.isLocked).thenReturn(true) `when`(deviceInfo.isSky).thenReturn(false) `when`(deviceInfo.isFips).thenReturn(true) + `when`(deviceInfo.hasTransport(Transport.NFC)).thenReturn(true) + `when`(deviceInfo.hasTransport(Transport.USB)).thenReturn(true) `when`(deviceInfo.getSupportedCapabilities(Transport.USB)).thenReturn(456) `when`(deviceInfo.getSupportedCapabilities(Transport.NFC)).thenReturn(789) - val info = - Info(name = "Tested Device", isNfc = true, usbPid = null, deviceInfo = deviceInfo) + val info = Info(name = "TestD", isNfc = true, usbPid = null, deviceInfo = deviceInfo) - assertEquals(Config(deviceConfig), info.config) + assertEquals(Config(deviceConfigMock), info.config) assertEquals(1234, info.serialNumber) assertEquals(Version(1, 2, 3).major, info.version.major) assertEquals(Version(1, 2, 3).minor, info.version.minor) assertEquals(Version(1, 2, 3).micro, info.version.micro) - assertEquals(FormFactor.USB_A_NANO.value, info.formFactor) + assertEquals(FormFactor.USB_C_KEYCHAIN.value, info.formFactor) assertTrue(info.isLocked) assertFalse(info.isSky) assertTrue(info.isFips) assertEquals(456, info.supportedCapabilities.usb) assertEquals(789, info.supportedCapabilities.nfc) - assertEquals("Tested Device", info.name) + assertEquals("TestD", info.name) assertTrue(info.isNfc) assertNull(info.usbPid) } + + private fun DeviceInfo.withTransport(transport: Transport, capabilities : Int = 0) : DeviceInfo { + `when`(hasTransport(transport)).thenReturn(true) + `when`(getSupportedCapabilities(transport)).thenReturn(capabilities) + return this + } + + private fun DeviceInfo.withoutTransport(transport: Transport) : DeviceInfo { + `when`(hasTransport(transport)).thenReturn(false) + return this + } + + @Test + fun withNfcCapabilities() { + val deviceInfo = deviceInfoMock.withTransport(Transport.NFC, 123) + val info = Info(name = "TestD", isNfc = false, usbPid = null, deviceInfo = deviceInfo) + assertEquals(123, info.supportedCapabilities.nfc) + } + + @Test + fun withoutNfcCapabilities() { + val deviceInfo = deviceInfoMock.withoutTransport(Transport.NFC) + val info = Info(name = "TestD", isNfc = false, usbPid = null, deviceInfo = deviceInfo) + assertNull(info.supportedCapabilities.nfc) + } + + @Test + fun withUsbCapabilities() { + val deviceInfo = deviceInfoMock.withTransport(Transport.USB, 454) + val info = Info(name = "TestD", isNfc = false, usbPid = null, deviceInfo = deviceInfo) + assertEquals(454, info.supportedCapabilities.usb) + } + + @Test + fun withoutUsbCapabilities() { + val deviceInfo = deviceInfoMock.withoutTransport(Transport.USB) + val info = Info(name = "TestD", isNfc = false, usbPid = null, deviceInfo = deviceInfo) + assertNull(info.supportedCapabilities.usb) + } }