Extract generic test code
This commit is contained in:
@@ -2,57 +2,42 @@ package gq.kirmanak.mealie.data.auth.impl
|
|||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import dagger.hilt.android.testing.HiltAndroidTest
|
import dagger.hilt.android.testing.HiltAndroidTest
|
||||||
|
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.TEST_PASSWORD
|
||||||
|
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.TEST_TOKEN
|
||||||
|
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.TEST_USERNAME
|
||||||
|
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.body
|
||||||
|
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.enqueueSuccessfulAuthResponse
|
||||||
|
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.enqueueUnsuccessfulAuthResponse
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import okhttp3.mockwebserver.MockResponse
|
|
||||||
import okhttp3.mockwebserver.MockWebServer
|
|
||||||
import okhttp3.mockwebserver.RecordedRequest
|
|
||||||
import org.junit.After
|
|
||||||
import org.junit.Before
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import java.nio.charset.Charset
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ExperimentalSerializationApi
|
@ExperimentalSerializationApi
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
@HiltAndroidTest
|
@HiltAndroidTest
|
||||||
class AuthDataSourceImplTest : BaseTest() {
|
class AuthDataSourceImplTest : MockServerTest() {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var subject: AuthDataSourceImpl
|
lateinit var subject: AuthDataSourceImpl
|
||||||
private lateinit var mockServer: MockWebServer
|
|
||||||
private lateinit var serverUrl: String
|
|
||||||
|
|
||||||
@Before
|
|
||||||
fun startMockServer() {
|
|
||||||
mockServer = MockWebServer().apply {
|
|
||||||
start()
|
|
||||||
}
|
|
||||||
serverUrl = mockServer.url("/").toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
fun stopMockServer() {
|
|
||||||
mockServer.shutdown()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when authentication is successful then token is correct`() = runBlocking {
|
fun `when authentication is successful then token is correct`() = runBlocking {
|
||||||
enqueueSuccessfulResponse()
|
mockServer.enqueueSuccessfulAuthResponse()
|
||||||
val token = subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
|
val token = subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
|
||||||
assertThat(token).isEqualTo(TEST_TOKEN)
|
assertThat(token).isEqualTo(TEST_TOKEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = HttpException::class)
|
@Test(expected = HttpException::class)
|
||||||
fun `when authentication isn't successful then throws`(): Unit = runBlocking {
|
fun `when authentication isn't successful then throws`(): Unit = runBlocking {
|
||||||
enqueueUnsuccessfulResponse()
|
mockServer.enqueueUnsuccessfulAuthResponse()
|
||||||
subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
|
subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when authentication is requested then body is correct`() = runBlocking {
|
fun `when authentication is requested then body is correct`() = runBlocking {
|
||||||
enqueueSuccessfulResponse()
|
mockServer.enqueueSuccessfulAuthResponse()
|
||||||
subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
|
subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
|
||||||
val body = mockServer.takeRequest().body()
|
val body = mockServer.takeRequest().body()
|
||||||
assertThat(body).isEqualTo("username=$TEST_USERNAME&password=$TEST_PASSWORD")
|
assertThat(body).isEqualTo("username=$TEST_USERNAME&password=$TEST_PASSWORD")
|
||||||
@@ -60,37 +45,10 @@ class AuthDataSourceImplTest : BaseTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when authentication is requested then path is correct`() = runBlocking {
|
fun `when authentication is requested then path is correct`() = runBlocking {
|
||||||
enqueueSuccessfulResponse()
|
mockServer.enqueueSuccessfulAuthResponse()
|
||||||
subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
|
subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
|
||||||
val path = mockServer.takeRequest().path
|
val path = mockServer.takeRequest().path
|
||||||
assertThat(path).isEqualTo("/api/auth/token")
|
assertThat(path).isEqualTo("/api/auth/token")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun RecordedRequest.body() = body.readString(Charset.defaultCharset())
|
|
||||||
|
|
||||||
private fun enqueueUnsuccessfulResponse() {
|
|
||||||
val response = MockResponse()
|
|
||||||
.setBody(UNSUCCESSFUL_AUTH_RESPONSE)
|
|
||||||
.setHeader("Content-Type", "application/json")
|
|
||||||
.setResponseCode(401)
|
|
||||||
mockServer.enqueue(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun enqueueSuccessfulResponse() {
|
|
||||||
val response = MockResponse()
|
|
||||||
.setBody(SUCCESSFUL_AUTH_RESPONSE)
|
|
||||||
.setHeader("Content-Type", "application/json")
|
|
||||||
.setResponseCode(200)
|
|
||||||
mockServer.enqueue(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val TEST_USERNAME = "TEST_USERNAME"
|
|
||||||
private const val TEST_PASSWORD = "TEST_PASSWORD"
|
|
||||||
private const val TEST_TOKEN = "TEST_TOKEN"
|
|
||||||
private const val SUCCESSFUL_AUTH_RESPONSE =
|
|
||||||
"{\"access_token\":\"$TEST_TOKEN\",\"token_type\":\"TEST_TOKEN_TYPE\"}"
|
|
||||||
private const val UNSUCCESSFUL_AUTH_RESPONSE =
|
|
||||||
"{\"detail\":\"Unauthorized\"}"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package gq.kirmanak.mealie.data.auth.impl
|
||||||
|
|
||||||
|
import okhttp3.mockwebserver.MockResponse
|
||||||
|
import okhttp3.mockwebserver.MockWebServer
|
||||||
|
import okhttp3.mockwebserver.RecordedRequest
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
|
object AuthImplTestData {
|
||||||
|
const val TEST_USERNAME = "TEST_USERNAME"
|
||||||
|
const val TEST_PASSWORD = "TEST_PASSWORD"
|
||||||
|
const val TEST_TOKEN = "TEST_TOKEN"
|
||||||
|
const val SUCCESSFUL_AUTH_RESPONSE =
|
||||||
|
"{\"access_token\":\"$TEST_TOKEN\",\"token_type\":\"TEST_TOKEN_TYPE\"}"
|
||||||
|
const val UNSUCCESSFUL_AUTH_RESPONSE =
|
||||||
|
"{\"detail\":\"Unauthorized\"}"
|
||||||
|
const val TEST_URL = "TEST_URL"
|
||||||
|
|
||||||
|
fun RecordedRequest.body() = body.readString(Charset.defaultCharset())
|
||||||
|
|
||||||
|
fun MockWebServer.enqueueUnsuccessfulAuthResponse() {
|
||||||
|
val response = MockResponse()
|
||||||
|
.setBody(UNSUCCESSFUL_AUTH_RESPONSE)
|
||||||
|
.setHeader("Content-Type", "application/json")
|
||||||
|
.setResponseCode(401)
|
||||||
|
enqueue(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MockWebServer.enqueueSuccessfulAuthResponse() {
|
||||||
|
val response = MockResponse()
|
||||||
|
.setBody(SUCCESSFUL_AUTH_RESPONSE)
|
||||||
|
.setHeader("Content-Type", "application/json")
|
||||||
|
.setResponseCode(200)
|
||||||
|
enqueue(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,12 +2,14 @@ package gq.kirmanak.mealie.data.auth.impl
|
|||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import dagger.hilt.android.testing.HiltAndroidTest
|
import dagger.hilt.android.testing.HiltAndroidTest
|
||||||
|
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.TEST_TOKEN
|
||||||
|
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.TEST_URL
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltAndroidTest
|
@HiltAndroidTest
|
||||||
class AuthStorageImplTest : BaseTest() {
|
class AuthStorageImplTest : HiltRobolectricTest() {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var subject: AuthStorageImpl
|
lateinit var subject: AuthStorageImpl
|
||||||
|
|
||||||
@@ -37,10 +39,4 @@ class AuthStorageImplTest : BaseTest() {
|
|||||||
fun `when reading url without storing data then returns null`() = runBlocking {
|
fun `when reading url without storing data then returns null`() = runBlocking {
|
||||||
assertThat(subject.getBaseUrl()).isNull()
|
assertThat(subject.getBaseUrl()).isNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val TEST_TOKEN = "TEST_TOKEN"
|
|
||||||
private const val TEST_URL = "TEST_URL"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ import org.robolectric.annotation.Config
|
|||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
@Config(application = HiltTestApplication::class)
|
@Config(application = HiltTestApplication::class)
|
||||||
abstract class BaseTest {
|
abstract class HiltRobolectricTest {
|
||||||
@get:Rule
|
@get:Rule
|
||||||
var hiltRule = HiltAndroidRule(this)
|
var hiltRule = HiltAndroidRule(this)
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package gq.kirmanak.mealie.data.auth.impl
|
||||||
|
|
||||||
|
import okhttp3.mockwebserver.MockWebServer
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
|
||||||
|
abstract class MockServerTest : HiltRobolectricTest() {
|
||||||
|
lateinit var mockServer: MockWebServer
|
||||||
|
lateinit var serverUrl: String
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun startMockServer() {
|
||||||
|
mockServer = MockWebServer().apply {
|
||||||
|
start()
|
||||||
|
}
|
||||||
|
serverUrl = mockServer.url("/").toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun stopMockServer() {
|
||||||
|
mockServer.shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user