From f38e39b82e94c283a0278d6927bc56e778200c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Garseg=20M=C3=B8rk?= <31205303+fredrikmork@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:12:19 +0100 Subject: [PATCH] Svaralternativer og svar (#71) --- .../no/nav/familie/pdf/pdf/PdfElementUtils.kt | 70 +++------- .../familie/pdf/pdf/VisningsvariantUtils.kt | 52 +++++--- .../no/nav/familie/pdf/pdf/domain/FeltMap.kt | 1 - .../no/nav/familie/pdf/pdf/PdfServiceTest.kt | 65 +++++++-- .../nav/familie/pdf/pdf/PdfValidatorTest.kt | 10 +- .../nav/familie/pdf/pdf/testdata/FeltMaps.kt | 123 +++++++++++------- "src/test/resources/s\303\270knad.json" | 41 +++++- 7 files changed, 224 insertions(+), 138 deletions(-) diff --git a/src/main/kotlin/no/nav/familie/pdf/pdf/PdfElementUtils.kt b/src/main/kotlin/no/nav/familie/pdf/pdf/PdfElementUtils.kt index 7bf4086..e2d9ef7 100644 --- a/src/main/kotlin/no/nav/familie/pdf/pdf/PdfElementUtils.kt +++ b/src/main/kotlin/no/nav/familie/pdf/pdf/PdfElementUtils.kt @@ -27,27 +27,9 @@ object PdfElementUtils { fun lagVerdiElement(element: VerdilisteElement): Paragraph = Paragraph().apply { - (element.label) - .takeIf { it.isNotEmpty() } - ?.let { - add( - Text(leggTilKolon(it)).apply { - settFont(FontStil.SEMIBOLD) - }, - ) - } - element.alternativer?.takeIf { it.isNotEmpty() }?.let { - add(Text("\n")) - add( - Text(it).apply { - settFont(FontStil.ITALIC) - setFontSize(10f) - }, - ) - } + add(Text(leggTilKolon(element.label)).apply { settFont(FontStil.SEMIBOLD) }) add(Text("\n")) add(element.verdi) - setFontSize(12f) isKeepTogether = true accessibilityProperties.role = StandardRoles.P } @@ -60,40 +42,19 @@ object PdfElementUtils { tekst } - fun lagPunktliste(element: VerdilisteElement): Paragraph = - Paragraph().apply { - add( - Text(element.label).apply { - settFont( - FontStil.SEMIBOLD, - ) - }, - ) - element.alternativer?.takeIf { it.isNotEmpty() }?.let { - add(Text("\n")) - add( - Text(it).apply { - settFont(FontStil.ITALIC) - setFontSize(10f) - }, - ) - } - element.verdi?.takeIf { it.isNotEmpty() }?.let { - add(Text("\n\n")) - val valgteAlternativer = element.verdi.split("\n\n") - val punktListe = - List().apply { - symbolIndent = 8f - setListSymbol("\u2022") - } - valgteAlternativer.forEach { alternativ -> - punktListe.add(ListItem(alternativ)) - } - add(punktListe) + fun lagPunktliste(punkter: kotlin.collections.List): Div = + Div().apply { + punkter.forEach { punkt -> + add(punktliste().apply { add(ListItem(punkt.label)) }) } - setFontSize(12f) isKeepTogether = true - accessibilityProperties.role = StandardRoles.P + accessibilityProperties.role = StandardRoles.DIV + } + + private fun punktliste() = + List().apply { + symbolIndent = 8f + setListSymbol("\u2022") } fun lagTekstElement( @@ -102,8 +63,8 @@ object PdfElementUtils { ): Paragraph = Paragraph().apply { add(Text(tekst)) - setFontSize(12f) settFont(fontStil) + isKeepTogether = true accessibilityProperties.role = StandardRoles.P } @@ -113,13 +74,16 @@ object PdfElementUtils { fun lagOverskriftH3(tekst: String): Paragraph = lagOverskrift(tekst, 14f, StandardRoles.H3) + fun lagOverskriftH4(tekst: String): Paragraph = lagOverskrift(tekst, 12f, StandardRoles.H4, false) + private fun lagOverskrift( tekst: String, tekstStørrelse: Float, rolle: String, + erFarget: Boolean = true, ): Paragraph = Paragraph(tekst).apply { - setFontColor(DeviceRgb(0, 52, 125)) + if (erFarget) setFontColor(DeviceRgb(0, 52, 125)) setFontSize(tekstStørrelse) settFont(FontStil.SEMIBOLD) accessibilityProperties.role = rolle diff --git a/src/main/kotlin/no/nav/familie/pdf/pdf/VisningsvariantUtils.kt b/src/main/kotlin/no/nav/familie/pdf/pdf/VisningsvariantUtils.kt index 4844330..759e81b 100644 --- a/src/main/kotlin/no/nav/familie/pdf/pdf/VisningsvariantUtils.kt +++ b/src/main/kotlin/no/nav/familie/pdf/pdf/VisningsvariantUtils.kt @@ -1,6 +1,7 @@ package no.nav.familie.pdf.pdf import com.itextpdf.layout.element.Div +import no.nav.familie.pdf.pdf.PdfElementUtils.lagOverskriftH4 import no.nav.familie.pdf.pdf.PdfElementUtils.lagPunktliste import no.nav.familie.pdf.pdf.PdfElementUtils.lagTabell import no.nav.familie.pdf.pdf.PdfElementUtils.lagTekstElement @@ -14,43 +15,58 @@ object VisningsvariantUtils { verdilisteElement: VerdilisteElement, seksjon: Div, ) { - when (visningsVariant) { - VisningsVariant.TABELL.toString() -> { - håndterTabeller(verdilisteElement, seksjon) - } - VisningsVariant.PUNKTLISTE.toString() -> { - håndterPunktliste(verdilisteElement, seksjon) - } - VisningsVariant.VEDLEGG.toString() -> { - håndterVedlegg(verdilisteElement, seksjon) + if (verdilisteElement.verdiliste?.isNotEmpty() == true) { + when (visningsVariant) { + VisningsVariant.TABELL.toString() -> { + håndterTabeller(verdilisteElement.verdiliste, seksjon) + } + + VisningsVariant.PUNKTLISTE.toString() -> { + håndterPunktliste(verdilisteElement, seksjon) + } + + VisningsVariant.VEDLEGG.toString() -> { + håndterVedlegg(verdilisteElement.verdiliste, seksjon) + } } } } private fun håndterTabeller( - verdilisteElement: VerdilisteElement, + verdiliste: List, seksjon: Div, - ) = verdilisteElement.verdiliste?.forEach { verdilisteElement -> - verdilisteElement.verdiliste?.let { seksjon.apply { add(lagTabell(verdilisteElement)) } } + ) = verdiliste.forEach { verdilisteElement -> + verdiliste.let { seksjon.apply { add(lagTabell(verdilisteElement)) } } } private fun håndterPunktliste( verdi: VerdilisteElement, seksjon: Div, ) { - seksjon.apply { - add(lagPunktliste(verdi)) + if (verdi.verdiliste?.isNotEmpty() == true) { + seksjon.apply { + add(lagOverskriftH4(verdi.label).apply { setMarginLeft(30f) }) + add(lagPunktliste(verdi.verdiliste).apply { setMarginLeft(30f) }) + } } } private fun håndterVedlegg( - verdilisteElement: VerdilisteElement, + verdiliste: List, seksjon: Div, ) { - verdilisteElement.verdiliste?.forEach { vedlegg -> + verdiliste.forEach { vedlegg -> vedlegg.verdi?.takeIf { it.isEmpty() }?.let { - seksjon.apply { add(lagTekstElement("Ingen vedlegg lastet opp i denne søknaden").apply { setMarginLeft(15f) }) } - } ?: håndterRekursivVerdiliste(verdilisteElement.verdiliste, seksjon) + seksjon.apply { + add( + lagTekstElement("Ingen vedlegg lastet opp i denne søknaden").apply { + setMarginLeft( + 15f, + ) + }, + ) + } + } ?: håndterRekursivVerdiliste(verdiliste, seksjon) } } } diff --git a/src/main/kotlin/no/nav/familie/pdf/pdf/domain/FeltMap.kt b/src/main/kotlin/no/nav/familie/pdf/pdf/domain/FeltMap.kt index 7b3db3c..7bfbebc 100644 --- a/src/main/kotlin/no/nav/familie/pdf/pdf/domain/FeltMap.kt +++ b/src/main/kotlin/no/nav/familie/pdf/pdf/domain/FeltMap.kt @@ -12,7 +12,6 @@ data class VerdilisteElement( val verdi: String? = null, val visningsVariant: String? = null, val verdiliste: List? = null, - val alternativer: String? = null, ) data class PdfConfig( diff --git a/src/test/kotlin/no/nav/familie/pdf/pdf/PdfServiceTest.kt b/src/test/kotlin/no/nav/familie/pdf/pdf/PdfServiceTest.kt index a0e2b8c..ddf7663 100644 --- a/src/test/kotlin/no/nav/familie/pdf/pdf/PdfServiceTest.kt +++ b/src/test/kotlin/no/nav/familie/pdf/pdf/PdfServiceTest.kt @@ -9,6 +9,8 @@ import no.nav.familie.pdf.no.nav.familie.pdf.pdf.utils.lagMedBarneTabell import no.nav.familie.pdf.no.nav.familie.pdf.pdf.utils.lagMedFlereArbeidsforhold import no.nav.familie.pdf.no.nav.familie.pdf.pdf.utils.lagMedForskjelligLabelIVerdiliste import no.nav.familie.pdf.no.nav.familie.pdf.pdf.utils.lagMedInnholdsfortegnelse +import no.nav.familie.pdf.no.nav.familie.pdf.pdf.utils.lagMedPunktliste +import no.nav.familie.pdf.no.nav.familie.pdf.pdf.utils.lagMedTomPunktliste import no.nav.familie.pdf.no.nav.familie.pdf.pdf.utils.lagMedTomVerdiliste import no.nav.familie.pdf.no.nav.familie.pdf.pdf.utils.lagMedTomtSkjemanummer import no.nav.familie.pdf.no.nav.familie.pdf.pdf.utils.lagMedVerdiliste @@ -44,6 +46,13 @@ class PdfServiceTest { lagToSiderInnholdsfortegnelse(), ) + @JvmStatic + fun tomPunktliste(): Stream = + Stream.of( + lagMedTomPunktliste(), + lagMedTomPunktliste(listOf()), + ) + @JvmStatic fun underOverskriftUtenSkjemanummer(): Stream = Stream.of( @@ -171,6 +180,34 @@ class PdfServiceTest { assertTrue(faktiskSideTekst.contains(label)) } } + + @Test + fun `Pdf lager forside uten innholdsfortegnelse`() { + // Arrange + val feltMap = lagUteninnholdsfortegnelse() + + // Act + val pdfDoc = opprettPdf(feltMap) + val førsteSideTekst = PdfTextExtractor.getTextFromPage(pdfDoc.getPage(1)) + + // Assert + assertTrue(førsteSideTekst.contains("Søknad om overgangsstønad")) + assertFalse(førsteSideTekst.contains("Innholdsfortegnelse")) + } + + @Test + fun `Pdf lager forside med innholdsfortegnelse`() { + // Arrange + val feltMap = lagMedInnholdsfortegnelse() + + // Act + val pdfDoc = opprettPdf(feltMap) + val førsteSideTekst = PdfTextExtractor.getTextFromPage(pdfDoc.getPage(1)) + + // Assert + assertTrue(førsteSideTekst.contains("Søknad om overgangsstønad")) + assertTrue(førsteSideTekst.contains("Innholdsfortegnelse")) + } //endregion //region Tabeller @@ -235,33 +272,39 @@ class PdfServiceTest { } //endregion + // region Punktliste @Test - fun `Pdf lager forside uten innholdsfortegnelse`() { + fun `Pdf lager en punktliste når visningsvarianten har PUNKTLISTE valgt`() { // Arrange - val feltMap = lagUteninnholdsfortegnelse() + val feltMap = lagMedPunktliste() // Act val pdfDoc = opprettPdf(feltMap) - val førsteSideTekst = PdfTextExtractor.getTextFromPage(pdfDoc.getPage(1)) + val tekstIPdf = PdfTextExtractor.getTextFromPage(pdfDoc.getPage(2)) // Assert - assertTrue(førsteSideTekst.contains("Søknad om overgangsstønad")) - assertFalse(førsteSideTekst.contains("Innholdsfortegnelse")) + val faktiskPunkter = tekstIPdf.count { it == '\u2022' } + val forventetPunkter = 5 + assertTrue( + faktiskPunkter == forventetPunkter, + "Forventet $forventetPunkter punkter men fikk $faktiskPunkter", + ) } - @Test - fun `Pdf lager forside med innholdsfortegnelse`() { + @ParameterizedTest + @MethodSource("tomPunktliste") + fun `Pdf lager ikke en punktliste når verdiliste er tom`() { // Arrange - val feltMap = lagMedInnholdsfortegnelse() + val feltMap = lagMedTomPunktliste() // Act val pdfDoc = opprettPdf(feltMap) - val førsteSideTekst = PdfTextExtractor.getTextFromPage(pdfDoc.getPage(1)) + val tekstIPdf = PdfTextExtractor.getTextFromPage(pdfDoc.getPage(2)) // Assert - assertTrue(førsteSideTekst.contains("Søknad om overgangsstønad")) - assertTrue(førsteSideTekst.contains("Innholdsfortegnelse")) + assertFalse(tekstIPdf.contains("Gjelder noe av dette deg?")) } + // endregion private fun opprettPdf(feltMap: FeltMap): PdfADocument { val result = pdfOppretterService.opprettPdf(feltMap) diff --git a/src/test/kotlin/no/nav/familie/pdf/pdf/PdfValidatorTest.kt b/src/test/kotlin/no/nav/familie/pdf/pdf/PdfValidatorTest.kt index e78374b..c788499 100644 --- a/src/test/kotlin/no/nav/familie/pdf/pdf/PdfValidatorTest.kt +++ b/src/test/kotlin/no/nav/familie/pdf/pdf/PdfValidatorTest.kt @@ -29,7 +29,13 @@ class PdfValidatorTest { // Act val result = PdfValidator.validerPdf(pdfBytes, standard) // Assert - // Spesial-tilfelle fordi regel 8.8-2 ikke er oppfylt ved klikkbar lenke i innholdsfortegnelsen - assertTrue(result.feiletRegel.contains("[specification=ISO 14289-2:2024 clause=8.8 testNumber=2]=12") || result.samsvarer, "Pdf-en samsvarer ikke med standarden $standard med feilen ${result.feiletRegel}") + // Spesialtilfelle fordi regel 8.8-2 ikke er oppfylt ved klikkbar lenke i innholdsfortegnelsen. + // Den trengs også å sjekkes med mellomrom på slutten i tillegg til uten. Noe rart med dataen. + assertTrue( + result.feiletRegel == "[[specification=ISO 14289-2:2024 clause=8.8 testNumber=2]=12 ]" || + result.feiletRegel == "[[specification=ISO 14289-2:2024 clause=8.8 testNumber=2]=12]" || + result.samsvarer, + "Pdf-en samsvarer ikke med standarden $standard med feilen ${result.feiletRegel}", + ) } } diff --git a/src/test/kotlin/no/nav/familie/pdf/pdf/testdata/FeltMaps.kt b/src/test/kotlin/no/nav/familie/pdf/pdf/testdata/FeltMaps.kt index 275bcb6..5afadd4 100644 --- a/src/test/kotlin/no/nav/familie/pdf/pdf/testdata/FeltMaps.kt +++ b/src/test/kotlin/no/nav/familie/pdf/pdf/testdata/FeltMaps.kt @@ -49,56 +49,6 @@ fun lagMedForskjelligLabelIVerdiliste(): FeltMap = ) //endregion -//region Adresse -fun lagMedTomAdresse(): FeltMap = - FeltMap( - label = søknadsTittel, - verdiliste = - listOf( - VerdilisteElement( - label = "Søker", - verdiliste = - listOf( - VerdilisteElement(label = "Adresse", verdi = ""), - ), - ), - ), - pdfConfig = PdfConfig(true, "nb"), - ) - -fun lagAdresseMedBareLinjeskift(): FeltMap = - FeltMap( - label = søknadsTittel, - verdiliste = - listOf( - VerdilisteElement( - label = "Søker", - verdiliste = - listOf( - VerdilisteElement(label = "Adresse", verdi = "\n\n\n\n"), - ), - ), - ), - pdfConfig = PdfConfig(true, "nb"), - ) - -fun lagAdresseMedFlereLinjeskift(): FeltMap = - FeltMap( - label = søknadsTittel, - verdiliste = - listOf( - VerdilisteElement( - label = "Søker", - verdiliste = - listOf( - VerdilisteElement(label = "Adresse", verdi = "Adresse 12\n\n\n\n0999 Oslo"), - ), - ), - ), - pdfConfig = PdfConfig(true, "nb"), - ) -//endregion - //region Innholdsfortegnelse fun lagToSiderInnholdsfortegnelse(): FeltMap = FeltMap(søknadsTittel, lagGjentattInnhold(48), pdfConfig = PdfConfig(true, "nb")) @@ -240,3 +190,76 @@ val innsendingsdetaljer = VerdilisteElement(label = "Født", verdi = "Ja"), ), ) +//endregion + +// region Punktliste +fun lagMedPunktliste(): FeltMap = + FeltMap( + label = søknadsTittel, + verdiliste = + listOf( + VerdilisteElement( + label = "Mer om situasjonen din", + verdiliste = + listOf( + VerdilisteElement( + label = "Gjelder noe av dette deg?", + verdiliste = + listOf( + VerdilisteElement( + label = "Svaralternativer", + visningsVariant = VisningsVariant.PUNKTLISTE.toString(), + verdiliste = + listOf( + VerdilisteElement( + label = "Jeg er syk", + ), + VerdilisteElement( + label = "Barnet mitt er sykt", + ), + VerdilisteElement( + label = "Jeg har søkt om barnepass", + ), + ), + ), + VerdilisteElement( + label = "Svar", + visningsVariant = VisningsVariant.PUNKTLISTE.toString(), + verdiliste = + listOf( + VerdilisteElement( + label = "Jeg er syk", + ), + VerdilisteElement( + label = "Barnet mitt er sykt", + ), + ), + ), + ), + ), + ), + ), + ), + pdfConfig = PdfConfig(true, språk = "nb"), + ) + +fun lagMedTomPunktliste(punktliste: List? = null): FeltMap = + FeltMap( + label = søknadsTittel, + verdiliste = + listOf( + VerdilisteElement( + label = "Mer om situasjonen din", + verdiliste = + listOf( + VerdilisteElement( + label = "Gjelder noe av dette deg?", + visningsVariant = VisningsVariant.PUNKTLISTE.toString(), + verdiliste = punktliste, + ), + ), + ), + ), + pdfConfig = PdfConfig(true, språk = "nb"), + ) +// endregion diff --git "a/src/test/resources/s\303\270knad.json" "b/src/test/resources/s\303\270knad.json" index 04328e4..c2f31cc 100644 --- "a/src/test/resources/s\303\270knad.json" +++ "b/src/test/resources/s\303\270knad.json" @@ -310,9 +310,44 @@ "verdiliste": [ { "label": "Gjelder noe av dette deg?", - "verdi": "Jeg er syk\n\nBarnet mitt er sykt", - "visningsVariant": "PUNKTLISTE", - "alternativer": "Jeg er syk / Barnet mitt er sykt / Jeg har søkt om barnepass, men ikke fått plass enda / Jeg har barn som trenger særlig tilsyn på grunn av fysiske, psykiske eller store sosiale problemer / Nei" + "verdiliste": [ + { + "label": "Svaralternativer", + "visningsVariant": "PUNKTLISTE", + "verdiliste": [ + { + "label": "Jeg er syk" + }, + { + "label": "Barnet mitt er sykt" + }, + { + "label": "Jeg har søkt om barnepass, men ikke fått plass enda" + }, + { + "label": "Jeg har barn som trenger særlig tilsyn på grunn av fysiske, psykiske eller store sosiale problemer" + }, + { + "label": "Nei" + } + ] + }, + { + "label": "Svar", + "visningsVariant": "PUNKTLISTE", + "verdiliste": [ + { + "label": "Jeg er syk" + }, + { + "label": "Barnet mitt er sykt" + }, + { + "label": "Nei" + } + ] + } + ] }, { "label": "Dokumentasjon på at du er syk",