Skip to content

Commit

Permalink
La til ny løsning for full app test
Browse files Browse the repository at this point in the history
  • Loading branch information
nilsmsa committed Jun 27, 2024
1 parent 220709a commit 5f3b1ff
Show file tree
Hide file tree
Showing 5 changed files with 373 additions and 202 deletions.
Original file line number Diff line number Diff line change
@@ -1,47 +1,29 @@
package no.nav.paw.arbeidssokerregisteret

import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import com.nimbusds.jwt.SignedJWT
import io.kotest.common.runBlocking
import io.kotest.core.spec.style.FreeSpec
import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder
import io.kotest.matchers.collections.shouldNotBeEmpty
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
import io.kotest.matchers.types.shouldBeInstanceOf
import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.serialization.jackson.*
import io.ktor.client.call.*
import io.ktor.server.auth.*
import io.ktor.server.testing.*
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
import no.nav.paw.arbeidssoekerregisteret.api.startstopp.models.ApiV1ArbeidssokerPeriodePutRequest
import no.nav.paw.arbeidssoekerregisteret.api.startstopp.models.Feil
import no.nav.paw.arbeidssokerregisteret.application.RequestValidator
import no.nav.paw.arbeidssokerregisteret.application.StartStoppRequestHandler
import no.nav.paw.arbeidssokerregisteret.auth.configureAuthentication
import no.nav.paw.arbeidssokerregisteret.domain.Identitetsnummer
import no.nav.paw.arbeidssokerregisteret.domain.NavAnsatt
import no.nav.paw.arbeidssokerregisteret.intern.v1.HarOpplysninger
import no.nav.paw.arbeidssokerregisteret.intern.v1.Hendelse
import no.nav.paw.arbeidssokerregisteret.intern.v1.Startet
import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.Bruker
import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.BrukerType
import no.nav.paw.arbeidssokerregisteret.intern.v1.vo.Opplysning
import no.nav.paw.arbeidssokerregisteret.plugins.configureHTTP
import no.nav.paw.arbeidssokerregisteret.plugins.configureSerialization
import no.nav.paw.arbeidssokerregisteret.routes.arbeidssokerRoutes
import no.nav.paw.arbeidssokerregisteret.services.AutorisasjonService
import no.nav.paw.arbeidssokerregisteret.services.PersonInfoService
import no.nav.paw.arbeidssokerregisteret.testdata.TestBruker
import no.nav.paw.kafkakeygenerator.client.inMemoryKafkaKeysMock
import no.nav.paw.pdl.graphql.generated.enums.Oppholdstillatelse
import no.nav.paw.pdl.graphql.generated.hentperson.*
import no.nav.security.mock.oauth2.MockOAuth2Server
import org.apache.kafka.clients.producer.ProducerRecord
import java.time.Instant
import java.util.*
import org.junit.jupiter.api.fail
import org.slf4j.LoggerFactory

