Skip to content

Commit

Permalink
Merge pull request #57 from RotBolt/task/55-tests-for-flaker-data-module
Browse files Browse the repository at this point in the history
Task/55 tests for flaker data module
  • Loading branch information
RotBolt authored Aug 27, 2023
2 parents b6bfe0d + 872eaa4 commit 0788e3a
Show file tree
Hide file tree
Showing 23 changed files with 271 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import io.rotlabs.di.FlakerDataContainer
import io.rotlabs.flakerandroidretrofit.ui.FlakerViewModel
import io.rotlabs.flakerdb.networkrequest.data.NetworkRequestRepo
import io.rotlabs.flakerdb.networkrequest.NetworkRequestRepo
import io.rotlabs.flakerprefs.PrefDataStore
import io.rotlabs.flakerretrofit.di.FlakerOkHttpCoreContainer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import android.util.Log
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.rotlabs.flakedomain.prefs.FlakerPrefs
import io.rotlabs.flakedomain.prefs.RetentionPolicy
import io.rotlabs.flakerandroidui.components.lists.NetworkRequestUi
import io.rotlabs.flakerandroidui.screens.prefs.FlakerPrefsUiDto
import io.rotlabs.flakerandroidui.screens.search.SearchUiDto
import io.rotlabs.flakerdb.networkrequest.data.NetworkRequestRepo
import io.rotlabs.flakerdb.networkrequest.NetworkRequestRepo
import io.rotlabs.flakerprefs.PrefDataStore
import io.rotlabs.flakerprefs.RetentionPolicy
import io.rotlabs.flakerprefs.dto.FlakerPrefs
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
Expand Down
15 changes: 13 additions & 2 deletions flaker-data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,26 @@ kotlin {
implementation(project(":flaker-domain"))
}
}
val commonTest by sourceSets.getting
val commonTest by sourceSets.getting {
dependencies {
implementation(libs.kotlin.test)
implementation(libs.kotlinx.coroutines.test)
implementation(libs.turbine)
}
}

val androidMain by sourceSets.getting {
dependsOn(commonMain)
dependencies {
implementation(libs.sqlDelight.android)
}
}
val androidUnitTest by sourceSets.getting
val androidUnitTest by sourceSets.getting {
dependencies {
implementation(libs.junit)
implementation(libs.sqlDelight.jvm)
}
}

