test: add unit tests for Room DAOs, LocalDateConverter, and JSON roundtrip
LocalDateConverterTest: added negative test for invalid string input (DateTimeParseException). CategoryDaoTest, LocationDaoTest: added getAll tests with multiple entities to verify complete retrieval. ItemDaoTest: fixed getExpiringSoon test (was calling non-existent getExpiringSoon(Int) instead of getExpiringSoonByCutoff(LocalDate)); added getAll, getById positive, and getById negative tests. JsonRoundtripTest (new): verifies lossless export-import roundtrip with multiple items covering all fields, nullable fields (null kcalPer100g, null expiryDate), and empty database edge case. TestFakes (new): extracted shared Fake DAO implementations from ImportExportRepositoryImplTest to avoid private class redeclaration errors across test files in the same package. Closes #22
This commit is contained in:
parent
5825b0351c
commit
0c1e06afca
7 changed files with 408 additions and 119 deletions
|
|
@ -84,4 +84,18 @@ internal class CategoryDaoTest {
|
|||
// Then
|
||||
assertNull(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_getAll_multipleCategories_returnsAll() = runBlocking {
|
||||
// Given
|
||||
dao.insert(CategoryEntity(name = "Lebensmittel"))
|
||||
dao.insert(CategoryEntity(name = "Hygiene"))
|
||||
dao.insert(CategoryEntity(name = "Medizin"))
|
||||
|
||||
// When
|
||||
val result = dao.getAll().first()
|
||||
|
||||
// Then
|
||||
assertEquals(3, result.size)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.first
|
|||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
|
@ -133,16 +134,53 @@ internal class ItemDaoTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun test_getExpiringSoon_itemExpiresInOneDayWithDaysUntil365_returnsItem() = runBlocking {
|
||||
fun test_getExpiringSoon_itemExpiresInOneDayWithCutoff365Days_returnsItem() = runBlocking {
|
||||
// Given
|
||||
val tomorrow = LocalDate.now().plusDays(1)
|
||||
dao.insert(buildItem(expiryDate = tomorrow))
|
||||
|
||||
// When
|
||||
val result = dao.getExpiringSoon(365).first()
|
||||
val cutoff = LocalDate.now().plusDays(365)
|
||||
val result = dao.getExpiringSoonByCutoff(cutoff).first()
|
||||
|
||||
// Then
|
||||
assertEquals(1, result.size)
|
||||
assertEquals("item-1", result.first().id)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_getAll_multipleItems_returnsAll() = runBlocking {
|
||||
// Given
|
||||
dao.insert(buildItem(id = "item-1"))
|
||||
dao.insert(buildItem(id = "item-2"))
|
||||
dao.insert(buildItem(id = "item-3"))
|
||||
|
||||
// When
|
||||
val result = dao.getAll().first()
|
||||
|
||||
// Then
|
||||
assertEquals(3, result.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_getById_existingItem_returnsItem() = runBlocking {
|
||||
// Given
|
||||
dao.insert(buildItem(id = "item-1"))
|
||||
|
||||
// When
|
||||
val result = dao.getById("item-1")
|
||||
|
||||
// Then
|
||||
assertEquals("item-1", result?.id)
|
||||
assertEquals("Wasser", result?.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_getById_nonExistentId_returnsNull() = runBlocking {
|
||||
// Given / When
|
||||
val result = dao.getById("does-not-exist")
|
||||
|
||||
// Then
|
||||
assertNull(result)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,4 +84,18 @@ internal class LocationDaoTest {
|
|||
// Then
|
||||
assertNull(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_getAll_multipleLocations_returnsAll() = runBlocking {
|
||||
// Given
|
||||
dao.insert(LocationEntity(name = "Keller"))
|
||||
dao.insert(LocationEntity(name = "Garage"))
|
||||
dao.insert(LocationEntity(name = "Dachboden"))
|
||||
|
||||
// When
|
||||
val result = dao.getAll().first()
|
||||
|
||||
// Then
|
||||
assertEquals(3, result.size)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ package de.krisenvorrat.app.data.db
|
|||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertThrows
|
||||
import org.junit.Test
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeParseException
|
||||
|
||||
class LocalDateConverterTest {
|
||||
|
||||
|
|
@ -56,4 +58,15 @@ class LocalDateConverterTest {
|
|||
// Then
|
||||
assertNull(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_toLocalDate_withInvalidString_throwsDateTimeParseException() {
|
||||
// Given
|
||||
val invalidString = "not-a-date"
|
||||
|
||||
// When / Then
|
||||
assertThrows(DateTimeParseException::class.java) {
|
||||
converter.toLocalDate(invalidString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,131 +1,14 @@
|
|||
package de.krisenvorrat.app.data.export
|
||||
|
||||
import de.krisenvorrat.app.data.db.dao.CategoryDao
|
||||
import de.krisenvorrat.app.data.db.dao.ItemDao
|
||||
import de.krisenvorrat.app.data.db.dao.LocationDao
|
||||
import de.krisenvorrat.app.data.db.dao.SettingsDao
|
||||
import de.krisenvorrat.app.data.db.entity.CategoryEntity
|
||||
import de.krisenvorrat.app.data.db.entity.ItemEntity
|
||||
import de.krisenvorrat.app.data.db.entity.LocationEntity
|
||||
import de.krisenvorrat.app.data.db.entity.SettingsEntity
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import java.time.LocalDate
|
||||
|
||||
private class FakeCategoryDao : CategoryDao {
|
||||
private val items = mutableListOf<CategoryEntity>()
|
||||
private val flow = MutableStateFlow<List<CategoryEntity>>(emptyList())
|
||||
|
||||
private fun emit() { flow.value = items.toList() }
|
||||
|
||||
override suspend fun insert(category: CategoryEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun update(category: CategoryEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun delete(category: CategoryEntity) = throw UnsupportedOperationException()
|
||||
override fun getAll(): Flow<List<CategoryEntity>> = flow
|
||||
override suspend fun getById(id: Int): CategoryEntity? = throw UnsupportedOperationException()
|
||||
|
||||
override suspend fun upsertAll(categories: List<CategoryEntity>) {
|
||||
categories.forEach { cat ->
|
||||
val idx = items.indexOfFirst { it.id == cat.id }
|
||||
if (idx >= 0) items[idx] = cat else items.add(cat)
|
||||
}
|
||||
emit()
|
||||
}
|
||||
|
||||
fun getItems(): List<CategoryEntity> = items.toList()
|
||||
}
|
||||
|
||||
private class FakeLocationDao : LocationDao {
|
||||
private val items = mutableListOf<LocationEntity>()
|
||||
private val flow = MutableStateFlow<List<LocationEntity>>(emptyList())
|
||||
|
||||
private fun emit() { flow.value = items.toList() }
|
||||
|
||||
override suspend fun insert(location: LocationEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun update(location: LocationEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun delete(location: LocationEntity) = throw UnsupportedOperationException()
|
||||
override fun getAll(): Flow<List<LocationEntity>> = flow
|
||||
override suspend fun getById(id: Int): LocationEntity? = throw UnsupportedOperationException()
|
||||
|
||||
override suspend fun upsertAll(locations: List<LocationEntity>) {
|
||||
locations.forEach { loc ->
|
||||
val idx = items.indexOfFirst { it.id == loc.id }
|
||||
if (idx >= 0) items[idx] = loc else items.add(loc)
|
||||
}
|
||||
emit()
|
||||
}
|
||||
|
||||
fun getItems(): List<LocationEntity> = items.toList()
|
||||
}
|
||||
|
||||
private class FakeItemDao : ItemDao {
|
||||
private val items = mutableListOf<ItemEntity>()
|
||||
private val flow = MutableStateFlow<List<ItemEntity>>(emptyList())
|
||||
|
||||
private fun emit() { flow.value = items.toList() }
|
||||
|
||||
override suspend fun insert(item: ItemEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun update(item: ItemEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun delete(item: ItemEntity) = throw UnsupportedOperationException()
|
||||
override fun getAll(): Flow<List<ItemEntity>> = flow
|
||||
override suspend fun getById(id: String): ItemEntity? = throw UnsupportedOperationException()
|
||||
override fun getByCategory(categoryId: Int): Flow<List<ItemEntity>> = throw UnsupportedOperationException()
|
||||
override fun getByLocation(locationId: Int): Flow<List<ItemEntity>> = throw UnsupportedOperationException()
|
||||
override fun getExpiringSoonByCutoff(cutoff: LocalDate): Flow<List<ItemEntity>> = throw UnsupportedOperationException()
|
||||
|
||||
override suspend fun upsertAll(items: List<ItemEntity>) {
|
||||
items.forEach { item ->
|
||||
val idx = this.items.indexOfFirst { it.id == item.id }
|
||||
if (idx >= 0) this.items[idx] = item else this.items.add(item)
|
||||
}
|
||||
emit()
|
||||
}
|
||||
|
||||
fun getItems(): List<ItemEntity> = items.toList()
|
||||
}
|
||||
|
||||
private class FakeSettingsDao : SettingsDao {
|
||||
private val items = mutableListOf<SettingsEntity>()
|
||||
private val flow = MutableStateFlow<List<SettingsEntity>>(emptyList())
|
||||
|
||||
private fun emit() { flow.value = items.toList() }
|
||||
|
||||
override suspend fun upsert(setting: SettingsEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun getValue(key: String): String? = throw UnsupportedOperationException()
|
||||
override fun getAll(): Flow<List<SettingsEntity>> = flow
|
||||
|
||||
override suspend fun upsertAll(settings: List<SettingsEntity>) {
|
||||
settings.forEach { setting ->
|
||||
val idx = items.indexOfFirst { it.key == setting.key }
|
||||
if (idx >= 0) items[idx] = setting else items.add(setting)
|
||||
}
|
||||
emit()
|
||||
}
|
||||
|
||||
fun getItems(): List<SettingsEntity> = items.toList()
|
||||
}
|
||||
|
||||
private val passThroughTransaction = DatabaseTransaction { block -> block() }
|
||||
|
||||
private fun buildItemEntity(id: String = "item1") = ItemEntity(
|
||||
id = id,
|
||||
name = "Konserve",
|
||||
categoryId = 1,
|
||||
quantity = 2.0,
|
||||
unit = "Stk",
|
||||
unitPrice = 1.5,
|
||||
kcalPer100g = null,
|
||||
expiryDate = null,
|
||||
locationId = 1,
|
||||
minStock = 1.0,
|
||||
notes = "",
|
||||
lastUpdated = 0L
|
||||
)
|
||||
|
||||
class ImportExportRepositoryImplTest {
|
||||
|
||||
private fun buildRepository(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,204 @@
|
|||
package de.krisenvorrat.app.data.export
|
||||
|
||||
import de.krisenvorrat.app.data.db.entity.CategoryEntity
|
||||
import de.krisenvorrat.app.data.db.entity.ItemEntity
|
||||
import de.krisenvorrat.app.data.db.entity.LocationEntity
|
||||
import de.krisenvorrat.app.data.db.entity.SettingsEntity
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import java.time.LocalDate
|
||||
|
||||
class JsonRoundtripTest {
|
||||
|
||||
private fun buildRepository(
|
||||
categoryDao: FakeCategoryDao = FakeCategoryDao(),
|
||||
locationDao: FakeLocationDao = FakeLocationDao(),
|
||||
itemDao: FakeItemDao = FakeItemDao(),
|
||||
settingsDao: FakeSettingsDao = FakeSettingsDao()
|
||||
) = ImportExportRepositoryImpl(
|
||||
categoryDao = categoryDao,
|
||||
locationDao = locationDao,
|
||||
itemDao = itemDao,
|
||||
settingsDao = settingsDao,
|
||||
transaction = passThroughTransaction
|
||||
)
|
||||
|
||||
@Test
|
||||
fun test_roundtrip_multipleItemsWithAllFields_dataIsPreservedLosslessly() = runBlocking {
|
||||
// Given
|
||||
val categories = listOf(
|
||||
CategoryEntity(id = 1, name = "Lebensmittel"),
|
||||
CategoryEntity(id = 2, name = "Hygiene")
|
||||
)
|
||||
val locations = listOf(
|
||||
LocationEntity(id = 1, name = "Keller"),
|
||||
LocationEntity(id = 2, name = "Garage")
|
||||
)
|
||||
val items = listOf(
|
||||
ItemEntity(
|
||||
id = "item-1",
|
||||
name = "Konserve",
|
||||
categoryId = 1,
|
||||
quantity = 10.0,
|
||||
unit = "Stk",
|
||||
unitPrice = 2.49,
|
||||
kcalPer100g = 180,
|
||||
expiryDate = LocalDate.of(2027, 6, 15),
|
||||
locationId = 1,
|
||||
minStock = 5.0,
|
||||
notes = "Ravioli",
|
||||
lastUpdated = 1700000000L
|
||||
),
|
||||
ItemEntity(
|
||||
id = "item-2",
|
||||
name = "Seife",
|
||||
categoryId = 2,
|
||||
quantity = 3.0,
|
||||
unit = "Stk",
|
||||
unitPrice = 0.99,
|
||||
kcalPer100g = null,
|
||||
expiryDate = null,
|
||||
locationId = 2,
|
||||
minStock = 1.0,
|
||||
notes = "",
|
||||
lastUpdated = 1700000001L
|
||||
)
|
||||
)
|
||||
val settings = listOf(
|
||||
SettingsEntity(key = "theme", value = "dark"),
|
||||
SettingsEntity(key = "language", value = "de")
|
||||
)
|
||||
|
||||
// Export-Repository mit vorhandenen Daten
|
||||
val exportCategoryDao = FakeCategoryDao()
|
||||
val exportLocationDao = FakeLocationDao()
|
||||
val exportItemDao = FakeItemDao()
|
||||
val exportSettingsDao = FakeSettingsDao()
|
||||
exportCategoryDao.upsertAll(categories)
|
||||
exportLocationDao.upsertAll(locations)
|
||||
exportItemDao.upsertAll(items)
|
||||
exportSettingsDao.upsertAll(settings)
|
||||
|
||||
val exportRepo = buildRepository(exportCategoryDao, exportLocationDao, exportItemDao, exportSettingsDao)
|
||||
|
||||
// When – Export
|
||||
val json = exportRepo.exportToJson()
|
||||
|
||||
// Then – Import in leeres Repository
|
||||
val importCategoryDao = FakeCategoryDao()
|
||||
val importLocationDao = FakeLocationDao()
|
||||
val importItemDao = FakeItemDao()
|
||||
val importSettingsDao = FakeSettingsDao()
|
||||
val importRepo = buildRepository(importCategoryDao, importLocationDao, importItemDao, importSettingsDao)
|
||||
|
||||
val result = importRepo.importFromJson(json)
|
||||
|
||||
// Then – Roundtrip ist verlustfrei
|
||||
assertTrue(result.isSuccess)
|
||||
|
||||
// Categories
|
||||
assertEquals(categories.size, importCategoryDao.getItems().size)
|
||||
categories.forEach { original ->
|
||||
val imported = importCategoryDao.getItems().find { it.id == original.id }
|
||||
assertEquals(original.name, imported?.name)
|
||||
}
|
||||
|
||||
// Locations
|
||||
assertEquals(locations.size, importLocationDao.getItems().size)
|
||||
locations.forEach { original ->
|
||||
val imported = importLocationDao.getItems().find { it.id == original.id }
|
||||
assertEquals(original.name, imported?.name)
|
||||
}
|
||||
|
||||
// Items – alle Felder prüfen
|
||||
assertEquals(items.size, importItemDao.getItems().size)
|
||||
items.forEach { original ->
|
||||
val imported = importItemDao.getItems().find { it.id == original.id }
|
||||
assertEquals(original.name, imported?.name)
|
||||
assertEquals(original.categoryId, imported?.categoryId)
|
||||
assertEquals(original.quantity, imported?.quantity)
|
||||
assertEquals(original.unit, imported?.unit)
|
||||
assertEquals(original.unitPrice, imported?.unitPrice)
|
||||
assertEquals(original.kcalPer100g, imported?.kcalPer100g)
|
||||
assertEquals(original.expiryDate, imported?.expiryDate)
|
||||
assertEquals(original.locationId, imported?.locationId)
|
||||
assertEquals(original.minStock, imported?.minStock)
|
||||
assertEquals(original.notes, imported?.notes)
|
||||
assertEquals(original.lastUpdated, imported?.lastUpdated)
|
||||
}
|
||||
|
||||
// Settings
|
||||
assertEquals(settings.size, importSettingsDao.getItems().size)
|
||||
settings.forEach { original ->
|
||||
val imported = importSettingsDao.getItems().find { it.key == original.key }
|
||||
assertEquals(original.value, imported?.value)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_roundtrip_itemWithNullableFields_nullsArePreserved() = runBlocking {
|
||||
// Given
|
||||
val categoryDao = FakeCategoryDao()
|
||||
val locationDao = FakeLocationDao()
|
||||
val itemDao = FakeItemDao()
|
||||
val settingsDao = FakeSettingsDao()
|
||||
categoryDao.upsertAll(listOf(CategoryEntity(id = 1, name = "Test")))
|
||||
locationDao.upsertAll(listOf(LocationEntity(id = 1, name = "Ort")))
|
||||
itemDao.upsertAll(listOf(
|
||||
ItemEntity(
|
||||
id = "null-item",
|
||||
name = "Ohne Extras",
|
||||
categoryId = 1,
|
||||
quantity = 1.0,
|
||||
unit = "Stk",
|
||||
unitPrice = 0.0,
|
||||
kcalPer100g = null,
|
||||
expiryDate = null,
|
||||
locationId = 1,
|
||||
minStock = 0.0,
|
||||
notes = "",
|
||||
lastUpdated = 0L
|
||||
)
|
||||
))
|
||||
val exportRepo = buildRepository(categoryDao, locationDao, itemDao, settingsDao)
|
||||
|
||||
// When
|
||||
val json = exportRepo.exportToJson()
|
||||
val importItemDao = FakeItemDao()
|
||||
val importCatDao = FakeCategoryDao()
|
||||
val importLocDao = FakeLocationDao()
|
||||
val importSetDao = FakeSettingsDao()
|
||||
val importRepo = buildRepository(importCatDao, importLocDao, importItemDao, importSetDao)
|
||||
val result = importRepo.importFromJson(json)
|
||||
|
||||
// Then
|
||||
assertTrue(result.isSuccess)
|
||||
val imported = importItemDao.getItems().first()
|
||||
assertEquals(null, imported.kcalPer100g)
|
||||
assertEquals(null, imported.expiryDate)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_roundtrip_emptyDatabase_producesEmptyCollections() = runBlocking {
|
||||
// Given
|
||||
val exportRepo = buildRepository()
|
||||
|
||||
// When
|
||||
val json = exportRepo.exportToJson()
|
||||
val importCategoryDao = FakeCategoryDao()
|
||||
val importLocationDao = FakeLocationDao()
|
||||
val importItemDao = FakeItemDao()
|
||||
val importSettingsDao = FakeSettingsDao()
|
||||
val importRepo = buildRepository(importCategoryDao, importLocationDao, importItemDao, importSettingsDao)
|
||||
val result = importRepo.importFromJson(json)
|
||||
|
||||
// Then
|
||||
assertTrue(result.isSuccess)
|
||||
assertEquals(0, importCategoryDao.getItems().size)
|
||||
assertEquals(0, importLocationDao.getItems().size)
|
||||
assertEquals(0, importItemDao.getItems().size)
|
||||
assertEquals(0, importSettingsDao.getItems().size)
|
||||
}
|
||||
}
|
||||
123
app/src/test/java/de/krisenvorrat/app/data/export/TestFakes.kt
Normal file
123
app/src/test/java/de/krisenvorrat/app/data/export/TestFakes.kt
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package de.krisenvorrat.app.data.export
|
||||
|
||||
import de.krisenvorrat.app.data.db.dao.CategoryDao
|
||||
import de.krisenvorrat.app.data.db.dao.ItemDao
|
||||
import de.krisenvorrat.app.data.db.dao.LocationDao
|
||||
import de.krisenvorrat.app.data.db.dao.SettingsDao
|
||||
import de.krisenvorrat.app.data.db.entity.CategoryEntity
|
||||
import de.krisenvorrat.app.data.db.entity.ItemEntity
|
||||
import de.krisenvorrat.app.data.db.entity.LocationEntity
|
||||
import de.krisenvorrat.app.data.db.entity.SettingsEntity
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import java.time.LocalDate
|
||||
|
||||
internal class FakeCategoryDao : CategoryDao {
|
||||
private val items = mutableListOf<CategoryEntity>()
|
||||
private val flow = MutableStateFlow<List<CategoryEntity>>(emptyList())
|
||||
|
||||
private fun emit() { flow.value = items.toList() }
|
||||
|
||||
override suspend fun insert(category: CategoryEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun update(category: CategoryEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun delete(category: CategoryEntity) = throw UnsupportedOperationException()
|
||||
override fun getAll(): Flow<List<CategoryEntity>> = flow
|
||||
override suspend fun getById(id: Int): CategoryEntity? = throw UnsupportedOperationException()
|
||||
|
||||
override suspend fun upsertAll(categories: List<CategoryEntity>) {
|
||||
categories.forEach { cat ->
|
||||
val idx = items.indexOfFirst { it.id == cat.id }
|
||||
if (idx >= 0) items[idx] = cat else items.add(cat)
|
||||
}
|
||||
emit()
|
||||
}
|
||||
|
||||
fun getItems(): List<CategoryEntity> = items.toList()
|
||||
}
|
||||
|
||||
internal class FakeLocationDao : LocationDao {
|
||||
private val items = mutableListOf<LocationEntity>()
|
||||
private val flow = MutableStateFlow<List<LocationEntity>>(emptyList())
|
||||
|
||||
private fun emit() { flow.value = items.toList() }
|
||||
|
||||
override suspend fun insert(location: LocationEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun update(location: LocationEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun delete(location: LocationEntity) = throw UnsupportedOperationException()
|
||||
override fun getAll(): Flow<List<LocationEntity>> = flow
|
||||
override suspend fun getById(id: Int): LocationEntity? = throw UnsupportedOperationException()
|
||||
|
||||
override suspend fun upsertAll(locations: List<LocationEntity>) {
|
||||
locations.forEach { loc ->
|
||||
val idx = items.indexOfFirst { it.id == loc.id }
|
||||
if (idx >= 0) items[idx] = loc else items.add(loc)
|
||||
}
|
||||
emit()
|
||||
}
|
||||
|
||||
fun getItems(): List<LocationEntity> = items.toList()
|
||||
}
|
||||
|
||||
internal class FakeItemDao : ItemDao {
|
||||
private val items = mutableListOf<ItemEntity>()
|
||||
private val flow = MutableStateFlow<List<ItemEntity>>(emptyList())
|
||||
|
||||
private fun emit() { flow.value = items.toList() }
|
||||
|
||||
override suspend fun insert(item: ItemEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun update(item: ItemEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun delete(item: ItemEntity) = throw UnsupportedOperationException()
|
||||
override fun getAll(): Flow<List<ItemEntity>> = flow
|
||||
override suspend fun getById(id: String): ItemEntity? = throw UnsupportedOperationException()
|
||||
override fun getByCategory(categoryId: Int): Flow<List<ItemEntity>> = throw UnsupportedOperationException()
|
||||
override fun getByLocation(locationId: Int): Flow<List<ItemEntity>> = throw UnsupportedOperationException()
|
||||
override fun getExpiringSoonByCutoff(cutoff: LocalDate): Flow<List<ItemEntity>> = throw UnsupportedOperationException()
|
||||
|
||||
override suspend fun upsertAll(items: List<ItemEntity>) {
|
||||
items.forEach { item ->
|
||||
val idx = this.items.indexOfFirst { it.id == item.id }
|
||||
if (idx >= 0) this.items[idx] = item else this.items.add(item)
|
||||
}
|
||||
emit()
|
||||
}
|
||||
|
||||
fun getItems(): List<ItemEntity> = items.toList()
|
||||
}
|
||||
|
||||
internal class FakeSettingsDao : SettingsDao {
|
||||
private val items = mutableListOf<SettingsEntity>()
|
||||
private val flow = MutableStateFlow<List<SettingsEntity>>(emptyList())
|
||||
|
||||
private fun emit() { flow.value = items.toList() }
|
||||
|
||||
override suspend fun upsert(setting: SettingsEntity) = throw UnsupportedOperationException()
|
||||
override suspend fun getValue(key: String): String? = throw UnsupportedOperationException()
|
||||
override fun getAll(): Flow<List<SettingsEntity>> = flow
|
||||
|
||||
override suspend fun upsertAll(settings: List<SettingsEntity>) {
|
||||
settings.forEach { setting ->
|
||||
val idx = items.indexOfFirst { it.key == setting.key }
|
||||
if (idx >= 0) items[idx] = setting else items.add(setting)
|
||||
}
|
||||
emit()
|
||||
}
|
||||
|
||||
fun getItems(): List<SettingsEntity> = items.toList()
|
||||
}
|
||||
|
||||
internal val passThroughTransaction = DatabaseTransaction { block -> block() }
|
||||
|
||||
internal fun buildItemEntity(id: String = "item1") = ItemEntity(
|
||||
id = id,
|
||||
name = "Konserve",
|
||||
categoryId = 1,
|
||||
quantity = 2.0,
|
||||
unit = "Stk",
|
||||
unitPrice = 1.5,
|
||||
kcalPer100g = null,
|
||||
expiryDate = null,
|
||||
locationId = 1,
|
||||
minStock = 1.0,
|
||||
notes = "",
|
||||
lastUpdated = 0L
|
||||
)
|
||||
Loading…
Reference in a new issue