ribesg
05/10/2022, 11:42 AMAleksei Tirman [JB]
05/10/2022, 12:46 PM@Test
fun test() = testApplication {
    application {
        routing {
            get("/redirect") {
                call.respondRedirect("/")
            }
            get("/") {
                call.respondText { "hello" }
            }
        }
    }
    assertEquals("hello", client.get("/redirect").bodyAsText())
}ribesg
05/11/2022, 2:58 PMribesg
05/11/2022, 2:59 PMpost<V1.OldTimeSlots> {
        call.respondRedirect(application.href(V1.EventTimeSlots()))
    }
    post<V1.EventTimeSlots> {
        …
        val response = EventTimeSlotsResponse(…)
        call.respond(HttpStatusCode.OK, response)
    }ribesg
05/11/2022, 3:00 PM@Test
    fun `EventTimeSlots endpoint should return event timeslots`() = testApplication {
        val client = createClient {
            install(ContentNegotiation) { json() }
            install(Resources)
        }
        val expectedResponse = EventTimeSlotsResponse(…)
        val response = <http://client.post|client.post>(V1.EventTimeSlots()) {
            contentType(ContentType.Application.Json)
            setBody(…)
        }.body<EventTimeSlotsResponse>()
        assertEquals(expectedResponse, response)
    }
    @Test
    fun `OldTimeslots endpoint should still work`() = testApplication {
        val client = createClient {
            install(ContentNegotiation) { json() }
            install(Resources)
        }
        val expectedResponse = EventTimeSlotsResponse(…)
        val response = <http://client.post|client.post>(V1.OldTimeSlots()) {
            contentType(ContentType.Application.Json)
            setBody(…)
        }.body<EventTimeSlotsResponse>()
        assertEquals(expectedResponse, response)
    }ribesg
05/11/2022, 3:02 PMio.ktor.client.call.NoTransformationFoundException: No transformation found: class io.ktor.utils.io.ByteBufferChannel -> class blabla.route.EventTimeSlotsResponse
with response from <http://localhost/v1/timeslots>:
status: 302 Found
response headers: 
Location: /v1/event-timeslots
, Date: Wed, 11 May 2022 15:01:33 GMT
, Server: Ktor/2.0.1
, Content-Length: 0Aleksei Tirman [JB]
05/11/2022, 3:40 PMribesg
05/11/2022, 3:43 PMribesg
05/12/2022, 8:52 AM@Resource("/a")
    @Serializable
    class A {
        @Resource("b")
        @Serializable
        data class B(val parent: A = A())
        @Resource("c")
        @Serializable
        data class C(val parent: B = B())
    }
    @Serializable
    data class RequestBody(val value: Int)
    @Serializable
    data class ResponseBody(val value: Int)
    @Test
    fun `Should follow redirects`() = testApplication {
        val value = 1337
        environment {
            config = MapApplicationConfig()
            module {
                install(CallLogging)
                install(DefaultHeaders)
                install(AutoHeadResponse)
                install(ServerContentNegotiation) { json() }
                install(ServerResources)
                routing {
                    post<A.B> {
                        call.respondRedirect(application.href(A.C()))
                    }
                    post<A.C> {
                        val requestBody = call.receive<RequestBody>()
                        call.respond(HttpStatusCode.OK, ResponseBody(requestBody.value))
                    }
                }
            }
        }
        val client = createClient {
            install(ClientContentNegotiation) { json() }
            install(ClientResources)
        }
        val result = <http://client.post|client.post>(A.B()) {
            contentType(ContentType.Application.Json)
            setBody(RequestBody(value))
        }.body<ResponseBody>()
        assertEquals(value, result.value)
    }Aleksei Tirman [JB]
05/12/2022, 10:32 AMHttpRedirect  plugin redirects requests only with GET  and HEAD methods by default. You can disable checking HTTP method to make it work:
val client = createClient {
    followRedirects = false
    install(HttpRedirect) {
        checkHttpMethod = false
    }
    install(ClientContentNegotiation) { json() }
    install(ClientResources)
}ribesg
05/12/2022, 10:34 AMAleksei Tirman [JB]
05/12/2022, 10:35 AMif (plugin.checkHttpMethod && origin.request.method !in ALLOWED_FOR_REDIRECT) {
    return@intercept origin
}Aleksei Tirman [JB]
05/12/2022, 10:36 AMALLOWED_FOR_REDIRECT is setOf(HttpMethod.Get, HttpMethod.Head)ribesg
05/12/2022, 10:36 AMfollowRedirects to false because it installs the HttpRedirect plugin with default config? It’s also weird to have to do that to modify the configAleksei Tirman [JB]
05/12/2022, 10:37 AMribesg
05/12/2022, 10:46 AMAleksei Tirman [JB]
05/12/2022, 10:47 AMribesg
05/12/2022, 10:50 AMribesg
05/12/2022, 10:50 AMribesg
05/12/2022, 11:03 AMribesg
05/12/2022, 11:12 AMcheckHttpMethod should apply only to old 301 and 302 codes and not 307 and 308. I’m also gonna use 308 in my case.