From 02d37696c947d16b77a7cdad0fe616259118ab18 Mon Sep 17 00:00:00 2001 From: Mikael Bjerga <6940327+bjerga@users.noreply.github.com> Date: Tue, 13 Aug 2024 10:48:30 +0200 Subject: [PATCH] Bytt til ny kontrakt for innsending (#664) --- api/build.gradle.kts | 2 - api/gradle.properties | 1 - .../api/HelsesjekkerRouting.kt | 5 +- .../api/hentforespoersel/TrengerRoute.kt | 13 +- .../api/innsending/InnsendingProducer.kt | 14 +- .../api/innsending/InnsendingRoute.kt | 146 +++---- .../api/innsending/InnsendingValidate.kt | 92 ---- .../api/validation/CustomConstraint.kt | 8 - .../validation/IdentitetsnummerConstraint.kt | 12 - .../OrganisasjonsnummerConstraint.kt | 12 - .../api/validation/TelefonnummerConstraint.kt | 10 - .../api/validation/TelefonnummerValidator.kt | 26 -- .../api/validation/ValidationResponse.kt | 15 - .../validation/ValidationResponseMapper.kt | 14 - api/src/main/resources/messages_no.properties | 9 - .../api/InnsendingProducerTest.kt | 12 +- .../HentForespoerselRouteKtTest.kt | 9 +- .../hentforespoersel/TrengerRouteKtTest.kt | 9 +- .../api/innsending/InnsendingRouteKtTest.kt | 41 +- .../api/innsending/InnsendingTest.kt | 34 -- .../innsending/InnsendingValidateKtTest.kt | 410 ------------------ .../inntektsmelding/api/utils/TestUtils.kt | 20 +- .../validation/TelefonnummerValidatorTest.kt | 41 -- .../felles/test/mock/GyldigData.kt | 83 ---- .../mock/{MockData.kt => MockForespoersel.kt} | 56 +-- .../felles/test/mock/MockInntektsmelding.kt | 12 + .../MapInntektsmeldingKtTest.kt | 22 +- .../integrasjonstest/InnsendingIT.kt | 55 ++- .../integrasjonstest/InnsendingServiceIT.kt | 36 +- .../integrasjonstest/mock/MockData.kt | 61 --- 30 files changed, 229 insertions(+), 1051 deletions(-) delete mode 100644 api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingValidate.kt delete mode 100644 api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/CustomConstraint.kt delete mode 100644 api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/IdentitetsnummerConstraint.kt delete mode 100644 api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/OrganisasjonsnummerConstraint.kt delete mode 100644 api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerConstraint.kt delete mode 100644 api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerValidator.kt delete mode 100644 api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/ValidationResponse.kt delete mode 100644 api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/ValidationResponseMapper.kt delete mode 100644 api/src/main/resources/messages_no.properties delete mode 100644 api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingTest.kt delete mode 100644 api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingValidateKtTest.kt delete mode 100644 api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerValidatorTest.kt delete mode 100644 felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/GyldigData.kt rename felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/{MockData.kt => MockForespoersel.kt} (87%) diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 1b5baf1c2..ab358ed3e 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -2,7 +2,6 @@ val ktorVersion: String by project val lettuceVersion: String by project val mockOauth2ServerVersion: String by project val tokenSupportVersion: String by project -val valiktorVersion: String by project tasks { test { @@ -27,7 +26,6 @@ dependencies { implementation("io.ktor:ktor-server-status-pages:$ktorVersion") implementation("no.nav.security:token-client-core:$tokenSupportVersion") implementation("no.nav.security:token-validation-ktor-v2:$tokenSupportVersion") - implementation("org.valiktor:valiktor-core:$valiktorVersion") testImplementation("io.ktor:ktor-client-content-negotiation:$ktorVersion") testImplementation("io.ktor:ktor-client-core:$ktorVersion") diff --git a/api/gradle.properties b/api/gradle.properties index b4d8a4beb..21d6e2850 100644 --- a/api/gradle.properties +++ b/api/gradle.properties @@ -2,4 +2,3 @@ # nyere versjon av mockOauth2ServerVersion finnes, men med bug mockOauth2ServerVersion=0.5.3 tokenSupportVersion=4.1.3 -valiktorVersion=0.12.0 diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/HelsesjekkerRouting.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/HelsesjekkerRouting.kt index b5cc1c842..3dbea652c 100644 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/HelsesjekkerRouting.kt +++ b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/HelsesjekkerRouting.kt @@ -9,7 +9,6 @@ import io.ktor.server.routing.get import io.ktor.server.routing.routing import io.prometheus.client.CollectorRegistry import io.prometheus.client.exporter.common.TextFormat -import java.util.Collections fun Application.helsesjekkerRouting() { routing { @@ -23,7 +22,9 @@ fun Application.helsesjekkerRouting() { val names = call.request.queryParameters .getAll("name[]") - ?.toSet() ?: Collections.emptySet() + ?.toSet() + .orEmpty() + call.respondTextWriter(ContentType.parse(TextFormat.CONTENT_TYPE_004)) { TextFormat.write004(this, CollectorRegistry.defaultRegistry.filteredMetricFamilySamples(names)) } diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/TrengerRoute.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/TrengerRoute.kt index 58cdf6215..ecf06f90a 100644 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/TrengerRoute.kt +++ b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/TrengerRoute.kt @@ -26,8 +26,6 @@ import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respond import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondBadRequest import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondForbidden import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondInternalServerError -import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.ValidationError -import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.ValidationResponse import no.nav.helsearbeidsgiver.utils.json.fromJson import no.nav.helsearbeidsgiver.utils.json.toJson import java.util.UUID @@ -98,16 +96,7 @@ fun Route.hentForespoerselRoute( logger.error("Klarte ikke lese request.", it) val response = ResultJson( - failure = - ValidationResponse( - listOf( - ValidationError( - property = HentForespoerselRequest::uuid.name, - error = it.message.orEmpty(), - value = "", - ), - ), - ).toJson(ValidationResponse.serializer()), + failure = "Mangler forespørsel-ID for Ã¥ hente forespørsel.".toJson(), ) respondBadRequest(response, ResultJson.serializer()) } diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingProducer.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingProducer.kt index 099af7a47..f28ea6b24 100644 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingProducer.kt +++ b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingProducer.kt @@ -1,7 +1,7 @@ package no.nav.helsearbeidsgiver.inntektsmelding.api.innsending import no.nav.helse.rapids_rivers.RapidsConnection -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmelding import no.nav.helsearbeidsgiver.felles.EventName import no.nav.helsearbeidsgiver.felles.Key import no.nav.helsearbeidsgiver.felles.json.toJson @@ -22,8 +22,7 @@ class InnsendingProducer( fun publish( transaksjonId: UUID, - forespoerselId: UUID, - request: Innsending, + skjemaInntektsmelding: SkjemaInntektsmelding, arbeidsgiverFnr: Fnr, ) { rapid @@ -32,13 +31,14 @@ class InnsendingProducer( Key.UUID to transaksjonId.toJson(), Key.DATA to mapOf( - Key.FORESPOERSEL_ID to forespoerselId.toJson(), + // TODO fjern i mottaker, sÃ¥ her + Key.FORESPOERSEL_ID to skjemaInntektsmelding.forespoerselId.toJson(), Key.ARBEIDSGIVER_FNR to arbeidsgiverFnr.toJson(), - Key.SKJEMA_INNTEKTSMELDING to request.toJson(Innsending.serializer()), + Key.SKJEMA_INNTEKTSMELDING to skjemaInntektsmelding.toJson(SkjemaInntektsmelding.serializer()), ).toJson(), ).also { - logger.info("Publiserte til kafka forespørselId: $forespoerselId og transaksjonId=$transaksjonId") - sikkerLogger.info("Publiserte til kafka forespørselId: $forespoerselId json=${it.toPretty()}") + logger.info("Publiserte til kafka forespørselId: ${skjemaInntektsmelding.forespoerselId} og transaksjonId=$transaksjonId") + sikkerLogger.info("Publiserte til kafka forespørselId: ${skjemaInntektsmelding.forespoerselId} json=${it.toPretty()}") } } } diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt index ce93c3749..d001165ef 100644 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt +++ b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRoute.kt @@ -6,12 +6,8 @@ import io.ktor.server.request.receiveText import io.ktor.server.routing.Route import io.ktor.server.routing.post import io.prometheus.client.Summary -import kotlinx.serialization.SerializationException import kotlinx.serialization.builtins.serializer import no.nav.helse.rapids_rivers.RapidsConnection -import no.nav.helsearbeidsgiver.domene.inntektsmelding.Utils.convert -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending -import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.AarsakInnsending import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmelding import no.nav.helsearbeidsgiver.felles.Tekst import no.nav.helsearbeidsgiver.felles.domene.ResultJson @@ -19,7 +15,6 @@ import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisConnection import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisPrefix import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisStore import no.nav.helsearbeidsgiver.inntektsmelding.api.RedisPoller -import no.nav.helsearbeidsgiver.inntektsmelding.api.RedisPollerTimeoutException import no.nav.helsearbeidsgiver.inntektsmelding.api.Routes import no.nav.helsearbeidsgiver.inntektsmelding.api.auth.Tilgangskontroll import no.nav.helsearbeidsgiver.inntektsmelding.api.auth.lesFnrFraAuthToken @@ -31,11 +26,8 @@ import no.nav.helsearbeidsgiver.inntektsmelding.api.sikkerLogger import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respond import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondBadRequest import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.respondInternalServerError -import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.ValidationResponse -import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.validationResponseMapper import no.nav.helsearbeidsgiver.utils.json.fromJson import no.nav.helsearbeidsgiver.utils.json.parseJson -import org.valiktor.ConstraintViolationException import java.util.UUID import kotlin.system.measureTimeMillis @@ -54,92 +46,82 @@ fun Route.innsendingRoute( .help("innsending endpoint latency in seconds") .register() - post(Routes.INNSENDING + "/{forespoerselId}") { - val transaksjonId = UUID.randomUUID() - - val forespoerselId = - call.parameters["forespoerselId"] - ?.runCatching(UUID::fromString) - ?.getOrNull() - - if (forespoerselId != null) { - val requestTimer = requestLatency.startTimer() - measureTimeMillis { - try { - val request = - call - .receiveText() - .parseJson() + // TODO ubrukt path param satt til optional. fjern i frontend, sÃ¥ her. + post(Routes.INNSENDING + "/{forespoerselId?}") { + val requestTimer = requestLatency.startTimer() + measureTimeMillis { + val transaksjonId = UUID.randomUUID() + + val skjema = + call + .receiveText() + .runCatching { + parseJson() .also { json -> - "Mottok innsending med forespørselId: $forespoerselId".let { + "Mottok inntektsmeldingsskjema.".let { logger.info(it) sikkerLogger.info("$it og request:\n$json") } - }.let { json -> - runCatching { - json - .fromJson(SkjemaInntektsmelding.serializer()) - .also { - val valideringsfeil = it.valider() - if (valideringsfeil.isNotEmpty()) { - val response = ValideringErrorResponse(valideringsfeil) - - respondBadRequest(response, ValideringErrorResponse.serializer()) - return@measureTimeMillis - } - }.convert( - sykmeldingsperioder = emptyList(), - aarsakInnsending = AarsakInnsending.Ny, - ) - }.getOrElse { error -> - sikkerLogger.debug("Noe gikk galt med nytt skjema.", error) - - json - .fromJson(Innsending.serializer()) - .also { - it.validate() - } - } - } - - tilgangskontroll.validerTilgangTilForespoersel(call.request, forespoerselId) + }.fromJson(SkjemaInntektsmelding.serializer()) + }.getOrElse { error -> + "Klarte ikke parse json for inntektsmeldingsskjema.".also { + logger.error(it) + sikkerLogger.error(it, error) + } + null + } - val innloggerFnr = call.request.lesFnrFraAuthToken() - producer.publish(transaksjonId, forespoerselId, request, innloggerFnr) + when { + skjema == null -> { + respondBadRequest(JsonErrorResponse(), JsonErrorResponse.serializer()) + } - val resultatJson = redisPoller.hent(transaksjonId).fromJson(ResultJson.serializer()) - sikkerLogger.info("Fikk resultat for innsending:\n$resultatJson") + skjema.valider().isNotEmpty() -> { + val valideringsfeil = skjema.valider() - if (resultatJson.success != null) { - respond(HttpStatusCode.Created, InnsendingResponse(forespoerselId), InnsendingResponse.serializer()) - } else { - val feilmelding = resultatJson.failure?.fromJson(String.serializer()) ?: Tekst.TEKNISK_FEIL_FORBIGAAENDE - respondInternalServerError(feilmelding, String.serializer()) - } - } catch (e: ConstraintViolationException) { - logger.info("Fikk valideringsfeil for forespørselId: $forespoerselId") - respondBadRequest(validationResponseMapper(e.constraintViolations), ValidationResponse.serializer()) - } catch (e: SerializationException) { - "Kunne ikke parse json for $forespoerselId".let { + "Fikk valideringsfeil: $valideringsfeil".also { logger.error(it) - sikkerLogger.error(it, e) - respondBadRequest(JsonErrorResponse(forespoerselId.toString()), JsonErrorResponse.serializer()) + sikkerLogger.error(it) } - } catch (e: RedisPollerTimeoutException) { - logger.info("Fikk timeout for forespørselId: $forespoerselId", e) - respondInternalServerError(RedisTimeoutResponse(forespoerselId), RedisTimeoutResponse.serializer()) + + val response = ValideringErrorResponse(valideringsfeil) + + respondBadRequest(response, ValideringErrorResponse.serializer()) } - }.also { - requestTimer.observeDuration() - logger.info("Api call to ${Routes.INNSENDING} took $it ms") - } - } else { - val feilmelding = "Forespørsel-ID mangler som stiparameter." - logger.error(feilmelding) - sikkerLogger.error(feilmelding) + else -> { + tilgangskontroll.validerTilgangTilForespoersel(call.request, skjema.forespoerselId) + + val avsenderFnr = call.request.lesFnrFraAuthToken() + + producer.publish(transaksjonId, skjema, avsenderFnr) + + val resultat = + runCatching { + redisPoller.hent(transaksjonId) + }.map { + it.fromJson(ResultJson.serializer()) + } - respondBadRequest(feilmelding, String.serializer()) + resultat + .onSuccess { + sikkerLogger.info("Fikk resultat for innsending:\n$it") + + if (it.success != null) { + respond(HttpStatusCode.Created, InnsendingResponse(skjema.forespoerselId), InnsendingResponse.serializer()) + } else { + val feilmelding = it.failure?.fromJson(String.serializer()) ?: Tekst.TEKNISK_FEIL_FORBIGAAENDE + respondInternalServerError(feilmelding, String.serializer()) + } + }.onFailure { + sikkerLogger.info("Fikk timeout for forespørselId: ${skjema.forespoerselId}", it) + respondInternalServerError(RedisTimeoutResponse(skjema.forespoerselId), RedisTimeoutResponse.serializer()) + } + } + } + }.also { + requestTimer.observeDuration() + logger.info("Api call to ${Routes.INNSENDING} took $it ms") } } } diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingValidate.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingValidate.kt deleted file mode 100644 index 6d78404d4..000000000 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingValidate.kt +++ /dev/null @@ -1,92 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.innsending - -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.FullLoennIArbeidsgiverPerioden -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Inntekt -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Naturalytelse -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Refusjon -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.RefusjonEndring -import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.isIdentitetsnummer -import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.isOrganisasjonsnummer -import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.isTelefonnummer -import org.valiktor.functions.isGreaterThan -import org.valiktor.functions.isGreaterThanOrEqualTo -import org.valiktor.functions.isLessThan -import org.valiktor.functions.isLessThanOrEqualTo -import org.valiktor.functions.isNotEmpty -import org.valiktor.functions.isNotNull -import org.valiktor.functions.isTrue -import org.valiktor.functions.validate -import org.valiktor.functions.validateForEach - -fun Innsending.validate() { - org.valiktor.validate(this) { innsendt -> - // sjekk om delvis eller komplett innsending: - if (isKomplettForespoersel(innsendt.forespurtData)) { // komplett innsending (settes per nÃ¥ fra frontend :/ ) - // validering kan komme til Ã¥ divergere mer i fremtiden - // Betaler arbeidsgiver full lønn til arbeidstaker - validate(Innsending::fullLønnIArbeidsgiverPerioden).isNotNull() // mÃ¥ gjøre dette eksplisitt siden kontrakten tillater nullable - validate(Innsending::fullLønnIArbeidsgiverPerioden).validate { - if (!it.utbetalerFullLønn) { - validate(FullLoennIArbeidsgiverPerioden::begrunnelse).isNotNull() - validate(FullLoennIArbeidsgiverPerioden::utbetalt).isNotNull() - validate(FullLoennIArbeidsgiverPerioden::utbetalt).isGreaterThanOrEqualTo(0.0) - validate(FullLoennIArbeidsgiverPerioden::utbetalt).isLessThan(1_000_000.0) - } - } - } - // Den ansatte - validate(Innsending::orgnrUnderenhet).isNotNull() - validate(Innsending::orgnrUnderenhet).isOrganisasjonsnummer() - // Arbeidsgiver - validate(Innsending::identitetsnummer).isNotNull() - validate(Innsending::identitetsnummer).isIdentitetsnummer() - // valider telefon - validate(Innsending::telefonnummer).isTelefonnummer() - // Er tillatt Ã¥ unngÃ¥ arbeidsgiverperioder nÃ¥r: - // - arbeidsgiver ikke betaler lønn i arbeidsgiverperioden - if (innsendt.fullLønnIArbeidsgiverPerioden?.utbetalerFullLønn == true) { - validate(Innsending::arbeidsgiverperioder).isNotEmpty() - } - // Brutto inntekt - validate(Innsending::inntekt).validate { - validate(Inntekt::bekreftet).isTrue() - validate(Inntekt::beregnetInntekt).isGreaterThanOrEqualTo(0.0) - validate(Inntekt::beregnetInntekt).isLessThan(1_000_000.0) - if (it.manueltKorrigert) { - validate(Inntekt::endringÃ…rsak).isNotNull() - } - } - // Betaler arbeidsgiver lønn under hele eller deler av sykefraværet - validate(Innsending::refusjon).validate { - if (it.utbetalerHeleEllerDeler) { - validate(Refusjon::refusjonPrMnd).isNotNull() - validate(Refusjon::refusjonPrMnd).isGreaterThanOrEqualTo(0.0) - validate(Refusjon::refusjonPrMnd).isLessThan(1_000_000.0) - validate(Refusjon::refusjonPrMnd).isLessThanOrEqualTo(innsendt.inntekt.beregnetInntekt) - - validate(Refusjon::refusjonEndringer).validateForEach { - validate(RefusjonEndring::beløp).isNotNull() - validate(RefusjonEndring::beløp).isGreaterThanOrEqualTo(0.0) - validate(RefusjonEndring::beløp).isLessThan(1_000_000.0) - validate(RefusjonEndring::beløp).isLessThanOrEqualTo(innsendt.inntekt.beregnetInntekt) - validate(RefusjonEndring::dato).isNotNull() - } - } - } - // Naturalytelser - validate(Innsending::naturalytelser).validateForEach { - validate(Naturalytelse::naturalytelse).isNotNull() - validate(Naturalytelse::dato).isNotNull() - validate(Naturalytelse::beløp).isNotNull() - validate(Naturalytelse::beløp).isGreaterThan(0.0) - validate(Naturalytelse::beløp).isLessThan(1_000_000.0) - } - validate(Innsending::bekreftOpplysninger).isTrue() - } -} - -fun isKomplettForespoersel(forespurtData: List?): Boolean { - // TODO: Midlertidig funksjon - heller enn Ã¥ la frontend fortelle oss, bør vi sjekke om dette er delvis eller komplett forespørsel pÃ¥ backend - return forespurtData.isNullOrEmpty() || forespurtData.size > 2 -} diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/CustomConstraint.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/CustomConstraint.kt deleted file mode 100644 index d8bb128ab..000000000 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/CustomConstraint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.validation - -import org.valiktor.Constraint - -interface CustomConstraint : Constraint { - override val messageBundle: String - get() = "messages" -} diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/IdentitetsnummerConstraint.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/IdentitetsnummerConstraint.kt deleted file mode 100644 index a58f4cb1e..000000000 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/IdentitetsnummerConstraint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.validation - -import no.nav.helsearbeidsgiver.utils.wrapper.Fnr -import org.valiktor.Validator - -object IdentitetsnummerConstraint : CustomConstraint - -fun Validator.Property.isIdentitetsnummer() = - this.validate(IdentitetsnummerConstraint) { - require(it != null) - Fnr.erGyldig(it) - } diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/OrganisasjonsnummerConstraint.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/OrganisasjonsnummerConstraint.kt deleted file mode 100644 index f69619270..000000000 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/OrganisasjonsnummerConstraint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.validation - -import no.nav.helsearbeidsgiver.utils.wrapper.Orgnr -import org.valiktor.Validator - -object OrganisasjonsnummerConstraint : CustomConstraint - -fun Validator.Property.isOrganisasjonsnummer() = - this.validate(OrganisasjonsnummerConstraint) { - require(it != null) - Orgnr.erGyldig(it) - } diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerConstraint.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerConstraint.kt deleted file mode 100644 index dd461b3aa..000000000 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerConstraint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.validation - -import org.valiktor.Validator - -object TelefonnummerConstraint : CustomConstraint - -fun Validator.Property.isTelefonnummer() = - this.validate(TelefonnummerConstraint) { - TelefonnummerValidator.isValid(it) - } diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerValidator.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerValidator.kt deleted file mode 100644 index 7e7a576fc..000000000 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerValidator.kt +++ /dev/null @@ -1,26 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.validation - -class TelefonnummerValidator( - input: String?, -) { - init { - require(input != null) - require(isEightDigits(input) || startsWithPlus(input) || isTwelveDigits(input)) { "Ikke et gyldig telefonnummer" } - } - - private fun startsWithPlus(input: String): Boolean = """\+\d{10}""".toRegex().matches(input) - - private fun isEightDigits(input: String) = """\d{8}""".toRegex().matches(input) - - private fun isTwelveDigits(input: String) = """00\d{10}""".toRegex().matches(input) - - companion object { - fun isValid(telefonnummer: String?): Boolean = - try { - TelefonnummerValidator(telefonnummer) - true - } catch (t: Throwable) { - false - } - } -} diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/ValidationResponse.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/ValidationResponse.kt deleted file mode 100644 index 6d34a4782..000000000 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/ValidationResponse.kt +++ /dev/null @@ -1,15 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.validation - -import kotlinx.serialization.Serializable - -@Serializable -class ValidationResponse( - val errors: List, -) - -@Serializable -class ValidationError( - val property: String, - val error: String, - val value: String, -) diff --git a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/ValidationResponseMapper.kt b/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/ValidationResponseMapper.kt deleted file mode 100644 index a40a01eab..000000000 --- a/api/src/main/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/ValidationResponseMapper.kt +++ /dev/null @@ -1,14 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.validation - -import org.valiktor.ConstraintViolation -import org.valiktor.i18n.mapToMessage -import java.util.Locale - -fun validationResponseMapper(violations: Set): ValidationResponse = - ValidationResponse( - violations - .mapToMessage(baseName = "messages", locale = Locale.forLanguageTag("no")) - .map { - ValidationError(it.property, it.message, it.value.toString()) - }, - ) diff --git a/api/src/main/resources/messages_no.properties b/api/src/main/resources/messages_no.properties deleted file mode 100644 index a9c25f9ad..000000000 --- a/api/src/main/resources/messages_no.properties +++ /dev/null @@ -1,9 +0,0 @@ -# suppress inspection "UnusedProperty" for whole file -no.nav.helsearbeidsgiver.inntektsmelding.api.validation.IdentitetsnummerConstraint.message=Ugyldig fødsels- eller D-nummer -no.nav.helsearbeidsgiver.inntektsmelding.api.validation.OrganisasjonsnummerConstraint.message=Ugyldig virksomhetsnummer -org.valiktor.constraints.NotEmpty.message=Må fylles ut -org.valiktor.constraints.Less.message=Må være mindre enn {value} -org.valiktor.constraints.Greater.message=Må være større enn {value} -org.valiktor.constraints.GreaterOrEqual.message=Må være større eller lik 0 -org.valiktor.constraints.NotNull.message=Må fylles ut -org.valiktor.constraints.True.message=Må krysses av \ No newline at end of file diff --git a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/InnsendingProducerTest.kt b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/InnsendingProducerTest.kt index 60ca340c7..01e5eed51 100644 --- a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/InnsendingProducerTest.kt +++ b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/InnsendingProducerTest.kt @@ -4,12 +4,12 @@ import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.ints.shouldBeExactly import io.kotest.matchers.maps.shouldContainExactly import no.nav.helse.rapids_rivers.testsupport.TestRapid -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmelding import no.nav.helsearbeidsgiver.felles.EventName import no.nav.helsearbeidsgiver.felles.Key import no.nav.helsearbeidsgiver.felles.json.toJson import no.nav.helsearbeidsgiver.felles.json.toMap -import no.nav.helsearbeidsgiver.felles.test.mock.gyldigInnsendingRequest +import no.nav.helsearbeidsgiver.felles.test.mock.mockSkjemaInntektsmelding import no.nav.helsearbeidsgiver.felles.test.rapidsrivers.firstMessage import no.nav.helsearbeidsgiver.inntektsmelding.api.innsending.InnsendingProducer import no.nav.helsearbeidsgiver.utils.json.toJson @@ -24,10 +24,10 @@ class InnsendingProducerTest : test("publiserer melding pÃ¥ forventet format") { val transaksjonId = UUID.randomUUID() - val forespoerselId = UUID.randomUUID() val avsenderFnr = Fnr.genererGyldig() + val skjema = mockSkjemaInntektsmelding() - producer.publish(transaksjonId, forespoerselId, gyldigInnsendingRequest, avsenderFnr) + producer.publish(transaksjonId, skjema, avsenderFnr) testRapid.inspektør.size shouldBeExactly 1 testRapid.firstMessage().toMap() shouldContainExactly @@ -36,9 +36,9 @@ class InnsendingProducerTest : Key.UUID to transaksjonId.toJson(), Key.DATA to mapOf( - Key.FORESPOERSEL_ID to forespoerselId.toJson(), + Key.FORESPOERSEL_ID to skjema.forespoerselId.toJson(), Key.ARBEIDSGIVER_FNR to avsenderFnr.toJson(), - Key.SKJEMA_INNTEKTSMELDING to gyldigInnsendingRequest.toJson(Innsending.serializer()), + Key.SKJEMA_INNTEKTSMELDING to skjema.toJson(SkjemaInntektsmelding.serializer()), ).toJson(), ) } diff --git a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/HentForespoerselRouteKtTest.kt b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/HentForespoerselRouteKtTest.kt index c3b57a802..c118aeeb8 100644 --- a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/HentForespoerselRouteKtTest.kt +++ b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/HentForespoerselRouteKtTest.kt @@ -4,6 +4,7 @@ import io.ktor.client.statement.bodyAsText import io.ktor.http.HttpStatusCode import io.mockk.clearAllMocks import io.mockk.coEvery +import kotlinx.serialization.builtins.serializer import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Periode @@ -28,7 +29,6 @@ import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.harTilgangResultat import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.hardcodedJson import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.ikkeTilgangResultat import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.jsonStrOrNull -import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.ValidationResponse import no.nav.helsearbeidsgiver.utils.json.fromJson import no.nav.helsearbeidsgiver.utils.json.toJson import no.nav.helsearbeidsgiver.utils.test.date.april @@ -101,7 +101,7 @@ class HentForespoerselRouteKtTest : ApiTest() { } @Test - fun `skal returnere valideringsfeil ved ugyldig request`() = + fun `skal returnere 400-feil ved ugyldig request`() = testApi { val ugyldigRequest = JsonObject( @@ -120,10 +120,9 @@ class HentForespoerselRouteKtTest : ApiTest() { assertNull(result.success) assertNotNull(result.failure) - val violations = result.failure!!.fromJson(ValidationResponse.serializer()).errors + val feilmelding = result.failure!!.fromJson(String.serializer()) - assertEquals(1, violations.size) - assertEquals("uuid", violations[0].property) + assertEquals("Mangler forespørsel-ID for Ã¥ hente forespørsel.", feilmelding) } @Test diff --git a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/TrengerRouteKtTest.kt b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/TrengerRouteKtTest.kt index 5a94d1b09..3d63bda41 100644 --- a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/TrengerRouteKtTest.kt +++ b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/hentforespoersel/TrengerRouteKtTest.kt @@ -4,6 +4,7 @@ import io.ktor.client.statement.bodyAsText import io.ktor.http.HttpStatusCode import io.mockk.clearAllMocks import io.mockk.coEvery +import kotlinx.serialization.builtins.serializer import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonObject import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Periode @@ -28,7 +29,6 @@ import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.harTilgangResultat import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.hardcodedJson import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.ikkeTilgangResultat import no.nav.helsearbeidsgiver.inntektsmelding.api.utils.jsonStrOrNull -import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.ValidationResponse import no.nav.helsearbeidsgiver.utils.json.fromJson import no.nav.helsearbeidsgiver.utils.json.toJson import no.nav.helsearbeidsgiver.utils.test.date.april @@ -101,7 +101,7 @@ class TrengerRouteKtTest : ApiTest() { } @Test - fun `skal returnere valideringsfeil ved ugyldig request`() = + fun `skal returnere 400-feil ved ugyldig request`() = testApi { val ugyldigRequest = JsonObject( @@ -120,10 +120,9 @@ class TrengerRouteKtTest : ApiTest() { assertNull(result.success) assertNotNull(result.failure) - val violations = result.failure!!.fromJson(ValidationResponse.serializer()).errors + val feilmelding = result.failure!!.fromJson(String.serializer()) - assertEquals(1, violations.size) - assertEquals("uuid", violations[0].property) + assertEquals("Mangler forespørsel-ID for Ã¥ hente forespørsel.", feilmelding) } @Test diff --git a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRouteKtTest.kt b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRouteKtTest.kt index 546a00bd1..79a1d4d2c 100644 --- a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRouteKtTest.kt +++ b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingRouteKtTest.kt @@ -1,18 +1,16 @@ -@file:Suppress("NonAsciiCharacters") - package no.nav.helsearbeidsgiver.inntektsmelding.api.innsending import io.ktor.client.statement.bodyAsText import io.ktor.http.HttpStatusCode import io.mockk.clearAllMocks import io.mockk.coEvery -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending +import kotlinx.serialization.builtins.serializer import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Inntektsmelding +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmelding import no.nav.helsearbeidsgiver.felles.domene.ResultJson -import no.nav.helsearbeidsgiver.felles.test.mock.delvisInnsendingRequest -import no.nav.helsearbeidsgiver.felles.test.mock.gyldigInnsendingRequest import no.nav.helsearbeidsgiver.felles.test.mock.mockDelvisInntektsmeldingDokument import no.nav.helsearbeidsgiver.felles.test.mock.mockInntektsmelding +import no.nav.helsearbeidsgiver.felles.test.mock.mockSkjemaInntektsmelding import no.nav.helsearbeidsgiver.inntektsmelding.api.RedisPollerTimeoutException import no.nav.helsearbeidsgiver.inntektsmelding.api.Routes import no.nav.helsearbeidsgiver.inntektsmelding.api.response.JsonErrorResponse @@ -28,10 +26,7 @@ import org.junit.jupiter.api.Test import java.util.UUID class InnsendingRouteKtTest : ApiTest() { - private val path = Routes.PREFIX + Routes.INNSENDING + "/${Mock.forespoerselId}" - - private val gyldigRequest = gyldigInnsendingRequest.toJson(Innsending.serializer()) - private val gyldigDelvisRequest = delvisInnsendingRequest.toJson(Innsending.serializer()) + private val path = Routes.PREFIX + Routes.INNSENDING + "/${UUID.randomUUID()}" @BeforeEach fun setup() { @@ -41,6 +36,8 @@ class InnsendingRouteKtTest : ApiTest() { @Test fun `mottar inntektsmelding og svarer OK`() = testApi { + val skjema = mockSkjemaInntektsmelding() + coEvery { mockRedisConnection.get(any()) } returnsMany listOf( harTilgangResultat, @@ -50,15 +47,17 @@ class InnsendingRouteKtTest : ApiTest() { .toString(), ) - val response = post(path, gyldigRequest) + val response = post(path, skjema, SkjemaInntektsmelding.serializer()) assertEquals(HttpStatusCode.Created, response.status) - assertEquals(InnsendingResponse(Mock.forespoerselId).toJsonStr(InnsendingResponse.serializer()), response.bodyAsText()) + assertEquals(InnsendingResponse(skjema.forespoerselId).toJsonStr(InnsendingResponse.serializer()), response.bodyAsText()) } @Test fun `mottar delvis inntektsmelding og svarer OK`() = testApi { + val delvisSkjema = mockSkjemaInntektsmelding().copy(agp = null) + coEvery { mockRedisConnection.get(any()) } returnsMany listOf( harTilgangResultat, @@ -68,36 +67,34 @@ class InnsendingRouteKtTest : ApiTest() { .toString(), ) - val response = post(path, gyldigDelvisRequest) + val response = post(path, delvisSkjema, SkjemaInntektsmelding.serializer()) assertEquals(HttpStatusCode.Created, response.status) - assertEquals(InnsendingResponse(Mock.forespoerselId).toJsonStr(InnsendingResponse.serializer()), response.bodyAsText()) + assertEquals(InnsendingResponse(delvisSkjema.forespoerselId).toJsonStr(InnsendingResponse.serializer()), response.bodyAsText()) } @Test fun `gir json-feil ved ugyldig request-json`() = testApi { - val response = post(path, "\"ikke en request\"".toJson()) + val response = post(path, "\"ikke en request\"", String.serializer()) val feilmelding = response.bodyAsText().fromJson(JsonErrorResponse.serializer()) assertEquals(HttpStatusCode.BadRequest, response.status) - assertEquals(Mock.forespoerselId.toString(), feilmelding.forespoerselId) + assertEquals(null, feilmelding.forespoerselId) assertEquals("Feil under serialisering.", feilmelding.error) } @Test fun `skal returnere feilmelding ved timeout fra Redis`() = testApi { - coEvery { mockRedisConnection.get(any()) } returns harTilgangResultat andThenThrows RedisPollerTimeoutException(Mock.forespoerselId) + val skjema = mockSkjemaInntektsmelding() - val response = post(path, gyldigRequest) + coEvery { mockRedisConnection.get(any()) } returns harTilgangResultat andThenThrows RedisPollerTimeoutException(skjema.forespoerselId) + + val response = post(path, skjema, SkjemaInntektsmelding.serializer()) assertEquals(HttpStatusCode.InternalServerError, response.status) - assertEquals(RedisTimeoutResponse(Mock.forespoerselId).toJsonStr(RedisTimeoutResponse.serializer()), response.bodyAsText()) + assertEquals(RedisTimeoutResponse(skjema.forespoerselId).toJsonStr(RedisTimeoutResponse.serializer()), response.bodyAsText()) } - - private object Mock { - val forespoerselId: UUID = UUID.randomUUID() - } } diff --git a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingTest.kt b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingTest.kt deleted file mode 100644 index 5de23e4be..000000000 --- a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingTest.kt +++ /dev/null @@ -1,34 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.innsending - -import io.kotest.core.spec.style.FunSpec -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Inntekt -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.NyStilling -import no.nav.helsearbeidsgiver.felles.test.mock.gyldigInnsendingRequest -import no.nav.helsearbeidsgiver.utils.json.fromJson -import no.nav.helsearbeidsgiver.utils.json.toJson -import no.nav.helsearbeidsgiver.utils.test.resource.readResource -import java.time.LocalDate - -class InnsendingTest : - FunSpec({ - test("skal serialisere InntektEndringÃ…rsak") { - val inntekt = - Inntekt( - bekreftet = false, - beregnetInntekt = 300.0, - endringÃ…rsak = NyStilling(LocalDate.now()), - manueltKorrigert = false, - ) - println(inntekt.toJson(Inntekt.serializer())) - } - - test("skal lese innsendingrequest") { - val request = "innsendingrequest.json".readResource().fromJson(Innsending.serializer()) - request.validate() - } - - test("skal kunne konvertere til json") { - println(gyldigInnsendingRequest.toJson(Innsending.serializer())) - } - }) diff --git a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingValidateKtTest.kt b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingValidateKtTest.kt deleted file mode 100644 index ad212f5e4..000000000 --- a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/innsending/InnsendingValidateKtTest.kt +++ /dev/null @@ -1,410 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.innsending - -import io.kotest.assertions.throwables.shouldNotThrowAny -import io.kotest.assertions.throwables.shouldThrowExactly -import io.kotest.core.spec.style.FunSpec -import io.kotest.datatest.withData -import io.kotest.matchers.shouldBe -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.AarsakInnsending -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.BegrunnelseIngenEllerRedusertUtbetalingKode -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Bonus -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Ferie -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.FullLoennIArbeidsgiverPerioden -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Inntekt -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Naturalytelse -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.NaturalytelseKode -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.NyStilling -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.NyStillingsprosent -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Nyansatt -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Permisjon -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Permittering -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Refusjon -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.RefusjonEndring -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Tariffendring -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.VarigLonnsendring -import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Periode -import no.nav.helsearbeidsgiver.felles.test.mock.delvisInnsendingRequest -import no.nav.helsearbeidsgiver.felles.test.mock.gyldigInnsendingRequest -import no.nav.helsearbeidsgiver.inntektsmelding.api.validation.validationResponseMapper -import org.valiktor.ConstraintViolationException -import java.time.LocalDate - -class InnsendingValidateKtTest : - FunSpec({ - - val now: LocalDate = LocalDate.now() - val zero = 0.0 - val maksInntekt = 1_000_001.0 - val maksRefusjon = 1_000_001.0 - val maksNaturalBeloep = 1_000_000.0 - val negativtBeloep = -0.1 - val hoeyereEnnInntekt = gyldigInnsendingRequest.inntekt.beregnetInntekt.plus(1) - - test("godtar fullstendig innsending") { - gyldigInnsendingRequest.validate() - } - - test("godtar delvis innsending") { - delvisInnsendingRequest.validate() - } - - test("skal gi feil om refusjonIarbeidsgiverperioden ikke settes (ved komplett innsending)") { - shouldThrowExactly { - gyldigInnsendingRequest - .copy( - fullLønnIArbeidsgiverPerioden = null, - ).validate() - } - } - - test("skal ikke godta tom liste med arbeidsgiverperioder nÃ¥r arbeidsgiver betaler lønn") { - shouldThrowExactly { - gyldigInnsendingRequest - .copy( - fullLønnIArbeidsgiverPerioden = FullLoennIArbeidsgiverPerioden(true), - arbeidsgiverperioder = emptyList(), - ).validate() - } - } - - test("skal godta tom liste med arbeidsgiverperioder nÃ¥r arbeidsgiver ikke betaler lønn") { - gyldigInnsendingRequest - .copy( - fullLønnIArbeidsgiverPerioden = - FullLoennIArbeidsgiverPerioden( - utbetalerFullLønn = false, - begrunnelse = BegrunnelseIngenEllerRedusertUtbetalingKode.FiskerMedHyre, - utbetalt = zero, - ), - arbeidsgiverperioder = emptyList(), - ).validate() - } - - test("skal godta arbeidsgiverperioder med gyldig periode (fom FØR tom)") { - gyldigInnsendingRequest - .copy( - arbeidsgiverperioder = listOf(Periode(now, now.plusDays(3))), - ).validate() - } - - test("midlertidig - komplett innsending har forespurtData-liste med minst tre elementer") { - gyldigInnsendingRequest - .copy( - forespurtData = listOf("eple", "banan", "appelsin"), - ).validate() - } - - test("midlertidig - komplett innsending kan ogsÃ¥ ha ingen eller tom forespurtData-liste") { - gyldigInnsendingRequest - .copy( - forespurtData = null, - ).validate() - gyldigInnsendingRequest - .copy( - forespurtData = emptyList(), - ).validate() - } - - test("skal gi feilmelding nÃ¥r orgnummer er ugyldig") { - shouldThrowExactly { - gyldigInnsendingRequest.copy(orgnrUnderenhet = "").validate() - } - shouldThrowExactly { - gyldigInnsendingRequest.copy(orgnrUnderenhet = TestData.NOT_VALID_ORGNR).validate() - } - } - - test("skal gi feilmelding nÃ¥r fnr er ugyldig") { - shouldThrowExactly { - gyldigInnsendingRequest.copy(identitetsnummer = "").validate() - } - shouldThrowExactly { - gyldigInnsendingRequest.copy(identitetsnummer = TestData.NOT_VALID_IDENTITETSNUMMER).validate() - } - } - - test("skal gi feilmelding nÃ¥r telefonnummer er ugyldig") { - shouldThrowExactly { - gyldigInnsendingRequest.copy(telefonnummer = "313").validate() - } - } - - test("skal godta tom liste med behandlingsdager") { - gyldigInnsendingRequest.copy(behandlingsdager = emptyList()).validate() - } - - test("skal godta tom liste med egenmeldinger") { - gyldigInnsendingRequest.copy(egenmeldingsperioder = emptyList()).validate() - } - - context(Innsending::inntekt.name) { - test("skal tillate inntekt pÃ¥ 0 kroner") { - val inntekt = gyldigInnsendingRequest.inntekt.copy(beregnetInntekt = zero) - gyldigInnsendingRequest - .copy( - inntekt = inntekt, - refusjon = Refusjon(utbetalerHeleEllerDeler = false), - ).validate() - } - - test("skal gi feil dersom beregnetInntekt er for høy") { - shouldThrowExactly { - val inntekt = gyldigInnsendingRequest.inntekt.copy(beregnetInntekt = maksInntekt) - gyldigInnsendingRequest.copy(inntekt = inntekt).validate() - } - } - - test("skal gi feil dersom beregnetInntekt er negativ") { - try { - val inntekt = gyldigInnsendingRequest.inntekt.copy(beregnetInntekt = negativtBeloep) - gyldigInnsendingRequest.copy(inntekt = inntekt).validate() - } catch (ex: ConstraintViolationException) { - val response = validationResponseMapper(ex.constraintViolations) - response.errors[0].property shouldBe "inntekt.beregnetInntekt" - response.errors[0].error shouldBe "MÃ¥ være større eller lik 0" - } - } - - test("skal gi feil dersom beregnetInntekt ikke er bekreftet") { - shouldThrowExactly { - val inntekt = gyldigInnsendingRequest.inntekt.copy(bekreftet = false) - gyldigInnsendingRequest.copy(inntekt = inntekt).validate() - } - } - - context(Inntekt::endringÃ…rsak.name) { - withData( - mapOf( - "Uten endringsÃ¥rsak" to null, - "Tariffendring" to Tariffendring(now, now), - "Ferie" to - Ferie( - listOf( - Periode(now, now), - ), - ), - "VarigLønnsendring" to VarigLonnsendring(now), - "Permisjon" to - Permisjon( - listOf( - Periode(now, now), - ), - ), - "Permittering" to - Permittering( - listOf( - Periode(now, now), - ), - ), - "NyStilling" to NyStilling(now), - "NyStillingsprosent" to NyStillingsprosent(now), - "Bonus" to Bonus(), - "Nyansatt" to Nyansatt, - ), - ) { endringAarsak -> - val gyldigInnsending = - gyldigInnsendingRequest.copy( - inntekt = - Inntekt( - endringÃ…rsak = endringAarsak, - beregnetInntekt = gyldigInnsendingRequest.inntekt.beregnetInntekt, - bekreftet = true, - manueltKorrigert = false, - ), - ) - - shouldNotThrowAny { - gyldigInnsending.validate() - } - } - } - } - - context(Innsending::fullLønnIArbeidsgiverPerioden.name) { - test("skal gi feil dersom arbeidsgiver ikke betaler lønn og begrunnelse er tom") { - val ugyldigInnsending = - gyldigInnsendingRequest.copy( - fullLønnIArbeidsgiverPerioden = - FullLoennIArbeidsgiverPerioden( - utbetalerFullLønn = false, - begrunnelse = null, - utbetalt = 1.0, - ), - ) - - shouldThrowExactly { - ugyldigInnsending.validate() - } - } - - context(FullLoennIArbeidsgiverPerioden::utbetalt.name) { - withData( - mapOf( - "feiler uten full lønn og utbetalt beløp er tomt" to null, - "feiler uten full lønn og utbetalt beløp er negativt" to negativtBeloep, - "feiler uten full lønn og utbetalt beløp er over maks" to maksInntekt, - ), - ) { utbetalt -> - val ugyldigInnsending = - gyldigInnsendingRequest.copy( - fullLønnIArbeidsgiverPerioden = - FullLoennIArbeidsgiverPerioden( - utbetalerFullLønn = false, - begrunnelse = BegrunnelseIngenEllerRedusertUtbetalingKode.ArbeidOpphoert, - utbetalt = utbetalt, - ), - ) - - shouldThrowExactly { - ugyldigInnsending.validate() - } - } - } - } - - context(Innsending::refusjon.name) { - withData( - mapOf( - "skal gi feil dersom refusjonsbeløp er udefinert" to null, - "skal gi feil dersom refusjonsbeløp er negativt" to negativtBeloep, - "skal gi feil dersom refusjonsbeløp er for høyt" to maksRefusjon, - "skal gi feil dersom refusjonsbeløp er høyere enn inntekt" to hoeyereEnnInntekt, - ), - ) { refusjonPrMnd -> - val ugyldigInnsending = - gyldigInnsendingRequest.copy( - refusjon = - Refusjon( - utbetalerHeleEllerDeler = true, - refusjonPrMnd = refusjonPrMnd, - ), - ) - - shouldThrowExactly { - ugyldigInnsending.validate() - } - } - - context(Refusjon::refusjonEndringer.name) { - test("Refusjon skal være større enn 0") { - val gyldigInnsending = - gyldigInnsendingRequest.copy( - refusjon = - Refusjon( - utbetalerHeleEllerDeler = true, - refusjonPrMnd = 1.0, - refusjonEndringer = null, - ), - ) - shouldNotThrowAny { - gyldigInnsending.validate() - } - } - - test("Refusjonendring beløp kan være 0") { - val gyldigInnsending = - gyldigInnsendingRequest.copy( - refusjon = - Refusjon( - utbetalerHeleEllerDeler = true, - refusjonPrMnd = 1.0, - refusjonEndringer = listOf(RefusjonEndring(zero, now)), - ), - ) - shouldNotThrowAny { - gyldigInnsending.validate() - } - } - - test("endringer pÃ¥ refusjon er ikke pÃ¥krevd") {} - withData( - mapOf( - "feiler ved endring av refusjon uten definert beløp" to RefusjonEndring(null, now), - "feiler ved endring av refusjon til negativt beløp" to RefusjonEndring(negativtBeloep, now), - "feiler ved endring av refusjon til over maksimalt beløp" to RefusjonEndring(maksRefusjon, now), - "feiler ved endring av refusjon til høyere enn inntekt" to RefusjonEndring(hoeyereEnnInntekt, now), - "feiler ved endring av refusjon uten satt dato" to RefusjonEndring(1.0, null), - ), - ) { refusjonEndring -> - val ugyldigInnsending = - gyldigInnsendingRequest.copy( - refusjon = - Refusjon( - utbetalerHeleEllerDeler = true, - refusjonPrMnd = 1.0, - refusjonEndringer = listOf(refusjonEndring), - ), - ) - - shouldThrowExactly { - ugyldigInnsending.validate() - } - } - } - } - - context(Innsending::naturalytelser.name) { - test("skal godta tom liste med naturalytelser") { - gyldigInnsendingRequest.copy(naturalytelser = emptyList()).validate() - } - - withData( - mapOf( - "skal ikke godta naturalytelser med negativt beløp" to negativtBeloep, - "skal ikke godta naturalytelser med for høyt beløp" to maksNaturalBeloep, - ), - ) { beloep -> - val ugyldigInnsending = - gyldigInnsendingRequest.copy( - naturalytelser = - listOf( - Naturalytelse( - naturalytelse = NaturalytelseKode.KOSTDOEGN, - dato = now, - beløp = beloep, - ), - ), - ) - - shouldThrowExactly { - ugyldigInnsending.validate() - } - } - } - test("skal gi feil dersom opplysninger ikke er bekreftet") { - shouldThrowExactly { - gyldigInnsendingRequest.copy(bekreftOpplysninger = false).validate() - } - } - - test("skal godta ulike Ã¥rsak innsendinger") { - gyldigInnsendingRequest.copy(Ã¥rsakInnsending = AarsakInnsending.NY).validate() - gyldigInnsendingRequest.copy(Ã¥rsakInnsending = AarsakInnsending.ENDRING).validate() - } - - test("skal bruke sprÃ¥kfil for feil") { - try { - gyldigInnsendingRequest - .copy( - naturalytelser = - listOf( - Naturalytelse( - NaturalytelseKode.BIL, - now, - maksNaturalBeloep.plus(1), - ), - ), - ).validate() - } catch (ex: ConstraintViolationException) { - val response = validationResponseMapper(ex.constraintViolations) - response.errors[0].property shouldBe "naturalytelser[0].beløp" - response.errors[0].error shouldBe "MÃ¥ være mindre enn 1 000 000" - } - } - }) - -private object TestData { - const val NOT_VALID_IDENTITETSNUMMER = "50012001987" - const val NOT_VALID_ORGNR = "123456789" -} diff --git a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/utils/TestUtils.kt b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/utils/TestUtils.kt index e14b6a038..c007b2541 100644 --- a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/utils/TestUtils.kt +++ b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/utils/TestUtils.kt @@ -16,7 +16,6 @@ import io.mockk.mockk import io.prometheus.client.CollectorRegistry import kotlinx.coroutines.runBlocking import kotlinx.serialization.KSerializer -import kotlinx.serialization.json.JsonElement import no.nav.helsearbeidsgiver.felles.domene.Tilgang import no.nav.helsearbeidsgiver.felles.domene.TilgangResultat import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisConnection @@ -69,32 +68,21 @@ class TestClient( } } - fun post( + fun post( path: String, - body: JsonElement, + body: T, + bodySerializer: KSerializer, block: HttpRequestBuilder.() -> Unit = { withAuth() }, ): HttpResponse = runBlocking { httpClient.post(path) { contentType(ContentType.Application.Json) - setBody(body) + setBody(body.toJson(bodySerializer)) block() } } - fun post( - path: String, - body: T, - bodySerializer: KSerializer, - block: HttpRequestBuilder.() -> Unit = { withAuth() }, - ): HttpResponse = - post( - path, - body.toJson(bodySerializer), - block, - ) - private fun HttpRequestBuilder.withAuth() { bearerAuth(authToken()) } diff --git a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerValidatorTest.kt b/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerValidatorTest.kt deleted file mode 100644 index b04baf143..000000000 --- a/api/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/api/validation/TelefonnummerValidatorTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -package no.nav.helsearbeidsgiver.inntektsmelding.api.validation - -import org.junit.jupiter.api.Assertions.assertFalse -import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.Test -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.NullSource -import org.junit.jupiter.params.provider.ValueSource - -class TelefonnummerValidatorTest { - @ParameterizedTest - @NullSource - @ValueSource(strings = ["", " "]) - fun `Tomt eller null er ikke gyldig telefonnummer`(tlf: String?) { - assertFalse(TelefonnummerValidator.isValid(tlf)) - } - - @Test - fun `8 sifre er OK`() { - val tlf = "12345678" - assertTrue(TelefonnummerValidator.isValid(tlf)) - } - - @ParameterizedTest - @ValueSource(strings = ["abcdefgh", "1234567a"]) - fun `Bokstaver er ikke gyldig`(tlf: String?) { - assertFalse(TelefonnummerValidator.isValid(tlf)) - } - - @ParameterizedTest - @ValueSource(strings = ["90000000", "+4790000000", "004790000000"]) - fun `Antall tegn mÃ¥ være 8, 11 eller 12`(tlf: String?) { - assertTrue(TelefonnummerValidator.isValid(tlf)) - } - - @ParameterizedTest - @ValueSource(strings = ["+90000000", "4790000000", "014790000000", "900000001", "0014790000000"]) - fun `ugyldige formater skal ikke godtas`(tlf: String?) { - assertFalse(TelefonnummerValidator.isValid(tlf)) - } -} diff --git a/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/GyldigData.kt b/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/GyldigData.kt deleted file mode 100644 index f203500a6..000000000 --- a/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/GyldigData.kt +++ /dev/null @@ -1,83 +0,0 @@ -package no.nav.helsearbeidsgiver.felles.test.mock - -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.AarsakInnsending -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.BegrunnelseIngenEllerRedusertUtbetalingKode -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.FullLoennIArbeidsgiverPerioden -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Inntekt -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Naturalytelse -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.NaturalytelseKode -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Refusjon -import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Periode -import java.time.LocalDate - -private const val VALID_IDENTITETSNUMMER = "20015001543" -private const val VALID_ORGNR = "123456785" - -val gyldigInnsendingRequest = - Innsending( - VALID_ORGNR, - VALID_IDENTITETSNUMMER, - listOf(LocalDate.now().plusDays(5)), - listOf( - Periode( - LocalDate.now(), - LocalDate.now().plusDays(2), - ), - ), - arbeidsgiverperioder = - listOf( - Periode( - LocalDate.now(), - LocalDate.now().plusDays(2), - ), - ), - LocalDate.now(), - listOf( - Periode( - LocalDate.now().plusDays(3), - LocalDate.now().plusDays(30), - ), - ), - Inntekt(true, 32100.0, endringÃ…rsak = null, false), - FullLoennIArbeidsgiverPerioden( - true, - BegrunnelseIngenEllerRedusertUtbetalingKode.ArbeidOpphoert, - ), - Refusjon(true, 200.0, LocalDate.now()), - listOf( - Naturalytelse( - NaturalytelseKode.KOSTDOEGN, - LocalDate.now(), - 300.0, - ), - ), - AarsakInnsending.ENDRING, - true, - "+4722222222", - ) - -val delvisInnsendingRequest = - Innsending( - orgnrUnderenhet = VALID_ORGNR, - identitetsnummer = VALID_IDENTITETSNUMMER, - behandlingsdager = emptyList(), - egenmeldingsperioder = emptyList(), - arbeidsgiverperioder = emptyList(), - bestemmendeFraværsdag = LocalDate.of(2001, 1, 1), - fraværsperioder = emptyList(), - inntekt = - Inntekt( - bekreftet = true, - beregnetInntekt = 10.0, - endringÃ…rsak = null, - manueltKorrigert = false, - ), - fullLønnIArbeidsgiverPerioden = null, - refusjon = Refusjon(false, null, null, null), - naturalytelser = emptyList(), - Ã¥rsakInnsending = AarsakInnsending.NY, - bekreftOpplysninger = true, - forespurtData = listOf("inntekt", "refusjon"), - telefonnummer = "22555555", - ) diff --git a/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockData.kt b/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockForespoersel.kt similarity index 87% rename from felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockData.kt rename to felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockForespoersel.kt index 55a1399fc..d854fbd50 100644 --- a/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockData.kt +++ b/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockForespoersel.kt @@ -1,6 +1,5 @@ package no.nav.helsearbeidsgiver.felles.test.mock -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.til import no.nav.helsearbeidsgiver.felles.domene.Forespoersel import no.nav.helsearbeidsgiver.felles.domene.ForespoerselType @@ -12,6 +11,25 @@ import no.nav.helsearbeidsgiver.utils.test.date.februar import no.nav.helsearbeidsgiver.utils.test.date.januar import java.util.UUID +fun mockForespoersel(): Forespoersel { + val orgnr = "789789789" + return Forespoersel( + type = ForespoerselType.KOMPLETT, + orgnr = orgnr, + fnr = "15055012345", + vedtaksperiodeId = UUID.randomUUID(), + sykmeldingsperioder = listOf(2.januar til 31.januar), + egenmeldingsperioder = listOf(1.januar til 1.januar), + bestemmendeFravaersdager = + mapOf( + orgnr to 1.januar, + "555767555" to 5.januar, + ), + forespurtData = mockForespurtData(), + erBesvart = false, + ) +} + fun mockForespurtData(): ForespurtData = ForespurtData( arbeidsgiverperiode = @@ -118,39 +136,3 @@ fun mockForespurtDataMedFastsattInntekt(): ForespurtData = ), ), ) - -fun mockForespoersel(): Forespoersel { - val orgnr = "789789789" - return Forespoersel( - type = ForespoerselType.KOMPLETT, - orgnr = orgnr, - fnr = "15055012345", - vedtaksperiodeId = UUID.randomUUID(), - sykmeldingsperioder = listOf(2.januar til 31.januar), - egenmeldingsperioder = listOf(1.januar til 1.januar), - bestemmendeFravaersdager = - mapOf( - orgnr to 1.januar, - "555767555" to 5.januar, - ), - forespurtData = mockForespurtData(), - erBesvart = false, - ) -} - -fun Innsending.tilForespoersel(vedtaksperiodeId: UUID): Forespoersel = - Forespoersel( - type = ForespoerselType.KOMPLETT, - orgnr = orgnrUnderenhet, - fnr = identitetsnummer, - vedtaksperiodeId = vedtaksperiodeId, - sykmeldingsperioder = fraværsperioder, - egenmeldingsperioder = egenmeldingsperioder, - bestemmendeFravaersdager = - fraværsperioder - .lastOrNull() - ?.let { mapOf(orgnrUnderenhet to it.fom) } - .orEmpty(), - forespurtData = mockForespurtData(), - erBesvart = false, - ) diff --git a/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockInntektsmelding.kt b/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockInntektsmelding.kt index 95986cb23..6afc00f32 100644 --- a/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockInntektsmelding.kt +++ b/felles/src/testFixtures/kotlin/no/nav/helsearbeidsgiver/felles/test/mock/MockInntektsmelding.kt @@ -17,6 +17,7 @@ import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Periode import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.RedusertLoennIAgp import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Sykmeldt import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaAvsender +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmelding import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmeldingSelvbestemt import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.til import no.nav.helsearbeidsgiver.felles.domene.EksternInntektsmelding @@ -41,6 +42,17 @@ import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Refusjon as RefusjonV1 private val dag = 24.desember(2022) private const val INNTEKT = 25_000.0 +fun mockSkjemaInntektsmelding(): SkjemaInntektsmelding { + val inntektsmelding = mockInntektsmeldingV1() + return SkjemaInntektsmelding( + forespoerselId = inntektsmelding.type.id, + avsenderTlf = inntektsmelding.avsender.tlf, + agp = inntektsmelding.agp, + inntekt = inntektsmelding.inntekt, + refusjon = inntektsmelding.refusjon, + ) +} + fun mockSkjemaInntektsmeldingSelvbestemt(): SkjemaInntektsmeldingSelvbestemt { val inntektsmelding = mockInntektsmeldingV1() return SkjemaInntektsmeldingSelvbestemt( diff --git a/innsending/src/test/kotlin/no.nav.helsearbeidsgiver.inntektsmelding.innsending/MapInntektsmeldingKtTest.kt b/innsending/src/test/kotlin/no.nav.helsearbeidsgiver.inntektsmelding.innsending/MapInntektsmeldingKtTest.kt index d4f545d7f..af9b68869 100644 --- a/innsending/src/test/kotlin/no.nav.helsearbeidsgiver.inntektsmelding.innsending/MapInntektsmeldingKtTest.kt +++ b/innsending/src/test/kotlin/no.nav.helsearbeidsgiver.inntektsmelding.innsending/MapInntektsmeldingKtTest.kt @@ -19,10 +19,11 @@ import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.NaturalytelseK import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Refusjon import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.til import no.nav.helsearbeidsgiver.felles.domene.Forespoersel +import no.nav.helsearbeidsgiver.felles.domene.ForespoerselType import no.nav.helsearbeidsgiver.felles.domene.ForespurtData import no.nav.helsearbeidsgiver.felles.domene.ForslagInntekt import no.nav.helsearbeidsgiver.felles.domene.ForslagRefusjon -import no.nav.helsearbeidsgiver.felles.test.mock.tilForespoersel +import no.nav.helsearbeidsgiver.felles.test.mock.mockForespurtData import no.nav.helsearbeidsgiver.utils.test.date.april import no.nav.helsearbeidsgiver.utils.test.date.august import no.nav.helsearbeidsgiver.utils.test.date.desember @@ -574,7 +575,24 @@ private object Mock { bekreftOpplysninger = true, ) - fun forespoersel(): Forespoersel = skjema().tilForespoersel(UUID.randomUUID()) + fun forespoersel(): Forespoersel { + val skjema = skjema() + return Forespoersel( + type = ForespoerselType.KOMPLETT, + orgnr = skjema.orgnrUnderenhet, + fnr = skjema.identitetsnummer, + vedtaksperiodeId = UUID.randomUUID(), + sykmeldingsperioder = skjema.fraværsperioder, + egenmeldingsperioder = skjema.egenmeldingsperioder, + bestemmendeFravaersdager = + skjema.fraværsperioder + .lastOrNull() + ?.let { mapOf(skjema.orgnrUnderenhet to it.fom) } + .orEmpty(), + forespurtData = mockForespurtData(), + erBesvart = false, + ) + } } private fun Forespoersel.utenPaakrevdAGP(): Forespoersel = diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt index 6c751c6d9..a719d5cda 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingIT.kt @@ -10,20 +10,23 @@ import io.mockk.coEvery import io.mockk.verify import kotlinx.serialization.builtins.serializer import no.nav.helsearbeidsgiver.dokarkiv.domene.OpprettOgFerdigstillResponse -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending +import no.nav.helsearbeidsgiver.domene.inntektsmelding.Utils.convert +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.AarsakInnsending +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmelding +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.til import no.nav.helsearbeidsgiver.felles.BehovType import no.nav.helsearbeidsgiver.felles.EventName import no.nav.helsearbeidsgiver.felles.Key +import no.nav.helsearbeidsgiver.felles.domene.Forespoersel import no.nav.helsearbeidsgiver.felles.domene.ForespoerselType import no.nav.helsearbeidsgiver.felles.json.les import no.nav.helsearbeidsgiver.felles.json.toJson import no.nav.helsearbeidsgiver.felles.json.toMap import no.nav.helsearbeidsgiver.felles.rapidsrivers.pritopic.Pri import no.nav.helsearbeidsgiver.felles.test.mock.mockForespurtData -import no.nav.helsearbeidsgiver.felles.test.mock.tilForespoersel +import no.nav.helsearbeidsgiver.felles.test.mock.mockSkjemaInntektsmelding import no.nav.helsearbeidsgiver.inntektsmelding.helsebro.domene.ForespoerselSvar import no.nav.helsearbeidsgiver.inntektsmelding.innsending.mapInntektsmelding -import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.mock.mockInnsending import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.utils.EndToEndTest import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.utils.bjarneBetjent import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.utils.fromJsonToString @@ -31,6 +34,11 @@ import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.utils.maxMekker import no.nav.helsearbeidsgiver.utils.json.fromJson import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer import no.nav.helsearbeidsgiver.utils.json.toJson +import no.nav.helsearbeidsgiver.utils.test.date.august +import no.nav.helsearbeidsgiver.utils.test.date.juli +import no.nav.helsearbeidsgiver.utils.test.date.juni +import no.nav.helsearbeidsgiver.utils.test.wrapper.genererGyldig +import no.nav.helsearbeidsgiver.utils.wrapper.Orgnr import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance @@ -45,7 +53,7 @@ class InnsendingIT : EndToEndTest() { @Test fun `skal ta imot forespørsel ny inntektsmelding, deretter opprette sak og oppgave`() { - forespoerselRepository.lagreForespoersel(Mock.forespoerselId.toString(), Mock.skjema.orgnrUnderenhet) + forespoerselRepository.lagreForespoersel(Mock.forespoerselId.toString(), Mock.forespoersel.orgnr) forespoerselRepository.oppdaterSakId(Mock.forespoerselId.toString(), Mock.SAK_ID) forespoerselRepository.oppdaterOppgaveId(Mock.forespoerselId.toString(), Mock.OPPGAVE_ID) @@ -70,8 +78,8 @@ class InnsendingIT : EndToEndTest() { Key.DATA to mapOf( Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), - Key.ARBEIDSGIVER_FNR to Mock.skjema.identitetsnummer.toJson(), - Key.SKJEMA_INNTEKTSMELDING to Mock.skjema.toJson(Innsending.serializer()), + Key.ARBEIDSGIVER_FNR to Mock.forespoersel.fnr.toJson(), + Key.SKJEMA_INNTEKTSMELDING to Mock.skjema.toJson(SkjemaInntektsmelding.serializer()), ).toJson(), ) @@ -131,7 +139,7 @@ class InnsendingIT : EndToEndTest() { @Test fun `skal ikke lagre duplikat inntektsmelding`() { - forespoerselRepository.lagreForespoersel(Mock.forespoerselId.toString(), Mock.skjema.orgnrUnderenhet) + forespoerselRepository.lagreForespoersel(Mock.forespoerselId.toString(), Mock.forespoersel.orgnr) forespoerselRepository.oppdaterSakId(Mock.forespoerselId.toString(), Mock.SAK_ID) forespoerselRepository.oppdaterOppgaveId(Mock.forespoerselId.toString(), Mock.OPPGAVE_ID) imRepository.lagreInntektsmelding(Mock.forespoerselId, Mock.innsendtInntektsmelding) @@ -160,7 +168,7 @@ class InnsendingIT : EndToEndTest() { mapOf( Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), Key.ARBEIDSGIVER_FNR to maxMekker.ident!!.toJson(), - Key.SKJEMA_INNTEKTSMELDING to Mock.skjema.toJson(Innsending.serializer()), + Key.SKJEMA_INNTEKTSMELDING to Mock.skjema.toJson(SkjemaInntektsmelding.serializer()), ).toJson(), ) @@ -239,14 +247,39 @@ class InnsendingIT : EndToEndTest() { const val OPPGAVE_ID = "neglisjert-sommer" val forespoerselId: UUID = UUID.randomUUID() - val skjema = mockInnsending().copy(identitetsnummer = bjarneBetjent.ident!!) + val skjema = mockSkjemaInntektsmelding() - private val forespoersel = skjema.tilForespoersel(UUID.randomUUID()) + private val orgnr = Orgnr.genererGyldig() + + val forespoersel = + Forespoersel( + type = ForespoerselType.KOMPLETT, + orgnr = orgnr.verdi, + fnr = bjarneBetjent.ident!!, + vedtaksperiodeId = UUID.randomUUID(), + sykmeldingsperioder = + listOf( + 1.juli til 12.juli, + 15.juli til 2.august, + ), + egenmeldingsperioder = + listOf( + 26.juni til 27.juni, + 29.juni til 29.juni, + ), + bestemmendeFravaersdager = mapOf(orgnr.verdi to 15.juli), + forespurtData = mockForespurtData(), + erBesvart = false, + ) val innsendtInntektsmelding = mapInntektsmelding( forespoersel = forespoersel, - skjema = skjema, + skjema = + skjema.convert( + sykmeldingsperioder = forespoersel.sykmeldingsperioder, + aarsakInnsending = AarsakInnsending.Endring, + ), fulltnavnArbeidstaker = bjarneBetjent.navn.fulltNavn(), virksomhetNavn = "Bedrift A/S", innsenderNavn = maxMekker.navn.fulltNavn(), diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt index a64d6297d..31af2048d 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/InnsendingServiceIT.kt @@ -7,8 +7,9 @@ import io.mockk.coEvery import kotlinx.serialization.builtins.serializer import kotlinx.serialization.json.JsonElement import no.nav.helsearbeidsgiver.dokarkiv.domene.OpprettOgFerdigstillResponse -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Inntektsmelding +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.skjema.SkjemaInntektsmelding +import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.til import no.nav.helsearbeidsgiver.felles.EventName import no.nav.helsearbeidsgiver.felles.Key import no.nav.helsearbeidsgiver.felles.domene.Forespoersel @@ -20,15 +21,18 @@ import no.nav.helsearbeidsgiver.felles.json.personMapSerializer import no.nav.helsearbeidsgiver.felles.json.toJson import no.nav.helsearbeidsgiver.felles.json.toMap import no.nav.helsearbeidsgiver.felles.rapidsrivers.redis.RedisPrefix -import no.nav.helsearbeidsgiver.felles.test.mock.gyldigInnsendingRequest import no.nav.helsearbeidsgiver.felles.test.mock.mockForespurtData import no.nav.helsearbeidsgiver.felles.test.mock.mockInntektsmelding +import no.nav.helsearbeidsgiver.felles.test.mock.mockSkjemaInntektsmelding import no.nav.helsearbeidsgiver.inntektsmelding.helsebro.domene.ForespoerselSvar import no.nav.helsearbeidsgiver.inntektsmelding.helsebro.toForespoersel import no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.utils.EndToEndTest import no.nav.helsearbeidsgiver.utils.json.fromJson import no.nav.helsearbeidsgiver.utils.json.serializer.UuidSerializer import no.nav.helsearbeidsgiver.utils.json.toJson +import no.nav.helsearbeidsgiver.utils.test.date.april +import no.nav.helsearbeidsgiver.utils.test.date.februar +import no.nav.helsearbeidsgiver.utils.test.date.mars import no.nav.helsearbeidsgiver.utils.test.wrapper.genererGyldig import no.nav.helsearbeidsgiver.utils.wrapper.Fnr import no.nav.helsearbeidsgiver.utils.wrapper.Orgnr @@ -68,9 +72,9 @@ class InnsendingServiceIT : EndToEndTest() { Key.UUID to transaksjonId.toJson(), Key.DATA to mapOf( - Key.FORESPOERSEL_ID to Mock.forespoerselId.toJson(), + Key.FORESPOERSEL_ID to mockSkjemaInntektsmelding().forespoerselId.toJson(), Key.ARBEIDSGIVER_FNR to Mock.fnrAg.toJson(), - Key.SKJEMA_INNTEKTSMELDING to gyldigInnsendingRequest.toJson(Innsending.serializer()), + Key.SKJEMA_INNTEKTSMELDING to mockSkjemaInntektsmelding().toJson(SkjemaInntektsmelding.serializer()), ).toJson(), ) @@ -214,17 +218,21 @@ class InnsendingServiceIT : EndToEndTest() { val forespoerselSvar = ForespoerselSvar.Suksess( type = ForespoerselType.KOMPLETT, - orgnr = gyldigInnsendingRequest.orgnrUnderenhet, - fnr = gyldigInnsendingRequest.identitetsnummer, + orgnr = orgnr.verdi, + fnr = Fnr.genererGyldig().verdi, vedtaksperiodeId = vedtaksperiodeId, - egenmeldingsperioder = gyldigInnsendingRequest.egenmeldingsperioder, - sykmeldingsperioder = gyldigInnsendingRequest.fraværsperioder, - skjaeringstidspunkt = gyldigInnsendingRequest.bestemmendeFraværsdag, - bestemmendeFravaersdager = - gyldigInnsendingRequest.fraværsperioder - .lastOrNull() - ?.let { mapOf(gyldigInnsendingRequest.orgnrUnderenhet to it.fom) } - .orEmpty(), + skjaeringstidspunkt = 17.mars, + sykmeldingsperioder = + listOf( + 3.mars til 13.mars, + 17.mars til 5.april, + ), + egenmeldingsperioder = + listOf( + 24.februar til 26.februar, + 1.mars til 1.mars, + ), + bestemmendeFravaersdager = mapOf(orgnr.verdi to 17.mars), forespurtData = mockForespurtData(), erBesvart = false, ) diff --git a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/mock/MockData.kt b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/mock/MockData.kt index 94e197d7f..282415220 100644 --- a/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/mock/MockData.kt +++ b/integrasjonstest/src/test/kotlin/no/nav/helsearbeidsgiver/inntektsmelding/integrasjonstest/mock/MockData.kt @@ -1,14 +1,5 @@ package no.nav.helsearbeidsgiver.inntektsmelding.integrasjonstest.mock -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.AarsakInnsending -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.BegrunnelseIngenEllerRedusertUtbetalingKode -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.FullLoennIArbeidsgiverPerioden -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Innsending -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Inntekt -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Naturalytelse -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.NaturalytelseKode -import no.nav.helsearbeidsgiver.domene.inntektsmelding.deprecated.Refusjon -import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.Periode import no.nav.helsearbeidsgiver.domene.inntektsmelding.v1.til import no.nav.helsearbeidsgiver.felles.domene.ForespoerselType import no.nav.helsearbeidsgiver.felles.test.mock.mockForespurtData @@ -17,60 +8,8 @@ import no.nav.helsearbeidsgiver.utils.test.date.januar import no.nav.helsearbeidsgiver.utils.test.wrapper.genererGyldig import no.nav.helsearbeidsgiver.utils.wrapper.Fnr import no.nav.helsearbeidsgiver.utils.wrapper.Orgnr -import java.time.LocalDate import java.util.UUID -fun mockInnsending(): Innsending = - Innsending( - orgnrUnderenhet = Orgnr.genererGyldig().verdi, - identitetsnummer = Fnr.genererGyldig().verdi, - behandlingsdager = listOf(LocalDate.now().plusDays(5)), - egenmeldingsperioder = - listOf( - Periode( - fom = LocalDate.now(), - tom = LocalDate.now().plusDays(2), - ), - ), - arbeidsgiverperioder = emptyList(), - bestemmendeFraværsdag = LocalDate.now(), - fraværsperioder = - listOf( - Periode( - fom = LocalDate.now().plusDays(3), - tom = LocalDate.now().plusDays(24), - ), - ), - inntekt = - Inntekt( - bekreftet = true, - beregnetInntekt = 32100.0, - endringÃ…rsak = null, - manueltKorrigert = false, - ), - fullLønnIArbeidsgiverPerioden = - FullLoennIArbeidsgiverPerioden( - utbetalerFullLønn = true, - begrunnelse = BegrunnelseIngenEllerRedusertUtbetalingKode.ArbeidOpphoert, - ), - refusjon = - Refusjon( - utbetalerHeleEllerDeler = true, - refusjonPrMnd = 200.0, - refusjonOpphører = LocalDate.now(), - ), - naturalytelser = - listOf( - Naturalytelse( - naturalytelse = NaturalytelseKode.KOSTDOEGN, - dato = LocalDate.now(), - beløp = 300.0, - ), - ), - Ã¥rsakInnsending = AarsakInnsending.ENDRING, - bekreftOpplysninger = true, - ) - fun mockForespoerselSvarSuksess(): ForespoerselSvar.Suksess { val orgnr = Orgnr.genererGyldig().verdi return ForespoerselSvar.Suksess(