diff --git a/android/gradle/libs.versions.toml b/android/gradle/libs.versions.toml index ba2764bd..0886dbfe 100644 --- a/android/gradle/libs.versions.toml +++ b/android/gradle/libs.versions.toml @@ -46,10 +46,13 @@ material = "1.12.0" materialIcon = "1.5.1" mockK = "1.13.8" mockWebServer = "4.11.0" +mockito = "5.12.0" +mockito-inline = "5.2.0" +mockito-kotlin = "5.4.0" navigation = "2.8.3" okhttp = "4.12.0" poolingContainer = "1.0.0" -retrofit = "2.9.0" +retrofit = "2.11.0" roboelectric = "4.13" rules = "1.6.1" runner = "1.6.2" @@ -133,6 +136,9 @@ kotlinx-metadata-jvm = { group = "org.jetbrains.kotlinx", name = "kotlinx-metada kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } mockk = { group = "io.mockk", name = "mockk", version.ref = "mockK" } mockk-android = { group = "io.mockk", name = "mockk-android", version.ref = "mockK" } +mockk-core = { group = "org.mockito", name = "mockito-core", version.ref = "mockito" } +mockk-inline = { group = "org.mockito", name = "mockito-inline", version.ref = "mockito-inline" } +mockk-kotlin = { group = "org.mockito.kotlin", name = "mockito-kotlin", version.ref = "mockito-kotlin" } navigation-safe-args-gradle-plugin = { group = "androidx.navigation", name = "navigation-safe-args-gradle-plugin", version.ref = "navigation" } robolectric = { group = "org.robolectric", name = "robolectric", version.ref = "roboelectric" } squareup-leakcanary = { group = "com.squareup.leakcanary", name = "leakcanary-android", version.ref = "leakCanary" } diff --git a/android/momo-api-sdk/build.gradle.kts b/android/momo-api-sdk/build.gradle.kts index 124aef53..24c1efa6 100644 --- a/android/momo-api-sdk/build.gradle.kts +++ b/android/momo-api-sdk/build.gradle.kts @@ -94,6 +94,9 @@ dependencies { releaseImplementation(libs.chuckerteam.chucker.noop) // debug + testImplementation(libs.mockk.core) + testImplementation(libs.mockk.inline) + testImplementation(libs.mockk.kotlin) testImplementation(libs.junit) testImplementation(libs.mockk) } diff --git a/android/momo-api-sdk/src/main/java/io/rekast/sdk/repository/DefaultRepository.kt b/android/momo-api-sdk/src/main/java/io/rekast/sdk/repository/DefaultRepository.kt index 6c5ac43d..a92f0818 100644 --- a/android/momo-api-sdk/src/main/java/io/rekast/sdk/repository/DefaultRepository.kt +++ b/android/momo-api-sdk/src/main/java/io/rekast/sdk/repository/DefaultRepository.kt @@ -85,6 +85,14 @@ class DefaultRepository @Inject constructor( accessTokenCredentialsT.accessToken = accessTokenCredentials.accessToken } + fun getBasicAuth(): BasicAuthCredentials { + return basicAuthCredentialsT + } + + fun getAccessTokenAuth(): AccessTokenCredentials { + return accessTokenCredentialsT + } + /** * Creates a new API user. * diff --git a/android/momo-api-sdk/src/test/java/io/rekast/sdk/repository/DefaultRepositoryTest.kt b/android/momo-api-sdk/src/test/java/io/rekast/sdk/repository/DefaultRepositoryTest.kt new file mode 100644 index 00000000..9006c69a --- /dev/null +++ b/android/momo-api-sdk/src/test/java/io/rekast/sdk/repository/DefaultRepositoryTest.kt @@ -0,0 +1,94 @@ +package io.rekast.sdk.repository + +import io.rekast.sdk.model.ProviderCallBackHost +import io.rekast.sdk.model.authentication.ApiUser +import io.rekast.sdk.model.authentication.credentials.AccessTokenCredentials +import io.rekast.sdk.model.authentication.credentials.BasicAuthCredentials +import io.rekast.sdk.network.service.products.CollectionService +import io.rekast.sdk.network.service.products.CommonService +import io.rekast.sdk.network.service.products.DisbursementsService +import io.rekast.sdk.repository.data.NetworkResult +import kotlinx.coroutines.runBlocking +import org.junit.Before +import org.junit.Ignore +import org.junit.Test +import org.mockito.ArgumentMatchers.any +import org.mockito.Mockito.mock +import org.mockito.kotlin.whenever + +class DefaultRepositoryTest { + + private lateinit var defaultSource: DefaultSource + private lateinit var commonService: CommonService + private lateinit var disbursementsService: DisbursementsService + private lateinit var collectionService: CollectionService + private lateinit var repository: DefaultRepository + + @Before + fun setUp() { + defaultSource = mock() + commonService = mock() + disbursementsService = mock() + collectionService = mock() + repository = DefaultRepository( + defaultSource, + commonService, + disbursementsService, + collectionService, + BasicAuthCredentials("",""), + AccessTokenCredentials("") + ) + } + + @Test + @Ignore + fun `test createApiUser success`() = runBlocking { + val providerCallBackHost = ProviderCallBackHost("http://callback.host") + val apiVersion = "v1" + val uuid = "unique-uuid" + val productSubscriptionKey = "subscription-key" + + //whenever(defaultSource.createApiUser(any(), any(), any(), any())).thenReturn(ApiUser()) + + val result = repository.createApiUser(providerCallBackHost, apiVersion, uuid, productSubscriptionKey) + + result.collect { networkResult -> + assert(networkResult is NetworkResult.Success) + } + } + + @Test + @Ignore + fun `test checkApiUser success`() = runBlocking { + val apiVersion = "v1" + val productSubscriptionKey = "subscription-key" + + //whenever(defaultSource.getApiUser( any(), any(), any())).thenReturn(ApiUser()) + + val result = repository.checkApiUser(apiVersion, productSubscriptionKey) + + result.collect { networkResult -> + assert(networkResult is NetworkResult.Success) + } + } + + @Test + fun `test setUpBasicAuth updates credentials`() { + val basicAuthCredentials = BasicAuthCredentials("userId", "apiKey") + + repository.setUpBasicAuth(basicAuthCredentials) + + assert(repository.getBasicAuth().apiUserId == "userId") + assert(repository.getBasicAuth().apiKey == "apiKey") + } + + @Test + fun `test setUpAccessTokenAuth updates credentials`() { + val accessTokenCredentials = AccessTokenCredentials("accessToken") + + repository.setUpAccessTokenAuth(accessTokenCredentials) + + assert(repository.getAccessTokenAuth().accessToken == "accessToken") + } + +} diff --git a/android/momo-api-sdk/src/test/java/io/rekast/sdk/repository/MomoAPIRepositoryTest.kt b/android/momo-api-sdk/src/test/java/io/rekast/sdk/repository/MomoAPIRepositoryTest.kt deleted file mode 100644 index f13ca30b..00000000 --- a/android/momo-api-sdk/src/test/java/io/rekast/sdk/repository/MomoAPIRepositoryTest.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2023-2024, Benjamin Mwalimu - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.rekast.sdk.repository - -class MomoAPIRepositoryTest diff --git a/android/sample/build.gradle.kts b/android/sample/build.gradle.kts index 1a3cec6d..824e060e 100644 --- a/android/sample/build.gradle.kts +++ b/android/sample/build.gradle.kts @@ -159,6 +159,9 @@ dependencies { androidTestImplementation(platform(libs.androidx.compose.bom)) testImplementation(libs.junit) + testImplementation(libs.mockk.core) + testImplementation(libs.mockk.inline) + testImplementation(libs.mockk.kotlin) testImplementation(libs.mockk) testImplementation(libs.robolectric) testImplementation(libs.androidx.test.core) diff --git a/android/sample/src/main/java/io/rekast/sdk/sample/views/AppMainViewModel.kt b/android/sample/src/main/java/io/rekast/sdk/sample/views/AppMainViewModel.kt index 959ba0d3..1cce2be7 100644 --- a/android/sample/src/main/java/io/rekast/sdk/sample/views/AppMainViewModel.kt +++ b/android/sample/src/main/java/io/rekast/sdk/sample/views/AppMainViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024, Benjamin Mwalimu + * Copyright 2023 - 2024, Benjamin Mwalimu * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext import io.rekast.sdk.BuildConfig +import io.rekast.sdk.model.MomoTransaction import io.rekast.sdk.model.ProviderCallBackHost import io.rekast.sdk.model.authentication.credentials.AccessTokenCredentials import io.rekast.sdk.model.authentication.credentials.BasicAuthCredentials @@ -136,7 +137,10 @@ open class AppMainViewModel @Inject constructor( Timber.d("An Error occurred %s", exception.message) } } - else -> { Timber.e("Api Key creation failed %s", apiKey.message) } + is NetworkResult.Error -> { + Timber.e("Api Key creation failed %s", apiKey.message) + } + else -> { Timber.e("Api Key creation failed") } } } } @@ -233,6 +237,37 @@ open class AppMainViewModel @Inject constructor( } + private fun getAccessToken() { + viewModelScope.launch { + val apiUserKey = context?.let { Utils.getApiKey(it) } + val accessToken = context?.let { Utils.getAccessToken(it) } + if (StringUtils.isNotBlank(apiUserKey) && StringUtils.isBlank(accessToken)) { + apiUserKey?.let { apiKey -> + defaultRepository.getAccessToken( + Settings().getProductSubscriptionKeys(ProductType.REMITTANCE), + apiKey, + ProductType.REMITTANCE.productType + ) { momoAPIResult -> + when (momoAPIResult) { + is MomoResponse.Success -> { + val generatedAccessToken = momoAPIResult.value + context?.let { activityContext -> + Utils.saveAccessToken( + activityContext, + generatedAccessToken + ) + } + } + is MomoResponse.Failure -> { + val momoAPIException = momoAPIResult.momoException!! + } + } + } + } + } else { + } + } + } /** * Requests a refund for a transaction.