1
+ package com.cjbooms.fabrikt.servers.ktor
2
+
3
+ import com.example.controllers.InstantDateTimeController.Companion.instantDateTimeRoutes
4
+ import io.ktor.client.request.*
5
+ import io.ktor.server.plugins.contentnegotiation.*
6
+ import io.ktor.server.plugins.dataconversion.*
7
+ import io.ktor.server.testing.*
8
+ import io.ktor.http.HttpStatusCode
9
+ import io.ktor.serialization.kotlinx.json.*
10
+ import io.mockk.CapturingSlot
11
+ import io.mockk.slot
12
+ import kotlinx.datetime.Instant
13
+ import org.junit.jupiter.api.Test
14
+ import kotlin.test.assertEquals
15
+
16
+ class KtorInstantDateTimeTest {
17
+
18
+ @Test
19
+ fun `handles correct date` () {
20
+ val listCapturingSlot: CapturingSlot <List <Instant >? > = slot()
21
+ val param2CapturingSlot: CapturingSlot <Instant ?> = slot()
22
+
23
+ testApplication {
24
+ configure(installInstantConverter = true )
25
+
26
+ routing {
27
+ instantDateTimeRoutes(InstantDateTimeControllerImpl (listCapturingSlot, param2CapturingSlot))
28
+ }
29
+
30
+ val response = client.get(" /instant-date-time?query_param2=2025-02-16T10:52:46Z" )
31
+
32
+ assertEquals(HttpStatusCode .OK , response.status)
33
+ assertEquals(null , listCapturingSlot.captured)
34
+ assertEquals(Instant .parse(" 2025-02-16T10:52:46Z" ), param2CapturingSlot.captured)
35
+ }
36
+ }
37
+
38
+ @Test
39
+ fun `handles correct list of date` () {
40
+ val listCapturingSlot: CapturingSlot <List <Instant >? > = slot()
41
+ val param2CapturingSlot: CapturingSlot <Instant ?> = slot()
42
+
43
+ testApplication {
44
+ configure(installInstantConverter = true )
45
+
46
+ routing {
47
+ instantDateTimeRoutes(InstantDateTimeControllerImpl (listCapturingSlot, param2CapturingSlot))
48
+ }
49
+
50
+ val response = client.get(" /instant-date-time?explode_list_query_param=2025-02-16T10:52:46Z&explode_list_query_param=2025-02-16T11:52:46Z&query_param2=2025-02-16T10:52:46Z" )
51
+
52
+ assertEquals(HttpStatusCode .OK , response.status)
53
+ assertEquals(listOf (Instant .parse(" 2025-02-16T10:52:46Z" ), Instant .parse(" 2025-02-16T11:52:46Z" )), listCapturingSlot.captured)
54
+ assertEquals(Instant .parse(" 2025-02-16T10:52:46Z" ), param2CapturingSlot.captured)
55
+ }
56
+ }
57
+
58
+ @Test
59
+ fun `returns 400 when date is invalid` () {
60
+ val listCapturingSlot: CapturingSlot <List <Instant >? > = slot()
61
+ val param2CapturingSlot: CapturingSlot <Instant ?> = slot()
62
+
63
+ testApplication {
64
+ configure(installInstantConverter = true )
65
+
66
+ routing {
67
+ instantDateTimeRoutes(InstantDateTimeControllerImpl (listCapturingSlot, param2CapturingSlot))
68
+ }
69
+
70
+ val response = client.get(" /instant-date-time?query_param2=20-02-16T10:52:46Z" )
71
+
72
+ assertEquals(HttpStatusCode .BadRequest , response.status)
73
+ }
74
+ }
75
+
76
+ @Test
77
+ fun `returns 400 when Instant converter is missing` () {
78
+ val listCapturingSlot: CapturingSlot <List <Instant >? > = slot()
79
+ val param2CapturingSlot: CapturingSlot <Instant ?> = slot()
80
+
81
+ testApplication {
82
+ configure(installInstantConverter = false )
83
+
84
+ routing {
85
+ instantDateTimeRoutes(InstantDateTimeControllerImpl (listCapturingSlot, param2CapturingSlot))
86
+ }
87
+
88
+ val response = client.get(" /instant-date-time?query_param2=2025-02-16T10:52:46Z" )
89
+
90
+ assertEquals(HttpStatusCode .BadRequest , response.status)
91
+ }
92
+ }
93
+
94
+ private fun ApplicationTestBuilder.configure (installInstantConverter : Boolean ) {
95
+ install(ContentNegotiation ) {
96
+ json()
97
+ }
98
+
99
+ if (installInstantConverter) {
100
+ install(DataConversion ) {
101
+ convert<Instant > {
102
+ decode { values ->
103
+ values.single().let { Instant .parse(it) }
104
+ }
105
+ }
106
+
107
+ convert<List <Instant >> {
108
+ decode { values ->
109
+ values.map { Instant .parse(it) }
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
0 commit comments