diff --git a/build.gradle.kts b/build.gradle.kts index 8b1fb60..4b60dce 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,6 +24,7 @@ repositories { } dependencies { + implementation("io.ktor:ktor-server-cors:$ktor_version") implementation("io.ktor:ktor-server-content-negotiation-jvm") implementation("io.ktor:ktor-server-core-jvm") implementation("io.ktor:ktor-serialization-kotlinx-json-jvm") diff --git a/src/main/kotlin/com/example/Application.kt b/src/main/kotlin/com/example/Application.kt index 7b0cc12..bfbd492 100644 --- a/src/main/kotlin/com/example/Application.kt +++ b/src/main/kotlin/com/example/Application.kt @@ -2,6 +2,7 @@ package com.example import com.example.plugins.* import io.ktor.server.application.* +import io.ktor.server.plugins.cors.routing.* fun main(args: Array) { io.ktor.server.netty.EngineMain.main(args) @@ -10,4 +11,8 @@ fun main(args: Array) { fun Application.module() { configureSerialization() configureRouting() + + install(CORS) { + anyHost() + } } diff --git a/src/main/kotlin/com/example/models/Customer.kt b/src/main/kotlin/com/example/models/Customer.kt new file mode 100644 index 0000000..9436fdc --- /dev/null +++ b/src/main/kotlin/com/example/models/Customer.kt @@ -0,0 +1,13 @@ +package com.example.models + +import kotlinx.serialization.Serializable + +@Serializable +data class Customer( + val id : String, + val firstName : String, + val lastName : String, + val email : String +) + +val customerStorage = mutableListOf() \ No newline at end of file diff --git a/src/main/kotlin/com/example/models/Order.kt b/src/main/kotlin/com/example/models/Order.kt new file mode 100644 index 0000000..953882a --- /dev/null +++ b/src/main/kotlin/com/example/models/Order.kt @@ -0,0 +1,31 @@ +package com.example.models + +import kotlinx.serialization.Serializable + +@Serializable +data class Order( + val number : String, + val contents : List +) + +@Serializable +data class OrderItem( + val item : String, + val amount : Int, + val price : Double +) + +val orderStorage = listOf(Order( + "2020-04-06-01", listOf( + OrderItem("Ham Sandwich", 2, 5.50), + OrderItem("Water", 1, 1.50), + OrderItem("Beer", 3, 2.30), + OrderItem("Cheesecake", 1, 3.75) + )), + Order("2020-04-03-01", listOf( + OrderItem("Cheeseburger", 1, 8.50), + OrderItem("Water", 2, 1.50), + OrderItem("Coke", 2, 1.76), + OrderItem("Ice Cream", 1, 2.35) + )) +) diff --git a/src/main/kotlin/com/example/plugins/Routing.kt b/src/main/kotlin/com/example/plugins/Routing.kt new file mode 100644 index 0000000..a012efd --- /dev/null +++ b/src/main/kotlin/com/example/plugins/Routing.kt @@ -0,0 +1,17 @@ +package com.example.plugins + +import com.example.routes.customerRouting +import com.example.routes.getOrderRoute +import com.example.routes.listOrdersRoute +import com.example.routes.totalizeOrderRoute +import io.ktor.server.application.* +import io.ktor.server.routing.* + +fun Application.configureRouting() { + routing { + customerRouting() + listOrdersRoute() + getOrderRoute() + totalizeOrderRoute() + } +} diff --git a/src/main/kotlin/com/example/routes/CustomerRoutes.kt b/src/main/kotlin/com/example/routes/CustomerRoutes.kt new file mode 100644 index 0000000..bdbea9f --- /dev/null +++ b/src/main/kotlin/com/example/routes/CustomerRoutes.kt @@ -0,0 +1,53 @@ +package com.example.routes + +import com.example.models.Customer +import com.example.models.customerStorage +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.request.* +import io.ktor.server.response.* +import io.ktor.server.routing.* + +fun Route.customerRouting() { + route("/customer") { + get { + if (customerStorage.isNotEmpty()) { + call.respond(customerStorage) + } else { + call.respondText("No customers found", status = HttpStatusCode.OK) + } + } + get("{id?}") { + + val id = call.parameters["id"] ?: return@get call.respondText( + "Missing id", + status = HttpStatusCode.BadRequest + ) + + val customer = customerStorage.find { it.id == id } ?: return@get call.respondText( + "No customer with id $id", + status = HttpStatusCode.NotFound + ) + call.respond(customer) + } + post { + + val customer = call.receive() + customerStorage.add(customer) + call.respondText("Custom stored correctly", status = HttpStatusCode.Created) + + } + delete("{id?}") { + + val id = call.parameters["id"] ?: return@delete call.respond(HttpStatusCode.BadRequest) + if (customerStorage.removeIf { it.id == id }) { + call.respondText( + "Customer removed!", + status = HttpStatusCode.Accepted + ) + } else { + call.respondText("Not Found", status = HttpStatusCode.NotFound) + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/example/routes/OrderRoutes.kt b/src/main/kotlin/com/example/routes/OrderRoutes.kt new file mode 100644 index 0000000..3b6b166 --- /dev/null +++ b/src/main/kotlin/com/example/routes/OrderRoutes.kt @@ -0,0 +1,42 @@ +package com.example.routes + +import com.example.models.orderStorage +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.response.* +import io.ktor.server.routing.* + +fun Route.listOrdersRoute() { + get("/order") { + if (orderStorage.isNotEmpty()) { + call.respond(orderStorage) + } + } +} + +fun Route.getOrderRoute() { + get("/order/{id?}") { + val id = call.parameters["id"] ?: return@get call.respondText( + "Bad Request", status = HttpStatusCode.BadRequest + ) + val order = orderStorage.find { it.number == id } ?: return@get call.respondText( + "Order Not Found", + status = HttpStatusCode.NotFound + ) + call.respond(order) + } +} + +fun Route.totalizeOrderRoute() { + get("/order/{id?}/total") { + val id = call.parameters["id"] ?: return@get call.respondText( + "Bad Request", status = HttpStatusCode.BadRequest + ) + val order = orderStorage.find { it.number == id } ?: return@get call.respondText( + "Not found", + status = HttpStatusCode.NotFound + ) + val total = order.contents.sumOf { it.price * it.amount } + call.respond(total) + } +} \ No newline at end of file diff --git a/src/test/kotlin/com/example/ApplicationTest.kt b/src/test/kotlin/com/example/ApplicationTest.kt deleted file mode 100644 index b4e0c54..0000000 --- a/src/test/kotlin/com/example/ApplicationTest.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.example - -import com.example.plugins.* -import io.ktor.client.request.* -import io.ktor.client.statement.* -import io.ktor.http.* -import io.ktor.server.testing.* -import kotlin.test.* - -class ApplicationTest { - @Test - fun testRoot() = testApplication { - application { - configureRouting() - } - client.get("/").apply { - assertEquals(HttpStatusCode.OK, status) - assertEquals("Hello World!", bodyAsText()) - } - } -} diff --git a/src/test/kotlin/com/example/OrderRouteTests.kt b/src/test/kotlin/com/example/OrderRouteTests.kt new file mode 100644 index 0000000..906a341 --- /dev/null +++ b/src/test/kotlin/com/example/OrderRouteTests.kt @@ -0,0 +1,21 @@ +package com.example + +import com.example.plugins.* +import io.ktor.client.request.* +import io.ktor.client.statement.* +import io.ktor.http.* +import io.ktor.server.testing.* +import kotlin.test.* + +class OrderRouteTests { + + @Test + fun testGetOrder() = testApplication { + val response = client.get("/order/2020-04-06-01") + assertEquals( + """{"number":"2020-04-06-01","contents":[{"item":"Ham Sandwich","amount":2,"price":5.5},{"item":"Water","amount":1,"price":1.5},{"item":"Beer","amount":3,"price":2.3},{"item":"Cheesecake","amount":1,"price":3.75}]}""", + response.bodyAsText() + ) + assertEquals(HttpStatusCode.OK, response.status) + } +}