Skip to content
Snippets Groups Projects
Unverified Commit f0965a8d authored by Matthias Urhahn's avatar Matthias Urhahn Committed by GitHub
Browse files

Implement algorithm to find highest priority certificate (EXPOSUREAPP-7948) (#3510)


* Implement algorithm to find highest priority certificate.

* Fix conflicts and adjust tests.

Co-authored-by: default avatarMohamed Metwalli <mohamed.metwalli@sap.com>
parent ea8644d7
No related branches found
No related tags found
No related merge requests found
Showing
with 297 additions and 12 deletions
...@@ -14,15 +14,17 @@ import dagger.Module ...@@ -14,15 +14,17 @@ import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import de.rki.coronawarnapp.R import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.covidcertificate.common.certificate.CertificatePersonIdentifier import de.rki.coronawarnapp.covidcertificate.common.certificate.CertificatePersonIdentifier
import de.rki.coronawarnapp.covidcertificate.common.certificate.TestDccV1
import de.rki.coronawarnapp.covidcertificate.common.qrcode.QrCodeString import de.rki.coronawarnapp.covidcertificate.common.qrcode.QrCodeString
import de.rki.coronawarnapp.covidcertificate.common.repository.TestCertificateContainerId import de.rki.coronawarnapp.covidcertificate.common.repository.TestCertificateContainerId
import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificate import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificate
import de.rki.coronawarnapp.covidcertificate.test.ui.details.TestCertificateDetailsViewModel
import de.rki.coronawarnapp.covidcertificate.test.ui.details.TestCertificateDetailsFragment import de.rki.coronawarnapp.covidcertificate.test.ui.details.TestCertificateDetailsFragment
import de.rki.coronawarnapp.covidcertificate.test.ui.details.TestCertificateDetailsFragmentArgs import de.rki.coronawarnapp.covidcertificate.test.ui.details.TestCertificateDetailsFragmentArgs
import de.rki.coronawarnapp.covidcertificate.test.ui.details.TestCertificateDetailsViewModel
import io.mockk.MockKAnnotations import io.mockk.MockKAnnotations
import io.mockk.every import io.mockk.every
import io.mockk.impl.annotations.MockK import io.mockk.impl.annotations.MockK
import io.mockk.mockk
import org.joda.time.DateTime import org.joda.time.DateTime
import org.joda.time.Instant import org.joda.time.Instant
import org.joda.time.LocalDate import org.joda.time.LocalDate
...@@ -88,6 +90,9 @@ class TestCertificateDetailsFragmentTest : BaseUITest() { ...@@ -88,6 +90,9 @@ class TestCertificateDetailsFragmentTest : BaseUITest() {
val testDate = DateTime.parse("12.05.2021 19:00", formatter).toInstant() val testDate = DateTime.parse("12.05.2021 19:00", formatter).toInstant()
return MutableLiveData( return MutableLiveData(
object : TestCertificate { object : TestCertificate {
override val rawCertificate: TestDccV1
get() = mockk()
override val containerId: TestCertificateContainerId override val containerId: TestCertificateContainerId
get() = TestCertificateContainerId("identifier") get() = TestCertificateContainerId("identifier")
override val targetName: String override val targetName: String
......
...@@ -27,4 +27,6 @@ interface CwaCovidCertificate { ...@@ -27,4 +27,6 @@ interface CwaCovidCertificate {
* The ID of the container holding this certificate in the CWA. * The ID of the container holding this certificate in the CWA.
*/ */
val containerId: CertificateContainerId val containerId: CertificateContainerId
val rawCertificate: DccV1.MetaData
} }
...@@ -11,5 +11,5 @@ data class PersonCertificates( ...@@ -11,5 +11,5 @@ data class PersonCertificates(
get() = certificates.first().personIdentifier get() = certificates.first().personIdentifier
val highestPriorityCertificate: CwaCovidCertificate val highestPriorityCertificate: CwaCovidCertificate
get() = certificates.first() get() = certificates.findHighestPriorityCertificate()
} }
package de.rki.coronawarnapp.covidcertificate.person.core
import de.rki.coronawarnapp.covidcertificate.common.certificate.CwaCovidCertificate
import de.rki.coronawarnapp.covidcertificate.recovery.core.RecoveryCertificate
import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificate
import de.rki.coronawarnapp.covidcertificate.vaccination.core.VaccinationCertificate
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toLocalDateUtc
import org.joda.time.Days
import org.joda.time.Duration
import org.joda.time.Instant
import timber.log.Timber
fun Collection<CwaCovidCertificate>.toCertificateSortOrder(): List<CwaCovidCertificate> {
return this.sortedBy { it.issuedAt }
}
/**
* 1
* PCR Test Certificate <= 48 hours
* Find Test Certificates (i.e. DGC with t[0]) where t[0].tt is set to LP6464-4 and the time difference between the
* time represented by t[0].sc and the current device time is <= 48 hours, sorted descending by t[0].sc
* (i.e. latest first).
* If there is one or more certificates matching these requirements,
* the first one is returned as a result of the operation.
*/
private fun Collection<CwaCovidCertificate>.rule1FindRecentPcrCertificate(
nowUtc: Instant
): CwaCovidCertificate? = this
.filterIsInstance<TestCertificate>()
.filter { it.rawCertificate.test.testType == "LP6464-4" }
.filter { Duration(it.rawCertificate.test.sampleCollectedAt, nowUtc) <= Duration.standardHours(48) }
.maxByOrNull { it.rawCertificate.test.sampleCollectedAt }
/**
* 2
* RAT Test Certificate <= 24 hours
* Find Test Certificates (i.e. DGC with t[0]) where t[0].tt is set to LP217198-3 and the time difference between
* the time represented by t[0].sc and the current device time is <= 24 hours, sorted descending by t[0].sc
* (i.e. latest first).
* If there is one or more certificates matching these requirements,
* the first one is returned as a result of the operation.
*/
private fun Collection<CwaCovidCertificate>.rule2FindRecentRaCertificate(
nowUtc: Instant
): CwaCovidCertificate? = this
.filterIsInstance<TestCertificate>()
.filter { it.rawCertificate.test.testType == "LP217198-3" }
.filter { Duration(it.rawCertificate.test.sampleCollectedAt, nowUtc) <= Duration.standardHours(24) }
.maxByOrNull { it.rawCertificate.test.sampleCollectedAt }
/**
* 3
* Series-completing Vaccination Certificate > 14 days:
* Find Vaccination Certificates (i.e. DGC with v[0]) where v[0].dn equal to v[0].sd and the time difference
* between the time represented by v[0].dt and the current device time is > 14 days, sorted descending by v[0].dt
* (i.e. latest first).
* If there is one or more certificates matching these requirements,
* the first one is returned as a result of the operation.
*/
private fun Collection<CwaCovidCertificate>.rule3FindRecentLastShot(
nowUtc: Instant
): CwaCovidCertificate? = this
.filterIsInstance<VaccinationCertificate>()
.filter {
with(it.rawCertificate.vaccination) { doseNumber == totalSeriesOfDoses }
}
.filter {
Days.daysBetween(it.rawCertificate.vaccination.vaccinatedAt, nowUtc.toLocalDateUtc()).days > 14
}
.maxByOrNull { it.rawCertificate.vaccination.vaccinatedAt }
/**
* 4
* Recovery Certificate <= 180 days
* Find Recovery Certificates (i.e. DGC with r[0]) where the time difference between the time
* represented by r[0].df and the current device time is <= 180 days, sorted descending by r[0].df
* i.e. latest first).
* If there is one or more certificates matching these requirements,
* the first one is returned as a result of the operation.
*/
private fun Collection<CwaCovidCertificate>.rule4findRecentRecovery(
nowUtc: Instant
): CwaCovidCertificate? = this
.filterIsInstance<RecoveryCertificate>()
.filter {
Days.daysBetween(it.rawCertificate.recovery.validFrom, nowUtc.toLocalDateUtc()).days <= 180
}.maxByOrNull { it.rawCertificate.recovery.validFrom }
/**
* 5
* Series-completing Vaccination Certificate <= 14 days
* Find Vaccination Certificates (i.e. DGC with v[0]) where v[0].dn equal to v[0].sd and the time difference
* between the time represented by v[0].dt and the current device time is <= 14 days,
* sorted descending by v[0].dt (i.e. latest first).
* If there is one or more certificates matching these requirements,
* the first one is returned as a result of the operation.
*/
private fun Collection<CwaCovidCertificate>.rule5findTooRecentFinalShot(
nowUtc: Instant
): CwaCovidCertificate? = this
.filterIsInstance<VaccinationCertificate>()
.filter {
with(it.rawCertificate.vaccination) { doseNumber == totalSeriesOfDoses }
}
.filter {
Days.daysBetween(it.rawCertificate.vaccination.vaccinatedAt, nowUtc.toLocalDateUtc()).days <= 14
}
.maxByOrNull { it.rawCertificate.vaccination.vaccinatedAt }
/**
* 6
* Other Vaccination Certificate
* Find Vaccination Certificates (i.e. DGC with v[0])sorted descending by v[0].dt (i.e. latest first).
* If there is one or more certificates matching these requirements,
* the first one is returned as a result of the operation.
*/
private fun Collection<CwaCovidCertificate>.rule6findOtherVaccinations(): CwaCovidCertificate? = this
.filterIsInstance<VaccinationCertificate>()
.maxByOrNull { it.rawCertificate.vaccination.vaccinatedAt }
/**
* 7
* Recovery Certificate > 180 days
* Find Recovery Certificates (i.e. DGC with r[0]) where the time difference between the time represented by r[0].df
* and the current device time is > 180 days, sorted descending by r[0].df (i.e. latest first).
* If there is one or more certificates matching these requirements,
* the first one is returned as a result of the operation.
*/
private fun Collection<CwaCovidCertificate>.rule7FindOldRecovery(
nowUtc: Instant
): CwaCovidCertificate? = this
.filterIsInstance<RecoveryCertificate>()
.filter {
Days.daysBetween(it.rawCertificate.recovery.validFrom, nowUtc.toLocalDateUtc()).days > 180
}
.maxByOrNull { it.rawCertificate.recovery.validFrom }
/**
* 8
* PCR Test Certificate > 48 hours
* Find Test Certificates (i.e. DGC with t[0]) where t[0].tt is set to LP6464-4 and the time difference between
* the time represented by t[0].sc and the current device time is > 48 hours,
* sorted descending by t[0].sc (i.e. latest first).
* If there is one or more certificates matching these requirements,
* the first one is returned as a result of the operation.
*/
private fun Collection<CwaCovidCertificate>.rule8FindOldPcrTest(
nowUtc: Instant
): CwaCovidCertificate? = this
.filterIsInstance<TestCertificate>()
.filter { it.rawCertificate.test.testType == "LP6464-4" }
.filter { Duration(it.rawCertificate.test.sampleCollectedAt, nowUtc) > Duration.standardHours(48) }
.maxByOrNull { it.rawCertificate.test.sampleCollectedAt }
/**
* 9
* RAT Test Certificate > 24 hours
* Find Test Certificates (i.e. DGC with t[0]) where t[0].tt is set to LP217198-3 and the time difference between
* the time represented by t[0].sc and the current device time is > 24 hours,
* sorted descending by t[0].sc (i.e. latest first).
* If there is one or more certificates matching these requirements,
* the first one is returned as a result of the operation.
*/
private fun Collection<CwaCovidCertificate>.rule9FindOldRaTest(
nowUtc: Instant
): CwaCovidCertificate? = this
.filterIsInstance<TestCertificate>()
.filter { it.rawCertificate.test.testType == "LP217198-3" }
.filter { Duration(it.rawCertificate.test.sampleCollectedAt, nowUtc) > Duration.standardHours(24) }
.maxByOrNull { it.rawCertificate.test.sampleCollectedAt }
@Suppress("ReturnCount")
fun Collection<CwaCovidCertificate>.findHighestPriorityCertificate(
nowUtc: Instant = Instant.now()
): CwaCovidCertificate {
Timber.d("findHighestPriorityCertificate(nowUtc=%s): %s", nowUtc, this)
rule1FindRecentPcrCertificate(nowUtc)?.let {
Timber.d("Rule 1 match (PCR Test Certificate <= 48 hours): %s", it)
return it
}
rule2FindRecentRaCertificate(nowUtc)?.let {
Timber.d("Rule 2 match (RA Test Certificate <= 24 hours): %s", it)
return it
}
rule3FindRecentLastShot(nowUtc)?.let {
Timber.d("Rule 3 match (Series-completing Vaccination Certificate > 14 days): %s", it)
return it
}
rule4findRecentRecovery(nowUtc)?.let {
Timber.d("Rule 4 match (Recovery Certificate <= 180 days): %s", it)
return it
}
rule5findTooRecentFinalShot(nowUtc)?.let {
Timber.d("Rule 5 match (Series-completing Vaccination Certificate <= 14 days): %s", it)
return it
}
rule6findOtherVaccinations()?.let {
Timber.d("Rule 6 match (Other Vaccination Certificate): %s", it)
return it
}
rule7FindOldRecovery(nowUtc)?.let {
Timber.d("Rule 7 match (Recovery Certificate > 180 days): %s", it)
return it
}
rule8FindOldPcrTest(nowUtc)?.let {
Timber.d("Rule 8 match (PCR Test Certificate > 48 hours): %s", it)
return it
}
rule9FindOldRaTest(nowUtc)?.let {
Timber.d("Rule 9 match (RAT Test Certificate > 24 hours): %s", it)
return it
}
/**
* Fallback: return the first DGC from the set.
* Note that this fallback should never apply in a real scenario.
*/
Timber.e("No priority match, this should not happen: %s", this)
return first()
}
...@@ -45,17 +45,12 @@ class PersonCertificatesProvider @Inject constructor( ...@@ -45,17 +45,12 @@ class PersonCertificatesProvider @Inject constructor(
mapping.entries.map { (personIdentifier, certs) -> mapping.entries.map { (personIdentifier, certs) ->
Timber.tag(TAG).v("PersonCertificates for %s with %d certs.", personIdentifier, certs.size) Timber.tag(TAG).v("PersonCertificates for %s with %d certs.", personIdentifier, certs.size)
PersonCertificates( PersonCertificates(
certificates = certs.toPrioritySortOrder(), certificates = certs.toCertificateSortOrder(),
isCwaUser = personIdentifier == cwaUser, isCwaUser = personIdentifier == cwaUser,
) )
}.toSet() }.toSet()
} }
fun Collection<CwaCovidCertificate>.toPrioritySortOrder(): List<CwaCovidCertificate> {
// TODO
return this.toList()
}
/** /**
* Set the current cwa user with regards to listed persons in the certificates tab. * Set the current cwa user with regards to listed persons in the certificates tab.
* After calling this [personCertificates] will emit new values. * After calling this [personCertificates] will emit new values.
......
package de.rki.coronawarnapp.covidcertificate.recovery.core package de.rki.coronawarnapp.covidcertificate.recovery.core
import de.rki.coronawarnapp.covidcertificate.common.certificate.CwaCovidCertificate import de.rki.coronawarnapp.covidcertificate.common.certificate.CwaCovidCertificate
import de.rki.coronawarnapp.covidcertificate.common.certificate.RecoveryDccV1
import de.rki.coronawarnapp.covidcertificate.common.repository.RecoveryCertificateContainerId import de.rki.coronawarnapp.covidcertificate.common.repository.RecoveryCertificateContainerId
import org.joda.time.LocalDate import org.joda.time.LocalDate
...@@ -9,4 +10,6 @@ interface RecoveryCertificate : CwaCovidCertificate { ...@@ -9,4 +10,6 @@ interface RecoveryCertificate : CwaCovidCertificate {
val testedPositiveOn: LocalDate val testedPositiveOn: LocalDate
val validFrom: LocalDate val validFrom: LocalDate
val validUntil: LocalDate val validUntil: LocalDate
override val rawCertificate: RecoveryDccV1
} }
...@@ -51,6 +51,9 @@ data class RecoveryCertificateContainer( ...@@ -51,6 +51,9 @@ data class RecoveryCertificateContainer(
override val containerId: RecoveryCertificateContainerId override val containerId: RecoveryCertificateContainerId
get() = this@RecoveryCertificateContainer.containerId get() = this@RecoveryCertificateContainer.containerId
override val rawCertificate: RecoveryDccV1
get() = certificate
override val personIdentifier: CertificatePersonIdentifier override val personIdentifier: CertificatePersonIdentifier
get() = certificate.personIdentifier get() = certificate.personIdentifier
......
package de.rki.coronawarnapp.covidcertificate.test.core package de.rki.coronawarnapp.covidcertificate.test.core
import de.rki.coronawarnapp.covidcertificate.common.certificate.CwaCovidCertificate import de.rki.coronawarnapp.covidcertificate.common.certificate.CwaCovidCertificate
import de.rki.coronawarnapp.covidcertificate.common.certificate.TestDccV1
import de.rki.coronawarnapp.covidcertificate.common.repository.TestCertificateContainerId import de.rki.coronawarnapp.covidcertificate.common.repository.TestCertificateContainerId
import org.joda.time.Instant import org.joda.time.Instant
...@@ -28,4 +29,6 @@ interface TestCertificate : CwaCovidCertificate { ...@@ -28,4 +29,6 @@ interface TestCertificate : CwaCovidCertificate {
val registeredAt: Instant val registeredAt: Instant
val isUpdatingData: Boolean val isUpdatingData: Boolean
val isCertificateRetrievalPending: Boolean val isCertificateRetrievalPending: Boolean
override val rawCertificate: TestDccV1
} }
...@@ -3,6 +3,7 @@ package de.rki.coronawarnapp.covidcertificate.test.core.storage ...@@ -3,6 +3,7 @@ package de.rki.coronawarnapp.covidcertificate.test.core.storage
import de.rki.coronawarnapp.covidcertificate.common.certificate.CertificatePersonIdentifier import de.rki.coronawarnapp.covidcertificate.common.certificate.CertificatePersonIdentifier
import de.rki.coronawarnapp.covidcertificate.common.certificate.DccQrCodeExtractor import de.rki.coronawarnapp.covidcertificate.common.certificate.DccQrCodeExtractor
import de.rki.coronawarnapp.covidcertificate.common.certificate.DccV1Parser import de.rki.coronawarnapp.covidcertificate.common.certificate.DccV1Parser
import de.rki.coronawarnapp.covidcertificate.common.certificate.TestDccV1
import de.rki.coronawarnapp.covidcertificate.common.qrcode.QrCodeString import de.rki.coronawarnapp.covidcertificate.common.qrcode.QrCodeString
import de.rki.coronawarnapp.covidcertificate.common.repository.CertificateRepoContainer import de.rki.coronawarnapp.covidcertificate.common.repository.CertificateRepoContainer
import de.rki.coronawarnapp.covidcertificate.common.repository.TestCertificateContainerId import de.rki.coronawarnapp.covidcertificate.common.repository.TestCertificateContainerId
...@@ -73,6 +74,9 @@ data class TestCertificateContainer( ...@@ -73,6 +74,9 @@ data class TestCertificateContainer(
override val containerId: TestCertificateContainerId override val containerId: TestCertificateContainerId
get() = this@TestCertificateContainer.containerId get() = this@TestCertificateContainer.containerId
override val rawCertificate: TestDccV1
get() = certificate
override val personIdentifier: CertificatePersonIdentifier override val personIdentifier: CertificatePersonIdentifier
get() = certificate.personIdentifier get() = certificate.personIdentifier
......
package de.rki.coronawarnapp.covidcertificate.vaccination.core package de.rki.coronawarnapp.covidcertificate.vaccination.core
import de.rki.coronawarnapp.covidcertificate.common.certificate.CwaCovidCertificate import de.rki.coronawarnapp.covidcertificate.common.certificate.CwaCovidCertificate
import de.rki.coronawarnapp.covidcertificate.common.certificate.VaccinationDccV1
import de.rki.coronawarnapp.covidcertificate.common.repository.VaccinationCertificateContainerId import de.rki.coronawarnapp.covidcertificate.common.repository.VaccinationCertificateContainerId
import org.joda.time.LocalDate import org.joda.time.LocalDate
...@@ -15,5 +16,7 @@ interface VaccinationCertificate : CwaCovidCertificate { ...@@ -15,5 +16,7 @@ interface VaccinationCertificate : CwaCovidCertificate {
val doseNumber: Int val doseNumber: Int
val totalSeriesOfDoses: Int val totalSeriesOfDoses: Int
override val rawCertificate: VaccinationDccV1
val isFinalShot get() = doseNumber == totalSeriesOfDoses val isFinalShot get() = doseNumber == totalSeriesOfDoses
} }
...@@ -69,6 +69,9 @@ data class VaccinationContainer internal constructor( ...@@ -69,6 +69,9 @@ data class VaccinationContainer internal constructor(
override val containerId: VaccinationCertificateContainerId override val containerId: VaccinationCertificateContainerId
get() = this@VaccinationContainer.containerId get() = this@VaccinationContainer.containerId
override val rawCertificate: VaccinationDccV1
get() = certificate
override val personIdentifier: CertificatePersonIdentifier override val personIdentifier: CertificatePersonIdentifier
get() = certificate.personIdentifier get() = certificate.personIdentifier
......
...@@ -19,6 +19,7 @@ import io.mockk.verify ...@@ -19,6 +19,7 @@ import io.mockk.verify
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.test.runBlockingTest
import org.joda.time.Instant
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import testhelpers.BaseTest import testhelpers.BaseTest
...@@ -34,18 +35,21 @@ class PersonCertificatesProviderTest : BaseTest() { ...@@ -34,18 +35,21 @@ class PersonCertificatesProviderTest : BaseTest() {
private val vaccinatedPersonACertificate1 = mockk<VaccinationCertificate>().apply { private val vaccinatedPersonACertificate1 = mockk<VaccinationCertificate>().apply {
every { personIdentifier } returns identifierA every { personIdentifier } returns identifierA
every { issuedAt } returns Instant.EPOCH
} }
private val vaccinatedPersonA = mockk<VaccinatedPerson>().apply { private val vaccinatedPersonA = mockk<VaccinatedPerson>().apply {
every { vaccinationCertificates } returns setOf(vaccinatedPersonACertificate1) every { vaccinationCertificates } returns setOf(vaccinatedPersonACertificate1)
} }
private val testWrapperACertificate = mockk<TestCertificate>().apply { private val testWrapperACertificate = mockk<TestCertificate>().apply {
every { personIdentifier } returns identifierA every { personIdentifier } returns identifierA
every { issuedAt } returns Instant.EPOCH
} }
private val testWrapperA = mockk<TestCertificateWrapper>().apply { private val testWrapperA = mockk<TestCertificateWrapper>().apply {
every { testCertificate } returns testWrapperACertificate every { testCertificate } returns testWrapperACertificate
} }
private val recoveryWrapperACertificate = mockk<RecoveryCertificate>().apply { private val recoveryWrapperACertificate = mockk<RecoveryCertificate>().apply {
every { personIdentifier } returns identifierA every { personIdentifier } returns identifierA
every { issuedAt } returns Instant.EPOCH
} }
private val recoveryWrapperA = mockk<RecoveryCertificateWrapper>().apply { private val recoveryWrapperA = mockk<RecoveryCertificateWrapper>().apply {
every { testCertificate } returns recoveryWrapperACertificate every { testCertificate } returns recoveryWrapperACertificate
......
package de.rki.coronawarnapp.covidcertificate.person.ui.overview package de.rki.coronawarnapp.covidcertificate.person.ui.overview
import de.rki.coronawarnapp.covidcertificate.common.certificate.CertificatePersonIdentifier import de.rki.coronawarnapp.covidcertificate.common.certificate.CertificatePersonIdentifier
import de.rki.coronawarnapp.covidcertificate.common.certificate.TestDccV1
import de.rki.coronawarnapp.covidcertificate.common.qrcode.QrCodeString import de.rki.coronawarnapp.covidcertificate.common.qrcode.QrCodeString
import de.rki.coronawarnapp.covidcertificate.common.repository.TestCertificateContainerId import de.rki.coronawarnapp.covidcertificate.common.repository.TestCertificateContainerId
import de.rki.coronawarnapp.covidcertificate.person.core.PersonCertificates import de.rki.coronawarnapp.covidcertificate.person.core.PersonCertificates
import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificate import de.rki.coronawarnapp.covidcertificate.test.core.TestCertificate
import io.mockk.mockk
import org.joda.time.Instant import org.joda.time.Instant
import org.joda.time.LocalDate import org.joda.time.LocalDate
import java.util.UUID import java.util.UUID
...@@ -72,4 +74,7 @@ fun testCertificate( ...@@ -72,4 +74,7 @@ fun testCertificate(
override val certificateIssuer: String = "certificateIssuer" override val certificateIssuer: String = "certificateIssuer"
override val certificateCountry: String = "certificateCountry" override val certificateCountry: String = "certificateCountry"
override val certificateId: String = "certificateId" override val certificateId: String = "certificateId"
override val rawCertificate: TestDccV1
get() = mockk()
} }
...@@ -20,6 +20,7 @@ import io.mockk.impl.annotations.MockK ...@@ -20,6 +20,7 @@ import io.mockk.impl.annotations.MockK
import io.mockk.just import io.mockk.just
import io.mockk.mockk import io.mockk.mockk
import io.mockk.mockkStatic import io.mockk.mockkStatic
import io.mockk.spyk
import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
...@@ -46,6 +47,7 @@ class PersonOverviewViewModelTest : BaseTest() { ...@@ -46,6 +47,7 @@ class PersonOverviewViewModelTest : BaseTest() {
fun setup() { fun setup() {
MockKAnnotations.init(this, true) MockKAnnotations.init(this, true)
mockkStatic("de.rki.coronawarnapp.contactdiary.util.ContactDiaryExtensionsKt") mockkStatic("de.rki.coronawarnapp.contactdiary.util.ContactDiaryExtensionsKt")
coEvery { testCertificateRepository.refresh(any()) } returns setOf(refreshResult) coEvery { testCertificateRepository.refresh(any()) } returns setOf(refreshResult)
coEvery { qrCodeGenerator.createQrCode(any(), any(), any(), any(), any()) } returns mockk() coEvery { qrCodeGenerator.createQrCode(any(), any(), any(), any(), any()) } returns mockk()
every { personCertificatesProvider.personCertificates } returns emptyFlow() every { personCertificatesProvider.personCertificates } returns emptyFlow()
...@@ -94,7 +96,13 @@ class PersonOverviewViewModelTest : BaseTest() { ...@@ -94,7 +96,13 @@ class PersonOverviewViewModelTest : BaseTest() {
@Test @Test
fun `Sorting - List has pending certificate`() { fun `Sorting - List has pending certificate`() {
every { personCertificatesProvider.personCertificates } returns every { personCertificatesProvider.personCertificates } returns
flowOf(PersonCertificatesData.certificatesWithPending) PersonCertificatesData.certificatesWithPending
.map {
spyk(it).apply {
every { highestPriorityCertificate } returns certificates.first()
}
}.run { flowOf(this.toSet()) }
instance.personCertificates.getOrAwaitValue().apply { instance.personCertificates.getOrAwaitValue().apply {
(get(0) as CovidTestCertificatePendingCard.Item).apply { certificate.fullName shouldBe "Max Mustermann" } (get(0) as CovidTestCertificatePendingCard.Item).apply { certificate.fullName shouldBe "Max Mustermann" }
(get(1) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Zeebee" } (get(1) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Zeebee" }
...@@ -105,7 +113,13 @@ class PersonOverviewViewModelTest : BaseTest() { ...@@ -105,7 +113,13 @@ class PersonOverviewViewModelTest : BaseTest() {
@Test @Test
fun `Sorting - List has pending & updating certificate`() { fun `Sorting - List has pending & updating certificate`() {
every { personCertificatesProvider.personCertificates } returns every { personCertificatesProvider.personCertificates } returns
flowOf(PersonCertificatesData.certificatesWithUpdating) PersonCertificatesData.certificatesWithUpdating
.map {
spyk(it).apply {
every { highestPriorityCertificate } returns certificates.first()
}
}.run { flowOf(this.toSet()) }
instance.personCertificates.getOrAwaitValue().apply { instance.personCertificates.getOrAwaitValue().apply {
(get(0) as CovidTestCertificatePendingCard.Item).apply { certificate.fullName shouldBe "Max Mustermann" } (get(0) as CovidTestCertificatePendingCard.Item).apply { certificate.fullName shouldBe "Max Mustermann" }
(get(1) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Zeebee" } (get(1) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Zeebee" }
...@@ -116,7 +130,13 @@ class PersonOverviewViewModelTest : BaseTest() { ...@@ -116,7 +130,13 @@ class PersonOverviewViewModelTest : BaseTest() {
@Test @Test
fun `Sorting - List has no CWA user`() { fun `Sorting - List has no CWA user`() {
every { personCertificatesProvider.personCertificates } returns every { personCertificatesProvider.personCertificates } returns
flowOf(PersonCertificatesData.certificatesWithoutCwaUser) PersonCertificatesData.certificatesWithoutCwaUser
.map {
spyk(it).apply {
every { highestPriorityCertificate } returns certificates.first()
}
}.run { flowOf(this.toSet()) }
instance.personCertificates.getOrAwaitValue().apply { instance.personCertificates.getOrAwaitValue().apply {
(get(0) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Andrea Schneider" } (get(0) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Andrea Schneider" }
(get(1) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Erika Musterfrau" } (get(1) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Erika Musterfrau" }
...@@ -127,7 +147,13 @@ class PersonOverviewViewModelTest : BaseTest() { ...@@ -127,7 +147,13 @@ class PersonOverviewViewModelTest : BaseTest() {
@Test @Test
fun `Sorting - List has CWA user`() { fun `Sorting - List has CWA user`() {
every { personCertificatesProvider.personCertificates } returns every { personCertificatesProvider.personCertificates } returns
flowOf(PersonCertificatesData.certificatesWithCwaUser) PersonCertificatesData.certificatesWithCwaUser
.map {
spyk(it).apply {
every { highestPriorityCertificate } returns certificates.first()
}
}.run { flowOf(this.toSet()) }
instance.personCertificates.getOrAwaitValue().apply { instance.personCertificates.getOrAwaitValue().apply {
(get(0) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Zeebee" } // CWA user (get(0) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Zeebee" } // CWA user
(get(1) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Andrea Schneider" } (get(1) as PersonCertificateCard.Item).apply { certificate.fullName shouldBe "Andrea Schneider" }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment