Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions src/main/kotlin/no/nav/tms/varsel/api/config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,3 @@ object HttpClientBuilder {
}
}
}

suspend inline fun <reified T> HttpClient.get(url: String, accessToken: String): T = withContext(Dispatchers.IO) {
request {
url(url)
method = HttpMethod.Get
header(HttpHeaders.Authorization, "Bearer $accessToken")
}.body()
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ data class AktivtVarsel(
@Deprecated("Use tidspunkt") val forstBehandlet: ZonedDateTime,
val tidspunkt: ZonedDateTime,
val isMasked: Boolean,
val spraakkode: String?,
val tekst: String?,
val link: String?,
val eksternVarslingSendt: Boolean,
Expand All @@ -26,6 +27,7 @@ data class AktivtVarsel(
forstBehandlet = varsel.opprettet,
tidspunkt = varsel.opprettet,
isMasked = varsel.innhold == null,
spraakkode = varsel.innhold?.spraakkode,
tekst = varsel.innhold?.tekst,
link = varsel.innhold?.link,
eksternVarslingSendt = varsel.eksternVarslingSendt,
Expand Down
33 changes: 19 additions & 14 deletions src/main/kotlin/no/nav/tms/varsel/api/varsel/VarselConsumer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@
package no.nav.tms.varsel.api.varsel

import io.ktor.client.HttpClient
import io.ktor.client.request.header
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.http.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import no.nav.tms.token.support.tokendings.exchange.TokendingsService
import no.nav.tms.varsel.api.ZonedDateTimeSerializer
import no.nav.tms.varsel.api.get
import java.time.ZonedDateTime

class VarselConsumer(
Expand All @@ -21,18 +18,18 @@ class VarselConsumer(
private val varselAuthorityClientId: String,
private val tokendingsService: TokendingsService
) {
suspend fun getAktiveVarsler(userToken: String): AktiveVarsler {
return getVarsler(userToken, "/varsel/sammendrag/aktive")
suspend fun getAktiveVarsler(userToken: String, preferertSpraak: String?): AktiveVarsler {
return getVarsler(userToken, "/varsel/sammendrag/aktive", preferertSpraak = preferertSpraak)
.let (AktiveVarsler::fromVarsler)
}

suspend fun getInaktiveVarsler(userToken: String): List<InaktivtVarsel> {
return getVarsler( userToken,"/varsel/sammendrag/inaktive")
suspend fun getInaktiveVarsler(userToken: String, preferertSpraak: String?): List<InaktivtVarsel> {
return getVarsler(userToken,"/varsel/sammendrag/inaktive", preferertSpraak = preferertSpraak)
.map(InaktivtVarsel::fromVarsel)
}

suspend fun getVarselbjelleVarsler(userToken: String): VarselbjelleVarsler {
return getVarsler(userToken, "/varsel/sammendrag/aktive")
suspend fun getVarselbjelleVarsler(userToken: String, preferertSpraak: String?): VarselbjelleVarsler {
return getVarsler(userToken, "/varsel/sammendrag/aktive", preferertSpraak = preferertSpraak)
.let(VarselbjelleVarsler::fromVarsler)
}

Expand All @@ -46,9 +43,16 @@ class VarselConsumer(
}
}

private suspend fun getVarsler(userToken: String, path: String): List<Varsel> {
private suspend fun getVarsler(userToken: String, path: String, preferertSpraak: String? = null): List<Varsel> {
val authorityToken = tokendingsService.exchangeToken(userToken, targetApp = varselAuthorityClientId)
return client.get("$varselAuthorityUrl$path", authorityToken)

return client.request {
url("$varselAuthorityUrl$path")
method = HttpMethod.Get
header(HttpHeaders.Authorization, "Bearer $authorityToken")

preferertSpraak?.let { parameter("preferert_spraak", it) }
}.body()
}
}

Expand All @@ -67,6 +71,7 @@ data class Varsel(

@Serializable
data class VarselInnhold(
val spraakkode: String,
val tekst: String,
val link: String?
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ data class VarselbjelleVarsel(
val varselId: String,
val tidspunkt: ZonedDateTime,
val isMasked: Boolean,
val spraakkode: String?,
val tekst: String?,
val link: String?,
val type: String,
Expand All @@ -46,6 +47,7 @@ data class VarselbjelleVarsel(
varselId = varselId,
tidspunkt = opprettet,
isMasked = innhold == null,
spraakkode = innhold?.spraakkode,
tekst = innhold?.tekst,
link = innhold?.link,
type = type.name,
Expand Down
31 changes: 21 additions & 10 deletions src/main/kotlin/no/nav/tms/varsel/api/varsel/varselRoutes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package no.nav.tms.varsel.api.varsel
import io.ktor.http.HttpStatusCode
import io.ktor.server.application.ApplicationCall
import io.ktor.server.application.call
import io.ktor.server.request.receive
import io.ktor.server.request.*
import io.ktor.server.response.respond
import io.ktor.server.routing.Route
import io.ktor.server.routing.get
Expand All @@ -17,27 +17,36 @@ fun Route.varsel(
varselConsumer: VarselConsumer
) {
get("inaktive") {
val inaktiveVarsler = varselConsumer.getInaktiveVarsler(call.userToken)

call.respond(HttpStatusCode.OK, inaktiveVarsler)
varselConsumer.getInaktiveVarsler(
userToken = call.userToken,
preferertSpraak = call.request.preferertSpraak
).let { inaktiveVarsler ->
call.respond(HttpStatusCode.OK, inaktiveVarsler)
}
}

get("aktive") {
val aktiveVarsler = varselConsumer.getAktiveVarsler(call.userToken)

call.respond(HttpStatusCode.OK, aktiveVarsler)
varselConsumer.getAktiveVarsler(
userToken = call.userToken,
preferertSpraak = call.request.preferertSpraak
).let { aktiveVarsler ->
call.respond(HttpStatusCode.OK, aktiveVarsler)
}
}

get("antall/aktive") {
val antallAktive = varselConsumer.getAktiveVarsler(call.userToken).let {
varselConsumer.getAktiveVarsler(
userToken = call.userToken,
preferertSpraak = null
).let {
AntallVarsler(
beskjeder = it.beskjeder.size,
oppgaver = it.oppgaver.size,
innbokser = it.innbokser.size
)
}.let { antallAktive ->
call.respond(HttpStatusCode.OK, antallAktive)
}

call.respond(HttpStatusCode.OK, antallAktive)
}

post("beskjed/inaktiver") {
Expand All @@ -60,3 +69,5 @@ data class InaktiverVarselBody(
private suspend fun ApplicationCall.varselId(): String = receive<InaktiverVarselBody>().let {
it.varselId ?: it.eventId ?: throw IllegalArgumentException("Mangler varselId eller eventId i body")
}

private val ApplicationRequest.preferertSpraak get() = queryParameters["preferert_spraak"]?.lowercase()
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package no.nav.tms.varsel.api.varsel

import io.ktor.http.*
import io.ktor.server.application.ApplicationCall
import io.ktor.server.application.call
import io.ktor.server.request.*
import io.ktor.server.response.respond
import io.ktor.server.routing.Route
import io.ktor.server.routing.get
Expand All @@ -12,21 +14,31 @@ import no.nav.tms.token.support.idporten.sidecar.user.IdportenUserFactory
import no.nav.tms.token.support.tokenx.validation.user.TokenXUser
import no.nav.tms.token.support.tokenx.validation.user.TokenXUserFactory


fun Route.varselbjelle(varselConsumer: VarselConsumer) {
route("/varselbjelle") {
get("/varsler") {
call.respond(varselConsumer.getVarselbjelleVarsler(idportenUser.tokenString))
varselConsumer.getVarselbjelleVarsler(
userToken = idportenUser.tokenString,
preferertSpraak = call.request.preferertSpraak
).let {
call.respond(HttpStatusCode.OK, it)
}
}
}
}

fun Route.bjellevarsler(varselConsumer: VarselConsumer) {
get("/bjellevarsler") {
call.respond(varselConsumer.getVarselbjelleVarsler(tokenxUser.tokenString))
varselConsumer.getVarselbjelleVarsler(
userToken = tokenxUser.tokenString,
preferertSpraak = call.request.preferertSpraak
).let {
call.respond(HttpStatusCode.OK, it)
}
}
}

private val ApplicationRequest.preferertSpraak get() = queryParameters["preferert_spraak"]?.lowercase()

private val PipelineContext<Unit, ApplicationCall>.idportenUser: IdportenUser
get() = IdportenUserFactory.createIdportenUser(this.call)
Expand Down
19 changes: 19 additions & 0 deletions src/test/kotlin/no/nav/tms/varsel/api/VarselRoutesTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,25 @@ class VarselRoutesTest {
postCount shouldBe 1
}

@Test
fun `bruker preferert spraak i kall til authority`() {
testApplication {
setupVarselAuthority(expectedSpraakkodeParam = "en")
mockVarselApi(
varselConsumer = setupVarselConsumer(),
authMockInstaller = installAuthenticatedMock(LevelOfAssurance.LEVEL_4)
)

client.get("/aktive?preferert_spraak=en").apply {
status shouldBe HttpStatusCode.OK
}

client.get("/inaktive?preferert_spraak=en").apply {
status shouldBe HttpStatusCode.OK
}
}
}

private fun varselRoutesTest(block: suspend ApplicationTestBuilder.(HttpClient) -> Unit) = testApplication {
createClient {
install(io.ktor.client.plugins.contentnegotiation.ContentNegotiation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ class VarselbjelleRoutesTest {
val varselbjellevarsler = Json.decodeFromString<VarselbjelleVarsler>(bodyAsText())
varselbjellevarsler.beskjeder.size shouldBe 2
varselbjellevarsler.oppgaver.size shouldBe 3
val beskjed = varselbjellevarsler.beskjeder.first { it.eventId == expectedBeskjed.varselId }
val beskjed = varselbjellevarsler.beskjeder.first { it.varselId == expectedBeskjed.varselId }
beskjed.varselId shouldBe expectedBeskjed.varselId
beskjed.eventId shouldBe expectedBeskjed.varselId
beskjed.isMasked shouldBe (expectedBeskjed.innhold == null)
beskjed.link shouldBe expectedBeskjed.innhold?.link
beskjed.spraakkode shouldBe expectedBeskjed.innhold?.spraakkode
beskjed.tekst shouldBe expectedBeskjed.innhold?.tekst
beskjed.eksternVarslingKanaler shouldBe expectedBeskjed.eksternVarslingKanaler
beskjed.tidspunkt shouldBe expectedBeskjed.opprettet
Expand Down Expand Up @@ -76,6 +77,7 @@ class VarselbjelleRoutesTest {
beskjed.eventId shouldBe expectedBeskjed.varselId
beskjed.isMasked shouldBe (expectedBeskjed.innhold == null)
beskjed.link shouldBe expectedBeskjed.innhold?.link
beskjed.spraakkode shouldBe expectedBeskjed.innhold?.spraakkode
beskjed.tekst shouldBe expectedBeskjed.innhold?.tekst
beskjed.eksternVarslingKanaler shouldBe expectedBeskjed.eksternVarslingKanaler
beskjed.tidspunkt shouldBe expectedBeskjed.opprettet
Expand All @@ -84,4 +86,23 @@ class VarselbjelleRoutesTest {
}
}
}

@Test
fun `bruker preferert spraak i kall til authority`() {
testApplication {
setupVarselAuthority(expectedSpraakkodeParam = "en")
mockVarselApi(
varselConsumer = setupVarselConsumer(),
authMockInstaller = installAuthenticatedMock(LevelOfAssurance.LEVEL_4)
)

client.get("/bjellevarsler?preferert_spraak=en").apply {
status shouldBe HttpStatusCode.OK
}

client.get("/varselbjelle/varsler?preferert_spraak=en").apply {
status shouldBe HttpStatusCode.OK
}
}
}
}
10 changes: 10 additions & 0 deletions src/test/kotlin/no/nav/tms/varsel/api/varselTestData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import io.ktor.server.application.call
import io.ktor.server.application.install
import io.ktor.server.auth.*
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
import io.ktor.server.request.*
import io.ktor.server.response.respond
import io.ktor.server.routing.get
import io.ktor.server.routing.routing
Expand Down Expand Up @@ -99,6 +100,7 @@ fun ApplicationTestBuilder.setupVarselAuthority(vararg varsler: TestVarsel) = se
fun ApplicationTestBuilder.setupVarselAuthority(
aktiveVarslerFromEventHandler: List<TestVarsel> = emptyList(),
inaktiveVarslerFromEventHandler: List<TestVarsel> = emptyList(),
expectedSpraakkodeParam: String? = null
) {
externalServices {
hosts(varselAuthorityTestUrl) {
Expand All @@ -109,18 +111,26 @@ fun ApplicationTestBuilder.setupVarselAuthority(
routing {
get("/varsel/sammendrag/aktive") {
call.request.headers["Authorization"] shouldBe "Bearer authorityToken"

call.request.preferertSpraak shouldBe expectedSpraakkodeParam

call.respond(HttpStatusCode.OK, aktiveVarslerFromEventHandler)
}

get("/varsel/sammendrag/inaktive") {
call.request.headers["Authorization"] shouldBe "Bearer authorityToken"

call.request.preferertSpraak shouldBe expectedSpraakkodeParam

call.respond(HttpStatusCode.OK, inaktiveVarslerFromEventHandler)
}
}
}
}
}

private val ApplicationRequest.preferertSpraak get() = queryParameters["preferert_spraak"]?.lowercase()

fun ApplicationTestBuilder.setupVarselConsumer(
tokendingsService: TokendingsService = mockk<TokendingsService>().apply {
coEvery { exchangeToken(any(), "test:varsel-authority") } returns "authorityToken"
Expand Down