diff --git a/src/main/kotlin/no/uib/echo/Application.kt b/src/main/kotlin/no/uib/echo/Application.kt index 5bcec254..bc61de55 100644 --- a/src/main/kotlin/no/uib/echo/Application.kt +++ b/src/main/kotlin/no/uib/echo/Application.kt @@ -80,6 +80,7 @@ fun Application.module() { configureRouting( adminKey, sendGridApiKey, + dev, FeatureToggles(sendEmailReg = sendEmailReg, sendEmailHap = sendEmailHap, rateLimit = true) ) } diff --git a/src/main/kotlin/no/uib/echo/plugins/Routing.kt b/src/main/kotlin/no/uib/echo/plugins/Routing.kt index 0c82d23b..8368f0a1 100644 --- a/src/main/kotlin/no/uib/echo/plugins/Routing.kt +++ b/src/main/kotlin/no/uib/echo/plugins/Routing.kt @@ -25,6 +25,8 @@ import io.ktor.routing.get import io.ktor.routing.post import io.ktor.routing.put import io.ktor.routing.routing +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import no.uib.echo.FeatureToggles import no.uib.echo.Response import no.uib.echo.plugins.Routing.deleteHappening @@ -45,7 +47,6 @@ import no.uib.echo.schema.HappeningJson import no.uib.echo.schema.HappeningSlugJson import no.uib.echo.schema.Registration import no.uib.echo.schema.RegistrationJson -import no.uib.echo.schema.ShortRegistrationJson import no.uib.echo.schema.SpotRange import no.uib.echo.schema.SpotRangeWithCountJson import no.uib.echo.schema.countRegistrationsDegreeYear @@ -53,8 +54,10 @@ import no.uib.echo.schema.insertOrUpdateHappening import no.uib.echo.schema.selectHappening import no.uib.echo.schema.selectSpotRanges import no.uib.echo.schema.toCsv +import no.uib.echo.schema.validateLink import no.uib.echo.sendConfirmationEmail import org.jetbrains.exposed.sql.SortOrder +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.StdOutSqlLogger import org.jetbrains.exposed.sql.addLogger import org.jetbrains.exposed.sql.and @@ -64,12 +67,15 @@ import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.lowerCase import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.transactions.transaction +import org.jetbrains.exposed.sql.update import org.joda.time.DateTime +import java.net.URLDecoder import java.time.Duration fun Application.configureRouting( adminKey: String, sendGridApiKey: String?, + dev: Boolean, featureToggles: FeatureToggles ) { val admin = "admin" @@ -100,14 +106,14 @@ fun Application.configureRouting( getStatus() authenticate("auth-$admin") { - deleteRegistration() - putHappening(sendGridApiKey, featureToggles.sendEmailHap) + putHappening(sendGridApiKey, featureToggles.sendEmailHap, dev) deleteHappening() getRegistrationCount() } - getRegistrations() + getRegistrations(dev) postRegistration(sendGridApiKey, featureToggles.sendEmailReg) + deleteRegistration(dev) } } } @@ -160,25 +166,14 @@ object Routing { } } - fun Route.getRegistrations() { + fun Route.getRegistrations(dev: Boolean) { get("/$registrationRoute/{link}") { val link = call.parameters["link"] val download = call.request.queryParameters["download"] != null val json = call.request.queryParameters["json"] != null val testing = call.request.queryParameters["testing"] != null - if ((link == null) || (link.length < 128)) { - call.respond(HttpStatusCode.NotFound) - return@get - } - - val hap = transaction { - addLogger(StdOutSqlLogger) - - Happening.select { - Happening.registrationsLink eq link - }.firstOrNull() - } + val hap = validateLink(link, dev) if (hap == null) { call.respond(HttpStatusCode.NotFound) @@ -419,24 +414,87 @@ object Routing { } } - fun Route.deleteRegistration() { - delete("/$registrationRoute") { + fun Route.deleteRegistration(dev: Boolean) { + delete("/$registrationRoute/{link}/{email}") { + fun stdResponse() { + } + + val link = call.parameters["link"] + val email = withContext(Dispatchers.IO) { + URLDecoder.decode(call.parameters["email"], "utf-8") + } + + val hap = validateLink(link, dev) + + if (hap == null || email == null) { + call.respond(HttpStatusCode.NotFound) + return@delete + } + try { - val shortReg = call.receive() + val reg = transaction { + addLogger(StdOutSqlLogger) + + Registration.select { + Registration.happeningSlug eq hap[slug] and + (Registration.email.lowerCase() eq email.lowercase()) + }.firstOrNull() + } + + if (reg == null) { + call.respond(HttpStatusCode.BadRequest) + return@delete + } transaction { addLogger(StdOutSqlLogger) + Answer.deleteWhere { + Answer.happeningSlug eq hap[slug] and + (Answer.registrationEmail.lowerCase() eq email.lowercase()) + } + Registration.deleteWhere { - Registration.happeningSlug eq shortReg.slug and - (Registration.email.lowerCase() eq shortReg.email.lowercase()) + Registration.happeningSlug eq hap[slug] and + (Registration.email.lowerCase() eq email.lowercase()) } } - call.respond( - HttpStatusCode.OK, - "Registration (${shortReg.type}) with email = ${shortReg.email} and slug = ${shortReg.slug} deleted." - ) + if (reg[Registration.waitList]) { + call.respond( + HttpStatusCode.OK, + "Registration with email = ${email.lowercase()} and slug = ${hap[slug]} deleted." + ) + return@delete + } + + val highestOnWaitList = transaction { + addLogger(StdOutSqlLogger) + + Registration.select { + Registration.waitList eq true + }.orderBy(Registration.submitDate).firstOrNull() + } + + if (highestOnWaitList == null) { + call.respond( + HttpStatusCode.OK, + "Registration with email = ${email.lowercase()} and slug = ${hap[slug]} deleted." + ) + } else { + transaction { + addLogger(StdOutSqlLogger) + + Registration.update({ Registration.email eq highestOnWaitList[Registration.email].lowercase() }) { + it[waitList] = false + } + } + call.respond( + HttpStatusCode.OK, + "Registration with email = ${email.lowercase()} and slug = ${hap[slug]} deleted, " + + "and registration with email = ${highestOnWaitList[Registration.email].lowercase()} moved off wait list." + ) + } } catch (e: Exception) { call.respond(HttpStatusCode.BadRequest, "Error deleting registration.") e.printStackTrace() @@ -444,11 +502,11 @@ object Routing { } } - fun Route.putHappening(sendGridApiKey: String?, sendEmail: Boolean) { + fun Route.putHappening(sendGridApiKey: String?, sendEmail: Boolean, dev: Boolean) { put("/$happeningRoute") { try { - val happ = call.receive() - val result = insertOrUpdateHappening(happ, sendEmail, sendGridApiKey) + val hap = call.receive() + val result = insertOrUpdateHappening(hap, sendGridApiKey, sendEmail, dev) call.respond(result.first, result.second) } catch (e: Exception) { diff --git a/src/main/kotlin/no/uib/echo/schema/Happening.kt b/src/main/kotlin/no/uib/echo/schema/Happening.kt index ab9e536e..cb633ad3 100644 --- a/src/main/kotlin/no/uib/echo/schema/Happening.kt +++ b/src/main/kotlin/no/uib/echo/schema/Happening.kt @@ -10,6 +10,7 @@ import no.uib.echo.schema.Happening.organizerEmail import no.uib.echo.schema.Happening.registrationDate import no.uib.echo.sendEmail import org.jetbrains.exposed.sql.Column +import org.jetbrains.exposed.sql.ResultRow import org.jetbrains.exposed.sql.StdOutSqlLogger import org.jetbrains.exposed.sql.Table import org.jetbrains.exposed.sql.addLogger @@ -75,8 +76,9 @@ fun selectHappening(slug: String): HappeningJson? { suspend fun insertOrUpdateHappening( newHappening: HappeningJson, + sendGridApiKey: String?, sendEmail: Boolean, - sendGridApiKey: String? + dev: Boolean, ): Pair { if (newHappening.spotRanges.isEmpty()) { return Pair( @@ -87,10 +89,13 @@ suspend fun insertOrUpdateHappening( val happening = selectHappening(newHappening.slug) val registrationsLink = - (1..REG_LINK_LENGTH).map { - (('A'..'Z') + ('a'..'z') + ('0'..'9')) - .random() - }.joinToString("") + if (dev) + newHappening.slug + else + (1..REG_LINK_LENGTH).map { + (('A'..'Z') + ('a'..'z') + ('0'..'9')) + .random() + }.joinToString("") if (happening == null) { transaction { @@ -223,3 +228,16 @@ fun spotRangeToString(spotRanges: List): String { } } ]" } + +fun validateLink(link: String?, dev: Boolean): ResultRow? { + if (link == null || (link.length != 128 && !dev)) + return null + + return transaction { + addLogger(StdOutSqlLogger) + + Happening.select { + Happening.registrationsLink eq link + }.firstOrNull() + } +} diff --git a/src/main/kotlin/no/uib/echo/schema/Registration.kt b/src/main/kotlin/no/uib/echo/schema/Registration.kt index 89bf07b4..f9ef1af5 100644 --- a/src/main/kotlin/no/uib/echo/schema/Registration.kt +++ b/src/main/kotlin/no/uib/echo/schema/Registration.kt @@ -26,8 +26,6 @@ data class RegistrationJson( val type: HAPPENING_TYPE ) -data class ShortRegistrationJson(val slug: String, val email: String, val type: HAPPENING_TYPE) - object Registration : Table() { val email: Column = text("email") val firstName: Column = text("first_name") diff --git a/src/test/kotlin/no/uib/echo/HappeningRegistrationTest.kt b/src/test/kotlin/no/uib/echo/HappeningRegistrationTest.kt index ca6593bd..808bf8a3 100644 --- a/src/test/kotlin/no/uib/echo/HappeningRegistrationTest.kt +++ b/src/test/kotlin/no/uib/echo/HappeningRegistrationTest.kt @@ -46,6 +46,7 @@ class HappeningRegistrationTest : StringSpec({ ) val everyoneInfiniteSpotRange = listOf(SpotRangeJson(0, 1, 5)) val onlyOneSpotRange = listOf(SpotRangeJson(1, 1, 5)) + val fewSpotRange = listOf(SpotRangeJson(5, 1, 5)) val exampleHappening1: (type: HAPPENING_TYPE) -> HappeningJson = { type -> @@ -135,6 +136,17 @@ class HappeningRegistrationTest : StringSpec({ "test@test.com" ) } + val exampleHappening9: (type: HAPPENING_TYPE) -> HappeningJson = + { type -> + HappeningJson( + "$type-med-få-plasser", + "$type med få plasser!", + "2020-02-18T16:27:05Z", + fewSpotRange, + type, + "test@test.com" + ) + } val exampleHappeningReg: (type: HAPPENING_TYPE) -> RegistrationJson = { type -> RegistrationJson( @@ -178,21 +190,22 @@ class HappeningRegistrationTest : StringSpec({ } for (t in be) { withContext(Dispatchers.IO) { - insertOrUpdateHappening(exampleHappening1(t), false, null) - insertOrUpdateHappening(exampleHappening2(t), false, null) - insertOrUpdateHappening(exampleHappening3(t), false, null) - insertOrUpdateHappening(exampleHappening4(t), false, null) - insertOrUpdateHappening(exampleHappening5(t), false, null) - insertOrUpdateHappening(exampleHappening6(t), false, null) - insertOrUpdateHappening(exampleHappening7(t), false, null) - insertOrUpdateHappening(exampleHappening8(t), false, null) + insertOrUpdateHappening(exampleHappening1(t), null, sendEmail = false, dev = true) + insertOrUpdateHappening(exampleHappening2(t), null, sendEmail = false, dev = true) + insertOrUpdateHappening(exampleHappening3(t), null, sendEmail = false, dev = true) + insertOrUpdateHappening(exampleHappening4(t), null, sendEmail = false, dev = true) + insertOrUpdateHappening(exampleHappening5(t), null, sendEmail = false, dev = true) + insertOrUpdateHappening(exampleHappening6(t), null, sendEmail = false, dev = true) + insertOrUpdateHappening(exampleHappening7(t), null, sendEmail = false, dev = true) + insertOrUpdateHappening(exampleHappening8(t), null, sendEmail = false, dev = true) + insertOrUpdateHappening(exampleHappening9(t), null, sendEmail = false, dev = true) } } } "Registrations with valid data should submit correctly." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { fun submitReg(degree: Degree, degreeYear: Int, type: HAPPENING_TYPE) { val submitRegCall: TestApplicationCall = @@ -237,7 +250,7 @@ class HappeningRegistrationTest : StringSpec({ "The same user should be able to sign up for two different happenings." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { for (b in listOf(exampleHappening1(t), exampleHappening2(t))) { @@ -259,7 +272,7 @@ class HappeningRegistrationTest : StringSpec({ "Registration with valid data and empty question list should submit correctly." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val submitRegCall: TestApplicationCall = @@ -279,7 +292,7 @@ class HappeningRegistrationTest : StringSpec({ "You should not be able to sign up for a happening more than once." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val submitRegCall: TestApplicationCall = @@ -314,7 +327,7 @@ class HappeningRegistrationTest : StringSpec({ "You should not be able to sign up for a happening more than once (wait list)." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val fillUpRegsCall: TestApplicationCall = @@ -382,7 +395,7 @@ class HappeningRegistrationTest : StringSpec({ "You should not be able to sign up for a happening before the registration date." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val submitRegCall: TestApplicationCall = @@ -402,7 +415,7 @@ class HappeningRegistrationTest : StringSpec({ "You should not be able to sign up for a happening that doesn't exist." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val submitRegCall: TestApplicationCall = @@ -427,7 +440,7 @@ class HappeningRegistrationTest : StringSpec({ "Email should contain @-sign." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val testCall: TestApplicationCall = @@ -448,7 +461,7 @@ class HappeningRegistrationTest : StringSpec({ "Degree year should not be smaller than one." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val testCall: TestApplicationCall = @@ -469,7 +482,7 @@ class HappeningRegistrationTest : StringSpec({ "Degree year should not be bigger than five." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val testCall: TestApplicationCall = @@ -490,7 +503,7 @@ class HappeningRegistrationTest : StringSpec({ "If the degree year is either four or five, the degree should not correspond to a bachelors degree." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { listOf( Degree.DTEK, @@ -521,7 +534,7 @@ class HappeningRegistrationTest : StringSpec({ "If the degree year is between one and three, the degree should not correspond to a masters degree." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { listOf(Degree.INF, Degree.PROG).map { deg -> for (t in be) { @@ -546,7 +559,7 @@ class HappeningRegistrationTest : StringSpec({ "If degree is KOGNI, degree year should be equal to three." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val testCall: TestApplicationCall = @@ -567,7 +580,7 @@ class HappeningRegistrationTest : StringSpec({ "If degree is ARMNINF, degree year should be equal to one." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val testCall: TestApplicationCall = @@ -588,7 +601,7 @@ class HappeningRegistrationTest : StringSpec({ "Terms should be accepted." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val testCall: TestApplicationCall = @@ -612,30 +625,9 @@ class HappeningRegistrationTest : StringSpec({ } } - "Trying to delete a registration with wrong Authorization header should not work." { - withTestApplication({ - configureRouting(adminKey, null, featureToggles) - }) { - val wrongAuth = "admin:feil-passord-100-bruh" - for (t in be) { - val testCall: TestApplicationCall = - handleRequest(method = HttpMethod.Delete, uri = "/${Routing.registrationRoute}") { - addHeader(HttpHeaders.ContentType, "application/json") - addHeader( - HttpHeaders.Authorization, - "Basic ${Base64.getEncoder().encodeToString(wrongAuth.toByteArray())}" - ) - setBody(gson.toJson(exampleHappeningReg(t))) - } - - testCall.response.status() shouldBe HttpStatusCode.Unauthorized - } - } - } - "If a happening has filled up every spot, a registration should be put on the wait list." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { for (i in 1..(exampleHappening1(t).spotRanges[0].spots)) { @@ -671,7 +663,7 @@ class HappeningRegistrationTest : StringSpec({ "You should not be able to sign up for a happening if you are not inside the degree year range." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { for (i in 1..2) { @@ -735,7 +727,7 @@ class HappeningRegistrationTest : StringSpec({ "Rate limit should work as expected." { withTestApplication({ - configureRouting(adminKey, null, featureToggles.copy(rateLimit = true)) + configureRouting(adminKey, null, true, featureToggles.copy(rateLimit = true)) }) { for (i in 1..200) { val submitRegCall: TestApplicationCall = @@ -781,7 +773,7 @@ class HappeningRegistrationTest : StringSpec({ "Should get correct count of registrations and wait list registrations, and produce correct CSV list" { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { val waitListCount = 10 @@ -896,7 +888,7 @@ class HappeningRegistrationTest : StringSpec({ "Should respond properly when not given slug of happening when count of registrations are requested" { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val getCountRegCall: TestApplicationCall = @@ -918,7 +910,7 @@ class HappeningRegistrationTest : StringSpec({ "Should accept registrations for happening with infinite spots" { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { fun submitReg(type: HAPPENING_TYPE, i: Int) { val submitRegCall: TestApplicationCall = @@ -951,7 +943,7 @@ class HappeningRegistrationTest : StringSpec({ "Should redirect if trying to get list of registrations via old FreeMarker page" { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val newSlug = "auto-link-test-100-$t" @@ -986,6 +978,92 @@ class HappeningRegistrationTest : StringSpec({ } } } + + "Should delete registrations properly" { + withTestApplication({ + configureRouting(adminKey, null, true, featureToggles) + }) { + val waitListAmount = 3 + + for (t in be) { + for (i in 1..exampleHappening9(t).spotRanges[0].spots) { + val submitRegCall: TestApplicationCall = + handleRequest(method = HttpMethod.Post, uri = "/${Routing.registrationRoute}") { + addHeader(HttpHeaders.ContentType, "application/json") + setBody( + gson.toJson( + exampleHappeningReg(t).copy( + email = "${t}$i@test.com", + slug = exampleHappening9(t).slug + ) + ) + ) + } + + submitRegCall.response.status() shouldBe HttpStatusCode.OK + val res = gson.fromJson(submitRegCall.response.content, ResponseJson::class.java) + res.code shouldBe Response.OK + res.title shouldBe "Påmeldingen din er registrert!" + res.desc shouldBe successfulRegMsg(t) + } + + for (i in 1..waitListAmount) { + val submitRegCall: TestApplicationCall = + handleRequest(method = HttpMethod.Post, uri = "/${Routing.registrationRoute}") { + addHeader(HttpHeaders.ContentType, "application/json") + setBody( + gson.toJson( + exampleHappeningReg(t).copy( + email = "waitlist${t}$i@test.com", + slug = exampleHappening9(t).slug + ) + ) + ) + } + + submitRegCall.response.status() shouldBe HttpStatusCode.Accepted + val res = gson.fromJson(submitRegCall.response.content, ResponseJson::class.java) + val code = Response.WaitList + val (_, title, desc) = resToJson(code, t, waitListSpot = i.toLong()) + + res.code shouldBe code + res.title shouldBe title + res.desc shouldBe desc + } + + // Delete $waitListAmount registrations, such that all the registrations + // previously on the wait list are now moved off the wait list. + for (i in 1..waitListAmount) { + val regEmail = "${t}$i@test.com" + val nextRegOnWaitListEmail = "waitlist${t}$i@test.com" + val deleteRegCall: TestApplicationCall = + handleRequest( + method = HttpMethod.Delete, + uri = "/${Routing.registrationRoute}/${exampleHappening9(t).slug}/$regEmail" + ) + + deleteRegCall.response.status() shouldBe HttpStatusCode.OK + deleteRegCall.response.content shouldBe + "Registration with email = ${regEmail.lowercase()} and slug = ${exampleHappening9(t).slug} deleted, " + + "and registration with email = ${nextRegOnWaitListEmail.lowercase()} moved off wait list." + } + + // Delete the registrations that were moved off the wait list in the previous for-loop. + for (i in 1..waitListAmount) { + val waitListRegEmail = "waitlist${t}$i@test.com" + val deleteWaitListRegCall: TestApplicationCall = + handleRequest( + method = HttpMethod.Delete, + uri = "/${Routing.registrationRoute}/${exampleHappening9(t).slug}/$waitListRegEmail" + ) + + deleteWaitListRegCall.response.status() shouldBe HttpStatusCode.OK + deleteWaitListRegCall.response.content shouldBe + "Registration with email = ${waitListRegEmail.lowercase()} and slug = ${exampleHappening9(t).slug} deleted." + } + } + } + } }) fun successfulRegMsg(type: HAPPENING_TYPE): String { diff --git a/src/test/kotlin/no/uib/echo/HappeningTest.kt b/src/test/kotlin/no/uib/echo/HappeningTest.kt index 48d357a2..c544c2e6 100644 --- a/src/test/kotlin/no/uib/echo/HappeningTest.kt +++ b/src/test/kotlin/no/uib/echo/HappeningTest.kt @@ -58,7 +58,7 @@ class HappeningTest : StringSpec({ "When trying to submit a happening, server should respond with OK." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val testCall: TestApplicationCall = @@ -78,7 +78,7 @@ class HappeningTest : StringSpec({ "Whe trying to update happening spots, server should respond with OK." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val submitHappeningCall: TestApplicationCall = @@ -110,7 +110,7 @@ class HappeningTest : StringSpec({ "When trying to update a happening with the exact same values, server should respond with ACCEPTED." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { for (t in be) { val submitBedpresCall: TestApplicationCall = @@ -142,7 +142,7 @@ class HappeningTest : StringSpec({ "When trying to submit a happening with bad data, server should respond with INTERNAL_SERVER_ERROR." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { val testCall: TestApplicationCall = handleRequest(method = HttpMethod.Put, uri = "/${Routing.happeningRoute}") { @@ -160,7 +160,7 @@ class HappeningTest : StringSpec({ "When trying to submit or update a happening with wrong Authorization header, server should respond with UNAUTHORIZED." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { val wrongAuth = "admin:damn-feil-passord-100" @@ -182,7 +182,7 @@ class HappeningTest : StringSpec({ "When trying to delete a happening with wrong Authorization header, server should respond with UNAUTHORIZED." { withTestApplication({ - configureRouting(adminKey, null, featureToggles) + configureRouting(adminKey, null, true, featureToggles) }) { val wrongAuth = "admin:damn-feil-passord-100"