diff --git a/Corona-Warn-App/schemas/de.rki.coronawarnapp.contactdiary.storage.ContactDiaryDatabase/1.json b/Corona-Warn-App/schemas/de.rki.coronawarnapp.contactdiary.storage.ContactDiaryDatabase/1.json new file mode 100644 index 0000000000000000000000000000000000000000..2b4c5f5e342a67902bd23aa0c3492586dac09a1d --- /dev/null +++ b/Corona-Warn-App/schemas/de.rki.coronawarnapp.contactdiary.storage.ContactDiaryDatabase/1.json @@ -0,0 +1,154 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "02f231d9ba162399bf1884e74266fa0e", + "entities": [ + { + "tableName": "ContactDiaryLocationEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`locationId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `locationName` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "locationId", + "columnName": "locationId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "locationName", + "columnName": "locationName", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "locationId" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "ContactDiaryLocationVisitEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `date` TEXT NOT NULL, `fkLocationId` INTEGER NOT NULL, FOREIGN KEY(`fkLocationId`) REFERENCES `ContactDiaryLocationEntity`(`locationId`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fkLocationId", + "columnName": "fkLocationId", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [ + { + "table": "ContactDiaryLocationEntity", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "fkLocationId" + ], + "referencedColumns": [ + "locationId" + ] + } + ] + }, + { + "tableName": "ContactDiaryPersonEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`personId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `fullName` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "personId", + "columnName": "personId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "fullName", + "columnName": "fullName", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "personId" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "ContactDiaryPersonEncounterEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `date` TEXT NOT NULL, `fkPersonId` INTEGER NOT NULL, FOREIGN KEY(`fkPersonId`) REFERENCES `ContactDiaryPersonEntity`(`personId`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fkPersonId", + "columnName": "fkPersonId", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [ + { + "table": "ContactDiaryPersonEntity", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "fkPersonId" + ], + "referencedColumns": [ + "personId" + ] + } + ] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '02f231d9ba162399bf1884e74266fa0e')" + ] + } +} \ No newline at end of file diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..11fb352a5b7f982f910ade41c89c384dd121783c --- /dev/null +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabaseTest.kt @@ -0,0 +1,130 @@ +package de.rki.coronawarnapp.contactdiary.storage + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryLocationEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryLocationVisitEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryLocationVisitWrapper +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryPersonEncounterEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryPersonEncounterWrapper +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryPersonEntity +import io.kotest.matchers.shouldBe +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.runBlocking +import org.joda.time.LocalDate +import org.junit.After +import org.junit.Test +import org.junit.runner.RunWith +import testhelpers.BaseTest + +@RunWith(AndroidJUnit4::class) +class ContactDiaryDatabaseTest : BaseTest() { + + // TestData + private val date = LocalDate.now() + private val person = ContactDiaryPersonEntity(personId = 1, fullName = "Peter") + private val location = ContactDiaryLocationEntity(locationId = 2, locationName = "Rewe Wiesloch") + private val personEncounter = ContactDiaryPersonEncounterEntity(id = 3, date = date, fkPersonId = person.personId) + private val locationVisit = ContactDiaryLocationVisitEntity(id = 4, date = date, fkLocationId = location.locationId) + + // DB + private val contactDiaryDatabase: ContactDiaryDatabase = + Room.inMemoryDatabaseBuilder( + ApplicationProvider.getApplicationContext(), + ContactDiaryDatabase::class.java + ) + .build() + + private val personDao = contactDiaryDatabase.personDao() + private val locationDao = contactDiaryDatabase.locationDao() + private val personEncounterDao = contactDiaryDatabase.personEncounterDao() + private val locationVisitDao = contactDiaryDatabase.locationVisitDao() + + private fun List<ContactDiaryPersonEncounterWrapper>.toContactDiaryPersonEncounterEntityList(): List<ContactDiaryPersonEncounterEntity> = + this.map { it.contactDiaryPersonEncounterEntity } + + private fun List<ContactDiaryLocationVisitWrapper>.toContactDiaryLocationVisitEntityList(): List<ContactDiaryLocationVisitEntity> = + this.map { it.contactDiaryLocationVisitEntity } + + @After + fun teardown() { + contactDiaryDatabase.clearAllTables() + } + + @Test + fun checkPersonEncounterDeletedWhenReferencedPersonDeleted() = runBlocking { + val personFlow = personDao.allEntries() + val personEncounterFlow = personEncounterDao + .allEntries() + .map { it.toContactDiaryPersonEncounterEntityList() } + + personFlow.first() shouldBe emptyList() + personEncounterFlow.first() shouldBe emptyList() + + personDao.insert(person) + personEncounterDao.insert(personEncounter) + personFlow.first() shouldBe listOf(person) + personEncounterFlow.first() shouldBe listOf(personEncounter) + + personDao.delete(person) + personFlow.first() shouldBe emptyList() + personEncounterFlow.first() shouldBe emptyList() + } + + @Test + fun checkLocationVisitDeletedWhenReferencedLocationDeleted() = runBlocking { + val locationFlow = locationDao.allEntries() + val locationVisitFlow = locationVisitDao + .allEntries() + .map { it.toContactDiaryLocationVisitEntityList() } + + locationFlow.first() shouldBe emptyList() + locationVisitFlow.first() shouldBe emptyList() + + locationDao.insert(location) + locationVisitDao.insert(locationVisit) + locationFlow.first() shouldBe listOf(location) + locationVisitFlow.first() shouldBe listOf(locationVisit) + + locationDao.delete(location) + locationFlow.first() shouldBe emptyList() + locationVisitFlow.first() shouldBe emptyList() + } + + @Test + fun getCorrectEntityForDate() = runBlocking { + val yesterday = LocalDate.now().minusDays(1) + val tomorrow = LocalDate.now().plusDays(1) + val personEncounterYesterday = + ContactDiaryPersonEncounterEntity(id = 5, date = yesterday, fkPersonId = person.personId) + val personEncounterTomorrow = + ContactDiaryPersonEncounterEntity(id = 6, date = tomorrow, fkPersonId = person.personId) + val locationVisitYesterday = + ContactDiaryLocationVisitEntity(id = 7, date = yesterday, fkLocationId = location.locationId) + val locationVisitTomorrow = + ContactDiaryLocationVisitEntity(id = 8, date = tomorrow, fkLocationId = location.locationId) + val encounterList = listOf(personEncounter, personEncounterYesterday, personEncounterTomorrow) + val visitList = listOf(locationVisit, locationVisitYesterday, locationVisitTomorrow) + val personEncounterFlow = personEncounterDao.allEntries().map { it.toContactDiaryPersonEncounterEntityList() } + val locationVisitFlow = locationVisitDao.allEntries() + .map { it.toContactDiaryLocationVisitEntityList() } + + personDao.insert(person) + personEncounterDao.insert(encounterList) + locationDao.insert(location) + locationVisitDao.insert(visitList) + + personEncounterFlow.first() shouldBe encounterList + locationVisitFlow.first() shouldBe visitList + + personEncounterDao.entitiesForDate(yesterday).first().toContactDiaryPersonEncounterEntityList() shouldBe listOf(personEncounterYesterday) + personEncounterDao.entitiesForDate(date).first().toContactDiaryPersonEncounterEntityList() shouldBe listOf(personEncounter) + personEncounterDao.entitiesForDate(tomorrow).first().toContactDiaryPersonEncounterEntityList() shouldBe listOf(personEncounterTomorrow) + + locationVisitDao.entitiesForDate(yesterday).first().toContactDiaryLocationVisitEntityList() shouldBe listOf(locationVisitYesterday) + locationVisitDao.entitiesForDate(date).first().toContactDiaryLocationVisitEntityList() shouldBe listOf(locationVisit) + locationVisitDao.entitiesForDate(tomorrow).first().toContactDiaryLocationVisitEntityList() shouldBe listOf(locationVisitTomorrow) + } +} diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionDoneFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionDoneFragmentTest.kt deleted file mode 100644 index 989bbcdcbeb17fcc04c3e0df15b236c11da33df8..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionDoneFragmentTest.kt +++ /dev/null @@ -1,58 +0,0 @@ -package de.rki.coronawarnapp.ui.submission - -import androidx.fragment.app.testing.launchFragment -import androidx.fragment.app.testing.launchFragmentInContainer -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.ext.junit.runners.AndroidJUnit4 -import dagger.Module -import dagger.android.ContributesAndroidInjector -import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.ui.submission.fragment.SubmissionDoneFragment -import de.rki.coronawarnapp.ui.submission.viewmodel.SubmissionDoneViewModel -import io.mockk.MockKAnnotations -import io.mockk.impl.annotations.MockK -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import testhelpers.BaseUITest - -@RunWith(AndroidJUnit4::class) -class SubmissionDoneFragmentTest : BaseUITest() { - - @MockK lateinit var viewModel: SubmissionDoneViewModel - - @Before - fun setup() { - MockKAnnotations.init(this, relaxed = true) - setupMockViewModel(object : SubmissionDoneViewModel.Factory { - override fun create(): SubmissionDoneViewModel = viewModel - }) - } - - @After - fun teardown() { - clearAllViewModels() - } - - @Test - fun launch_fragment() { - launchFragment<SubmissionDoneFragment>() - } - - @Test fun testDoneClicked() { - val scenario = launchFragmentInContainer<SubmissionDoneFragment>() - onView(withId(R.id.submission_done_button_done)) - .perform(click()) - - // TODO verify result - } -} - -@Module -abstract class SubmissionDoneTestModule { - @ContributesAndroidInjector - abstract fun submissionDoneScreen(): SubmissionDoneFragment -} diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionOtherWarningFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionOtherWarningFragmentTest.kt deleted file mode 100644 index eb4a3dba7d25d21d9461208ff1d5604a5cf1f794..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionOtherWarningFragmentTest.kt +++ /dev/null @@ -1,83 +0,0 @@ -package de.rki.coronawarnapp.ui.submission - -import androidx.fragment.app.testing.launchFragment -import androidx.fragment.app.testing.launchFragmentInContainer -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.action.ViewActions.scrollTo -import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.ext.junit.runners.AndroidJUnit4 -import dagger.Module -import dagger.android.ContributesAndroidInjector -import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.submission.Symptoms -import de.rki.coronawarnapp.ui.submission.symptoms.calendar.SubmissionSymptomCalendarViewModel -import de.rki.coronawarnapp.ui.submission.symptoms.introduction.SubmissionSymptomIntroductionViewModel -import de.rki.coronawarnapp.ui.submission.warnothers.SubmissionResultPositiveOtherWarningFragment -import de.rki.coronawarnapp.ui.submission.warnothers.SubmissionResultPositiveOtherWarningViewModel -import io.mockk.MockKAnnotations -import io.mockk.impl.annotations.MockK -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import testhelpers.BaseUITest - -@RunWith(AndroidJUnit4::class) -class SubmissionOtherWarningFragmentTest : BaseUITest() { - - @MockK lateinit var viewModel: SubmissionResultPositiveOtherWarningViewModel - @MockK lateinit var symptomIntroViewModel: SubmissionSymptomIntroductionViewModel - @MockK lateinit var symptomCalendarViewModel: SubmissionSymptomCalendarViewModel - - // @MockK lateinit var symptoms: Symptoms - - @Before - fun setup() { - MockKAnnotations.init(this, relaxed = true) - setupMockViewModel(object : SubmissionSymptomIntroductionViewModel.Factory { - override fun create(): SubmissionSymptomIntroductionViewModel = symptomIntroViewModel - }) - - /* every { symptomIntroViewModel.symptomIndication } returns MutableLiveData() - every { symptomIntroViewModel. } returns MutableLiveData() - - symptomIntroViewModel.onPositiveSymptomIndication() - symptomIntroViewModel.symptomIndication.postValue("tesasdf") */ - - setupMockViewModel(object : SubmissionSymptomCalendarViewModel.Factory { - override fun create(symptomIndication: Symptoms.Indication): SubmissionSymptomCalendarViewModel = - symptomCalendarViewModel - }) - - setupMockViewModel(object : SubmissionResultPositiveOtherWarningViewModel.Factory { - override fun create(symptoms: Symptoms): SubmissionResultPositiveOtherWarningViewModel = - viewModel - }) - } - - @After - fun teardown() { - clearAllViewModels() - } - - @Test - fun launch_fragment() { - launchFragment<SubmissionResultPositiveOtherWarningFragment>() - } - - @Test fun testOtherWarningNextClicked() { - val scenario = launchFragmentInContainer<SubmissionResultPositiveOtherWarningFragment>() - onView(withId(R.id.submission_positive_other_warning_button_next)) - .perform(scrollTo()) - .perform(click()) - - // TODO verify result - } -} - -@Module -abstract class SubmissionOtherWarningTestModule { - @ContributesAndroidInjector - abstract fun submissionOtherWarningScreen(): SubmissionResultPositiveOtherWarningFragment -} diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt deleted file mode 100644 index b592443c863b3a5d634d83696455ae1b42252418..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt +++ /dev/null @@ -1,68 +0,0 @@ -package de.rki.coronawarnapp.ui.submission - -import androidx.fragment.app.testing.launchFragment -import androidx.fragment.app.testing.launchFragmentInContainer -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.action.ViewActions.scrollTo -import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.ext.junit.runners.AndroidJUnit4 -import dagger.Module -import dagger.android.ContributesAndroidInjector -import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.submission.Symptoms -import de.rki.coronawarnapp.ui.submission.symptoms.calendar.SubmissionSymptomCalendarFragment -import de.rki.coronawarnapp.ui.submission.symptoms.calendar.SubmissionSymptomCalendarViewModel -import io.mockk.MockKAnnotations -import io.mockk.impl.annotations.MockK -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import testhelpers.BaseUITest - -@RunWith(AndroidJUnit4::class) -class SubmissionSymptomCalendarFragmentTest : BaseUITest() { - - @MockK lateinit var viewModel: SubmissionSymptomCalendarViewModel - - /* private val symptoms = Symptoms(Symptoms.StartOf.OneToTwoWeeksAgo, POSITIVE) - private val positiveSymptomIndication = POSITIVE; - private val negativeSymptomIndication = Symptoms.Indication.NEGATIVE; - private val noSymptomIndication = Symptoms.Indication.NO_INFORMATION;*/ - - @Before - fun setup() { - MockKAnnotations.init(this, relaxed = true) - - setupMockViewModel(object : SubmissionSymptomCalendarViewModel.Factory { - override fun create(symptomIndication: Symptoms.Indication): SubmissionSymptomCalendarViewModel = - viewModel - }) - } - - @After - fun teardown() { - clearAllViewModels() - } - - @Test - fun launch_fragment() { - launchFragment<SubmissionSymptomCalendarFragment>() - } - - @Test fun testSymptomCalendarNextClicked() { - val scenario = launchFragmentInContainer<SubmissionSymptomCalendarFragment>() - onView(withId(R.id.symptom_button_next)) - .perform(scrollTo()) - .perform(click()) - - // TODO verify result - } -} - -@Module -abstract class SubmissionSymptomCalendarFragmentTestModule { - @ContributesAndroidInjector - abstract fun submissionSymptomCalendarScreen(): SubmissionSymptomCalendarFragment -} diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt index 993882d9306c564008e1ba4f3efee7be8e2b8538..cc999d6c3f93320ac4c2f84c447d0d29d6b307d5 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt @@ -15,12 +15,12 @@ import de.rki.coronawarnapp.ui.submission.testresult.SubmissionTestResultConsent import de.rki.coronawarnapp.ui.submission.testresult.SubmissionTestResultConsentGivenViewModel import io.mockk.MockKAnnotations import io.mockk.impl.annotations.MockK +import io.mockk.mockk +import io.mockk.verify import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mockito.mock -import org.mockito.Mockito.verify import testhelpers.BaseUITest @RunWith(AndroidJUnit4::class) @@ -49,7 +49,7 @@ class SubmissionTestResultConsentGivenFragmentTest : BaseUITest() { @Test fun testEventConsentGivenContinueWithSymptomsClicked() { - val mockNavController = mock(NavController::class.java) + val mockNavController = mockk<NavController>() val scenario = launchFragmentInContainer<SubmissionTestResultConsentGivenFragment>() scenario.onFragment { fragment -> @@ -57,7 +57,9 @@ class SubmissionTestResultConsentGivenFragmentTest : BaseUITest() { } // Verify that performing a click prompts the correct Navigation action onView(ViewMatchers.withId(R.id.submission_test_result_button_consent_given_continue)).perform(ViewActions.click()) - verify(mockNavController).navigate(R.id.action_submissionTestResultConsentGivenFragment_to_submissionSymptomIntroductionFragment) + verify { + mockNavController.navigate(R.id.action_submissionTestResultConsentGivenFragment_to_submissionSymptomIntroductionFragment) + } } } diff --git a/Corona-Warn-App/src/androidTest/java/testhelpers/FragmentTestModuleRegistrar.kt b/Corona-Warn-App/src/androidTest/java/testhelpers/FragmentTestModuleRegistrar.kt index 2e7625e1fc676f8106f7e15034a670ff387547e9..1370a3a2bc1b1e7af66cf722933061d02bb15fa6 100644 --- a/Corona-Warn-App/src/androidTest/java/testhelpers/FragmentTestModuleRegistrar.kt +++ b/Corona-Warn-App/src/androidTest/java/testhelpers/FragmentTestModuleRegistrar.kt @@ -10,11 +10,8 @@ import de.rki.coronawarnapp.ui.onboarding.OnboardingTestFragmentModule import de.rki.coronawarnapp.ui.onboarding.OnboardingTracingFragmentTestModule import de.rki.coronawarnapp.ui.submission.SubmissionContactTestModule import de.rki.coronawarnapp.ui.submission.SubmissionDispatcherTestModule -import de.rki.coronawarnapp.ui.submission.SubmissionDoneTestModule import de.rki.coronawarnapp.ui.submission.SubmissionIntroTestModule -import de.rki.coronawarnapp.ui.submission.SubmissionOtherWarningTestModule import de.rki.coronawarnapp.ui.submission.SubmissionQRScanFragmentModule -import de.rki.coronawarnapp.ui.submission.SubmissionSymptomCalendarFragmentTestModule import de.rki.coronawarnapp.ui.submission.SubmissionSymptomIntroFragmentTestModule import de.rki.coronawarnapp.ui.submission.SubmissionTanTestModule import de.rki.coronawarnapp.ui.submission.SubmissionTestResultConsentGivenTestModule @@ -36,11 +33,8 @@ import de.rki.coronawarnapp.ui.submission.SubmissionTestResultTestModule SubmissionTanTestModule::class, SubmissionTestResultTestModule::class, SubmissionTestResultConsentGivenTestModule::class, - SubmissionOtherWarningTestModule::class, SubmissionSymptomIntroFragmentTestModule::class, - SubmissionSymptomCalendarFragmentTestModule::class, SubmissionContactTestModule::class, - SubmissionDoneTestModule::class, SubmissionQRScanFragmentModule::class ] ) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryModule.kt new file mode 100644 index 0000000000000000000000000000000000000000..b32ac7a951a0aaf8c05e6ad11f7abf7cf73f9c98 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ContactDiaryModule.kt @@ -0,0 +1,42 @@ +package de.rki.coronawarnapp.contactdiary + +import dagger.Module +import dagger.Provides +import de.rki.coronawarnapp.contactdiary.storage.ContactDiaryDatabase +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryLocationDao +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryLocationVisitDao +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryPersonDao +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryPersonEncounterDao +import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository +import de.rki.coronawarnapp.contactdiary.storage.repo.DefaultContactDiaryRepository +import javax.inject.Singleton + +@Module +class ContactDiaryModule { + + @Singleton + @Provides + fun contactDiaryDatabase(contactDiaryDatabaseFactory: ContactDiaryDatabase.Factory): ContactDiaryDatabase = + contactDiaryDatabaseFactory.create() + + @Provides + fun locationDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryLocationDao = + contactDiaryDatabase.locationDao() + + @Provides + fun locationVisitDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryLocationVisitDao = + contactDiaryDatabase.locationVisitDao() + + @Provides + fun personDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryPersonDao = + contactDiaryDatabase.personDao() + + @Provides + fun personEncounterDao(contactDiaryDatabase: ContactDiaryDatabase): ContactDiaryPersonEncounterDao = + contactDiaryDatabase.personEncounterDao() + + @Singleton + @Provides + fun contactDiaryRepo(defaultContactDiaryRepository: DefaultContactDiaryRepository): ContactDiaryRepository = + defaultContactDiaryRepository +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryElement.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryElement.kt deleted file mode 100644 index ec1a863b74e3e3a09b905aba791f2219a05a2c0d..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryElement.kt +++ /dev/null @@ -1,17 +0,0 @@ -package de.rki.coronawarnapp.contactdiary.model - -import java.time.Instant - -interface ContactDiaryElement { - - val createdAt: Instant - - val people: List<Person> - val locations: List<Location> - - val numberOfPersons: Int - get() = people.size - - val numberOfLocations: Int - get() = locations.size -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt new file mode 100644 index 0000000000000000000000000000000000000000..4618a0b9da3230445c696dde7aae7834289dbc13 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocation.kt @@ -0,0 +1,9 @@ +package de.rki.coronawarnapp.contactdiary.model + +interface ContactDiaryLocation { + val locationId: Long + var locationName: String +} + +fun List<ContactDiaryLocation>.sortByNameAndIdASC(): List<ContactDiaryLocation> = + this.sortedWith(compareBy({ it.locationName }, { it.locationId })) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocationVisit.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocationVisit.kt new file mode 100644 index 0000000000000000000000000000000000000000..a1f4061d7966086715a548e5c50784a8f9f1a085 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryLocationVisit.kt @@ -0,0 +1,12 @@ +package de.rki.coronawarnapp.contactdiary.model + +import org.joda.time.LocalDate + +interface ContactDiaryLocationVisit { + val id: Long + val date: LocalDate + val contactDiaryLocation: ContactDiaryLocation +} + +fun List<ContactDiaryLocationVisit>.sortByNameAndIdASC(): List<ContactDiaryLocationVisit> = + this.sortedWith(compareBy({ it.contactDiaryLocation.locationName }, { it.contactDiaryLocation.locationId })) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryPerson.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryPerson.kt new file mode 100644 index 0000000000000000000000000000000000000000..5657484a05b1e2c808c21c69808a8d456f5ab4a0 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryPerson.kt @@ -0,0 +1,9 @@ +package de.rki.coronawarnapp.contactdiary.model + +interface ContactDiaryPerson { + val personId: Long + var fullName: String +} + +fun List<ContactDiaryPerson>.sortByNameAndIdASC(): List<ContactDiaryPerson> = + this.sortedWith(compareBy({ it.fullName }, { it.personId })) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryPersonEncounter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryPersonEncounter.kt new file mode 100644 index 0000000000000000000000000000000000000000..60bf3887a3680388cbb6ec527eaf5e0bfc86ffec --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/ContactDiaryPersonEncounter.kt @@ -0,0 +1,12 @@ +package de.rki.coronawarnapp.contactdiary.model + +import org.joda.time.LocalDate + +interface ContactDiaryPersonEncounter { + val id: Long + val date: LocalDate + val contactDiaryPerson: ContactDiaryPerson +} + +fun List<ContactDiaryPersonEncounter>.sortByNameAndIdASC(): List<ContactDiaryPersonEncounter> = + this.sortedWith(compareBy({ it.contactDiaryPerson.fullName }, { it.contactDiaryPerson.personId })) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryElement.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryElement.kt deleted file mode 100644 index 0bd0eaf80c02fb4f55021845dfefd0498c0d6359..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryElement.kt +++ /dev/null @@ -1,9 +0,0 @@ -package de.rki.coronawarnapp.contactdiary.model - -import java.time.Instant - -data class DefaultContactDiaryElement( - override val createdAt: Instant, - override val people: List<Person>, - override val locations: List<Location> -) : ContactDiaryElement diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt new file mode 100644 index 0000000000000000000000000000000000000000..65bf6c6e5be5df3b6215d18c2bc2e371bec46e29 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocation.kt @@ -0,0 +1,6 @@ +package de.rki.coronawarnapp.contactdiary.model + +data class DefaultContactDiaryLocation( + override val locationId: Long = 0L, + override var locationName: String +) : ContactDiaryLocation diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocationVisit.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocationVisit.kt new file mode 100644 index 0000000000000000000000000000000000000000..0c2124a3c625123c3bac258c68db6e82e92e6702 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryLocationVisit.kt @@ -0,0 +1,9 @@ +package de.rki.coronawarnapp.contactdiary.model + +import org.joda.time.LocalDate + +data class DefaultContactDiaryLocationVisit( + override val id: Long = 0L, + override val date: LocalDate, + override val contactDiaryLocation: ContactDiaryLocation +) : ContactDiaryLocationVisit diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryPerson.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryPerson.kt new file mode 100644 index 0000000000000000000000000000000000000000..fdf73bd6e014940d71c58ea54726050df3519c20 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryPerson.kt @@ -0,0 +1,6 @@ +package de.rki.coronawarnapp.contactdiary.model + +data class DefaultContactDiaryPerson( + override val personId: Long = 0L, + override var fullName: String +) : ContactDiaryPerson diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryPersonEncounter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryPersonEncounter.kt new file mode 100644 index 0000000000000000000000000000000000000000..bdd303ef066b478fc64b0063e8800bab7a098285 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultContactDiaryPersonEncounter.kt @@ -0,0 +1,9 @@ +package de.rki.coronawarnapp.contactdiary.model + +import org.joda.time.LocalDate + +data class DefaultContactDiaryPersonEncounter( + override val id: Long = 0L, + override val date: LocalDate, + override val contactDiaryPerson: ContactDiaryPerson +) : ContactDiaryPersonEncounter diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultLocation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultLocation.kt deleted file mode 100644 index 37ed6bfa0ace2d4019dcfe7d70beeaf699edc954..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultLocation.kt +++ /dev/null @@ -1,3 +0,0 @@ -package de.rki.coronawarnapp.contactdiary.model - -data class DefaultLocation(override var locationName: String) : Location diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultPerson.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultPerson.kt deleted file mode 100644 index 9a8ed3414b8bba6e45294e61877fefba2fdef1a7..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/DefaultPerson.kt +++ /dev/null @@ -1,3 +0,0 @@ -package de.rki.coronawarnapp.contactdiary.model - -data class DefaultPerson(override var fullName: String) : Person diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/Location.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/Location.kt deleted file mode 100644 index b2195b3339876962cadbda7eb0e6f4a3f4f08981..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/Location.kt +++ /dev/null @@ -1,5 +0,0 @@ -package de.rki.coronawarnapp.contactdiary.model - -interface Location { - var locationName: String -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/Person.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/Person.kt deleted file mode 100644 index 7fcc04e912e97153438e196efa0d959d4ef317af..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/model/Person.kt +++ /dev/null @@ -1,5 +0,0 @@ -package de.rki.coronawarnapp.contactdiary.model - -interface Person { - var fullName: String -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabase.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabase.kt new file mode 100644 index 0000000000000000000000000000000000000000..b80474dca2a053ec526af698686352a6904cb838 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryDatabase.kt @@ -0,0 +1,48 @@ +package de.rki.coronawarnapp.contactdiary.storage + +import android.content.Context +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase +import androidx.room.TypeConverters +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryLocationDao +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryLocationVisitDao +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryPersonDao +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryPersonEncounterDao +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryLocationEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryLocationVisitEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryPersonEncounterEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryPersonEntity +import de.rki.coronawarnapp.util.database.CommonConverters +import de.rki.coronawarnapp.util.di.AppContext +import javax.inject.Inject + +@Database( + entities = [ + ContactDiaryLocationEntity::class, + ContactDiaryLocationVisitEntity::class, + ContactDiaryPersonEntity::class, + ContactDiaryPersonEncounterEntity::class + ], + version = 1, + exportSchema = true +) +@TypeConverters(CommonConverters::class) +abstract class ContactDiaryDatabase : RoomDatabase() { + + abstract fun locationDao(): ContactDiaryLocationDao + abstract fun locationVisitDao(): ContactDiaryLocationVisitDao + abstract fun personDao(): ContactDiaryPersonDao + abstract fun personEncounterDao(): ContactDiaryPersonEncounterDao + + class Factory @Inject constructor(@AppContext private val ctx: Context) { + fun create(): ContactDiaryDatabase = Room + .databaseBuilder(ctx, ContactDiaryDatabase::class.java, CONTACT_DIARY_DATABASE_NAME) + .fallbackToDestructiveMigration() + .build() + } + + companion object { + private const val CONTACT_DIARY_DATABASE_NAME = "ContactDiary-db" + } +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryRepository.kt deleted file mode 100644 index e4dd8e0dca43eef4c54053e3c70b720fd278da6b..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/ContactDiaryRepository.kt +++ /dev/null @@ -1,3 +0,0 @@ -package de.rki.coronawarnapp.contactdiary.storage - -class ContactDiaryRepository diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/BaseDao.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/BaseDao.kt new file mode 100644 index 0000000000000000000000000000000000000000..f6c96c1a458a47a32305fb63f9bfbb313aba0ea6 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/BaseDao.kt @@ -0,0 +1,15 @@ +package de.rki.coronawarnapp.contactdiary.storage.dao + +import kotlinx.coroutines.flow.Flow + +interface BaseDao<in T, out U> { + suspend fun insert(entity: T) + suspend fun insert(entities: List<T>) + suspend fun update(entity: T) + suspend fun update(entities: List<T>) + suspend fun delete(entity: T) + suspend fun delete(entities: List<T>) + suspend fun deleteAll() + suspend fun entityForId(id: Long): U + fun allEntries(): Flow<List<U>> +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/BaseRoomDao.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/BaseRoomDao.kt new file mode 100644 index 0000000000000000000000000000000000000000..22776a74dcd7f6327730d0435f529c71a793a128 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/BaseRoomDao.kt @@ -0,0 +1,25 @@ +package de.rki.coronawarnapp.contactdiary.storage.dao + +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.Update + +abstract class BaseRoomDao<T, U> : BaseDao<T, U> { + @Insert + abstract override suspend fun insert(entity: T) + + @Insert + abstract override suspend fun insert(entities: List<T>) + + @Update + abstract override suspend fun update(entity: T) + + @Update + abstract override suspend fun update(entities: List<T>) + + @Delete + abstract override suspend fun delete(entity: T) + + @Delete + abstract override suspend fun delete(entities: List<T>) +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryLocationDao.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryLocationDao.kt new file mode 100644 index 0000000000000000000000000000000000000000..4d9cfa474c3b876266969d55767b95650d3d6efe --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryLocationDao.kt @@ -0,0 +1,19 @@ +package de.rki.coronawarnapp.contactdiary.storage.dao + +import androidx.room.Dao +import androidx.room.Query +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryLocationEntity +import kotlinx.coroutines.flow.Flow + +@Dao +abstract class ContactDiaryLocationDao : BaseRoomDao<ContactDiaryLocationEntity, ContactDiaryLocationEntity>() { + + @Query("SELECT * FROM locations") + abstract override fun allEntries(): Flow<List<ContactDiaryLocationEntity>> + + @Query("SELECT * FROM locations WHERE locationId = :id") + abstract override suspend fun entityForId(id: Long): ContactDiaryLocationEntity + + @Query("DELETE FROM locations") + abstract override suspend fun deleteAll() +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryLocationVisitDao.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryLocationVisitDao.kt new file mode 100644 index 0000000000000000000000000000000000000000..ac587cc8ca8d311674633f459b3bcace1f5d0abe --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryLocationVisitDao.kt @@ -0,0 +1,29 @@ +package de.rki.coronawarnapp.contactdiary.storage.dao + +import androidx.room.Dao +import androidx.room.Query +import androidx.room.Transaction +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryLocationVisitEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryLocationVisitWrapper +import kotlinx.coroutines.flow.Flow +import org.joda.time.LocalDate + +@Dao +abstract class ContactDiaryLocationVisitDao : + BaseRoomDao<ContactDiaryLocationVisitEntity, ContactDiaryLocationVisitWrapper>() { + + @Transaction + @Query("SELECT * FROM locationvisits") + abstract override fun allEntries(): Flow<List<ContactDiaryLocationVisitWrapper>> + + @Transaction + @Query("SELECT * FROM locationvisits WHERE id = :id") + abstract override suspend fun entityForId(id: Long): ContactDiaryLocationVisitWrapper + + @Transaction + @Query("SELECT * FROM locationvisits WHERE date = :date") + abstract fun entitiesForDate(date: LocalDate): Flow<List<ContactDiaryLocationVisitWrapper>> + + @Query("DELETE FROM locationvisits") + abstract override suspend fun deleteAll() +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryPersonDao.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryPersonDao.kt new file mode 100644 index 0000000000000000000000000000000000000000..4889c64f5c13de5bf361c69a86748f7a358267fa --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryPersonDao.kt @@ -0,0 +1,19 @@ +package de.rki.coronawarnapp.contactdiary.storage.dao + +import androidx.room.Dao +import androidx.room.Query +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryPersonEntity +import kotlinx.coroutines.flow.Flow + +@Dao +abstract class ContactDiaryPersonDao : BaseRoomDao<ContactDiaryPersonEntity, ContactDiaryPersonEntity>() { + + @Query("SELECT * FROM persons") + abstract override fun allEntries(): Flow<List<ContactDiaryPersonEntity>> + + @Query("SELECT * FROM persons WHERE personId = :id") + abstract override suspend fun entityForId(id: Long): ContactDiaryPersonEntity + + @Query("DELETE FROM persons") + abstract override suspend fun deleteAll() +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryPersonEncounterDao.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryPersonEncounterDao.kt new file mode 100644 index 0000000000000000000000000000000000000000..696370f45f1127cce5f09b40f21eb5ff3e5cb1ce --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/dao/ContactDiaryPersonEncounterDao.kt @@ -0,0 +1,29 @@ +package de.rki.coronawarnapp.contactdiary.storage.dao + +import androidx.room.Dao +import androidx.room.Query +import androidx.room.Transaction +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryPersonEncounterEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.ContactDiaryPersonEncounterWrapper +import kotlinx.coroutines.flow.Flow +import org.joda.time.LocalDate + +@Dao +abstract class ContactDiaryPersonEncounterDao : + BaseRoomDao<ContactDiaryPersonEncounterEntity, ContactDiaryPersonEncounterWrapper>() { + + @Transaction + @Query("SELECT * FROM personencounters") + abstract override fun allEntries(): Flow<List<ContactDiaryPersonEncounterWrapper>> + + @Transaction + @Query("SELECT * FROM personencounters WHERE id = :id") + abstract override suspend fun entityForId(id: Long): ContactDiaryPersonEncounterWrapper + + @Transaction + @Query("SELECT * FROM personencounters WHERE date = :date") + abstract fun entitiesForDate(date: LocalDate): Flow<List<ContactDiaryPersonEncounterWrapper>> + + @Query("DELETE FROM personencounters") + abstract override suspend fun deleteAll() +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt new file mode 100644 index 0000000000000000000000000000000000000000..ffd350e419111ae73d764ef4f5aae5564e244d9d --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt @@ -0,0 +1,15 @@ +package de.rki.coronawarnapp.contactdiary.storage.entity + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation + +@Entity(tableName = "locations") +data class ContactDiaryLocationEntity( + @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "locationId") override val locationId: Long = 0L, + @ColumnInfo(name = "locationName") override var locationName: String +) : ContactDiaryLocation + +fun ContactDiaryLocation.toContactDiaryLocationEntity(): ContactDiaryLocationEntity = + ContactDiaryLocationEntity(this.locationId, this.locationName) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationVisitEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationVisitEntity.kt new file mode 100644 index 0000000000000000000000000000000000000000..3bfdd7541c082e0559f490ae39a3fda5bef1ff6b --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationVisitEntity.kt @@ -0,0 +1,32 @@ +package de.rki.coronawarnapp.contactdiary.storage.entity + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.Index +import androidx.room.PrimaryKey +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocationVisit +import org.joda.time.LocalDate + +@Entity( + tableName = "locationvisits", + foreignKeys = [ + ForeignKey( + entity = ContactDiaryLocationEntity::class, + parentColumns = ["locationId"], + childColumns = ["fkLocationId"], + onDelete = ForeignKey.CASCADE, + onUpdate = ForeignKey.CASCADE, + deferred = true + ) + ], + indices = [Index("fkLocationId")] +) +data class ContactDiaryLocationVisitEntity( + @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Long = 0L, + @ColumnInfo(name = "date") val date: LocalDate, + @ColumnInfo(name = "fkLocationId") val fkLocationId: Long +) + +fun ContactDiaryLocationVisit.toContactDiaryLocationVisitEntity(): ContactDiaryLocationVisitEntity = + ContactDiaryLocationVisitEntity(id = this.id, date = this.date, fkLocationId = this.contactDiaryLocation.locationId) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationVisitWrapper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationVisitWrapper.kt new file mode 100644 index 0000000000000000000000000000000000000000..333659e2cdb0f3e8a116457c1bea579581906dcc --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationVisitWrapper.kt @@ -0,0 +1,24 @@ +package de.rki.coronawarnapp.contactdiary.storage.entity + +import androidx.room.Embedded +import androidx.room.Relation +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocationVisit +import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryLocationVisit +import de.rki.coronawarnapp.contactdiary.model.sortByNameAndIdASC + +class ContactDiaryLocationVisitWrapper( + @Embedded val contactDiaryLocationVisitEntity: ContactDiaryLocationVisitEntity, + @Relation(parentColumn = "fkLocationId", entityColumn = "locationId") + val contactDiaryLocationEntity: ContactDiaryLocationEntity +) + +fun ContactDiaryLocationVisitWrapper.toContactDiaryLocationVisit(): ContactDiaryLocationVisit = + DefaultContactDiaryLocationVisit( + id = this.contactDiaryLocationVisitEntity.id, + date = this.contactDiaryLocationVisitEntity.date, + contactDiaryLocation = this.contactDiaryLocationEntity + ) + +fun List<ContactDiaryLocationVisitWrapper>.toContactDiaryLocationVisitSortedList(): List<ContactDiaryLocationVisit> = + this.map { it.toContactDiaryLocationVisit() } + .sortByNameAndIdASC() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEncounterEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEncounterEntity.kt new file mode 100644 index 0000000000000000000000000000000000000000..a98ba8661d9f28757e2adee4ce7cdd28f6655e89 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEncounterEntity.kt @@ -0,0 +1,32 @@ +package de.rki.coronawarnapp.contactdiary.storage.entity + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.Index +import androidx.room.PrimaryKey +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter +import org.joda.time.LocalDate + +@Entity( + tableName = "personencounters", + foreignKeys = [ + ForeignKey( + entity = ContactDiaryPersonEntity::class, + parentColumns = ["personId"], + childColumns = ["fkPersonId"], + onDelete = ForeignKey.CASCADE, + onUpdate = ForeignKey.CASCADE, + deferred = true + ) + ], + indices = [Index("fkPersonId")] +) +data class ContactDiaryPersonEncounterEntity( + @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Long = 0L, + @ColumnInfo(name = "date") val date: LocalDate, + @ColumnInfo(name = "fkPersonId") val fkPersonId: Long +) + +fun ContactDiaryPersonEncounter.toContactDiaryPersonEncounterEntity(): ContactDiaryPersonEncounterEntity = + ContactDiaryPersonEncounterEntity(id = this.id, date = this.date, fkPersonId = this.contactDiaryPerson.personId) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEncounterWrapper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEncounterWrapper.kt new file mode 100644 index 0000000000000000000000000000000000000000..26acf434fef972a91e789c3f2286fe2629f5ca23 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEncounterWrapper.kt @@ -0,0 +1,25 @@ +package de.rki.coronawarnapp.contactdiary.storage.entity + +import androidx.room.Embedded +import androidx.room.Relation +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter +import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryPersonEncounter +import de.rki.coronawarnapp.contactdiary.model.sortByNameAndIdASC + +data class ContactDiaryPersonEncounterWrapper( + @Embedded val contactDiaryPersonEncounterEntity: ContactDiaryPersonEncounterEntity, + @Relation(parentColumn = "fkPersonId", entityColumn = "personId") + val contactDiaryPersonEntity: ContactDiaryPersonEntity +) + +fun ContactDiaryPersonEncounterWrapper.toContactDiaryPersonEncounter(): ContactDiaryPersonEncounter = + DefaultContactDiaryPersonEncounter( + id = this.contactDiaryPersonEncounterEntity.id, + date = this.contactDiaryPersonEncounterEntity.date, + contactDiaryPerson = contactDiaryPersonEntity + ) + +fun List<ContactDiaryPersonEncounterWrapper>.toContactDiaryPersonEncounterSortedList(): + List<ContactDiaryPersonEncounter> = + this.map { it.toContactDiaryPersonEncounter() } + .sortByNameAndIdASC() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt new file mode 100644 index 0000000000000000000000000000000000000000..be31909b96e9b1e8141fb9048cd4316f649a510d --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt @@ -0,0 +1,15 @@ +package de.rki.coronawarnapp.contactdiary.storage.entity + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPerson + +@Entity(tableName = "persons") +data class ContactDiaryPersonEntity( + @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "personId") override val personId: Long = 0L, + @ColumnInfo(name = "fullName") override var fullName: String +) : ContactDiaryPerson + +fun ContactDiaryPerson.toContactDiaryPersonEntity(): ContactDiaryPersonEntity = + ContactDiaryPersonEntity(this.personId, this.fullName) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/repo/ContactDiaryRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/repo/ContactDiaryRepository.kt new file mode 100644 index 0000000000000000000000000000000000000000..04d042a3cd64b99ccab73af2ef2b0f2fdfaa44d6 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/repo/ContactDiaryRepository.kt @@ -0,0 +1,41 @@ +package de.rki.coronawarnapp.contactdiary.storage.repo + +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocationVisit +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPerson +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter +import kotlinx.coroutines.flow.Flow +import org.joda.time.LocalDate + +interface ContactDiaryRepository { + + // Location + val locations: Flow<List<ContactDiaryLocation>> + suspend fun addLocation(contactDiaryLocation: ContactDiaryLocation) + suspend fun updateLocation(contactDiaryLocation: ContactDiaryLocation) + suspend fun deleteLocation(contactDiaryLocation: ContactDiaryLocation) + suspend fun deleteLocations(contactDiaryLocations: List<ContactDiaryLocation>) + suspend fun deleteAllLocations() + + // Location visit + val locationVisits: Flow<List<ContactDiaryLocationVisit>> + fun locationVisitsForDate(date: LocalDate): Flow<List<ContactDiaryLocationVisit>> + suspend fun addLocationVisit(contactDiaryLocationVisit: ContactDiaryLocationVisit) + suspend fun deleteLocationVisit(contactDiaryLocationVisit: ContactDiaryLocationVisit) + suspend fun deleteAllLocationVisits() + + // Person + val people: Flow<List<ContactDiaryPerson>> + suspend fun addPerson(contactDiaryPerson: ContactDiaryPerson) + suspend fun updatePerson(contactDiaryPerson: ContactDiaryPerson) + suspend fun deletePerson(contactDiaryPerson: ContactDiaryPerson) + suspend fun deletePeople(contactDiaryPeople: List<ContactDiaryPerson>) + suspend fun deleteAllPeople() + + // Person encounter + val personEncounters: Flow<List<ContactDiaryPersonEncounter>> + fun personEncountersForDate(date: LocalDate): Flow<List<ContactDiaryPersonEncounter>> + suspend fun addPersonEncounter(contactDiaryPersonEncounter: ContactDiaryPersonEncounter) + suspend fun deletePersonEncounter(contactDiaryPersonEncounter: ContactDiaryPersonEncounter) + suspend fun deleteAllPersonEncounters() +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/repo/DefaultContactDiaryRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/repo/DefaultContactDiaryRepository.kt new file mode 100644 index 0000000000000000000000000000000000000000..91a482917bc8649c569c0e8e6d827b4eab4487e4 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/repo/DefaultContactDiaryRepository.kt @@ -0,0 +1,186 @@ +package de.rki.coronawarnapp.contactdiary.storage.repo + +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocationVisit +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPerson +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter +import de.rki.coronawarnapp.contactdiary.model.sortByNameAndIdASC +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryLocationDao +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryLocationVisitDao +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryPersonDao +import de.rki.coronawarnapp.contactdiary.storage.dao.ContactDiaryPersonEncounterDao +import de.rki.coronawarnapp.contactdiary.storage.entity.toContactDiaryLocationEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.toContactDiaryLocationVisitEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.toContactDiaryLocationVisitSortedList +import de.rki.coronawarnapp.contactdiary.storage.entity.toContactDiaryPersonEncounterEntity +import de.rki.coronawarnapp.contactdiary.storage.entity.toContactDiaryPersonEncounterSortedList +import de.rki.coronawarnapp.contactdiary.storage.entity.toContactDiaryPersonEntity +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import org.joda.time.LocalDate +import timber.log.Timber +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class DefaultContactDiaryRepository @Inject constructor( + private val contactDiaryLocationDao: ContactDiaryLocationDao, + private val contactDiaryLocationVisitDao: ContactDiaryLocationVisitDao, + private val contactDiaryPersonDao: ContactDiaryPersonDao, + private val contactDiaryPersonEncounterDao: ContactDiaryPersonEncounterDao +) : ContactDiaryRepository { + + // Location + override val locations: Flow<List<ContactDiaryLocation>> = contactDiaryLocationDao + .allEntries() + .map { it.sortByNameAndIdASC() } + + override suspend fun addLocation(contactDiaryLocation: ContactDiaryLocation) { + Timber.d("Adding location $contactDiaryLocation") + contactDiaryLocationDao.insert(contactDiaryLocation.toContactDiaryLocationEntity()) + } + + override suspend fun updateLocation(contactDiaryLocation: ContactDiaryLocation) { + Timber.d("Updating location $contactDiaryLocation") + val contactDiaryContactDiaryLocationEntity = contactDiaryLocation.toContactDiaryLocationEntity() + executeWhenIdNotDefault(contactDiaryContactDiaryLocationEntity.locationId) { + contactDiaryLocationDao.insert(contactDiaryContactDiaryLocationEntity) + } + } + + override suspend fun deleteLocation(contactDiaryLocation: ContactDiaryLocation) { + Timber.d("Deleting location $contactDiaryLocation") + val contactDiaryContactDiaryLocationEntity = contactDiaryLocation.toContactDiaryLocationEntity() + executeWhenIdNotDefault(contactDiaryContactDiaryLocationEntity.locationId) { + contactDiaryLocationDao.delete(contactDiaryContactDiaryLocationEntity) + } + } + + override suspend fun deleteLocations(contactDiaryLocations: List<ContactDiaryLocation>) { + Timber.d("Deleting location $contactDiaryLocations") + val contactDiaryLocationEntities = contactDiaryLocations + .map { + val contactDiaryLocationEntity = it.toContactDiaryLocationEntity() + executeWhenIdNotDefault(contactDiaryLocationEntity.locationId) + return@map contactDiaryLocationEntity + } + contactDiaryLocationDao.delete(contactDiaryLocationEntities) + } + + override suspend fun deleteAllLocations() { + Timber.d("Clearing contact diary location table") + contactDiaryLocationDao.deleteAll() + } + + // Location visit + override val locationVisits: Flow<List<ContactDiaryLocationVisit>> = + contactDiaryLocationVisitDao + .allEntries() + .map { it.toContactDiaryLocationVisitSortedList() } + + override fun locationVisitsForDate(date: LocalDate): Flow<List<ContactDiaryLocationVisit>> = + contactDiaryLocationVisitDao + .entitiesForDate(date) + .map { it.toContactDiaryLocationVisitSortedList() } + + override suspend fun addLocationVisit(contactDiaryLocationVisit: ContactDiaryLocationVisit) { + Timber.d("Adding location visit $contactDiaryLocationVisit") + executeWhenIdNotDefault(contactDiaryLocationVisit.id) { + val contactDiaryLocationVisitEntity = contactDiaryLocationVisit.toContactDiaryLocationVisitEntity() + contactDiaryLocationVisitDao.insert(contactDiaryLocationVisitEntity) + } + } + + override suspend fun deleteLocationVisit(contactDiaryLocationVisit: ContactDiaryLocationVisit) { + Timber.d("Deleting location visit $contactDiaryLocationVisit") + executeWhenIdNotDefault(contactDiaryLocationVisit.id) { + val contactDiaryLocationVisitEntity = contactDiaryLocationVisit.toContactDiaryLocationVisitEntity() + contactDiaryLocationVisitDao.delete(contactDiaryLocationVisitEntity) + } + } + + override suspend fun deleteAllLocationVisits() { + Timber.d("Clearing contact diary location visit table") + contactDiaryLocationVisitDao.deleteAll() + } + + // Person + override val people: Flow<List<ContactDiaryPerson>> = contactDiaryPersonDao + .allEntries() + .map { it.sortByNameAndIdASC() } + + override suspend fun addPerson(contactDiaryPerson: ContactDiaryPerson) { + Timber.d("Adding person $contactDiaryPerson") + contactDiaryPersonDao.insert(contactDiaryPerson.toContactDiaryPersonEntity()) + } + + override suspend fun updatePerson(contactDiaryPerson: ContactDiaryPerson) { + Timber.d("Updating person $contactDiaryPerson") + val contactDiaryPersonEntity = contactDiaryPerson.toContactDiaryPersonEntity() + executeWhenIdNotDefault(contactDiaryPersonEntity.personId) { + contactDiaryPersonDao.update(contactDiaryPersonEntity) + } + } + + override suspend fun deletePerson(contactDiaryPerson: ContactDiaryPerson) { + Timber.d("Deleting person $contactDiaryPerson") + val contactDiaryPersonEntity = contactDiaryPerson.toContactDiaryPersonEntity() + executeWhenIdNotDefault(contactDiaryPersonEntity.personId) { + contactDiaryPersonDao.delete(contactDiaryPersonEntity) + } + } + + override suspend fun deletePeople(contactDiaryPeople: List<ContactDiaryPerson>) { + Timber.d("Deleting people $contactDiaryPeople") + val contactDiaryPersonEntities = contactDiaryPeople + .map { + val contactDiaryPersonEntity = it.toContactDiaryPersonEntity() + executeWhenIdNotDefault(contactDiaryPersonEntity.personId) + return@map contactDiaryPersonEntity + } + contactDiaryPersonDao.delete(contactDiaryPersonEntities) + } + + override suspend fun deleteAllPeople() { + Timber.d("Clearing contact diary person table") + contactDiaryPersonDao.deleteAll() + } + + // Person encounter + override val personEncounters: Flow<List<ContactDiaryPersonEncounter>> = + contactDiaryPersonEncounterDao + .allEntries() + .map { it.toContactDiaryPersonEncounterSortedList() } + + override fun personEncountersForDate(date: LocalDate): Flow<List<ContactDiaryPersonEncounter>> = + contactDiaryPersonEncounterDao + .entitiesForDate(date) + .map { it.toContactDiaryPersonEncounterSortedList() } + + override suspend fun addPersonEncounter(contactDiaryPersonEncounter: ContactDiaryPersonEncounter) { + Timber.d("Adding person encounter $contactDiaryPersonEncounter") + val contactDiaryPersonEncounterEntity = contactDiaryPersonEncounter.toContactDiaryPersonEncounterEntity() + contactDiaryPersonEncounterDao.insert(contactDiaryPersonEncounterEntity) + } + + override suspend fun deletePersonEncounter(contactDiaryPersonEncounter: ContactDiaryPersonEncounter) { + Timber.d("Deleting person encounter $contactDiaryPersonEncounter") + executeWhenIdNotDefault(contactDiaryPersonEncounter.id) { + val contactDiaryPersonEncounterEntity = contactDiaryPersonEncounter.toContactDiaryPersonEncounterEntity() + contactDiaryPersonEncounterDao.delete(contactDiaryPersonEncounterEntity) + } + } + + override suspend fun deleteAllPersonEncounters() { + Timber.d("Clearing contact diary person encounter table") + contactDiaryPersonEncounterDao.deleteAll() + } + + private suspend fun executeWhenIdNotDefault(id: Long, action: (suspend () -> Unit) = { }) { + if (id != 0L) { + action() + } else { + throw IllegalArgumentException("Entity has default id") + } + } +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt index 7673f4e16733553d6e9817bc3f604e55aa7206c5..33e6de9bfa70e0ef27a5b06a82b9d66789927796 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DataReset.kt @@ -22,6 +22,7 @@ package de.rki.coronawarnapp.util import android.annotation.SuppressLint import android.content.Context import de.rki.coronawarnapp.appconfig.AppConfigProvider +import de.rki.coronawarnapp.contactdiary.storage.ContactDiaryDatabase import de.rki.coronawarnapp.diagnosiskeys.download.KeyPackageSyncSettings import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository import de.rki.coronawarnapp.nearby.modules.detectiontracker.ExposureDetectionTracker @@ -50,7 +51,8 @@ class DataReset @Inject constructor( private val submissionRepository: SubmissionRepository, private val exposureDetectionTracker: ExposureDetectionTracker, private val keyPackageSyncSettings: KeyPackageSyncSettings, - private val riskLevelStorage: RiskLevelStorage + private val riskLevelStorage: RiskLevelStorage, + private val contactDiaryDatabase: ContactDiaryDatabase ) { private val mutex = Mutex() @@ -78,6 +80,9 @@ class DataReset @Inject constructor( keyPackageSyncSettings.clear() riskLevelStorage.clear() + // Clear contact diary database + contactDiaryDatabase.clearAllTables() + Timber.w("CWA LOCAL DATA DELETION COMPLETED.") } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt index 6a869aa15a472ceb4d54b28ebbb2413f016556d4..9e23785a4d36a4bfeaff26b44520258ec36cede2 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/di/ApplicationComponent.kt @@ -9,6 +9,7 @@ import de.rki.coronawarnapp.appconfig.AppConfigModule import de.rki.coronawarnapp.appconfig.AppConfigProvider import de.rki.coronawarnapp.bugreporting.BugReporter import de.rki.coronawarnapp.bugreporting.BugReportingModule +import de.rki.coronawarnapp.contactdiary.ContactDiaryModule import de.rki.coronawarnapp.diagnosiskeys.DiagnosisKeysModule import de.rki.coronawarnapp.diagnosiskeys.DownloadDiagnosisKeysTaskModule import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository @@ -68,7 +69,8 @@ import javax.inject.Singleton DeviceForTestersModule::class, BugReportingModule::class, SerializationModule::class, - WorkerBinder::class + WorkerBinder::class, + ContactDiaryModule::class ] ) interface ApplicationComponent : AndroidInjector<CoronaWarnApplication> {