From fa07ef06e6fadffdfc77434b54e1278d31b6a392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frode=20Lind=C3=A5s?= Date: Mon, 21 Oct 2024 09:00:46 +0200 Subject: [PATCH] =?UTF-8?q?Henter=20n=C3=A5=20filtere=20fra=20databasen,?= =?UTF-8?q?=20og=20endepunkter=20for=20=C3=A5=20administrere=20filter.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api-kontrakt/build.gradle.kts | 2 +- .../no/nav/aap/oppgave/filter/FilterDto.kt | 11 +- .../no/nav/aap/oppgave/filter/FilterId.kt | 5 + .../no/nav/aap/oppgave/filter/FilterAPI.kt | 51 +++- .../aap/oppgave/filter/FilterRepository.kt | 252 ++++++++++++++++-- .../aap/oppgave/plukk/PlukkOppgaveService.kt | 2 +- .../kotlin/no/nav/aap/oppgave/server/App.kt | 13 +- .../oppgave/{ApiTest.kt => OppgaveApiTest.kt} | 120 ++++++++- .../nav/aap/oppgave/OppgaveRepositoryTest.kt | 4 +- .../oppgave/filter/FilterRepositoryTest.kt | 151 +++++++++++ .../flyway/V1.6__Nye_tabeller_for_filter.sql | 25 ++ 11 files changed, 579 insertions(+), 57 deletions(-) create mode 100644 api-kontrakt/src/main/kotlin/no/nav/aap/oppgave/filter/FilterId.kt rename app/src/test/kotlin/no/nav/aap/oppgave/{ApiTest.kt => OppgaveApiTest.kt} (77%) create mode 100644 app/src/test/kotlin/no/nav/aap/oppgave/filter/FilterRepositoryTest.kt create mode 100644 dbflyway/src/main/resources/flyway/V1.6__Nye_tabeller_for_filter.sql diff --git a/api-kontrakt/build.gradle.kts b/api-kontrakt/build.gradle.kts index e1ad253..8acced3 100644 --- a/api-kontrakt/build.gradle.kts +++ b/api-kontrakt/build.gradle.kts @@ -13,7 +13,7 @@ val jacksonVersion = "2.18.0" dependencies { implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jacksonVersion") - + api("no.nav:ktor-openapi-generator:1.0.46") } java { diff --git a/api-kontrakt/src/main/kotlin/no/nav/aap/oppgave/filter/FilterDto.kt b/api-kontrakt/src/main/kotlin/no/nav/aap/oppgave/filter/FilterDto.kt index 173f722..9598f40 100644 --- a/api-kontrakt/src/main/kotlin/no/nav/aap/oppgave/filter/FilterDto.kt +++ b/api-kontrakt/src/main/kotlin/no/nav/aap/oppgave/filter/FilterDto.kt @@ -1,10 +1,15 @@ package no.nav.aap.oppgave.filter import no.nav.aap.oppgave.verdityper.Behandlingstype +import java.time.LocalDateTime data class FilterDto( - val id: Long, - val navn: String, + val id: Long? = null, + val beskrivelse: String, val avklaringsbehovKoder: Set = emptySet(), - val behandlingstyper: Set = emptySet() + val behandlingstyper: Set = emptySet(), + val opprettetAv: String, + val opprettetTidspunkt: LocalDateTime, + val endretAv: String? = null, + val endretTidspunkt: LocalDateTime? = null, ) \ No newline at end of file diff --git a/api-kontrakt/src/main/kotlin/no/nav/aap/oppgave/filter/FilterId.kt b/api-kontrakt/src/main/kotlin/no/nav/aap/oppgave/filter/FilterId.kt new file mode 100644 index 0000000..f0d964b --- /dev/null +++ b/api-kontrakt/src/main/kotlin/no/nav/aap/oppgave/filter/FilterId.kt @@ -0,0 +1,5 @@ +package no.nav.aap.oppgave.filter + +import com.papsign.ktor.openapigen.annotations.parameters.PathParam + +data class FilterId(@PathParam("filterId") val filterId: Long) diff --git a/app/src/main/kotlin/no/nav/aap/oppgave/filter/FilterAPI.kt b/app/src/main/kotlin/no/nav/aap/oppgave/filter/FilterAPI.kt index 7335b07..0df2197 100644 --- a/app/src/main/kotlin/no/nav/aap/oppgave/filter/FilterAPI.kt +++ b/app/src/main/kotlin/no/nav/aap/oppgave/filter/FilterAPI.kt @@ -2,19 +2,62 @@ package no.nav.aap.oppgave.filter import com.papsign.ktor.openapigen.route.path.normal.NormalOpenAPIRoute import com.papsign.ktor.openapigen.route.path.normal.get +import com.papsign.ktor.openapigen.route.path.normal.post import com.papsign.ktor.openapigen.route.response.respond import com.papsign.ktor.openapigen.route.route import io.micrometer.prometheusmetrics.PrometheusMeterRegistry import no.nav.aap.komponenter.dbconnect.transaction import no.nav.aap.oppgave.metrikker.httpCallCounter +import no.nav.aap.oppgave.server.authenticate.ident +import java.time.LocalDateTime import javax.sql.DataSource -fun NormalOpenAPIRoute.filterApi(dataSource: DataSource, prometheus: PrometheusMeterRegistry) = +fun NormalOpenAPIRoute.hentFilterApi(dataSource: DataSource, prometheus: PrometheusMeterRegistry) = - route("/filter").get> { _ -> + route("/filter").get> { prometheus.httpCallCounter("/filter").increment() val filterListe = dataSource.transaction(readOnly = true) { connection -> - FilterRepository(connection).hentAlleFilter() + FilterRepository(connection).hentAlle() } respond(filterListe) - } \ No newline at end of file + } + +fun NormalOpenAPIRoute.opprettEllerOppdaterFilterApi(dataSource: DataSource, prometheus: PrometheusMeterRegistry) = + + route("/filter").post { _, request -> + prometheus.httpCallCounter("/filter").increment() + + val filterId = dataSource.transaction { connection -> + val filterRepo = FilterRepository(connection) + + if (request.id != null) { + filterRepo.oppdater(OppdaterFilter( + id = request.id!!, + beskrivelse = request.beskrivelse, + avklaringsbehovtyper = request.avklaringsbehovKoder, + behandlingstyper = request.behandlingstyper, + endretAv = ident(), + endretTidspunkt = LocalDateTime.now(), + )) + } else { + filterRepo.opprett(OpprettFilter( + beskrivelse = request.beskrivelse, + avklaringsbehovtyper = request.avklaringsbehovKoder, + behandlingstyper = request.behandlingstyper, + opprettetAv = ident(), + opprettetTidspunkt = LocalDateTime.now(), + )) + } + } + respond(request.copy(id = filterId)) + } + +fun NormalOpenAPIRoute.slettFilterApi(dataSource: DataSource, prometheus: PrometheusMeterRegistry) = + + route("/filter/{filterId}/slett").post { _, req -> + prometheus.httpCallCounter("/filter/{filterId}/slett").increment() + dataSource.transaction { connection -> + FilterRepository(connection).slettFilter(req.filterId) + } + respond(Unit) + } diff --git a/app/src/main/kotlin/no/nav/aap/oppgave/filter/FilterRepository.kt b/app/src/main/kotlin/no/nav/aap/oppgave/filter/FilterRepository.kt index c9424b9..a94b86d 100644 --- a/app/src/main/kotlin/no/nav/aap/oppgave/filter/FilterRepository.kt +++ b/app/src/main/kotlin/no/nav/aap/oppgave/filter/FilterRepository.kt @@ -2,35 +2,229 @@ package no.nav.aap.oppgave.filter import no.nav.aap.komponenter.dbconnect.DBConnection import no.nav.aap.oppgave.verdityper.Behandlingstype -import no.nav.aap.postmottak.kontrakt.avklaringsbehov.Definisjon +import java.time.LocalDateTime + +data class OpprettFilter( + val beskrivelse: String, + val avklaringsbehovtyper: Set = emptySet(), + val behandlingstyper: Set = emptySet(), + val opprettetAv: String, + val opprettetTidspunkt: LocalDateTime, +) + +data class OppdaterFilter( + val id: Long, + val beskrivelse: String, + val avklaringsbehovtyper: Set = emptySet(), + val behandlingstyper: Set = emptySet(), + val endretAv: String? = null, + val endretTidspunkt: LocalDateTime? = null, +) -// Forløpig mock repository class FilterRepository(private val connection: DBConnection) { - private val filterDtoMap = mapOf( - 1L to FilterDto(1L, "Alle oppgaver"), - 2L to FilterDto(2L, "Alle postmottak oppgaver", - avklaringsbehovKoder = Definisjon.entries.map {it.kode}.toSet()), - 3L to FilterDto(3L, "Alle behandlingsflyt oppgaver", - avklaringsbehovKoder = no.nav.aap.behandlingsflyt.kontrakt.avklaringsbehov.Definisjon.entries.map {it.kode}.toSet()), - 4L to FilterDto(4L, "Alle førstegangsbehandling oppgaver", - behandlingstyper = setOf(Behandlingstype.FØRSTEGANGSBEHANDLING)), - 5L to FilterDto(5L, "Alle revurdering oppgaver", - behandlingstyper = setOf(Behandlingstype.REVURDERING)), - 6L to FilterDto(6L, "Alle tilbakekreving oppgaver", - behandlingstyper = setOf(Behandlingstype.TILBAKEKREVING)), - 7L to FilterDto(7L, "Alle klage oppgaver", - behandlingstyper = setOf(Behandlingstype.KLAGE)), - 8L to FilterDto(8L, "Alle dokumenthåndtering oppgaver", - behandlingstyper = setOf(Behandlingstype.DOKUMENT_HÅNDTERING)), - ) - - fun hentFilter(filterId: Long): FilterDto? { - return filterDtoMap[filterId] - } - - fun hentAlleFilter(): List { - return filterDtoMap.values.toList() - } - -} \ No newline at end of file + fun hentAlle(): List { + return hentFilter(null) + } + + fun hent(filterId: Long): FilterDto? { + return hentFilter(filterId).firstOrNull() + } + + fun opprett(filter: OpprettFilter): Long { + val filterId = opprettFilter(filter) + opprettFilterAvklaringsbehovtyper(filterId, filter.avklaringsbehovtyper) + opprettFilterBehandlingstyper(filterId, filter.behandlingstyper) + return filterId + } + + fun oppdater(filter: OppdaterFilter): Long { + oppdaterFilter(filter) + slettFilterParametre(filter.id) + opprettFilterAvklaringsbehovtyper(filter.id, filter.avklaringsbehovtyper) + opprettFilterBehandlingstyper(filter.id, filter.behandlingstyper) + return filter.id + } + + fun slettFilter(id: Long) { + connection.execute("UPDATE FILTER SET SLETTET = TRUE WHERE ID = ?") { + setParams { + setLong(1, id) + } + } + } + + private fun oppdaterFilter(filter: OppdaterFilter) { + connection.execute("UPDATE FILTER SET BESKRIVELSE = ?, ENDRET_AV = ?, ENDRET_TIDSPUNKT = ? WHERE ID = ?") { + setParams { + setString(1, filter.beskrivelse) + setString(2, filter.endretAv) + setLocalDateTime(3, filter.endretTidspunkt) + setLong(4, filter.id) + } + } + } + + private fun slettFilterParametre(filterId: Long) { + connection.execute("DELETE FROM FILTER_AVKLARINGSBEHOVTYPE WHERE FILTER_ID = ?") { + setParams { setLong(1, filterId) } + } + connection.execute("DELETE FROM FILTER_BEHANDLINGSTYPE WHERE FILTER_ID = ?") { + setParams { setLong(1, filterId) } + } + } + + private fun opprettFilter(filter: OpprettFilter): Long { + val insertFilterSql = """ + INSERT INTO FILTER (BESKRIVELSE, OPPRETTET_AV, OPPRETTET_TIDSPUNKT) VALUES (?, ?, ?) + """.trimIndent() + + return connection.executeReturnKey(insertFilterSql) { + setParams { + setString(1, filter.beskrivelse) + setString(2, filter.opprettetAv) + setLocalDateTime(3, filter.opprettetTidspunkt) + } + } + } + + private fun opprettFilterAvklaringsbehovtyper(filterId: Long, avklaringsbehovtyper: Set) { + val insertFilterAvklaringsbehovtypeSql = """ + INSERT INTO FILTER_AVKLARINGSBEHOVTYPE (FILTER_ID, AVKLARINGSBEHOVTYPE) VALUES (?, ?) + """.trimIndent() + + connection.executeBatch(insertFilterAvklaringsbehovtypeSql, avklaringsbehovtyper) { + setParams { + setLong(1, filterId) + setString(2, it) + } + } + } + + private fun opprettFilterBehandlingstyper(filterId: Long, behandlingstyper: Set) { + val insertFilterAvklaringsbehovtypeSql = """ + INSERT INTO FILTER_BEHANDLINGSTYPE (FILTER_ID, BEHANDLINGSTYPE) VALUES (?, ?) + """.trimIndent() + + connection.executeBatch(insertFilterAvklaringsbehovtypeSql, behandlingstyper) { + setParams { + setLong(1, filterId) + setString(2, it.name) + } + } + } + + + private fun hentFilter(filterId: Long?): List { + val filterIdClause = if (filterId != null) " AND ID = ?" else "" + val query = """ + SELECT + ID, BESKRIVELSE, OPPRETTET_AV, OPPRETTET_TIDSPUNKT, ENDRET_AV, ENDRET_TIDSPUNKT + FROM + FILTER + WHERE + SLETTET = FALSE $filterIdClause + """.trimIndent() + + val alleFilter = connection.queryList(query) { + setParams { + if (filterId != null) { + setLong(1, filterId) + } + } + setRowMapper { row -> + FilterDto( + id = row.getLong("ID"), + beskrivelse = row.getString("BESKRIVELSE"), + opprettetAv = row.getString("OPPRETTET_AV"), + opprettetTidspunkt = row.getLocalDateTime("OPPRETTET_TIDSPUNKT"), + endretAv = row.getStringOrNull("ENDRET_AV"), + endretTidspunkt = row.getLocalDateTimeOrNull("ENDRET_TIDSPUNKT"), + ) + } + } + val alleFilterAvklaringsbehovtype = hentAlleFilterAvklaringsbehovtype(filterId) + val alleFilterBehandlingstyper = hentAlleFilterBehandlingstyper(filterId) + val alleFilterMedFelter = alleFilter.map { filter -> + filter.copy( + avklaringsbehovKoder = alleFilterAvklaringsbehovtype[filter.id] ?: emptySet(), + behandlingstyper = alleFilterBehandlingstyper[filter.id] ?: emptySet() + ) + } + return alleFilterMedFelter + } + + private fun hentAlleFilterAvklaringsbehovtype(filterId: Long?): Map> { + val filterIdClause = if (filterId != null) " AND FILTER_ID = ?" else "" + val query = """ + SELECT + F.ID AS FILTER_ID, + FA.AVKLARINGSBEHOVTYPE + FROM + FILTER F, + FILTER_AVKLARINGSBEHOVTYPE FA + WHERE + F.ID = FA.FILTER_ID AND + F.SLETTET = FALSE + $filterIdClause + """.trimIndent() + + val alleAvklaringsbehovFiltre = connection.queryList(query) { + setParams { + if (filterId != null) { + setLong(1, filterId) + } + } + setRowMapper { row -> + Pair(row.getLong("FILTER_ID"), row.getString("AVKLARINGSBEHOVTYPE")) + } + } + + return alleAvklaringsbehovFiltre + .groupBy { it.first } + .mapValues { entry -> + entry.value.map { + it.second + }.toSet() + } + } + + private fun hentAlleFilterBehandlingstyper(filterId: Long?): Map> { + val filterIdClause = if (filterId != null) " AND FILTER_ID = ?" else "" + val query = """ + SELECT + F.ID AS FILTER_ID, + FB.BEHANDLINGSTYPE + FROM + FILTER F, + FILTER_BEHANDLINGSTYPE FB + WHERE + F.ID = FB.FILTER_ID AND + F.SLETTET = FALSE + $filterIdClause + """.trimIndent() + + val alleBehandlingstypeFiltre = connection.queryList(query) { + setParams { + if (filterId != null) { + setLong(1, filterId) + } + } + setRowMapper { row -> + Pair(row.getLong("FILTER_ID"), Behandlingstype.valueOf(row.getString("BEHANDLINGSTYPE"))) + } + } + + return alleBehandlingstypeFiltre + .groupBy { it.first } + .mapValues { entry -> + entry.value.map { + it.second + }.toSet() + } + } + +} + + + diff --git a/app/src/main/kotlin/no/nav/aap/oppgave/plukk/PlukkOppgaveService.kt b/app/src/main/kotlin/no/nav/aap/oppgave/plukk/PlukkOppgaveService.kt index 340b490..681fb9c 100644 --- a/app/src/main/kotlin/no/nav/aap/oppgave/plukk/PlukkOppgaveService.kt +++ b/app/src/main/kotlin/no/nav/aap/oppgave/plukk/PlukkOppgaveService.kt @@ -14,7 +14,7 @@ class PlukkOppgaveService(val connection: DBConnection) { fun plukkNesteOppgave(filterId: Long, ident: String, token: OidcToken, maksAntallForsøk: Int = 10): NesteOppgaveDto? { val filterRepo = FilterRepository(connection) - val filter = filterRepo.hentFilter(filterId) + val filter = filterRepo.hent(filterId) if (filter == null) { throw IllegalArgumentException("Finner ikke filter med id: $filterId") } diff --git a/app/src/main/kotlin/no/nav/aap/oppgave/server/App.kt b/app/src/main/kotlin/no/nav/aap/oppgave/server/App.kt index 4c70bd4..622050d 100644 --- a/app/src/main/kotlin/no/nav/aap/oppgave/server/App.kt +++ b/app/src/main/kotlin/no/nav/aap/oppgave/server/App.kt @@ -7,7 +7,6 @@ import com.zaxxer.hikari.HikariDataSource import io.ktor.http.HttpHeaders import io.ktor.http.HttpStatusCode import io.ktor.server.application.Application -import io.ktor.server.application.call import io.ktor.server.application.install import io.ktor.server.auth.authenticate import io.ktor.server.engine.embeddedServer @@ -27,7 +26,9 @@ import no.nav.aap.komponenter.server.AZURE import no.nav.aap.komponenter.server.commonKtorModule import no.nav.aap.oppgave.alleÅpneOppgaverApi import no.nav.aap.oppgave.avreserverOppgave -import no.nav.aap.oppgave.filter.filterApi +import no.nav.aap.oppgave.filter.hentFilterApi +import no.nav.aap.oppgave.filter.opprettEllerOppdaterFilterApi +import no.nav.aap.oppgave.filter.slettFilterApi import no.nav.aap.oppgave.flyttOppgave import no.nav.aap.oppgave.hentOppgaveApi import no.nav.aap.oppgave.mineOppgaverApi @@ -47,9 +48,7 @@ fun main() { .error("Ikke-håndert exception: ${e::class.qualifiedName}. Se sikker logg for stacktrace") SECURE_LOGGER.error("Uhåndtert feil", e) } - embeddedServer(Netty, 8080) { server(DbConfig()) }.start(wait = true) - } internal fun Application.server(dbConfig: DbConfig) { @@ -75,15 +74,19 @@ internal fun Application.server(dbConfig: DbConfig) { routing { authenticate(AZURE) { apiRouting { + //Oppgave endepunkt oppdaterBehandlingOppgaverApi(dataSource, prometheus) oppdaterPostmottakOppgaverApi(dataSource, prometheus) plukkApi(dataSource, prometheus) hentOppgaveApi(dataSource, prometheus) mineOppgaverApi(dataSource, prometheus) alleÅpneOppgaverApi(dataSource, prometheus) - filterApi(dataSource, prometheus) avreserverOppgave(dataSource, prometheus) flyttOppgave(dataSource, prometheus) + //Filter endepunkt + hentFilterApi(dataSource, prometheus) + opprettEllerOppdaterFilterApi(dataSource, prometheus) + slettFilterApi(dataSource, prometheus) } } actuator(prometheus) diff --git a/app/src/test/kotlin/no/nav/aap/oppgave/ApiTest.kt b/app/src/test/kotlin/no/nav/aap/oppgave/OppgaveApiTest.kt similarity index 77% rename from app/src/test/kotlin/no/nav/aap/oppgave/ApiTest.kt rename to app/src/test/kotlin/no/nav/aap/oppgave/OppgaveApiTest.kt index 083ad60..51e0410 100644 --- a/app/src/test/kotlin/no/nav/aap/oppgave/ApiTest.kt +++ b/app/src/test/kotlin/no/nav/aap/oppgave/OppgaveApiTest.kt @@ -23,11 +23,13 @@ import no.nav.aap.komponenter.httpklient.httpclient.tokenprovider.azurecc.Client import no.nav.aap.oppgave.fakes.Fakes import no.nav.aap.oppgave.fakes.FakesConfig import no.nav.aap.oppgave.filter.FilterDto +import no.nav.aap.oppgave.filter.FilterId import no.nav.aap.oppgave.plukk.FinnNesteOppgaveDto import no.nav.aap.oppgave.plukk.NesteOppgaveDto import no.nav.aap.oppgave.server.DbConfig import no.nav.aap.oppgave.server.initDatasource import no.nav.aap.oppgave.server.server +import no.nav.aap.oppgave.verdityper.Behandlingstype import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.Test @@ -40,7 +42,7 @@ import java.time.temporal.ChronoUnit import java.util.UUID import kotlin.test.AfterTest -class ApiTest { +class OppgaveApiTest { @AfterTest fun tearDown() { @@ -49,6 +51,7 @@ class ApiTest { @Test fun `Opprett, plukk og avslutt oppgave`() { + leggInnFilterForTest() val saksnummer = "123456" val referanse = UUID.randomUUID() @@ -86,6 +89,7 @@ class ApiTest { @Test fun `Opprett, oppgave ble automatisk plukket og avslutt oppgave`() { + leggInnFilterForTest() val saksnummer = "654321" val referanse = UUID.randomUUID() @@ -126,6 +130,7 @@ class ApiTest { @Test fun `Skal ikke få plukket oppgave dersom tilgang nektes`() { + leggInnFilterForTest() val saksnummer = "100001" val referanse = UUID.randomUUID() @@ -146,6 +151,7 @@ class ApiTest { @Test fun `Skal forsøke å reservere flere oppgaver dersom bruker ikke har tilgang på den første`() { + leggInnFilterForTest() val saksnummer1 = "100002" val referanse1 = UUID.randomUUID() @@ -175,14 +181,73 @@ class ApiTest { assertThat(nesteOppgave!!.avklaringsbehovReferanse.referanse).isEqualTo(referanse1) } + @Test - fun `Hent alle filter`() { - //TODO endre denne når full funksjonalitet er ferdig utviklet - val filterListe = client.get>( - URI.create("http://localhost:8080/filter"), - GetRequest() - ) - assertThat(filterListe).hasSize(8) + fun `Hente filter`() { + opprettEllerOpdaterFilter(FilterDto( + beskrivelse = "Simpelt filter", + opprettetAv = "test", + opprettetTidspunkt = LocalDateTime.now(), + )) + + val alleFilter = hentAlleFilter() + + assertThat(alleFilter).hasSize(1) + } + + + @Test + fun `Endre filter`() { + // Opprett filter + opprettEllerOpdaterFilter(FilterDto( + beskrivelse = "Avklare sykdom i førstegangsbehandling filter", + behandlingstyper = setOf(Behandlingstype.FØRSTEGANGSBEHANDLING), + avklaringsbehovKoder = setOf(Definisjon.AVKLAR_SYKDOM.kode), + opprettetAv = "test", + opprettetTidspunkt = LocalDateTime.now(), + )) + + // Sjekk lagret filter + val alleFilter = hentAlleFilter() + assertThat(alleFilter).hasSize(1) + val hentetFilter = alleFilter.first() + assertThat(hentetFilter.behandlingstyper).isEqualTo(setOf(Behandlingstype.FØRSTEGANGSBEHANDLING)) + assertThat(hentetFilter.avklaringsbehovKoder).isEqualTo(setOf(Definisjon.AVKLAR_SYKDOM.kode)) + + // Oppdater filter + opprettEllerOpdaterFilter(hentetFilter.copy( + beskrivelse = "Forslå vedtak i revurdering filter", + behandlingstyper = setOf(Behandlingstype.REVURDERING), + avklaringsbehovKoder = setOf(Definisjon.FORESLÅ_VEDTAK.kode), + endretAv = "test", + endretTidspunkt = LocalDateTime.now(), + )) + + // Sjekk oppdatert filter + val alleFilterEtterOppdatering = hentAlleFilter() + assertThat(alleFilterEtterOppdatering).hasSize(1) + val hentetFilterEtterOppdatering = alleFilterEtterOppdatering.first() + assertThat(hentetFilterEtterOppdatering.beskrivelse).isEqualTo("Forslå vedtak i revurdering filter") + assertThat(hentetFilterEtterOppdatering.behandlingstyper).isEqualTo(setOf(Behandlingstype.REVURDERING)) + assertThat(hentetFilterEtterOppdatering.avklaringsbehovKoder).isEqualTo(setOf(Definisjon.FORESLÅ_VEDTAK.kode)) + } + + @Test + fun `Slette filter`() { + opprettEllerOpdaterFilter(FilterDto( + beskrivelse = "Simpelt filter", + opprettetAv = "test", + opprettetTidspunkt = LocalDateTime.now(), + )) + + val alleFilter = hentAlleFilter() + assertThat(alleFilter).hasSize(1) + + val hentetFilter = alleFilter.first() + slettFilter(FilterId(hentetFilter.id!!)) + + val alleFilterEtterSletting = hentAlleFilter() + assertThat(alleFilterEtterSletting).hasSize(0) } private fun Definisjon.tilDefinisjonDTO(): DefinisjonDTO { @@ -193,13 +258,13 @@ class ApiTest { ) } - data class Behandlingsbehov( + private data class Behandlingsbehov( val definisjon: Definisjon, val status: no.nav.aap.behandlingsflyt.kontrakt.avklaringsbehov.Status = no.nav.aap.behandlingsflyt.kontrakt.avklaringsbehov.Status.OPPRETTET, val endringer: List ) - data class Endring( + private data class Endring( val status: no.nav.aap.behandlingsflyt.kontrakt.avklaringsbehov.Status, val endretAv: String = "Kelvin", ) @@ -240,9 +305,10 @@ class ApiTest { } private fun hentNesteOppgave(): NesteOppgaveDto? { + val alleFilter = hentAlleFilter() val nesteOppgave: NesteOppgaveDto? = client.post( URI.create("http://localhost:8080/neste-oppgave"), - PostRequest(body = FinnNesteOppgaveDto(filterId = 1)) + PostRequest(body = FinnNesteOppgaveDto(filterId = alleFilter.first().id!!)) ) return nesteOppgave } @@ -266,6 +332,27 @@ class ApiTest { )!! } + private fun opprettEllerOpdaterFilter(filter: FilterDto): FilterDto? { + return client.post( + URI.create("http://localhost:8080/filter"), + PostRequest(body = filter) + ) + } + + private fun hentAlleFilter(): List { + return client.get>( + URI.create("http://localhost:8080/filter"), + GetRequest() + )!! + } + + private fun slettFilter(filterId: FilterId): Unit? { + return client.post( + URI.create("http://localhost:8080/filter/${filterId.filterId}/slett"), + PostRequest(body = filterId) + ) + } + companion object { private val postgres = postgreSQLContainer() val fakesConfig: FakesConfig = FakesConfig() @@ -290,9 +377,18 @@ class ApiTest { }.start() private fun resetDatabase() { + @Suppress("SqlWithoutWhere") initDatasource(dbConfig).transaction { - @Suppress("SqlWithoutWhere") it.execute("DELETE FROM OPPGAVE") + it.execute("DELETE FROM FILTER_AVKLARINGSBEHOVTYPE") + it.execute("DELETE FROM FILTER_BEHANDLINGSTYPE") + it.execute("DELETE FROM FILTER") + } + } + + private fun leggInnFilterForTest() { + initDatasource(dbConfig).transaction { + it.execute("INSERT INTO FILTER (BESKRIVELSE, OPPRETTET_AV, OPPRETTET_TIDSPUNKT) VALUES ('Alle oppgaver', 'test', current_timestamp)") } } diff --git a/app/src/test/kotlin/no/nav/aap/oppgave/OppgaveRepositoryTest.kt b/app/src/test/kotlin/no/nav/aap/oppgave/OppgaveRepositoryTest.kt index 4ee6153..be22180 100644 --- a/app/src/test/kotlin/no/nav/aap/oppgave/OppgaveRepositoryTest.kt +++ b/app/src/test/kotlin/no/nav/aap/oppgave/OppgaveRepositoryTest.kt @@ -130,10 +130,10 @@ class OppgaveRepositoryTest { } private fun avklaringsbehovFilter(vararg avklaringsbehovKoder: String) = - FilterDto(1, "Filter for test", avklaringsbehovKoder = avklaringsbehovKoder.toSet()) + FilterDto(1, "Filter for test", avklaringsbehovKoder = avklaringsbehovKoder.toSet(), opprettetAv = "test", opprettetTidspunkt = LocalDateTime.now()) private fun behandlingstypeFilter(vararg behandlingstyper: Behandlingstype) = - FilterDto(1, "Filter for test", behandlingstyper = behandlingstyper.toSet()) + FilterDto(1, "Filter for test", behandlingstyper = behandlingstyper.toSet(), opprettetAv = "test", opprettetTidspunkt = LocalDateTime.now()) private fun avsluttOppgave(oppgaveId: OppgaveId) { InitTestDatabase.dataSource.transaction { connection -> diff --git a/app/src/test/kotlin/no/nav/aap/oppgave/filter/FilterRepositoryTest.kt b/app/src/test/kotlin/no/nav/aap/oppgave/filter/FilterRepositoryTest.kt new file mode 100644 index 0000000..ab9e64a --- /dev/null +++ b/app/src/test/kotlin/no/nav/aap/oppgave/filter/FilterRepositoryTest.kt @@ -0,0 +1,151 @@ +package no.nav.aap.oppgave.filter + +import no.nav.aap.behandlingsflyt.kontrakt.avklaringsbehov.Definisjon +import no.nav.aap.komponenter.dbconnect.transaction +import no.nav.aap.komponenter.dbtest.InitTestDatabase +import no.nav.aap.oppgave.verdityper.Behandlingstype +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import java.time.LocalDateTime +import kotlin.test.AfterTest + +class FilterRepositoryTest { + + @AfterTest + fun tearDown() { + @Suppress("SqlWithoutWhere") + InitTestDatabase.dataSource.transaction { + it.execute("DELETE FROM FILTER_AVKLARINGSBEHOVTYPE") + it.execute("DELETE FROM FILTER_BEHANDLINGSTYPE") + it.execute("DELETE FROM FILTER") + } + } + + @Test + fun `Opprett enkelt filter og hent det ut igjen`() { + InitTestDatabase.dataSource.transaction { connection -> + val filterRepo = FilterRepository(connection) + val nyttFilter = OpprettFilter( + beskrivelse = "Basic filter", + opprettetAv = "test", + opprettetTidspunkt = LocalDateTime.now() + ) + val filterId = filterRepo.opprett(nyttFilter) + + val filter = filterRepo.hent(filterId) + assertThat(filter).isNotNull() + assertThat(filter!!.beskrivelse).isEqualTo("Basic filter") + + val alleFilter = filterRepo.hentAlle() + assertThat(alleFilter).hasSize(1) + assertThat(alleFilter.first().beskrivelse).isEqualTo("Basic filter") + } + } + + @Test + fun `Opprett filter med avklaringsbehov`() { + InitTestDatabase.dataSource.transaction { connection -> + val filterRepo = FilterRepository(connection) + val nyttFilter = OpprettFilter( + beskrivelse = "Filter for avklar sykdom oppgave", + opprettetAv = "test", + opprettetTidspunkt = LocalDateTime.now(), + avklaringsbehovtyper = setOf(Definisjon.AVKLAR_SYKDOM.kode) + ) + filterRepo.opprett(nyttFilter) + + val alleFilter = filterRepo.hentAlle() + assertThat(alleFilter).hasSize(1) + assertThat(alleFilter.first().beskrivelse).isEqualTo("Filter for avklar sykdom oppgave") + assertThat(alleFilter.first().behandlingstyper).hasSize(0) + assertThat(alleFilter.first().avklaringsbehovKoder).hasSize(1) + assertThat(alleFilter.first().avklaringsbehovKoder.contains(Definisjon.AVKLAR_SYKDOM.kode)).isTrue() + } + } + + @Test + fun `Opprett filter med behandlingstype'`() { + InitTestDatabase.dataSource.transaction { connection -> + val filterRepo = FilterRepository(connection) + val nyttFilter = OpprettFilter( + beskrivelse = "Filter for førstegangsbehandling", + opprettetAv = "test", + opprettetTidspunkt = LocalDateTime.now(), + behandlingstyper = setOf(Behandlingstype.FØRSTEGANGSBEHANDLING) + ) + filterRepo.opprett(nyttFilter) + + val alleFilter = filterRepo.hentAlle() + assertThat(alleFilter).hasSize(1) + assertThat(alleFilter.first().beskrivelse).isEqualTo("Filter for førstegangsbehandling") + assertThat(alleFilter.first().avklaringsbehovKoder).hasSize(0) + assertThat(alleFilter.first().behandlingstyper).hasSize(1) + assertThat(alleFilter.first().behandlingstyper.contains(Behandlingstype.FØRSTEGANGSBEHANDLING)).isTrue() + } + } + + @Test + fun `Oppdater filter med både behandlingstype og avklaringsbehov`() { + InitTestDatabase.dataSource.transaction { connection -> + val filterRepo = FilterRepository(connection) + val nyttFilter = OpprettFilter( + beskrivelse = "Filter for avklar sykdom oppgave og førstegangsbehandling", + opprettetAv = "test1", + opprettetTidspunkt = LocalDateTime.now(), + behandlingstyper = setOf(Behandlingstype.FØRSTEGANGSBEHANDLING), + avklaringsbehovtyper = setOf(Definisjon.AVKLAR_SYKDOM.kode) + ) + val filterId = filterRepo.opprett(nyttFilter) + + var alleFilter = filterRepo.hentAlle() + assertThat(alleFilter).hasSize(1) + var hentetFilter = alleFilter.first() + assertThat(hentetFilter.beskrivelse).isEqualTo("Filter for avklar sykdom oppgave og førstegangsbehandling") + assertThat(hentetFilter.behandlingstyper).hasSize(1) + assertThat(hentetFilter.behandlingstyper.contains(Behandlingstype.FØRSTEGANGSBEHANDLING)).isTrue() + assertThat(hentetFilter.avklaringsbehovKoder).hasSize(1) + assertThat(hentetFilter.avklaringsbehovKoder.contains(Definisjon.AVKLAR_SYKDOM.kode)).isTrue() + + val oppdaterFilter = OppdaterFilter( + id = filterId, + beskrivelse = "Filter for avklar barnetillegg og revurdering", + behandlingstyper = setOf(Behandlingstype.REVURDERING), + avklaringsbehovtyper = setOf(Definisjon.AVKLAR_BARNETILLEGG.kode), + endretAv = "test2", + endretTidspunkt = LocalDateTime.now() + ) + filterRepo.oppdater(oppdaterFilter) + + alleFilter = filterRepo.hentAlle() + assertThat(alleFilter).hasSize(1) + hentetFilter = alleFilter.first() + assertThat(hentetFilter.beskrivelse).isEqualTo("Filter for avklar barnetillegg og revurdering") + assertThat(hentetFilter.behandlingstyper).hasSize(1) + assertThat(hentetFilter.behandlingstyper.contains(Behandlingstype.REVURDERING)).isTrue() + assertThat(hentetFilter.avklaringsbehovKoder).hasSize(1) + assertThat(hentetFilter.avklaringsbehovKoder.contains(Definisjon.AVKLAR_BARNETILLEGG.kode)).isTrue() + } + } + + @Test + fun `Logisk sletting av filter`() { + InitTestDatabase.dataSource.transaction { connection -> + val filterRepo = FilterRepository(connection) + val nyttFilter = OpprettFilter( + beskrivelse = "Test filter", + opprettetAv = "test", + opprettetTidspunkt = LocalDateTime.now() + ) + val filterId = filterRepo.opprett(nyttFilter) + + var alleFilter = filterRepo.hentAlle() + assertThat(alleFilter).hasSize(1) + + filterRepo.slettFilter(filterId) + + alleFilter = filterRepo.hentAlle() + assertThat(alleFilter).hasSize(0) + } + } + +} \ No newline at end of file diff --git a/dbflyway/src/main/resources/flyway/V1.6__Nye_tabeller_for_filter.sql b/dbflyway/src/main/resources/flyway/V1.6__Nye_tabeller_for_filter.sql new file mode 100644 index 0000000..ab353dc --- /dev/null +++ b/dbflyway/src/main/resources/flyway/V1.6__Nye_tabeller_for_filter.sql @@ -0,0 +1,25 @@ + +CREATE TABLE FILTER +( + ID BIGSERIAL NOT NULL PRIMARY KEY, + BESKRIVELSE VARCHAR(100) NOT NULL, + SLETTET BOOLEAN NOT NULL DEFAULT FALSE, + OPPRETTET_AV VARCHAR(20) NOT NULL, + OPPRETTET_TIDSPUNKT TIMESTAMP(3) NOT NULL, + ENDRET_AV VARCHAR(20), + ENDRET_TIDSPUNKT TIMESTAMP(3) +); + +CREATE TABLE FILTER_AVKLARINGSBEHOVTYPE +( + ID BIGSERIAL NOT NULL PRIMARY KEY, + FILTER_ID BIGINT NOT NULL REFERENCES FILTER (ID), + AVKLARINGSBEHOVTYPE VARCHAR(4) NOT NULL +); + +CREATE TABLE FILTER_BEHANDLINGSTYPE +( + ID BIGSERIAL NOT NULL PRIMARY KEY, + FILTER_ID BIGINT NOT NULL REFERENCES FILTER (ID), + BEHANDLINGSTYPE VARCHAR(40) NOT NULL +);