class ApplicationTest : FreeSpec({
val mockOAuthServer = MockOAuth2Server()
Expand All @@ -58,28 +40,13 @@ class ApplicationTest : FreeSpec({
configureHTTP()
configureAuthentication(mockOAuthServer)
}

val autorisasjonService = mockk<AutorisasjonService>()
val personInfoService = mockk<PersonInfoService>()
val producer: ProducerMock<Long, Hendelse> = ProducerMock()
val personToken = mockOAuthServer.issueToken(
claims = mapOf(
"acr" to "idporten-loa-high",
"pid" to "12345678909"
)
)
val ansattToken = mockOAuthServer.issueToken(
claims = mapOf(
"oid" to "989f736f-14db-45dc-b8d1-94d621dbf2bb",
"NAVident" to "test"
)
)
val hendeleTopic = "hendelseTopic"

val kafkaKeys = inMemoryKafkaKeysMock()
fun getKey(id: String) = runBlocking { kafkaKeys.getIdAndKey(id).key }
fun getId(id: String) = runBlocking { kafkaKeys.getIdAndKey(id).id }
val startStoppRequestHandler = StartStoppRequestHandler(
hendelseTopic = hendeleTopic,
hendelseTopic = "any",
requestValidator = RequestValidator(
autorisasjonService = autorisasjonService,
personInfoService = personInfoService
Expand All @@ -92,168 +59,32 @@ class ApplicationTest : FreeSpec({
arbeidssokerRoutes(startStoppRequestHandler, mockk())
}
}
val client = createClient {
install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) {
jackson {
registerKotlinModule()
registerModule(JavaTimeModule())
val client = createClient { defaultConfig() }
val logger = LoggerFactory.getLogger("ApplicationTest")
TestBruker::class.sealedSubclasses.shouldNotBeEmpty()
TestBruker::class.sealedSubclasses
.mapNotNull { it.objectInstance }
.forEach { (id, person, resultFunction, httpStatus, error) ->
logger.info("Running test for $id")
personInfoService.setPersonInfo(id, person)
val status = client.startPeriode(id, mockOAuthServer.personToken(id))
status.status shouldBe httpStatus
error?.also { expectedErrorResponse ->
val body = status.body<Feil>()
body.feilKode shouldBe expectedErrorResponse.feilKode
body.aarsakTilAvvisning?.regel shouldBe expectedErrorResponse.aarsakTilAvvisning?.regel
expectedErrorResponse.aarsakTilAvvisning?.detaljer?.also { expectedDetails ->
body.aarsakTilAvvisning?.detaljer.shouldNotBeNull()
body.aarsakTilAvvisning?.detaljer?.shouldContainExactlyInAnyOrder(expectedDetails)
}
}
}
}

val id = "12345678909"
val person = Person(
foedsel = Foedsel("2000-03-04", 2000).list(),
statsborgerskap = "NOR".statsborgerskap(),
opphold = emptyList(),
folkeregisterpersonstatus = bosatt.folkeregisterpersonstatus(),
bostedsadresse = bostedsadresse(
vegadresse = Vegadresse("1201")
),
innflyttingTilNorge = "2018-01-02T13:23:12".innflytting(),
utflyttingFraNorge = "2017-01-02".utflytting()
)
personInfoService.setPersonInfo(id, person)
val status = client.startPeriode(id, personToken)
status.status shouldBe HttpStatusCode.NoContent
verify(
actual = producer.next(),
expected = ProducerRecord(
hendeleTopic,
getKey(id),
Startet(
hendelseId = UUID.randomUUID(),
id = getId(id),
identitetsnummer = id,
metadata = no.nav.paw.arbeidssokerregisteret.intern.v1.vo.Metadata(
tidspunkt = Instant.now(),
kilde = "paw-arbeidssokerregisteret-api-start-stopp-perioder",
utfoertAv = Bruker(
id = id,
type = BrukerType.SLUTTBRUKER
),
aarsak = "any",
tidspunktFraKilde = null
),
opplysninger = setOf(
Opplysning.ER_OVER_18_AAR,
Opplysning.BOSATT_ETTER_FREG_LOVEN,
Opplysning.ER_EU_EOES_STATSBORGER,
Opplysning.HAR_NORSK_ADRESSE,
Opplysning.SISTE_FLYTTING_VAR_INN_TIL_NORGE,
Opplysning.IKKE_ANSATT,
Opplysning.SAMME_SOM_INNLOGGET_BRUKER,
Opplysning.INGEN_INFORMASJON_OM_OPPHOLDSTILLATELSE
resultFunction(kafkaKeys)?.also { expectedRecord ->
verify(
actual = producer.next(),
expected = expectedRecord
)
)
)
)
}
}
}
}
})

inline fun <reified A> verify(
actual: ProducerRecord<Long, Hendelse>,
expected: ProducerRecord<Long, A>
) where A : Hendelse, A : HarOpplysninger {
actual.key() shouldBe expected.key()
val actualValue = actual.value().shouldBeInstanceOf<A>()
actualValue.id shouldBe expected.value().id
actualValue.identitetsnummer shouldBe expected.value().identitetsnummer
actualValue.metadata.utfoertAv.id shouldBe expected.value().metadata.utfoertAv.id
actualValue.metadata.utfoertAv.type shouldBe expected.value().metadata.utfoertAv.type
actualValue.opplysninger shouldContainExactlyInAnyOrder expected.value().opplysninger
}

const val bosatt = "bosattEtterFolkeregisterloven"
const val ikkeBosatt = "ikkeBosatt"
const val doed = "doedIFolkeregisteret"
const val forsvunnet = "forsvunnet"
const val opphoert = "opphoert"
const val dNummer = "dNummer"

val emptyMetadat = Metadata(emptyList())

fun String?.innflytting(): List<InnflyttingTilNorge> = list().map {
InnflyttingTilNorge(
folkeregistermetadata = Folkeregistermetadata(
gyldighetstidspunkt = it,
ajourholdstidspunkt = it
)
)
}

fun String?.utflytting(): List<UtflyttingFraNorge> = list().map {
UtflyttingFraNorge(
utflyttingsdato = it,
folkeregistermetadata = Folkeregistermetadata(
gyldighetstidspunkt = it,
ajourholdstidspunkt = it
)
)
}

fun bostedsadresse(
vegadresse: Vegadresse? = null,
matrikkeladresse: Matrikkeladresse? = null,
utenlandskAdresse: UtenlandskAdresse? = null
): List<Bostedsadresse> = listOfNotNull(
if (vegadresse == null && matrikkeladresse == null && utenlandskAdresse == null) null
else {
Bostedsadresse(
vegadresse = vegadresse,
matrikkeladresse = matrikkeladresse,
utenlandskAdresse = utenlandskAdresse,
)
}
)

fun String.folkeregisterpersonstatus(): List<Folkeregisterpersonstatus> =
list().map { Folkeregisterpersonstatus(it, emptyMetadat) }

fun folkeregisterpersonstatus(status: String, vararg statuser: String): List<Folkeregisterpersonstatus> =
(status.list() + statuser).map { Folkeregisterpersonstatus(it, emptyMetadat) }

fun statsborgerskap(cc: String, vararg ccs: String): List<Statsborgerskap> =
(cc.list() + ccs).map { Statsborgerskap(it, emptyMetadat) }

fun String.statsborgerskap(): List<Statsborgerskap> = list().map { Statsborgerskap(it, emptyMetadat) }

fun <A : Any?> A.list(): List<A> = listOfNotNull(this)

fun Pair<String, String?>?.opphold(): List<Opphold> = list()
.filterNotNull()
.map {
Opphold(
oppholdFra = it.first,
oppholdTil = it.second,
type = if (it.second == null) Oppholdstillatelse.PERMANENT else Oppholdstillatelse.MIDLERTIDIG,
metadata = emptyMetadat
)
}

fun AutorisasjonService.setHarTilgangTilBruker(ansatt: NavAnsatt, bruker: String, tilgang: Boolean) {
every { verifiserVeilederTilgangTilBruker(ansatt, Identitetsnummer(bruker)) } returns tilgang
}

fun PersonInfoService.setPersonInfo(identitetsnummer: String, person: Person) {
coEvery {
with(any<RequestScope>()) {
hentPersonInfo(identitetsnummer)
}
} returns person
}

suspend fun HttpClient.startPeriode(identitetsnummer: String, token: SignedJWT): HttpResponse =
put("/api/v1/arbeidssoker/periode") {
bearerAuth(token.serialize())
headers {
append(HttpHeaders.ContentType, ContentType.Application.Json)
}
setBody(
ApiV1ArbeidssokerPeriodePutRequest(
identitetsnummer = identitetsnummer,
periodeTilstand = ApiV1ArbeidssokerPeriodePutRequest.PeriodeTilstand.STARTET
)
)
}
Loading

0 comments on commit 5f3b1ff

Please sign in to comment.