Add auth repo and storage tests
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package gq.kirmanak.mealient.data.auth.impl
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.core.content.edit
|
||||
import gq.kirmanak.mealient.data.auth.AuthStorage
|
||||
import gq.kirmanak.mealient.di.AuthModule.Companion.ENCRYPTED
|
||||
@@ -53,8 +54,13 @@ class AuthStorageImpl @Inject constructor(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val AUTH_HEADER_KEY = "authHeader"
|
||||
private const val EMAIL_KEY = "email"
|
||||
private const val PASSWORD_KEY = "password"
|
||||
@VisibleForTesting
|
||||
const val AUTH_HEADER_KEY = "authHeader"
|
||||
|
||||
@VisibleForTesting
|
||||
const val EMAIL_KEY = "email"
|
||||
|
||||
@VisibleForTesting
|
||||
const val PASSWORD_KEY = "password"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package gq.kirmanak.mealient.data.auth.impl
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.auth.AuthDataSource
|
||||
import gq.kirmanak.mealient.data.auth.AuthRepo
|
||||
import gq.kirmanak.mealient.data.auth.AuthStorage
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_PASSWORD
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_TOKEN
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_USERNAME
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class AuthRepoImplTest {
|
||||
|
||||
@MockK
|
||||
lateinit var dataSource: AuthDataSource
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var storage: AuthStorage
|
||||
|
||||
lateinit var subject: AuthRepo
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockKAnnotations.init(this)
|
||||
subject = AuthRepoImpl(storage, dataSource)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when isAuthorizedFlow then reads from storage`() = runTest {
|
||||
every { storage.authHeaderFlow } returns flowOf("", null, "header")
|
||||
assertThat(subject.isAuthorizedFlow.toList()).isEqualTo(listOf(true, false, true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when authenticate successfully then saves to storage`() = runTest {
|
||||
coEvery { dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD)) } returns TEST_TOKEN
|
||||
subject.authenticate(TEST_USERNAME, TEST_PASSWORD)
|
||||
coVerifyAll {
|
||||
storage.setAuthHeader(TEST_AUTH_HEADER)
|
||||
storage.setEmail(TEST_USERNAME)
|
||||
storage.setPassword(TEST_PASSWORD)
|
||||
}
|
||||
confirmVerified(storage)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when authenticate fails then does not change storage`() = runTest {
|
||||
coEvery { dataSource.authenticate(any(), any()) } throws RuntimeException()
|
||||
runCatching { subject.authenticate("invalid", "") }
|
||||
confirmVerified(storage)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when logout then removes email, password and header`() = runTest {
|
||||
subject.logout()
|
||||
coVerifyAll {
|
||||
storage.setEmail(null)
|
||||
storage.setPassword(null)
|
||||
storage.setAuthHeader(null)
|
||||
}
|
||||
confirmVerified(storage)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when invalidate then does not authenticate without email`() = runTest {
|
||||
coEvery { storage.getEmail() } returns null
|
||||
coEvery { storage.getPassword() } returns TEST_PASSWORD
|
||||
subject.invalidateAuthHeader()
|
||||
confirmVerified(dataSource)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when invalidate then does not authenticate without password`() = runTest {
|
||||
coEvery { storage.getEmail() } returns TEST_USERNAME
|
||||
coEvery { storage.getPassword() } returns null
|
||||
subject.invalidateAuthHeader()
|
||||
confirmVerified(dataSource)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when invalidate with credentials then calls authenticate`() = runTest {
|
||||
coEvery { storage.getEmail() } returns TEST_USERNAME
|
||||
coEvery { storage.getPassword() } returns TEST_PASSWORD
|
||||
coEvery { dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD)) } returns TEST_TOKEN
|
||||
subject.invalidateAuthHeader()
|
||||
coVerifyAll {
|
||||
dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when invalidate with credentials and auth fails then clears email`() = runTest {
|
||||
coEvery { storage.getEmail() } returns "invalid"
|
||||
coEvery { storage.getPassword() } returns ""
|
||||
coEvery { dataSource.authenticate(any(), any()) } throws RuntimeException()
|
||||
subject.invalidateAuthHeader()
|
||||
coVerify { storage.setEmail(null) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package gq.kirmanak.mealient.data.auth.impl
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import gq.kirmanak.mealient.data.auth.AuthStorage
|
||||
import gq.kirmanak.mealient.data.auth.impl.AuthStorageImpl.Companion.AUTH_HEADER_KEY
|
||||
import gq.kirmanak.mealient.data.auth.impl.AuthStorageImpl.Companion.EMAIL_KEY
|
||||
import gq.kirmanak.mealient.data.auth.impl.AuthStorageImpl.Companion.PASSWORD_KEY
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_PASSWORD
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_USERNAME
|
||||
import gq.kirmanak.mealient.test.HiltRobolectricTest
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import javax.inject.Inject
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@HiltAndroidTest
|
||||
class AuthStorageImplTest : HiltRobolectricTest() {
|
||||
|
||||
@Inject
|
||||
@ApplicationContext
|
||||
lateinit var context: Context
|
||||
|
||||
lateinit var subject: AuthStorage
|
||||
|
||||
lateinit var sharedPreferences: SharedPreferences
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
sharedPreferences = context.getSharedPreferences("test", Context.MODE_PRIVATE)
|
||||
subject = AuthStorageImpl(sharedPreferences)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when authHeaderFlow is observed then sends value immediately`() = runTest {
|
||||
sharedPreferences.edit(commit = true) { putString(AUTH_HEADER_KEY, TEST_AUTH_HEADER) }
|
||||
assertThat(subject.authHeaderFlow.first()).isEqualTo(TEST_AUTH_HEADER)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when authHeader is observed then sends null if nothing saved`() = runTest {
|
||||
assertThat(subject.authHeaderFlow.first()).isEqualTo(null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when setEmail then edits shared preferences`() = runTest {
|
||||
subject.setEmail(TEST_USERNAME)
|
||||
assertThat(sharedPreferences.getString(EMAIL_KEY, null)).isEqualTo(TEST_USERNAME)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when getPassword then reads shared preferences`() = runTest {
|
||||
sharedPreferences.edit(commit = true) { putString(PASSWORD_KEY, TEST_PASSWORD) }
|
||||
assertThat(subject.getPassword()).isEqualTo(TEST_PASSWORD)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user