val iosMain by sourceSets.getting {
dependsOn(commonMain)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package io.rotlabs.di

import android.content.Context
import io.rotlabs.flakerdb.DbDriverFactory
import io.rotlabs.flakerdb.networkrequest.data.NetworkRequestRepo
import io.rotlabs.flakerdb.networkrequest.data.NetworkRequestRepoImpl
import io.rotlabs.flakerdb.networkrequest.NetworkRequestRepo
import io.rotlabs.flakerdb.networkrequest.NetworkRequestRepoImpl
import io.rotlabs.flakerprefs.DataStoreFactory
import io.rotlabs.flakerprefs.PrefDataStore
import io.rotlabs.flakerprefs.PrefDataStoreImpl
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.rotlabs.flakerdb

import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver

internal actual fun testDbDriverFactory(): SqlDriver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY).also {
FlakerDatabase.Schema.create(it)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ package io.rotlabs.flakerdb
import app.cash.sqldelight.db.SqlDriver

expect class DbDriverFactory {

fun createDriver(): SqlDriver
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package io.rotlabs.flakerdb.networkrequest.data
package io.rotlabs.flakerdb.networkrequest

import io.rotlabs.flakedomain.networkrequest.NetworkRequest
import io.rotlabs.flakerprefs.RetentionPolicy
import io.rotlabs.flakedomain.prefs.RetentionPolicy
import kotlinx.coroutines.flow.Flow

interface NetworkRequestRepo {
suspend fun selectAll(): List<NetworkRequest>
suspend fun insert(networkRequest: NetworkRequest)
fun observeAll(): Flow<List<NetworkRequest>>
suspend fun deleteExpiredData(retentionPolicy: RetentionPolicy)
suspend fun deleteAll()
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package io.rotlabs.flakerdb.networkrequest.data
package io.rotlabs.flakerdb.networkrequest

import app.cash.sqldelight.coroutines.asFlow
import app.cash.sqldelight.coroutines.mapToList
import app.cash.sqldelight.db.SqlDriver
import io.rotlabs.flakedomain.networkrequest.NetworkRequest
import io.rotlabs.flakedomain.prefs.RetentionPolicy
import io.rotlabs.flakedomain.prefs.toMilliSeconds
import io.rotlabs.flakerdb.FlakerDatabase
import io.rotlabs.flakerprefs.RetentionPolicy
import io.rotlabs.flakerprefs.toMilliSeconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import kotlinx.datetime.Clock

Expand Down Expand Up @@ -85,4 +84,10 @@ internal class NetworkRequestRepoImpl(
networkRequestQueries.deleteOldData(expiryTimeMillis)
}
}

override suspend fun deleteAll() {
withContext(dispatcher) {
networkRequestQueries.deleteAll()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.rotlabs.flakerprefs

import io.rotlabs.flakerprefs.dto.FlakerPrefs
import io.rotlabs.flakedomain.prefs.FlakerPrefs
import kotlinx.coroutines.flow.Flow

interface PrefDataStore {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import io.rotlabs.flakerprefs.dto.FlakerPrefs
import io.rotlabs.flakedomain.prefs.FlakerPrefs
import io.rotlabs.flakedomain.prefs.RetentionPolicy
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);
deleteOldData:
DELETE
FROM network_request
WHERE created_at < ?;
WHERE created_at < ?;

deleteAll:
DELETE FROM network_request;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.rotlabs.flakerdb

import app.cash.sqldelight.db.SqlDriver

internal expect fun testDbDriverFactory(): SqlDriver
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package io.rotlabs.flakerdb.networkrequest

import app.cash.turbine.test
import io.rotlabs.flakedomain.networkrequest.NetworkRequest
import io.rotlabs.flakedomain.prefs.RetentionPolicy
import io.rotlabs.flakerdb.testDbDriverFactory
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

@OptIn(ExperimentalCoroutinesApi::class)
class NetworkRequestRepoTest {

private lateinit var networkRequestRepo: NetworkRequestRepo

private val testDispatcher = UnconfinedTestDispatcher()

private suspend fun NetworkRequestRepo.seed() {
insert(
NetworkRequest(
host = "https://jsonplaceholder.typicode.com",
path = "/todos/1",
method = "GET",
requestTime = 1693127126000,
responseCode = 200,
responseTimeTaken = 100,
isFailedByFlaker = false,
createdAt = 1693127139000
)
)
}

@BeforeTest
fun setup() = runBlocking {
networkRequestRepo = NetworkRequestRepoImpl(
sqlDriver = testDbDriverFactory(),
dispatcher = testDispatcher
)

networkRequestRepo.deleteAll()
networkRequestRepo.seed()
}

@Test
fun `test selectAll`() = runBlocking {
val networkRequests = networkRequestRepo.selectAll()
assertTrue(networkRequests.isNotEmpty())
assertEquals(1, networkRequests.size)
}

@Test
fun `test observeAll`() = runBlocking {
val networkRequests = networkRequestRepo.observeAll()
networkRequests.test {
assertEquals(1, awaitItem().size)
networkRequestRepo.insert(
NetworkRequest(
host = "https://jsonplaceholder.typicode.com",
path = "/todos/1",
method = "GET",
requestTime = 1693127126000,
responseCode = 500,
responseTimeTaken = 100,
isFailedByFlaker = true,
createdAt = 1693127139000
)
)
val items = awaitItem()
assertEquals(2, items.size)
assertEquals(500, items[1].responseCode)
assertEquals(true, items[1].isFailedByFlaker)
}
}

@Test
fun `test deleteAll`() = runBlocking {
assertEquals(1, networkRequestRepo.selectAll().size)
networkRequestRepo.deleteAll()
assertEquals(0, networkRequestRepo.selectAll().size)
}

@Test
fun `test deleteExpiredData`() = runBlocking {
// insert 2 days before time
val networkRequest0 = NetworkRequest(
host = "https://jsonplaceholder.typicode.com",
path = "/todos/1",
method = "GET",
requestTime = 1692955276000,
responseCode = 200,
responseTimeTaken = 100,
isFailedByFlaker = false,
createdAt = 1692955276000
)
networkRequestRepo.insert(networkRequest0)
assertEquals(2, networkRequestRepo.selectAll().size)
networkRequestRepo.deleteExpiredData(RetentionPolicy.ONE_DAY)
assertEquals(1, networkRequestRepo.selectAll().size)

// insert 7 days before time
val networkRequest1 = NetworkRequest(
host = "https://jsonplaceholder.typicode.com",
path = "/todos/1",
method = "GET",
requestTime = 1692523289000,
responseCode = 200,
responseTimeTaken = 100,
isFailedByFlaker = false,
createdAt = 1692523289000
)
networkRequestRepo.insert(networkRequest1)
assertEquals(2, networkRequestRepo.selectAll().size)
networkRequestRepo.deleteExpiredData(RetentionPolicy.SEVEN_DAYS)
assertEquals(1, networkRequestRepo.selectAll().size)

// insert 15 days before time
val networkRequest2 = NetworkRequest(
host = "https://jsonplaceholder.typicode.com",
path = "/todos/1",
method = "GET",
requestTime = 1690968089000,
responseCode = 200,
responseTimeTaken = 100,
isFailedByFlaker = false,
createdAt = 1690968089000
)
networkRequestRepo.insert(networkRequest2)
assertEquals(2, networkRequestRepo.selectAll().size)
networkRequestRepo.deleteExpiredData(RetentionPolicy.FIFTEEN_DAYS)
assertEquals(1, networkRequestRepo.selectAll().size)

// insert 30 days before time
val networkRequest3 = NetworkRequest(
host = "https://jsonplaceholder.typicode.com",
path = "/todos/1",
method = "GET",
requestTime = 1688256089000,
responseCode = 200,
responseTimeTaken = 100,
isFailedByFlaker = false,
createdAt = 1688256089000
)
networkRequestRepo.insert(networkRequest3)
assertEquals(2, networkRequestRepo.selectAll().size)
networkRequestRepo.deleteExpiredData(RetentionPolicy.THIRTY_DAYS)
assertEquals(1, networkRequestRepo.selectAll().size)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.rotlabs.flakerprefs

import io.rotlabs.flakedomain.prefs.FlakerPrefs
import io.rotlabs.flakedomain.prefs.RetentionPolicy
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class PrefsDataStoreTest {

private lateinit var prefDataStore: PrefDataStore

@BeforeTest
fun setup() {
val dataStore = createDataStore { DATASTORE_FILE_NAME }
prefDataStore = PrefDataStoreImpl(dataStore)
}

@Test
fun `test save and get prefs`() = runBlocking {
prefDataStore.savePrefs(
FlakerPrefs(
shouldIntercept = true,
delay = 1000,
failPercent = 10,
variancePercent = 10,
retentionPolicy = RetentionPolicy.ONE_DAY
)
)
val prefs = prefDataStore.getPrefs().first()
assertTrue(prefs.shouldIntercept)
assertEquals(1000, prefs.delay)
assertEquals(10, prefs.failPercent)
assertEquals(10, prefs.variancePercent)
assertEquals(prefs.retentionPolicy, RetentionPolicy.ONE_DAY)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import platform.Foundation.NSUserDomainMask

actual class DataStoreFactory {
actual fun create(): DataStore<Preferences> {
NSDocumentDirectory
return createDataStore {
val documentDirectory: NSURL? = NSFileManager.defaultManager.URLForDirectory(
directory = NSDocumentDirectory,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.rotlabs.flakerdb

import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.driver.native.inMemoryDriver
import io.rotlabs.flakerdb.FlakerDatabase

internal actual fun testDbDriverFactory(): SqlDriver = inMemoryDriver(FlakerDatabase.Schema)
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
package io.rotlabs.flakerprefs.dto

import io.rotlabs.flakerprefs.RetentionPolicy
package io.rotlabs.flakedomain.prefs

data class FlakerPrefs(
val shouldIntercept: Boolean,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.rotlabs.flakerprefs
package io.rotlabs.flakedomain.prefs

enum class RetentionPolicy(val value: String) {
ONE_DAY("1 day"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.rotlabs.flakerretrofit

import io.rotlabs.flakedomain.networkrequest.NetworkRequest
import io.rotlabs.flakerdb.networkrequest.data.NetworkRequestRepo
import io.rotlabs.flakerdb.networkrequest.NetworkRequestRepo
import io.rotlabs.flakerprefs.PrefDataStore
import io.rotlabs.flakerretrofit.di.FlakerOkHttpCoreContainer
import io.rotlabs.flakerretrofit.dto.FlakerFailResponse
Expand Down
Loading

0 comments on commit 0788e3a

Please sign in to comment.