From 8f415aa3fd138ee5cfacf57072a754a7e73efceb Mon Sep 17 00:00:00 2001 From: Giannis Stamatopoulos Date: Fri, 2 Feb 2024 14:29:45 +0200 Subject: [PATCH] Adds unit tests for DashBoard Interactor. --- .../ec/commonfeature/util/DocumentHelper.kt | 13 +- .../ec/commonfeature/util/TestsConstants.kt | 63 +++ .../interactor/TestDashboardInteractor.kt | 378 +++++++++++++++ .../eu/europa/ec/testfeature/Constants.kt | 447 +++++++++++++++++- .../walletcore/WalletCoreHelper.kt | 33 ++ .../europa/ec/testlogic/base/ContextHelper.kt | 18 +- 6 files changed, 934 insertions(+), 18 deletions(-) create mode 100644 common-feature/src/main/java/eu/europa/ec/commonfeature/util/TestsConstants.kt create mode 100644 dashboard-feature/src/test/java/eu/europa/ec/dashboardfeature/interactor/TestDashboardInteractor.kt create mode 100644 test-feature/src/main/java/eu/europa/ec/testfeature/walletcore/WalletCoreHelper.kt rename dashboard-feature/src/test/java/eu/europa/ec/dashboardfeature/ExampleUnitTest.kt => test-logic/src/main/java/eu/europa/ec/testlogic/base/ContextHelper.kt (65%) diff --git a/common-feature/src/main/java/eu/europa/ec/commonfeature/util/DocumentHelper.kt b/common-feature/src/main/java/eu/europa/ec/commonfeature/util/DocumentHelper.kt index fef3215a..77798295 100644 --- a/common-feature/src/main/java/eu/europa/ec/commonfeature/util/DocumentHelper.kt +++ b/common-feature/src/main/java/eu/europa/ec/commonfeature/util/DocumentHelper.kt @@ -25,16 +25,21 @@ import eu.europa.ec.eudi.wallet.document.nameSpacedDataJSONObject import eu.europa.ec.resourceslogic.R import eu.europa.ec.resourceslogic.provider.ResourceProvider import org.json.JSONArray +import org.json.JSONException import org.json.JSONObject fun extractValueFromDocumentOrEmpty( document: Document, key: String ): String { - val docType = document.docType.toDocumentTypeUi() - val documentJsonObject = - document.nameSpacedDataJSONObject.get(docType.codeName) as? JSONObject - return documentJsonObject?.getStringFromJsonOrEmpty(key) ?: "" + return try { + val docType = document.docType.toDocumentTypeUi() + val documentJsonObject = + document.nameSpacedDataJSONObject.get(docType.codeName) as? JSONObject + return documentJsonObject?.getStringFromJsonOrEmpty(key) ?: "" + } catch (e: JSONException) { + "" + } } fun extractFullNameFromDocumentOrEmpty(document: Document): String { diff --git a/common-feature/src/main/java/eu/europa/ec/commonfeature/util/TestsConstants.kt b/common-feature/src/main/java/eu/europa/ec/commonfeature/util/TestsConstants.kt new file mode 100644 index 00000000..4334710e --- /dev/null +++ b/common-feature/src/main/java/eu/europa/ec/commonfeature/util/TestsConstants.kt @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 European Commission + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work + * except in compliance with the Licence. + * + * You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/software/page/eupl + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the Licence for the specific language + * governing permissions and limitations under the Licence. + */ + +package eu.europa.ec.commonfeature.util + +import androidx.annotation.VisibleForTesting +import eu.europa.ec.commonfeature.model.DocumentTypeUi +import eu.europa.ec.commonfeature.model.DocumentUi + +@VisibleForTesting(otherwise = VisibleForTesting.NONE) +object TestsConstants { + const val mockedId1 = "000001" + const val mockedId2 = "000002" + const val mockedUserFirstName = "JAN" + const val mockedUserBase64Portrait = "SE" + const val mockedDocUiNamePid = "National ID" + const val mockedDocUiNameMdl = "Driving License" + const val mockedNoUserFistNameFound = "" + const val mockedNoUserBase64PortraitFound = "" + const val mockedNoExpirationDateFound = "-" + const val mockedFormattedExpirationDate = "30 Mar 2050" + + val mockedFullPidUi = DocumentUi( + documentId = mockedId1, + documentName = mockedDocUiNamePid, + documentType = DocumentTypeUi.PID, + documentExpirationDateFormatted = mockedFormattedExpirationDate, + documentImage = "", + documentDetails = emptyList(), + ) + + val mockedFullMdlUi = DocumentUi( + documentId = mockedId2, + documentName = mockedDocUiNameMdl, + documentType = DocumentTypeUi.MDL, + documentExpirationDateFormatted = mockedFormattedExpirationDate, + documentImage = "", + documentDetails = emptyList(), + ) + + val mockedMdlUiWithNoUserNameAndNoUserImage: DocumentUi = mockedFullMdlUi + + val mockedMdlUiWithNoExpirationDate: DocumentUi = mockedFullMdlUi.copy( + documentExpirationDateFormatted = mockedNoExpirationDateFound + ) + + val mockedFullDocumentsUi: List = listOf( + mockedFullPidUi, mockedFullMdlUi + ) +} \ No newline at end of file diff --git a/dashboard-feature/src/test/java/eu/europa/ec/dashboardfeature/interactor/TestDashboardInteractor.kt b/dashboard-feature/src/test/java/eu/europa/ec/dashboardfeature/interactor/TestDashboardInteractor.kt new file mode 100644 index 00000000..24be3670 --- /dev/null +++ b/dashboard-feature/src/test/java/eu/europa/ec/dashboardfeature/interactor/TestDashboardInteractor.kt @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2023 European Commission + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work + * except in compliance with the Licence. + * + * You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/software/page/eupl + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the Licence for the specific language + * governing permissions and limitations under the Licence. + */ + +package eu.europa.ec.dashboardfeature.interactor + +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothManager +import android.content.Context +import eu.europa.ec.businesslogic.config.ConfigLogic +import eu.europa.ec.businesslogic.config.WalletCoreConfig +import eu.europa.ec.businesslogic.controller.walletcore.WalletCoreDocumentsController +import eu.europa.ec.commonfeature.util.TestsConstants.mockedDocUiNameMdl +import eu.europa.ec.commonfeature.util.TestsConstants.mockedDocUiNamePid +import eu.europa.ec.commonfeature.util.TestsConstants.mockedFullDocumentsUi +import eu.europa.ec.commonfeature.util.TestsConstants.mockedMdlUiWithNoExpirationDate +import eu.europa.ec.commonfeature.util.TestsConstants.mockedMdlUiWithNoUserNameAndNoUserImage +import eu.europa.ec.commonfeature.util.TestsConstants.mockedNoExpirationDateFound +import eu.europa.ec.commonfeature.util.TestsConstants.mockedNoUserBase64PortraitFound +import eu.europa.ec.commonfeature.util.TestsConstants.mockedNoUserFistNameFound +import eu.europa.ec.commonfeature.util.TestsConstants.mockedUserBase64Portrait +import eu.europa.ec.commonfeature.util.TestsConstants.mockedUserFirstName +import eu.europa.ec.eudi.wallet.EudiWalletConfig +import eu.europa.ec.resourceslogic.R +import eu.europa.ec.resourceslogic.provider.ResourceProvider +import eu.europa.ec.testfeature.mockedExceptionWithMessage +import eu.europa.ec.testfeature.mockedExceptionWithNoMessage +import eu.europa.ec.testfeature.mockedFullDocuments +import eu.europa.ec.testfeature.mockedGenericErrorMessage +import eu.europa.ec.testfeature.mockedMdlWithNoExpirationDate +import eu.europa.ec.testfeature.mockedMdlWithNoUserNameAndNoUserImage +import eu.europa.ec.testfeature.walletcore.getMockedEudiWalletConfig +import eu.europa.ec.testlogic.base.TestApplication +import eu.europa.ec.testlogic.base.getMockedContext +import eu.europa.ec.testlogic.extension.runFlowTest +import eu.europa.ec.testlogic.extension.runTest +import eu.europa.ec.testlogic.rule.CoroutineTestRule +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.times +import org.mockito.kotlin.verify +import org.robolectric.RobolectricTestRunner +import org.robolectric.Shadows +import org.robolectric.annotation.Config +import org.robolectric.shadows.ShadowBluetoothAdapter +import kotlin.test.assertEquals + +@RunWith(RobolectricTestRunner::class) +@Config(application = TestApplication::class) +class TestDashboardInteractor { + + @get:Rule + val coroutineRule = CoroutineTestRule() + + @Mock + private lateinit var resourceProvider: ResourceProvider + + @Mock + private lateinit var walletCoreDocumentsController: WalletCoreDocumentsController + + @Mock + private lateinit var walletCoreConfig: WalletCoreConfig + + @Mock + private lateinit var configLogic: ConfigLogic + + private lateinit var bluetoothManager: BluetoothManager + private lateinit var shadowBluetoothAdapter: ShadowBluetoothAdapter + + private lateinit var interactor: DashboardInteractor + + private lateinit var closeable: AutoCloseable + + @Before + fun before() { + closeable = MockitoAnnotations.openMocks(this) + + interactor = DashboardInteractorImpl( + resourceProvider = resourceProvider, + walletCoreDocumentsController = walletCoreDocumentsController, + walletCoreConfig = walletCoreConfig, + configLogic = configLogic + ) + + `when`(resourceProvider.genericErrorMessage()).thenReturn(mockedGenericErrorMessage) + `when`(resourceProvider.provideContext()).thenReturn(getMockedContext()) + + bluetoothManager = + getMockedContext().getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager + shadowBluetoothAdapter = Shadows.shadowOf(bluetoothManager.adapter) + } + + @After + fun after() { + closeable.close() + } + + //region isBleAvailable + + // Case 1: + // BluetoothAdapter.getDefaultAdapter()?.isEnabled returns true. + @Test + fun `Given Case 1, When isBleAvailable is called, Then it returns true`() { + // Given + val expectedBluetoothAdapterEnabled = true + mockBluetoothAdapterEnabledState(enabled = expectedBluetoothAdapterEnabled) + + // When + val actual = interactor.isBleAvailable() + + // Then + assertEquals(expectedBluetoothAdapterEnabled, actual) + } + + // Case 2: + // BluetoothAdapter.getDefaultAdapter()?.isEnabled returns false. + @Test + fun `Given Case 2, When isBleAvailable is called, Then it returns false`() { + // Given + val expectedBluetoothAdapterEnabled = false + mockBluetoothAdapterEnabledState(enabled = expectedBluetoothAdapterEnabled) + + // When + val actual = interactor.isBleAvailable() + + // Then + assertEquals(expectedBluetoothAdapterEnabled, actual) + } + //endregion + + //region isBleCentralClientModeEnabled + + // Case 1: + // Configuration of Wallet Core has BLE_CLIENT_CENTRAL_MODE for its bleTransferMode. + @Test + fun `Given Case 1, When isBleCentralClientModeEnabled is called, Then it returns true`() { + // Given + val expectedBleCentralClientModeEnabled = true + + val mockedConfig = getMockedEudiWalletConfig { + bleTransferMode(EudiWalletConfig.BLE_CLIENT_CENTRAL_MODE) + } + + `when`(walletCoreConfig.config).thenReturn(mockedConfig) + + // When + val actual = interactor.isBleCentralClientModeEnabled() + + // Then + assertEquals(expectedBleCentralClientModeEnabled, actual) + } + + // Case 2: + // Configuration of Wallet Core has BLE_SERVER_PERIPHERAL_MODE for its bleTransferMode. + @Test + fun `Given Case 2, When isBleCentralClientModeEnabled is called, Then it returns false`() { + // Given + val expectedBleCentralClientModeEnabled = false + + val mockedConfig = getMockedEudiWalletConfig { + bleTransferMode(EudiWalletConfig.BLE_SERVER_PERIPHERAL_MODE) + } + + `when`(walletCoreConfig.config).thenReturn(mockedConfig) + + // When + val actual = interactor.isBleCentralClientModeEnabled() + + // Then + assertEquals(expectedBleCentralClientModeEnabled, actual) + } + //endregion + + //region getDocuments + + // Case 1: + // walletCoreDocumentsController.getAllDocuments() returns + // a full PID and a full mDL. + + // Case 1 Expected Result: + // DashboardInteractorPartialState.Success state, with: + // 1. the list of Documents transformed to DocumentUi objects, + // 2. an actual user name, and + // 3. an actual (base64 encoded) user image. + @Test + fun `Given Case 1, When getDocuments is called, Then Case 1 Expected Result is returned`() { + coroutineRule.runTest { + // Given + mockGetStringForDocumentsCall() + + `when`(walletCoreDocumentsController.getAllDocuments()) + .thenReturn(mockedFullDocuments) + + // When + interactor.getDocuments().runFlowTest { + // Then + assertEquals( + DashboardInteractorPartialState.Success( + documents = mockedFullDocumentsUi, + userFirstName = mockedUserFirstName, + userBase64Portrait = mockedUserBase64Portrait + ), + awaitItem() + ) + } + } + } + + // Case 2: + // walletCoreDocumentsController.getAllDocuments() returns + // an mDL with no user name, and + // no user image. + + // Case 2 Expected Result: + // DashboardInteractorPartialState.Success state, with: + // 1. the Document transformed to DocumentUi object, + // 2. empty string for the user name, and + // 3. empty string for the user image. + @Test + fun `Given Case 2, When getDocuments is called, Then Case 2 Expected Result is returned`() { + coroutineRule.runTest { + // Given + mockGetStringForDocumentsCall() + + `when`(walletCoreDocumentsController.getAllDocuments()) + .thenReturn(listOf(mockedMdlWithNoUserNameAndNoUserImage)) + + // When + interactor.getDocuments().runFlowTest { + // Then + assertEquals( + DashboardInteractorPartialState.Success( + documents = listOf(mockedMdlUiWithNoUserNameAndNoUserImage), + userFirstName = mockedNoUserFistNameFound, + userBase64Portrait = mockedNoUserBase64PortraitFound + ), + awaitItem() + ) + } + } + } + + // Case 3: + // walletCoreDocumentsController.getAllDocuments() returns + // an mDL with no expiration date. + + // Case 3 Expected Result: + // DashboardInteractorPartialState.Success state, with: + // 1. the Document transformed to DocumentUi object, + // 2. an actual user name, and + // 3. an actual (base64 encoded) user image. + @Test + fun `Given Case 3, When getDocuments is called, Then Case 3 Expected Result is returned`() { + coroutineRule.runTest { + // Given + mockGetStringForDocumentsCall() + + `when`(walletCoreDocumentsController.getAllDocuments()) + .thenReturn(listOf(mockedMdlWithNoExpirationDate)) + + // When + interactor.getDocuments().runFlowTest { + // Then + assertEquals( + DashboardInteractorPartialState.Success( + documents = listOf(mockedMdlUiWithNoExpirationDate), + userFirstName = mockedUserFirstName, + userBase64Portrait = mockedUserBase64Portrait + ), + awaitItem() + ) + } + } + } + + // Case 4: + // walletCoreDocumentsController.getAllDocuments() throws an exception with a message. + @Test + fun `Given Case 4, When getDocuments is called, Then it returns Failed with exception's localized message`() { + coroutineRule.runTest { + // Given + `when`(walletCoreDocumentsController.getAllDocuments()) + .thenThrow(mockedExceptionWithMessage) + + // When + interactor.getDocuments().runFlowTest { + // Then + assertEquals( + DashboardInteractorPartialState.Failure( + error = mockedExceptionWithMessage.localizedMessage!! + ), + awaitItem() + ) + } + } + } + + // Case 5: + // walletCoreDocumentsController.getAllDocuments() throws an exception with no message. + @Test + fun `Given Case 5, When getDocuments is called, Then it returns Failed with the generic error message`() { + coroutineRule.runTest { + // Given + `when`(walletCoreDocumentsController.getAllDocuments()) + .thenThrow(mockedExceptionWithNoMessage) + + // When + interactor.getDocuments().runFlowTest { + // Then + assertEquals( + DashboardInteractorPartialState.Failure( + error = mockedGenericErrorMessage + ), + awaitItem() + ) + } + } + } + //endregion + + //region getAppVersion + @Test + fun `Given an App Version, When getAppVersion is called, Then it returns the Apps Version`() { + // Given + val expectedAppVersion = "2024.01.1" + `when`(configLogic.appVersion) + .thenReturn(expectedAppVersion) + + // When + val actualAppVersion = interactor.getAppVersion() + + // Then + assertEquals(expectedAppVersion, actualAppVersion) + verify(configLogic, times(1)) + .appVersion + } + //endregion + + //region Mock Calls of the Dependencies + private fun mockBluetoothAdapterEnabledState(enabled: Boolean) { + val newBluetoothAdapterState = if (enabled) { + BluetoothAdapter.STATE_ON + } else { + BluetoothAdapter.STATE_OFF + } + shadowBluetoothAdapter.setState(newBluetoothAdapterState) + } + + private fun mockGetStringForDocumentsCall() { + `when`(resourceProvider.getString(R.string.pid)) + .thenReturn(mockedDocUiNamePid) + + `when`(resourceProvider.getString(R.string.mdl)) + .thenReturn(mockedDocUiNameMdl) + + `when`(resourceProvider.getString(R.string.dashboard_document_no_expiration_found)) + .thenReturn(mockedNoExpirationDateFound) + } + //endregion +} \ No newline at end of file diff --git a/test-feature/src/main/java/eu/europa/ec/testfeature/Constants.kt b/test-feature/src/main/java/eu/europa/ec/testfeature/Constants.kt index 85acfea0..c426da12 100644 --- a/test-feature/src/main/java/eu/europa/ec/testfeature/Constants.kt +++ b/test-feature/src/main/java/eu/europa/ec/testfeature/Constants.kt @@ -16,8 +16,453 @@ package eu.europa.ec.testfeature +import eu.europa.ec.eudi.wallet.document.Document +import java.time.Instant + const val mockedGenericErrorMessage = "resourceProvider's genericErrorMessage" const val plainFailureMessage = "failure message" val mockedExceptionWithMessage = RuntimeException("Exception to test interactor.") -val mockedExceptionWithNoMessage = RuntimeException() \ No newline at end of file +val mockedExceptionWithNoMessage = RuntimeException() + +const val mockedDocumentCreationDate = "2024-01-25T14:25:00.073Z" +const val mockedId1 = "000001" +const val mockedId2 = "000002" +val mockedPidFields: Map = mapOf( + "family_name" to byteArrayOf(105, 65, 78, 68, 69, 82, 83, 83, 79, 78), + "given_name" to byteArrayOf(99, 74, 65, 78), + "birth_date" to byteArrayOf(-39, 3, -20, 106, 49, 57, 56, 53, 45, 48, 51, 45, 51, 48), + "age_over_18" to byteArrayOf(-11), + "age_over_15" to byteArrayOf(-11), + "age_over_21" to byteArrayOf(-11), + "age_over_60" to byteArrayOf(-12), + "age_over_65" to byteArrayOf(-12), + "age_over_68" to byteArrayOf(-12), + "age_in_years" to byteArrayOf(24, 38), + "age_birth_year" to byteArrayOf(25, 7, -63), + "family_name_birth" to byteArrayOf(105, 65, 78, 68, 69, 82, 83, 83, 79, 78), + "given_name_birth" to byteArrayOf(99, 74, 65, 78), + "birth_place" to byteArrayOf(102, 83, 87, 69, 68, 69, 78), + "birth_country" to byteArrayOf(98, 83, 69), + "birth_state" to byteArrayOf(98, 83, 69), + "birth_city" to byteArrayOf(107, 75, 65, 84, 82, 73, 78, 69, 72, 79, 76, 77), + "resident_address" to byteArrayOf( + 111, + 70, + 79, + 82, + 84, + 85, + 78, + 65, + 71, + 65, + 84, + 65, + 78, + 32, + 49, + 53 + ), + "resident_country" to byteArrayOf(98, 83, 69), + "resident_state" to byteArrayOf(98, 83, 69), + "resident_city" to byteArrayOf(107, 75, 65, 84, 82, 73, 78, 69, 72, 79, 76, 77), + "resident_postal_code" to byteArrayOf(101, 54, 52, 49, 51, 51), + "resident_street" to byteArrayOf(108, 70, 79, 82, 84, 85, 78, 65, 71, 65, 84, 65, 78), + "resident_house_number" to byteArrayOf(98, 49, 50), + "gender" to byteArrayOf(1), + "nationality" to byteArrayOf(98, 83, 69), + "issuance_date" to byteArrayOf( + -64, + 116, + 50, + 48, + 48, + 57, + 45, + 48, + 49, + 45, + 48, + 49, + 84, + 48, + 48, + 58, + 48, + 48, + 58, + 48, + 48, + 90 + ), + "expiry_date" to byteArrayOf( + -64, + 116, + 50, + 48, + 53, + 48, + 45, + 48, + 51, + 45, + 51, + 48, + 84, + 48, + 48, + 58, + 48, + 48, + 58, + 48, + 48, + 90 + ), + "issuing_authority" to byteArrayOf(99, 85, 84, 79), + "document_number" to byteArrayOf(105, 49, 49, 49, 49, 49, 49, 49, 49, 52), + "administrative_number" to byteArrayOf(106, 57, 48, 49, 48, 49, 54, 55, 52, 54, 52), + "issuing_country" to byteArrayOf(98, 83, 69), + "issuing_jurisdiction" to byteArrayOf(100, 83, 69, 45, 73), +) +val mockedMdlFields: Map = mapOf( + "family_name" to byteArrayOf(105, 65, 78, 68, 69, 82, 83, 83, 79, 78), + "given_name" to byteArrayOf(99, 74, 65, 78), + "birth_date" to byteArrayOf(-39, 3, -20, 106, 49, 57, 56, 53, 45, 48, 51, 45, 51, 48), + "issue_date" to byteArrayOf( + -64, + 116, + 50, + 48, + 48, + 57, + 45, + 48, + 49, + 45, + 48, + 49, + 84, + 48, + 48, + 58, + 48, + 48, + 58, + 48, + 48, + 90 + ), + "expiry_date" to byteArrayOf( + -64, + 116, + 50, + 48, + 53, + 48, + 45, + 48, + 51, + 45, + 51, + 48, + 84, + 48, + 48, + 58, + 48, + 48, + 58, + 48, + 48, + 90 + ), + "issuing_country" to byteArrayOf(98, 83, 69), + "issuing_authority" to byteArrayOf(99, 85, 84, 79), + "document_number" to byteArrayOf(105, 49, 49, 49, 49, 49, 49, 49, 49, 52), + "portrait" to byteArrayOf(98, 83, 69), + "driving_privileges" to byteArrayOf( + -126, + -93, + 106, + 105, + 115, + 115, + 117, + 101, + 95, + 100, + 97, + 116, + 101, + -39, + 3, + -20, + 106, + 50, + 48, + 49, + 48, + 45, + 48, + 55, + 45, + 48, + 49, + 107, + 101, + 120, + 112, + 105, + 114, + 121, + 95, + 100, + 97, + 116, + 101, + -39, + 3, + -20, + 106, + 50, + 48, + 53, + 48, + 45, + 48, + 51, + 45, + 51, + 48, + 117, + 118, + 101, + 104, + 105, + 99, + 108, + 101, + 95, + 99, + 97, + 116, + 101, + 103, + 111, + 114, + 121, + 95, + 99, + 111, + 100, + 101, + 97, + 65, + -93, + 106, + 105, + 115, + 115, + 117, + 101, + 95, + 100, + 97, + 116, + 101, + -39, + 3, + -20, + 106, + 50, + 48, + 48, + 56, + 45, + 48, + 53, + 45, + 49, + 57, + 107, + 101, + 120, + 112, + 105, + 114, + 121, + 95, + 100, + 97, + 116, + 101, + -39, + 3, + -20, + 106, + 50, + 48, + 53, + 48, + 45, + 48, + 51, + 45, + 51, + 48, + 117, + 118, + 101, + 104, + 105, + 99, + 108, + 101, + 95, + 99, + 97, + 116, + 101, + 103, + 111, + 114, + 121, + 95, + 99, + 111, + 100, + 101, + 97, + 66 + ), + "un_distinguishing_sign" to byteArrayOf(97, 83), + "administrative_number" to byteArrayOf(106, 57, 48, 49, 48, 49, 54, 55, 52, 54, 52), + "sex" to byteArrayOf(1), + "height" to byteArrayOf(24, -76), + "weight" to byteArrayOf(24, 91), + "eye_colour" to byteArrayOf(101, 98, 108, 97, 99, 107), + "hair_colour" to byteArrayOf(101, 98, 108, 97, 99, 107), + "birth_place" to byteArrayOf(102, 83, 87, 69, 68, 69, 78), + "resident_address" to byteArrayOf( + 111, + 70, + 79, + 82, + 84, + 85, + 78, + 65, + 71, + 65, + 84, + 65, + 78, + 32, + 49, + 53 + ), + "portrait_capture_date" to byteArrayOf( + -64, + 116, + 50, + 48, + 50, + 51, + 45, + 48, + 51, + 45, + 50, + 51, + 84, + 48, + 48, + 58, + 48, + 48, + 58, + 48, + 48, + 90 + ), + "signature_usual_mark" to byteArrayOf(98, 83, 69), + "age_in_years" to byteArrayOf(24, 38), + "age_birth_year" to byteArrayOf(25, 7, -63), + "issuing_jurisdiction" to byteArrayOf(100, 83, 69, 45, 73), + "nationality" to byteArrayOf(98, 83, 69), + "resident_city" to byteArrayOf(102, 83, 87, 69, 68, 69, 78), + "resident_state" to byteArrayOf(98, 83, 69), + "resident_postal_code" to byteArrayOf(101, 54, 52, 49, 51, 51), + "resident_country" to byteArrayOf(98, 83, 69), + "family_name_national_character" to byteArrayOf( + 105, + 65, + 78, + 68, + 69, + 82, + 83, + 83, + 79, + 78 + ), + "given_name_national_character" to byteArrayOf(99, 74, 65, 78), + "age_over_15" to byteArrayOf(-11), + "age_over_18" to byteArrayOf(-11), + "age_over_21" to byteArrayOf(-11), + "age_over_60" to byteArrayOf(-12), + "age_over_65" to byteArrayOf(-12), + "age_over_68" to byteArrayOf(-12), +) + +const val mockedPidDocType = "eu.europa.ec.eudiw.pid.1" +const val mockedPidCodeName = "eu.europa.ec.eudiw.pid.1" +const val mockedMdlDocType = "org.iso.18013.5.1.mDL" +const val mockedMdlCodeName = "org.iso.18013.5.1" + +val mockedFullPid = Document( + id = mockedId1, + docType = mockedPidDocType, + name = "EU PID", + hardwareBacked = false, + createdAt = Instant.parse(mockedDocumentCreationDate), + requiresUserAuth = false, + nameSpacedData = mapOf( + mockedPidCodeName to mockedPidFields + ) +) + +val mockedFullMdl = Document( + id = mockedId2, + docType = mockedMdlDocType, + name = "mDL", + hardwareBacked = false, + createdAt = Instant.parse(mockedDocumentCreationDate), + requiresUserAuth = false, + nameSpacedData = mapOf( + mockedMdlCodeName to mockedMdlFields + ) +) + +val mockedMdlWithNoExpirationDate: Document = mockedFullMdl.copy( + nameSpacedData = mapOf( + mockedMdlCodeName to + mockedMdlFields + .minus("expiry_date") + ) +) + +val mockedMdlWithNoUserNameAndNoUserImage: Document = mockedFullMdl.copy( + nameSpacedData = mapOf( + mockedMdlCodeName to + mockedMdlFields + .minus("given_name") + .minus("portrait") + ) +) + +val mockedFullDocuments: List = listOf( + mockedFullPid, mockedFullMdl +) \ No newline at end of file diff --git a/test-feature/src/main/java/eu/europa/ec/testfeature/walletcore/WalletCoreHelper.kt b/test-feature/src/main/java/eu/europa/ec/testfeature/walletcore/WalletCoreHelper.kt new file mode 100644 index 00000000..1f334bb6 --- /dev/null +++ b/test-feature/src/main/java/eu/europa/ec/testfeature/walletcore/WalletCoreHelper.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 European Commission + * + * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European + * Commission - subsequent versions of the EUPL (the "Licence"); You may not use this work + * except in compliance with the Licence. + * + * You may obtain a copy of the Licence at: + * https://joinup.ec.europa.eu/software/page/eupl + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the Licence for the specific language + * governing permissions and limitations under the Licence. + */ + +package eu.europa.ec.testfeature.walletcore + +import eu.europa.ec.eudi.wallet.EudiWalletConfig +import eu.europa.ec.testlogic.base.getMockedContext + +fun getMockedEudiWalletConfig(extras: (EudiWalletConfig.Builder.() -> EudiWalletConfig.Builder)? = null): EudiWalletConfig { + return if (extras != null) { + EudiWalletConfig + .Builder(getMockedContext()) + .extras() + .build() + } else { + EudiWalletConfig + .Builder(getMockedContext()) + .build() + } +} \ No newline at end of file diff --git a/dashboard-feature/src/test/java/eu/europa/ec/dashboardfeature/ExampleUnitTest.kt b/test-logic/src/main/java/eu/europa/ec/testlogic/base/ContextHelper.kt similarity index 65% rename from dashboard-feature/src/test/java/eu/europa/ec/dashboardfeature/ExampleUnitTest.kt rename to test-logic/src/main/java/eu/europa/ec/testlogic/base/ContextHelper.kt index 180ef56d..53f2b423 100644 --- a/dashboard-feature/src/test/java/eu/europa/ec/dashboardfeature/ExampleUnitTest.kt +++ b/test-logic/src/main/java/eu/europa/ec/testlogic/base/ContextHelper.kt @@ -14,19 +14,11 @@ * governing permissions and limitations under the Licence. */ -package eu.europa.ec.dashboardfeature +package eu.europa.ec.testlogic.base -import org.junit.Assert.assertEquals -import org.junit.Test +import android.content.Context +import org.robolectric.RuntimeEnvironment -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } +fun getMockedContext(): Context { + return RuntimeEnvironment.getApplication().applicationContext } \ No newline at end of file