From 3d77d9c91df6719f841cd63cc4069584bef39fd4 Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Fri, 30 Aug 2024 15:05:55 +0200 Subject: [PATCH 1/6] Add integration tests for GET and PUT, includes WIP DELETE tests --- .../order/controller/OrderControllerTest.kt | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt index 0ff12502..119c6e28 100644 --- a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt @@ -18,6 +18,7 @@ import no.nb.mlt.wls.order.model.OrderType import no.nb.mlt.wls.order.model.ProductLine import no.nb.mlt.wls.order.payloads.ApiOrderPayload import no.nb.mlt.wls.order.payloads.toOrder +import no.nb.mlt.wls.order.payloads.toUpdateOrderPayload import no.nb.mlt.wls.order.repository.OrderRepository import no.nb.mlt.wls.order.service.SynqOrderService import org.assertj.core.api.Assertions.assertThat @@ -32,6 +33,7 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT import org.springframework.context.ApplicationContext import org.springframework.data.mongodb.repository.config.EnableMongoRepositories +import org.springframework.http.HttpStatus import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.csrf @@ -164,6 +166,100 @@ class OrderControllerTest( .expectStatus().is5xxServerError } + @Test + fun `getOrder returns the order`() { + webTestClient + .mutateWith(csrf()) + .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .get() + .uri("/order/{hostName}/{hostOrderId}", clientName, duplicateOrderPayload.hostOrderId) + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus().isOk + .expectBody(ApiOrderPayload::class.java) + } + + @Test + fun `getOrder for wrong client throws`() { + webTestClient + .mutateWith(csrf()) + .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .get() + .uri("/order/{hostName}/{hostOrderId}", "ALMA", duplicateOrderPayload.hostOrderId) + .exchange() + .expectStatus().isForbidden + } + + @Test + fun `updateOrder with valid payload updates order`() { + val testPayload = + testOrderPayload.toOrder().toUpdateOrderPayload() + .copy( + productLine = + listOf( + ProductLine("mlt-420", OrderLineStatus.NOT_STARTED), + ProductLine("mlt-421", OrderLineStatus.NOT_STARTED) + ) + ) + + // TODO - Check list elements + webTestClient + .mutateWith(csrf()) + .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .put() + .uri("/order") + .bodyValue(testPayload) + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus().isOk + } + + @Test + fun `updateOrder when order is being processed errors`() { + val testPayload = testOrderPayload.copy(orderId = "mlt-test-order-processing", status = OrderStatus.IN_PROGRESS) + val testUpdatePayload = testPayload.toOrder().toUpdateOrderPayload().copy(orderType = OrderType.DIGITIZATION) + runTest { + repository.save(testPayload.toOrder()).awaitSingle() + + webTestClient + .mutateWith(csrf()) + .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .put() + .uri("/order") + .bodyValue(testUpdatePayload) + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus().isEqualTo(HttpStatus.CONFLICT) + } + } + + // FIXME - Spec? + @Test + fun `deleteOrder when valid deletes order`() { + webTestClient + .mutateWith(csrf()) + .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .delete() + .uri("/order") + .exchange() + .expectStatus().is2xxSuccessful + } + + @Test + fun `deleteOrder handles synq error`() { + coEvery { + // FIXME - deleteOrder call + synqOrderService.createOrder(any()) + } returns ResponseEntity.badRequest().build() + webTestClient + .mutateWith(csrf()) + .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .delete() + .uri("/order") + .exchange() + .expectStatus().is5xxServerError + } + @Test fun `deleteOrder with valid data deletes order`() = runTest { From 0f3199f617a477f1762cf0d5aa46f40cf5b322aa Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Tue, 3 Sep 2024 09:05:12 +0200 Subject: [PATCH 2/6] Disable DELETE tests Awaiting endpoint --- .../order/controller/OrderControllerTest.kt | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt index 119c6e28..5adb458e 100644 --- a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt @@ -233,31 +233,31 @@ class OrderControllerTest( } } - // FIXME - Spec? + // FIXME - use delete endpoint when merged into main @Test fun `deleteOrder when valid deletes order`() { - webTestClient - .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) - .delete() - .uri("/order") - .exchange() - .expectStatus().is2xxSuccessful +// webTestClient +// .mutateWith(csrf()) +// .mutateWith(mockJwt().jwt { it.subject(clientName) }) +// .delete() +// .exchange() +// .expectStatus().is2xxSuccessful + assertThat(true) } + // FIXME - use delete endpoint when merged into main @Test fun `deleteOrder handles synq error`() { - coEvery { - // FIXME - deleteOrder call - synqOrderService.createOrder(any()) - } returns ResponseEntity.badRequest().build() - webTestClient - .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) - .delete() - .uri("/order") - .exchange() - .expectStatus().is5xxServerError +// coEvery { +// synqOrderService.createOrder(any()) +// } returns ResponseEntity.badRequest().build() +// webTestClient +// .mutateWith(csrf()) +// .mutateWith(mockJwt().jwt { it.subject(clientName) }) +// .delete() +// .exchange() +// .expectStatus().is5xxServerError + assertThat(true) } @Test From 2109d61ab57cc8ff18d55f0c050da1134e82a184 Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Tue, 3 Sep 2024 09:41:29 +0200 Subject: [PATCH 3/6] More testing - Extend and fix update order happy test - Add TODO related to get order functionality --- .../order/controller/OrderControllerTest.kt | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt index 5adb458e..0bbf21a1 100644 --- a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt @@ -11,6 +11,7 @@ import no.nb.mlt.wls.EnableTestcontainers import no.nb.mlt.wls.core.data.HostName import no.nb.mlt.wls.core.data.Owner import no.nb.mlt.wls.core.data.synq.SynqError +import no.nb.mlt.wls.order.model.Order import no.nb.mlt.wls.order.model.OrderLineStatus import no.nb.mlt.wls.order.model.OrderReceiver import no.nb.mlt.wls.order.model.OrderStatus @@ -104,14 +105,14 @@ class OrderControllerTest( .mutateWith(mockJwt().jwt { it.subject(clientName) }) .post() .accept(MediaType.APPLICATION_JSON) - .bodyValue(duplicateOrderPayload) + .bodyValue(dop) .exchange() .expectStatus().isOk .expectBody() .consumeWith { response -> - assertThat(response.responseBody?.hostOrderId).isEqualTo(duplicateOrderPayload.hostOrderId) - assertThat(response.responseBody?.hostName).isEqualTo(duplicateOrderPayload.hostName) - assertThat(response.responseBody?.productLine).isEqualTo(duplicateOrderPayload.productLine) + assertThat(response.responseBody?.hostOrderId).isEqualTo(dop.hostOrderId) + assertThat(response.responseBody?.hostName).isEqualTo(dop.hostName) + assertThat(response.responseBody?.productLine).isEqualTo(dop.productLine) } } @@ -123,13 +124,13 @@ class OrderControllerTest( .post() .accept(MediaType.APPLICATION_JSON) .bodyValue( - duplicateOrderPayload.copy(productLine = listOf(ProductLine("AAAAAAAAA", OrderLineStatus.PICKED))) + dop.copy(productLine = listOf(ProductLine("AAAAAAAAA", OrderLineStatus.PICKED))) ) .exchange() .expectStatus().isOk .expectBody() .consumeWith { response -> - assertThat(response.responseBody?.productLine).isEqualTo(duplicateOrderPayload.productLine) + assertThat(response.responseBody?.productLine).isEqualTo(dop.productLine) } } @@ -166,34 +167,43 @@ class OrderControllerTest( .expectStatus().is5xxServerError } + // TODO - Should this endpoint really be returning Orders directly? @Test fun `getOrder returns the order`() { webTestClient .mutateWith(csrf()) .mutateWith(mockJwt().jwt { it.subject(clientName) }) .get() - .uri("/order/{hostName}/{hostOrderId}", clientName, duplicateOrderPayload.hostOrderId) + .uri("/{hostName}/{hostOrderId}", dop.hostName, dop.hostOrderId) .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus().isOk - .expectBody(ApiOrderPayload::class.java) + .expectBody(Order::class.java) + .consumeWith { response -> + assertThat(response?.responseBody?.hostOrderId.equals(dop.hostOrderId)) + assertThat(response?.responseBody?.status?.equals(dop.status)) + } } @Test fun `getOrder for wrong client throws`() { webTestClient .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .mutateWith(mockJwt().jwt { it.subject("ALMA") }) .get() - .uri("/order/{hostName}/{hostOrderId}", "ALMA", duplicateOrderPayload.hostOrderId) + .uri("/{hostName}/{hostOrderId}", dop.hostName, dop.hostOrderId) .exchange() .expectStatus().isForbidden } @Test fun `updateOrder with valid payload updates order`() { + coEvery { + synqOrderService.updateOrder(any()) + } returns ResponseEntity.ok().build() + val testPayload = - testOrderPayload.toOrder().toUpdateOrderPayload() + dop.toOrder().toUpdateOrderPayload() .copy( productLine = listOf( @@ -202,16 +212,21 @@ class OrderControllerTest( ) ) - // TODO - Check list elements webTestClient .mutateWith(csrf()) .mutateWith(mockJwt().jwt { it.subject(clientName) }) .put() - .uri("/order") .bodyValue(testPayload) .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus().isOk + .expectBody() + .consumeWith { response -> + val products = response.responseBody?.productLine + products?.map { + assertThat(testPayload.productLine.contains(it)) + } + } } @Test @@ -225,7 +240,6 @@ class OrderControllerTest( .mutateWith(csrf()) .mutateWith(mockJwt().jwt { it.subject(clientName) }) .put() - .uri("/order") .bodyValue(testUpdatePayload) .accept(MediaType.APPLICATION_JSON) .exchange() @@ -307,8 +321,9 @@ class OrderControllerTest( callbackUrl = "callbackUrl" ) + // dop = Duplicate Order Payload // Will exist in the database - private val duplicateOrderPayload = + private val dop = ApiOrderPayload( orderId = "order-123456", hostName = HostName.AXIELL, @@ -332,7 +347,7 @@ class OrderControllerTest( fun populateDb() { // Make sure we start with clean DB instance for each test runBlocking { - repository.deleteAll().then(repository.save(duplicateOrderPayload.toOrder())).awaitSingle() + repository.deleteAll().then(repository.save(dop.toOrder())).awaitSingle() } } } From 2f917cecc00fd5e90392f19bc42aa1aca16e99e4 Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Thu, 5 Sep 2024 09:23:08 +0200 Subject: [PATCH 4/6] Finalize tests Fix second DELETE test and handle merge from main --- .../order/controller/OrderControllerTest.kt | 46 +++++++------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt index 0bbf21a1..fb9c3ed1 100644 --- a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt @@ -247,33 +247,6 @@ class OrderControllerTest( } } - // FIXME - use delete endpoint when merged into main - @Test - fun `deleteOrder when valid deletes order`() { -// webTestClient -// .mutateWith(csrf()) -// .mutateWith(mockJwt().jwt { it.subject(clientName) }) -// .delete() -// .exchange() -// .expectStatus().is2xxSuccessful - assertThat(true) - } - - // FIXME - use delete endpoint when merged into main - @Test - fun `deleteOrder handles synq error`() { -// coEvery { -// synqOrderService.createOrder(any()) -// } returns ResponseEntity.badRequest().build() -// webTestClient -// .mutateWith(csrf()) -// .mutateWith(mockJwt().jwt { it.subject(clientName) }) -// .delete() -// .exchange() -// .expectStatus().is5xxServerError - assertThat(true) - } - @Test fun `deleteOrder with valid data deletes order`() = runTest { @@ -285,16 +258,31 @@ class OrderControllerTest( .mutateWith(csrf()) .mutateWith(mockJwt().jwt { it.subject("axiell") }) .delete() - .uri("/${duplicateOrderPayload.hostName}/${duplicateOrderPayload.hostOrderId}") + .uri("/${dop.hostName}/${dop.hostOrderId}") .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus().isOk - val order = repository.findByHostNameAndHostOrderId(duplicateOrderPayload.hostName, duplicateOrderPayload.hostOrderId).awaitSingleOrNull() + val order = repository.findByHostNameAndHostOrderId(dop.hostName, dop.hostOrderId).awaitSingleOrNull() assertThat(order).isNull() } + @Test + fun `deleteOrder handles synq error`() { + coEvery { + synqOrderService.deleteOrder(any(), any()) + } returns ResponseEntity.internalServerError().build() + webTestClient + .mutateWith(csrf()) + .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .delete() + .uri("/${dop.hostName}/${dop.hostOrderId}") + .exchange() + .expectStatus().is5xxServerError + assertThat(true) + } + // ///////////////////////////////////////////////////////////////////////////// // //////////////////////////////// Test Help ////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////// From 526985288aaa038f19d5994401cb053ee598077a Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Fri, 6 Sep 2024 08:19:51 +0200 Subject: [PATCH 5/6] Unify URI handling --- .../no/nb/mlt/wls/order/controller/OrderControllerTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt index fb9c3ed1..045a36d3 100644 --- a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt @@ -258,7 +258,7 @@ class OrderControllerTest( .mutateWith(csrf()) .mutateWith(mockJwt().jwt { it.subject("axiell") }) .delete() - .uri("/${dop.hostName}/${dop.hostOrderId}") + .uri("/{hostName}/{hostOrderId}") .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus().isOk @@ -277,7 +277,7 @@ class OrderControllerTest( .mutateWith(csrf()) .mutateWith(mockJwt().jwt { it.subject(clientName) }) .delete() - .uri("/${dop.hostName}/${dop.hostOrderId}") + .uri("/{hostName}/{hostOrderId}", dop.hostName, dop.hostOrderId) .exchange() .expectStatus().is5xxServerError assertThat(true) From e2be66bcc4aab7952a4a5f2b3039a9fbb0b8ef7c Mon Sep 17 00:00:00 2001 From: Noah Bjerkli Aanonli Date: Fri, 6 Sep 2024 08:59:18 +0200 Subject: [PATCH 6/6] Change test naming scheme, updates comments - Remove abbreviations for test payloads - clientName -> client --- .../order/controller/OrderControllerTest.kt | 63 +++++++++-------- .../mlt/wls/order/service/OrderServiceTest.kt | 16 ++--- .../controller/ProductControllerTest.kt | 8 ++- .../wls/product/service/ProductServiceTest.kt | 69 ++++++++++++------- 4 files changed, 92 insertions(+), 64 deletions(-) diff --git a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt index 045a36d3..8852b950 100644 --- a/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/order/controller/OrderControllerTest.kt @@ -59,7 +59,7 @@ class OrderControllerTest( private lateinit var webTestClient: WebTestClient - val clientName: String = HostName.AXIELL.name + val client: String = HostName.AXIELL.name @BeforeEach fun setUp() { @@ -83,7 +83,7 @@ class OrderControllerTest( webTestClient .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .mutateWith(mockJwt().jwt { it.subject(client) }) .post() .accept(MediaType.APPLICATION_JSON) .bodyValue(testOrderPayload) @@ -102,17 +102,17 @@ class OrderControllerTest( fun `createOrder with duplicate payload returns OK`() { webTestClient .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .mutateWith(mockJwt().jwt { it.subject(client) }) .post() .accept(MediaType.APPLICATION_JSON) - .bodyValue(dop) + .bodyValue(duplicateOrderPayload) .exchange() .expectStatus().isOk .expectBody() .consumeWith { response -> - assertThat(response.responseBody?.hostOrderId).isEqualTo(dop.hostOrderId) - assertThat(response.responseBody?.hostName).isEqualTo(dop.hostName) - assertThat(response.responseBody?.productLine).isEqualTo(dop.productLine) + assertThat(response.responseBody?.hostOrderId).isEqualTo(duplicateOrderPayload.hostOrderId) + assertThat(response.responseBody?.hostName).isEqualTo(duplicateOrderPayload.hostName) + assertThat(response.responseBody?.productLine).isEqualTo(duplicateOrderPayload.productLine) } } @@ -120,17 +120,17 @@ class OrderControllerTest( fun `createOrder payload with different data but same ID returns DB entry`() { webTestClient .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .mutateWith(mockJwt().jwt { it.subject(client) }) .post() .accept(MediaType.APPLICATION_JSON) .bodyValue( - dop.copy(productLine = listOf(ProductLine("AAAAAAAAA", OrderLineStatus.PICKED))) + duplicateOrderPayload.copy(productLine = listOf(ProductLine("AAAAAAAAA", OrderLineStatus.PICKED))) ) .exchange() .expectStatus().isOk .expectBody() .consumeWith { response -> - assertThat(response.responseBody?.productLine).isEqualTo(dop.productLine) + assertThat(response.responseBody?.productLine).isEqualTo(duplicateOrderPayload.productLine) } } @@ -142,7 +142,7 @@ class OrderControllerTest( webTestClient .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .mutateWith(mockJwt().jwt { it.subject(client) }) .post() .accept(MediaType.APPLICATION_JSON) .bodyValue(testOrderPayload) @@ -159,7 +159,7 @@ class OrderControllerTest( webTestClient .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .mutateWith(mockJwt().jwt { it.subject(client) }) .post() .accept(MediaType.APPLICATION_JSON) .bodyValue(testOrderPayload) @@ -167,21 +167,21 @@ class OrderControllerTest( .expectStatus().is5xxServerError } - // TODO - Should this endpoint really be returning Orders directly? + // FIXME - Endpoint should be returning DTO instead of direct Orders @Test fun `getOrder returns the order`() { webTestClient .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .mutateWith(mockJwt().jwt { it.subject(client) }) .get() - .uri("/{hostName}/{hostOrderId}", dop.hostName, dop.hostOrderId) + .uri("/{hostName}/{hostOrderId}", duplicateOrderPayload.hostName, duplicateOrderPayload.hostOrderId) .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus().isOk .expectBody(Order::class.java) .consumeWith { response -> - assertThat(response?.responseBody?.hostOrderId.equals(dop.hostOrderId)) - assertThat(response?.responseBody?.status?.equals(dop.status)) + assertThat(response?.responseBody?.hostOrderId.equals(duplicateOrderPayload.hostOrderId)) + assertThat(response?.responseBody?.status?.equals(duplicateOrderPayload.status)) } } @@ -191,7 +191,7 @@ class OrderControllerTest( .mutateWith(csrf()) .mutateWith(mockJwt().jwt { it.subject("ALMA") }) .get() - .uri("/{hostName}/{hostOrderId}", dop.hostName, dop.hostOrderId) + .uri("/{hostName}/{hostOrderId}", duplicateOrderPayload.hostName, duplicateOrderPayload.hostOrderId) .exchange() .expectStatus().isForbidden } @@ -203,7 +203,7 @@ class OrderControllerTest( } returns ResponseEntity.ok().build() val testPayload = - dop.toOrder().toUpdateOrderPayload() + duplicateOrderPayload.toOrder().toUpdateOrderPayload() .copy( productLine = listOf( @@ -214,7 +214,7 @@ class OrderControllerTest( webTestClient .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .mutateWith(mockJwt().jwt { it.subject(client) }) .put() .bodyValue(testPayload) .accept(MediaType.APPLICATION_JSON) @@ -238,7 +238,7 @@ class OrderControllerTest( webTestClient .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .mutateWith(mockJwt().jwt { it.subject(client) }) .put() .bodyValue(testUpdatePayload) .accept(MediaType.APPLICATION_JSON) @@ -258,12 +258,12 @@ class OrderControllerTest( .mutateWith(csrf()) .mutateWith(mockJwt().jwt { it.subject("axiell") }) .delete() - .uri("/{hostName}/{hostOrderId}") + .uri("/{hostName}/{hostOrderId}", duplicateOrderPayload.hostName, duplicateOrderPayload.hostOrderId) .accept(MediaType.APPLICATION_JSON) .exchange() .expectStatus().isOk - val order = repository.findByHostNameAndHostOrderId(dop.hostName, dop.hostOrderId).awaitSingleOrNull() + val order = repository.findByHostNameAndHostOrderId(duplicateOrderPayload.hostName, duplicateOrderPayload.hostOrderId).awaitSingleOrNull() assertThat(order).isNull() } @@ -275,9 +275,9 @@ class OrderControllerTest( } returns ResponseEntity.internalServerError().build() webTestClient .mutateWith(csrf()) - .mutateWith(mockJwt().jwt { it.subject(clientName) }) + .mutateWith(mockJwt().jwt { it.subject(client) }) .delete() - .uri("/{hostName}/{hostOrderId}", dop.hostName, dop.hostOrderId) + .uri("/{hostName}/{hostOrderId}", duplicateOrderPayload.hostName, duplicateOrderPayload.hostOrderId) .exchange() .expectStatus().is5xxServerError assertThat(true) @@ -287,7 +287,9 @@ class OrderControllerTest( // //////////////////////////////// Test Help ////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////// - // Will be used in most tests + /** + * Payload which is used in most tests + */ private val testOrderPayload = ApiOrderPayload( orderId = "axiell-order-69", @@ -309,9 +311,10 @@ class OrderControllerTest( callbackUrl = "callbackUrl" ) - // dop = Duplicate Order Payload - // Will exist in the database - private val dop = + /** + * Payload which will exist in the database + */ + private val duplicateOrderPayload = ApiOrderPayload( orderId = "order-123456", hostName = HostName.AXIELL, @@ -335,7 +338,7 @@ class OrderControllerTest( fun populateDb() { // Make sure we start with clean DB instance for each test runBlocking { - repository.deleteAll().then(repository.save(dop.toOrder())).awaitSingle() + repository.deleteAll().then(repository.save(duplicateOrderPayload.toOrder())).awaitSingle() } } } diff --git a/src/test/kotlin/no/nb/mlt/wls/order/service/OrderServiceTest.kt b/src/test/kotlin/no/nb/mlt/wls/order/service/OrderServiceTest.kt index c4d7dfbf..297c3f3e 100644 --- a/src/test/kotlin/no/nb/mlt/wls/order/service/OrderServiceTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/order/service/OrderServiceTest.kt @@ -120,11 +120,11 @@ class OrderServiceTest { @Test fun `update existing order with no errors returns ok`() { runTest { - every { db.findByHostNameAndHostOrderId(uop.hostName, uop.hostOrderId) } returns Mono.just(op.toOrder()) + every { db.findByHostNameAndHostOrderId(updateOrderPayload.hostName, updateOrderPayload.hostOrderId) } returns Mono.just(op.toOrder()) coEvery { synq.updateOrder(any()) } returns ResponseEntity.ok().build() every { db.save(any()) } returns Mono.just(op.toOrder()) - assertThat(cut.updateOrder(uop, client).statusCode.is2xxSuccessful) + assertThat(cut.updateOrder(updateOrderPayload, client).statusCode.is2xxSuccessful) } } @@ -134,7 +134,7 @@ class OrderServiceTest { assertThatExceptionOfType(ResponseStatusException::class.java).isThrownBy { runTest { - cut.updateOrder(uop, client) + cut.updateOrder(updateOrderPayload, client) } }.withMessageContaining("does not exist") } @@ -149,7 +149,7 @@ class OrderServiceTest { assertThatExceptionOfType(ResponseStatusException::class.java).isThrownBy { runTest { - cut.updateOrder(uop, client) + cut.updateOrder(updateOrderPayload, client) } }.withMessageContaining("409 CONFLICT") } @@ -158,7 +158,7 @@ class OrderServiceTest { fun `update order which you don't own throws`() { assertThatExceptionOfType(ResponseStatusException::class.java).isThrownBy { runBlocking { - cut.updateOrder(uop, "Alma") + cut.updateOrder(updateOrderPayload, "Alma") } }.withMessageContaining("403 FORBIDDEN") } @@ -170,7 +170,7 @@ class OrderServiceTest { assertThatExceptionOfType(ServerErrorException::class.java).isThrownBy { runTest { - cut.updateOrder(uop, client) + cut.updateOrder(updateOrderPayload, client) } } } @@ -205,9 +205,9 @@ class OrderServiceTest { ) /** - * Used for testing order update functionality (uop = update order payload) + * Used for testing order update functionality */ - private val uop = + private val updateOrderPayload = ApiUpdateOrderPayload( hostName = HostName.AXIELL, hostOrderId = "axiell-order-69", diff --git a/src/test/kotlin/no/nb/mlt/wls/product/controller/ProductControllerTest.kt b/src/test/kotlin/no/nb/mlt/wls/product/controller/ProductControllerTest.kt index 845df6e5..866f12d3 100644 --- a/src/test/kotlin/no/nb/mlt/wls/product/controller/ProductControllerTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/product/controller/ProductControllerTest.kt @@ -169,7 +169,9 @@ class ProductControllerTest( // //////////////////////////////// Test Help ////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////// - // Will be used in most tests + /** + * Payload which will be used in most tests + */ private val testProductPayload = ApiProductPayload( hostId = "mlt-420", @@ -183,7 +185,9 @@ class ProductControllerTest( quantity = 1.0 ) - // Will exist in the database + /** + * Payload which will exist in the database + */ private val duplicateProductPayload = ApiProductPayload( hostId = "product-12346", diff --git a/src/test/kotlin/no/nb/mlt/wls/product/service/ProductServiceTest.kt b/src/test/kotlin/no/nb/mlt/wls/product/service/ProductServiceTest.kt index b07d0cf1..3db3fbcf 100644 --- a/src/test/kotlin/no/nb/mlt/wls/product/service/ProductServiceTest.kt +++ b/src/test/kotlin/no/nb/mlt/wls/product/service/ProductServiceTest.kt @@ -43,78 +43,99 @@ class ProductServiceTest { @Test fun `save called with payload missing hostId throws`() { - assertExceptionThrownWithMessage(tpp.copy(hostId = ""), "hostId is required", ServerWebInputException::class.java) - assertExceptionThrownWithMessage(tpp.copy(hostId = "\t\n"), "hostId is required", ServerWebInputException::class.java) - assertExceptionThrownWithMessage(tpp.copy(hostId = " "), "hostId is required", ServerWebInputException::class.java) + assertExceptionThrownWithMessage(testProductPayload.copy(hostId = ""), "hostId is required", ServerWebInputException::class.java) + assertExceptionThrownWithMessage(testProductPayload.copy(hostId = "\t\n"), "hostId is required", ServerWebInputException::class.java) + assertExceptionThrownWithMessage(testProductPayload.copy(hostId = " "), "hostId is required", ServerWebInputException::class.java) } @Test fun `save called with payload missing description throws`() { - assertExceptionThrownWithMessage(tpp.copy(description = ""), "description is required", ServerWebInputException::class.java) - assertExceptionThrownWithMessage(tpp.copy(description = "\t\n"), "description is required", ServerWebInputException::class.java) - assertExceptionThrownWithMessage(tpp.copy(description = " "), "description is required", ServerWebInputException::class.java) + assertExceptionThrownWithMessage(testProductPayload.copy(description = ""), "description is required", ServerWebInputException::class.java) + assertExceptionThrownWithMessage( + testProductPayload.copy(description = "\t\n"), + "description is required", + ServerWebInputException::class.java + ) + assertExceptionThrownWithMessage( + testProductPayload.copy(description = " "), + "description is required", + ServerWebInputException::class.java + ) } @Test fun `save called with payload missing productCategory throws`() { - assertExceptionThrownWithMessage(tpp.copy(productCategory = ""), "category is required", ServerWebInputException::class.java) - assertExceptionThrownWithMessage(tpp.copy(productCategory = "\t\n"), "category is required", ServerWebInputException::class.java) - assertExceptionThrownWithMessage(tpp.copy(productCategory = " "), "category is required", ServerWebInputException::class.java) + assertExceptionThrownWithMessage(testProductPayload.copy(productCategory = ""), "category is required", ServerWebInputException::class.java) + assertExceptionThrownWithMessage( + testProductPayload.copy(productCategory = "\t\n"), + "category is required", + ServerWebInputException::class.java + ) + assertExceptionThrownWithMessage( + testProductPayload.copy(productCategory = " "), + "category is required", + ServerWebInputException::class.java + ) } @Test fun `save called with existing product, returns existing product`() = runTest { - every { db.findByHostNameAndHostId(tpp.hostName, tpp.hostId) } returns Mono.just(tpp.toProduct()) + every { + db.findByHostNameAndHostId( + testProductPayload.hostName, + testProductPayload.hostId + ) + } returns Mono.just(testProductPayload.toProduct()) - val response = cut.save(tpp) + val response = cut.save(testProductPayload) - assertThat(response.body).isEqualTo(tpp) + assertThat(response.body).isEqualTo(testProductPayload) assertThat(response.statusCode).isEqualTo(OK) } @Test fun `save called with product that SynQ says exists, returns without a product`() = runTest { - every { db.findByHostNameAndHostId(tpp.hostName, tpp.hostId) } returns Mono.empty() + every { db.findByHostNameAndHostId(testProductPayload.hostName, testProductPayload.hostId) } returns Mono.empty() coEvery { synq.createProduct(any()) } returns ResponseEntity.ok().build() - val response = cut.save(tpp) + val response = cut.save(testProductPayload) assertThat(response.body).isNull() assertThat(response.statusCode).isEqualTo(OK) } @Test fun `save when synq fails handles it gracefully`() { - every { db.findByHostNameAndHostId(tpp.hostName, tpp.hostId) } returns Mono.empty() + every { db.findByHostNameAndHostId(testProductPayload.hostName, testProductPayload.hostId) } returns Mono.empty() coEvery { synq.createProduct(any()) } throws ServerErrorException( "Failed to create product in SynQ, the storage system responded with error code: '420' and error text: 'Blaze it LMAO'", Exception("420 Blaze it") ) - assertExceptionThrownWithMessage(tpp, "error code: '420' and error text: 'Blaze it LMAO'", ServerErrorException::class.java) + assertExceptionThrownWithMessage(testProductPayload, "error code: '420' and error text: 'Blaze it LMAO'", ServerErrorException::class.java) } @Suppress("ReactiveStreamsUnusedPublisher") @Test fun `save when DB fails handles it gracefully`() { - every { db.findByHostNameAndHostId(tpp.hostName, tpp.hostId) } returns Mono.error(TimeoutException()) + every { db.findByHostNameAndHostId(testProductPayload.hostName, testProductPayload.hostId) } returns Mono.error(TimeoutException()) coEvery { synq.createProduct(any()) } returns ResponseEntity.created(URI.create("")).build() every { db.save(any()) } returns Mono.error(Exception("DB is down")) - assertExceptionThrownWithMessage(tpp, "Failed to save product in the database", ServerErrorException::class.java) + assertExceptionThrownWithMessage(testProductPayload, "Failed to save product in the database", ServerErrorException::class.java) } @Test fun `save with no errors returns created product`() = runTest { - every { db.findByHostNameAndHostId(tpp.hostName, tpp.hostId) } returns Mono.empty() + every { db.findByHostNameAndHostId(testProductPayload.hostName, testProductPayload.hostId) } returns Mono.empty() coEvery { synq.createProduct(any()) } returns ResponseEntity.created(URI.create("")).build() - every { db.save(any()) } returns Mono.just(tpp.toProduct()) + every { db.save(any()) } returns Mono.just(testProductPayload.toProduct()) - val response = cut.save(tpp) - val cleanedProduct = tpp.copy(quantity = 0.0, location = null) + val response = cut.save(testProductPayload) + val cleanedProduct = testProductPayload.copy(quantity = 0.0, location = null) assertThat(response.body).isEqualTo(cleanedProduct) assertThat(response.statusCode).isEqualTo(CREATED) @@ -124,8 +145,8 @@ class ProductServiceTest { // //////////////////////////////// Test Help ////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////// - // Will be used in most tests (tpp = test product payload) - private val tpp = + // Will be used in most tests + private val testProductPayload = ApiProductPayload( hostId = "mlt-420", hostName = HostName.AXIELL,