ScanCarteModelesManquantsTest.kt
143 lignes · 5143 octets
package fr.ebii.card2vcf.ui import android.content.Context import android.graphics.Bitmap import androidx.room.Room import androidx.test.core.app.ApplicationProvider import fr.ebii.card2vcf.data.ContactImageStore import fr.ebii.card2vcf.data.ContactRepository import fr.ebii.card2vcf.data.CrmDatabase import fr.ebii.card2vcf.ocr.ModelesManquantsException import fr.ebii.card2vcf.ocr.OcrEngine import fr.ebii.card2vcf.ocr.OcrException import fr.ebii.card2vcf.ocr.OcrResult import fr.ebii.card2vcf.scan.ScanEngine import fr.ebii.card2vcf.scan.ScanResult import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.setMain import org.junit.After import org.junit.Before import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertIs import kotlin.test.assertSame import kotlin.test.assertTrue /** * Sans modèle OCR, la capture aboutit quand même : la carte est photographiée et * redressée, seul le remplissage des champs manque. Le scan ne doit donc pas finir * en erreur générique mais proposer le téléchargement — ou la saisie manuelle, * en conservant l'image redressée. */ @OptIn(ExperimentalCoroutinesApi::class) @RunWith(RobolectricTestRunner::class) @Config(sdk = [31]) class ScanCarteModelesManquantsTest { private lateinit var db: CrmDatabase private lateinit var repo: ContactRepository private lateinit var source: Bitmap private lateinit var redressee: Bitmap private val dispatcher = StandardTestDispatcher() private class ScanFactice(private val resultat: Bitmap) : ScanEngine { override fun scan(source: Bitmap, manualCorners: fr.ebii.card2vcf.scan.ScanCorners?) = ScanResult(bitmap = resultat) } private class OcrQuiEchoue(private val erreur: OcrException) : OcrEngine { override fun recognize(bitmap: Bitmap): OcrResult = throw erreur } @Before fun setUp() { Dispatchers.setMain(dispatcher) val ctx = ApplicationProvider.getApplicationContext<Context>() db = Room.inMemoryDatabaseBuilder(ctx, CrmDatabase::class.java) .allowMainThreadQueries() .build() repo = ContactRepository(db.crmContactDao(), ContactImageStore(ctx)) source = Bitmap.createBitmap(4, 4, Bitmap.Config.ARGB_8888) redressee = Bitmap.createBitmap(8, 8, Bitmap.Config.ARGB_8888) } @After fun tearDown() { db.close() Dispatchers.resetMain() } private fun viewModel(erreur: OcrException) = ScanCarteViewModel( scanEngine = ScanFactice(redressee), ocrEngine = OcrQuiEchoue(erreur), repository = repo, calcul = dispatcher, ) @Test fun `des modeles manquants donnent un etat dedie et non une erreur generique`() = runTest(dispatcher) { val vm = viewModel(ModelesManquantsException(listOf("fra", "eng"))) vm.processCapture(source) testScheduler.advanceUntilIdle() val etat = vm.state.value assertIs<ScanUiState.ModelesManquants>(etat) assertEquals(listOf("fra", "eng"), etat.langues) } @Test fun `l'image redressee est conservee pour la saisie manuelle`() = runTest(dispatcher) { val vm = viewModel(ModelesManquantsException(listOf("fra"))) vm.processCapture(source) testScheduler.advanceUntilIdle() val etat = assertIs<ScanUiState.ModelesManquants>(vm.state.value) assertSame(redressee, etat.preview, "la capture redressée ne doit pas être jetée") } @Test fun `saisir a la main ouvre un brouillon vide portant la photo de carte`() = runTest(dispatcher) { val vm = viewModel(ModelesManquantsException(listOf("fra"))) vm.processCapture(source) testScheduler.advanceUntilIdle() vm.saisirAlaMain() val etat = assertIs<ScanUiState.DraftReady>(vm.state.value) assertSame(redressee, etat.draft.preview) assertEquals("", etat.draft.rawOcrText) assertTrue(etat.draft.card.fullName.isNullOrEmpty(), "aucun champ ne doit être pré-rempli") assertTrue(etat.draft.card.emails.isEmpty()) assertTrue(etat.draft.card.phones.isEmpty()) } @Test fun `saisir a la main est sans effet hors de l'etat modeles manquants`() = runTest(dispatcher) { val vm = viewModel(ModelesManquantsException(listOf("fra"))) vm.saisirAlaMain() assertIs<ScanUiState.Idle>(vm.state.value) } @Test fun `une autre erreur OCR reste une erreur generique`() = runTest(dispatcher) { val vm = viewModel(OcrException("OCR vide — reprenez la photo")) vm.processCapture(source) testScheduler.advanceUntilIdle() val etat = assertIs<ScanUiState.Error>(vm.state.value) assertEquals("OCR vide — reprenez la photo", etat.message) } }
GitRust