From 53db4408e2c51e863ff07aebd570e03a1f0bc9bf Mon Sep 17 00:00:00 2001 From: Swordsteel Date: Wed, 5 Mar 2025 22:17:07 +0100 Subject: [PATCH] update get type(s) for pagination and filter - update TypesEndpoint for all new endpoints - update application to use properties for sql script - update types controller - update types.http for all types of types calls - update test mocking for service - update getTypes to use filter, page, and show in TypesController - add validation dependency - update unit test for uuid assertion from test library in - remove UUIDAssert.kt - update IdentityControllerTest - update MappingKtTest - update NodeControllerTest - update TypeControllerTest - update TypesControllerTest - add test library dependency - update getTypes to handle filter limit and offset in TypeService - update TypeRepository - add findAllContaining with filter, limit and offset - add findAll with limit and offset - update type database with specific name key - split Type and Types --- build.gradle.kts | 2 + http/type.http | 4 - http/types.http | 17 ++ sql/002-types.sql | 6 + sql/initial/002-types.sql | 9 +- .../ltd/hlaeja/controller/TypeEndpoint.kt | 20 +- .../ltd/hlaeja/controller/TypesEndpoint.kt | 210 ++++++++++++++++++ .../resources/application.yml | 7 + .../resources/postgres/data.sql | 8 +- .../resources/postgres/reset.sql | 6 +- .../ltd/hlaeja/controller/TypeController.kt | 6 - .../ltd/hlaeja/controller/TypesController.kt | 36 +++ .../ltd/hlaeja/repository/TypeRepository.kt | 20 +- .../kotlin/ltd/hlaeja/service/TypeService.kt | 9 +- .../kotlin/ltd/hlaeja/assertj/UUIDAssert.kt | 15 -- .../controller/IdentityControllerTest.kt | 9 +- .../hlaeja/controller/NodeControllerTest.kt | 8 +- .../hlaeja/controller/TypeControllerTest.kt | 25 +-- .../hlaeja/controller/TypesControllerTest.kt | 49 ++++ .../ltd/hlaeja/service/TypeServiceTest.kt | 20 +- .../kotlin/ltd/hlaeja/util/MappingKtTest.kt | 18 +- 21 files changed, 407 insertions(+), 97 deletions(-) create mode 100644 http/types.http create mode 100644 sql/002-types.sql create mode 100644 src/integration-test/kotlin/ltd/hlaeja/controller/TypesEndpoint.kt create mode 100644 src/main/kotlin/ltd/hlaeja/controller/TypesController.kt delete mode 100644 src/test/kotlin/ltd/hlaeja/assertj/UUIDAssert.kt create mode 100644 src/test/kotlin/ltd/hlaeja/controller/TypesControllerTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index 0624103..283ebd1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,12 +16,14 @@ dependencies { implementation(hlaeja.library.jwt) implementation(hlaeja.springboot.starter.actuator) implementation(hlaeja.springboot.starter.r2dbc) + implementation(hlaeja.springboot.starter.validation) implementation(hlaeja.springboot.starter.webflux) runtimeOnly(hlaeja.postgresql) runtimeOnly(hlaeja.postgresql.r2dbc) testImplementation(hlaeja.assertj.core) + testImplementation(hlaeja.library.test) testImplementation(hlaeja.mockk) testImplementation(hlaeja.projectreactor.reactor.test) testImplementation(hlaeja.kotlin.test.junit5) diff --git a/http/type.http b/http/type.http index b307552..532bd1c 100644 --- a/http/type.http +++ b/http/type.http @@ -1,7 +1,3 @@ -### let all types -GET {{hostname}}/types - - ### add type by name POST {{hostname}}/type Content-Type: application/json diff --git a/http/types.http b/http/types.http new file mode 100644 index 0000000..4fcd4f2 --- /dev/null +++ b/http/types.http @@ -0,0 +1,17 @@ +### get all types +GET {{hostname}}/types + +### get all types +GET {{hostname}}/types/page-1 + +### get all types +GET {{hostname}}/types/page-1/show-2 + +### get all types +GET {{hostname}}/types/filter-{filter} + +### get all types +GET {{hostname}}/types/filter-{filter}/page-1 + +### get all types +GET {{hostname}}/types/filter-{filter}/page-1/show-2 diff --git a/sql/002-types.sql b/sql/002-types.sql new file mode 100644 index 0000000..1eca666 --- /dev/null +++ b/sql/002-types.sql @@ -0,0 +1,6 @@ +-- make name index unique order by name + +DROP INDEX IF EXISTS types_name_key; + +CREATE UNIQUE INDEX IF NOT EXISTS types_name_key + ON types (name ASC); diff --git a/sql/initial/002-types.sql b/sql/initial/002-types.sql index 235788d..8024ff0 100644 --- a/sql/initial/002-types.sql +++ b/sql/initial/002-types.sql @@ -3,15 +3,20 @@ CREATE TABLE IF NOT EXISTS public.types ( - id UUID DEFAULT gen_uuid_v7(), + id UUID DEFAULT gen_uuid_v7(), timestamp timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP, - name VARCHAR(50) UNIQUE NOT NULL, + name VARCHAR(50) NOT NULL, CONSTRAINT pk_contact_types PRIMARY KEY (id) ); ALTER TABLE IF EXISTS public.types OWNER to role_administrator; +-- Index: types_name_key +-- DROP INDEX IF EXISTS types_name_key; + +CREATE UNIQUE INDEX IF NOT EXISTS types_name_key + ON types (name ASC); -- Revoke all permissions from existing roles REVOKE ALL ON TABLE public.types FROM role_administrator, role_maintainer, role_support, role_service; diff --git a/src/integration-test/kotlin/ltd/hlaeja/controller/TypeEndpoint.kt b/src/integration-test/kotlin/ltd/hlaeja/controller/TypeEndpoint.kt index 1fc0be7..affab1b 100644 --- a/src/integration-test/kotlin/ltd/hlaeja/controller/TypeEndpoint.kt +++ b/src/integration-test/kotlin/ltd/hlaeja/controller/TypeEndpoint.kt @@ -2,7 +2,6 @@ package ltd.hlaeja.controller import ltd.hlaeja.library.deviceRegistry.Type import ltd.hlaeja.test.container.PostgresContainer -import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.SoftAssertions import org.assertj.core.api.junit.jupiter.InjectSoftAssertions import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension @@ -35,23 +34,6 @@ class TypeEndpoint { webClient = WebTestClient.bindToServer().baseUrl("http://localhost:$port").build() } - @Nested - inner class GetTypes { - - @Test - fun `get types`() { - // when - val result = webClient.get().uri("/types").exchange() - - // then - result.expectStatus().isOk() - .expectBody>() - .consumeWith { - assertThat(it.responseBody?.size).isEqualTo(5) - } - } - } - @Nested inner class CreateType { @@ -80,7 +62,7 @@ class TypeEndpoint { fun `added type - fail name take`() { // given val request = Type.Request( - name = "Thing 1", + name = "Thing 1 v1", ) // when diff --git a/src/integration-test/kotlin/ltd/hlaeja/controller/TypesEndpoint.kt b/src/integration-test/kotlin/ltd/hlaeja/controller/TypesEndpoint.kt new file mode 100644 index 0000000..1fc5e0b --- /dev/null +++ b/src/integration-test/kotlin/ltd/hlaeja/controller/TypesEndpoint.kt @@ -0,0 +1,210 @@ +package ltd.hlaeja.controller + +import ltd.hlaeja.library.deviceRegistry.Type +import ltd.hlaeja.test.container.PostgresContainer +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.CsvSource +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT +import org.springframework.boot.test.web.server.LocalServerPort +import org.springframework.test.web.reactive.server.WebTestClient +import org.springframework.test.web.reactive.server.expectBody + +@PostgresContainer +@SpringBootTest(webEnvironment = RANDOM_PORT) +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class TypesEndpoint { + + @LocalServerPort + var port: Int = 0 + + lateinit var webClient: WebTestClient + + @BeforeEach + fun setup() { + webClient = WebTestClient.bindToServer().baseUrl("http://localhost:$port").build() + } + + @Test + fun `get types default - success`() { + // when + val result = webClient.get().uri("/types").exchange() + + // then + result.expectStatus().isOk() + .expectBody>() + .consumeWith { + assertThat(it.responseBody?.size).isEqualTo(4) + } + } + + @ParameterizedTest + @CsvSource( + value = [ + "1,4", + "2,0", + ], + ) + fun `get types by page - success`(page: Int, expected: Int) { + // when + val result = webClient.get().uri("/types/page-$page").exchange() + + // then + result.expectStatus().isOk() + .expectBody>() + .consumeWith { + assertThat(it.responseBody?.size).isEqualTo(expected) + } + } + + @Test + fun `get types by pages - fail`() { + // when + val result = webClient.get().uri("/types/page-0").exchange() + + // then + result.expectStatus().isBadRequest + } + + @ParameterizedTest + @CsvSource( + value = [ + "1,2,2", + "2,2,2", + "3,2,0", + ], + ) + fun `get types by page and show - success`(page: Int, show: Int, expected: Int) { + // when + val result = webClient.get().uri("/types/page-$page/show-$show").exchange() + + // then + result.expectStatus().isOk() + .expectBody>() + .consumeWith { + assertThat(it.responseBody?.size).isEqualTo(expected) + } + } + + @ParameterizedTest + @CsvSource( + value = [ + "0,1", + "1,0", + ], + ) + fun `get types by page and show - fail`(page: Int, show: Int) { + // when + val result = webClient.get().uri("/types/page-$page/show-$show").exchange() + + // then + result.expectStatus().isBadRequest + } + + @ParameterizedTest + @CsvSource( + value = [ + "'',4", + "v1,3", + "v2,1", + "v3,0", + ], + ) + fun `get types filter - success`(filter: String, expected: Int) { + // when + val result = webClient.get().uri("/types/filter-$filter").exchange() + + // then + result.expectStatus().isOk() + .expectBody>() + .consumeWith { + assertThat(it.responseBody?.size).isEqualTo(expected) + } + } + + @ParameterizedTest + @CsvSource( + value = [ + "'',1,4", + "'',2,0", + "v1,1,3", + "v1,2,0", + "v2,1,1", + "v2,2,0", + "v3,1,0", + ], + ) + fun `get types by filter and page - success`(filter: String, page: Int, expected: Int) { + // when + val result = webClient.get().uri("/types/filter-$filter/page-$page").exchange() + + // then + result.expectStatus().isOk() + .expectBody>() + .consumeWith { + assertThat(it.responseBody?.size).isEqualTo(expected) + } + } + + @ParameterizedTest + @CsvSource( + value = [ + "'',0", + "v1,0", + ], + ) + fun `get types by filter and page - fail`(filter: String, page: Int) { + // when + val result = webClient.get().uri("/types/filter-$filter/page-$page").exchange() + + // then + result.expectStatus().isBadRequest + } + + @ParameterizedTest + @CsvSource( + value = [ + "'',1,2,2", + "'',2,2,2", + "'',3,2,0", + "v1,1,2,2", + "v1,2,2,1", + "v1,3,2,0", + "v2,1,2,1", + "v2,2,2,0", + "v3,1,2,0", + ], + ) + fun `get types by filter, page and show - success`(filter: String, page: Int, show: Int, expected: Int) { + // when + val result = webClient.get().uri("/types/filter-$filter/page-$page/show-$show").exchange() + + // then + result.expectStatus().isOk() + .expectBody>() + .consumeWith { + assertThat(it.responseBody?.size).isEqualTo(expected) + } + } + + @ParameterizedTest + @CsvSource( + value = [ + "'',1,0", + "'',0,1", + "v1,1,0", + "v1,0,1", + ], + ) + fun `get types by filter, page and show - fail`(filter: String, page: Int, show: Int) { + // when + val result = webClient.get().uri("/types/filter-$filter/page-$page/show-$show").exchange() + + // then + result.expectStatus().isBadRequest + } +} diff --git a/src/integration-test/resources/application.yml b/src/integration-test/resources/application.yml index 32c88c7..7ce3f7d 100644 --- a/src/integration-test/resources/application.yml +++ b/src/integration-test/resources/application.yml @@ -6,3 +6,10 @@ spring: url: r2dbc:postgresql://placeholder username: placeholder password: placeholder + +container: + postgres: + version: postgres:17 + init: postgres/schema.sql + before: postgres/data.sql + after: postgres/reset.sql diff --git a/src/integration-test/resources/postgres/data.sql b/src/integration-test/resources/postgres/data.sql index 93d0123..4ec5c92 100644 --- a/src/integration-test/resources/postgres/data.sql +++ b/src/integration-test/resources/postgres/data.sql @@ -1,9 +1,9 @@ -- Test data INSERT INTO public.types (id, timestamp, name) -VALUES ('00000000-0000-0000-0001-000000000001'::uuid, '2000-01-01 00:00:00.000001 +00:00', 'Thing 1'), - ('00000000-0000-0000-0001-000000000002'::uuid, '2000-01-01 00:00:00.000001 +00:00', 'Thing 2'), - ('00000000-0000-0000-0001-000000000003'::uuid, '2000-01-01 00:00:00.000001 +00:00', 'Thing 3'), - ('00000000-0000-0000-0001-000000000004'::uuid, '2000-01-01 00:00:00.000001 +00:00', 'Thing 4'); +VALUES ('00000000-0000-0000-0001-000000000001'::uuid, '2000-01-01 00:00:00.000001 +00:00', 'Thing 1 v1'), + ('00000000-0000-0000-0001-000000000002'::uuid, '2000-01-01 00:00:00.000001 +00:00', 'Thing 2 v1'), + ('00000000-0000-0000-0001-000000000003'::uuid, '2000-01-01 00:00:00.000001 +00:00', 'Thing 3 v2'), + ('00000000-0000-0000-0001-000000000004'::uuid, '2000-01-01 00:00:00.000001 +00:00', 'Thing 4 v1'); INSERT INTO public.devices (id, timestamp, type) VALUES ('00000000-0000-0000-0002-000000000001'::uuid, '2000-01-01 00:00:00.000001 +00:00', '00000000-0000-0000-0001-000000000001'::uuid), diff --git a/src/integration-test/resources/postgres/reset.sql b/src/integration-test/resources/postgres/reset.sql index ada530d..919c38c 100644 --- a/src/integration-test/resources/postgres/reset.sql +++ b/src/integration-test/resources/postgres/reset.sql @@ -1,8 +1,8 @@ -- Disable triggers on the tables -- Truncate tables -TRUNCATE TABLE types; -TRUNCATE TABLE devices; -TRUNCATE TABLE nodes; +TRUNCATE TABLE nodes CASCADE; +TRUNCATE TABLE devices CASCADE; +TRUNCATE TABLE types CASCADE; -- Enable triggers on the account table diff --git a/src/main/kotlin/ltd/hlaeja/controller/TypeController.kt b/src/main/kotlin/ltd/hlaeja/controller/TypeController.kt index 4b155b4..dd93c8b 100644 --- a/src/main/kotlin/ltd/hlaeja/controller/TypeController.kt +++ b/src/main/kotlin/ltd/hlaeja/controller/TypeController.kt @@ -1,12 +1,9 @@ package ltd.hlaeja.controller -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map import ltd.hlaeja.library.deviceRegistry.Type import ltd.hlaeja.service.TypeService import ltd.hlaeja.util.toTypeEntity import ltd.hlaeja.util.toTypeResponse -import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RestController @@ -16,9 +13,6 @@ class TypeController( private val service: TypeService, ) { - @GetMapping("/types") - fun getTypes(): Flow = service.getTypes().map { it.toTypeResponse() } - @PostMapping("/type") suspend fun addType( @RequestBody register: Type.Request, diff --git a/src/main/kotlin/ltd/hlaeja/controller/TypesController.kt b/src/main/kotlin/ltd/hlaeja/controller/TypesController.kt new file mode 100644 index 0000000..f591326 --- /dev/null +++ b/src/main/kotlin/ltd/hlaeja/controller/TypesController.kt @@ -0,0 +1,36 @@ +package ltd.hlaeja.controller + +import jakarta.validation.constraints.Min +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import ltd.hlaeja.library.deviceRegistry.Type +import ltd.hlaeja.service.TypeService +import ltd.hlaeja.util.toTypeResponse +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RestController + +@RestController +class TypesController( + private val service: TypeService, +) { + companion object { + const val DEFAULT_PAGE: Int = 1 + const val DEFAULT_SIZE: Int = 25 + } + + @GetMapping( + "/types", + "/types/page-{page}", + "/types/page-{page}/show-{show}", + "/types/filter-{filter}", + "/types/filter-{filter}/page-{page}", + "/types/filter-{filter}/page-{page}/show-{show}", + ) + fun getTypes( + @PathVariable(required = false) @Min(1) page: Int = DEFAULT_PAGE, + @PathVariable(required = false) @Min(1) show: Int = DEFAULT_SIZE, + @PathVariable(required = false) filter: String? = null, + ): Flow = service.getTypes((page - 1) * show, show, filter) + .map { it.toTypeResponse() } +} diff --git a/src/main/kotlin/ltd/hlaeja/repository/TypeRepository.kt b/src/main/kotlin/ltd/hlaeja/repository/TypeRepository.kt index 6734468..71b9a18 100644 --- a/src/main/kotlin/ltd/hlaeja/repository/TypeRepository.kt +++ b/src/main/kotlin/ltd/hlaeja/repository/TypeRepository.kt @@ -1,9 +1,27 @@ package ltd.hlaeja.repository import java.util.UUID +import kotlinx.coroutines.flow.Flow import ltd.hlaeja.entity.TypeEntity + +import org.springframework.data.r2dbc.repository.Query import org.springframework.data.repository.kotlin.CoroutineCrudRepository +import org.springframework.data.repository.query.Param import org.springframework.stereotype.Repository @Repository -interface TypeRepository : CoroutineCrudRepository +interface TypeRepository : CoroutineCrudRepository { + + @Query("SELECT * FROM types ORDER BY name LIMIT :limit OFFSET :offset") + fun findAll( + @Param("offset") offset: Int, + @Param("limit") limit: Int, + ): Flow + + @Query("SELECT * FROM types WHERE name ILIKE :filter ORDER BY name LIMIT :limit OFFSET :offset") + fun findAllContaining( + @Param("filter") filter: String, + @Param("offset") offset: Int, + @Param("limit") limit: Int, + ): Flow +} diff --git a/src/main/kotlin/ltd/hlaeja/service/TypeService.kt b/src/main/kotlin/ltd/hlaeja/service/TypeService.kt index 2dc1681..8334c4f 100644 --- a/src/main/kotlin/ltd/hlaeja/service/TypeService.kt +++ b/src/main/kotlin/ltd/hlaeja/service/TypeService.kt @@ -16,7 +16,14 @@ class TypeService( private val typeRepository: TypeRepository, ) { - fun getTypes(): Flow = typeRepository.findAll() + fun getTypes( + page: Int, + show: Int, + filter: String?, + ): Flow = when { + !filter.isNullOrEmpty() -> typeRepository.findAllContaining("%$filter%", page, show) + else -> typeRepository.findAll(page, show) + } suspend fun addType( entity: TypeEntity, diff --git a/src/test/kotlin/ltd/hlaeja/assertj/UUIDAssert.kt b/src/test/kotlin/ltd/hlaeja/assertj/UUIDAssert.kt deleted file mode 100644 index 427c71c..0000000 --- a/src/test/kotlin/ltd/hlaeja/assertj/UUIDAssert.kt +++ /dev/null @@ -1,15 +0,0 @@ -package ltd.hlaeja.assertj - -import java.util.UUID -import org.assertj.core.api.AbstractAssert - -class UUIDAssert(actual: UUID) : AbstractAssert(actual, UUIDAssert::class.java) { - fun isUUID(expected: String): UUIDAssert { - objects.assertEqual(this.info, this.actual, UUID.fromString(expected)) - return this.myself - } -} - -fun assertThat(actual: UUID): UUIDAssert { - return UUIDAssert(actual) -} diff --git a/src/test/kotlin/ltd/hlaeja/controller/IdentityControllerTest.kt b/src/test/kotlin/ltd/hlaeja/controller/IdentityControllerTest.kt index 6c222cf..47e9dfd 100644 --- a/src/test/kotlin/ltd/hlaeja/controller/IdentityControllerTest.kt +++ b/src/test/kotlin/ltd/hlaeja/controller/IdentityControllerTest.kt @@ -8,9 +8,10 @@ import java.time.ZoneId import java.time.ZonedDateTime import java.util.UUID import kotlinx.coroutines.test.runTest -import ltd.hlaeja.assertj.assertThat import ltd.hlaeja.entity.NodeEntity import ltd.hlaeja.service.NodeService +import ltd.hlaeja.test.isEqualToUuid +import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -48,8 +49,8 @@ class IdentityControllerTest { // then coVerify(exactly = 1) { service.getNodeFromDevice(any()) } - assertThat(response.node).isUUID("00000000-0000-0000-0000-000000000001") - assertThat(response.client).isUUID("00000000-0000-0000-0000-000000000002") - assertThat(response.device).isUUID("00000000-0000-0000-0000-000000000003") + assertThat(response.node).isEqualToUuid("00000000-0000-0000-0000-000000000001") + assertThat(response.client).isEqualToUuid("00000000-0000-0000-0000-000000000002") + assertThat(response.device).isEqualToUuid("00000000-0000-0000-0000-000000000003") } } diff --git a/src/test/kotlin/ltd/hlaeja/controller/NodeControllerTest.kt b/src/test/kotlin/ltd/hlaeja/controller/NodeControllerTest.kt index 84e38d1..d53da92 100644 --- a/src/test/kotlin/ltd/hlaeja/controller/NodeControllerTest.kt +++ b/src/test/kotlin/ltd/hlaeja/controller/NodeControllerTest.kt @@ -5,10 +5,10 @@ import io.mockk.coVerify import io.mockk.mockk import java.util.UUID import kotlinx.coroutines.test.runTest -import ltd.hlaeja.assertj.assertThat import ltd.hlaeja.entity.NodeEntity import ltd.hlaeja.library.deviceRegistry.Node import ltd.hlaeja.service.NodeService +import ltd.hlaeja.test.isEqualToUuid import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -42,9 +42,9 @@ class NodeControllerTest { // then coVerify(exactly = 1) { service.addNode(any()) } - assertThat(response.id).isUUID("00000000-0000-0000-0000-000000000003") - assertThat(response.client).isUUID("00000000-0000-0000-0000-000000000001") - assertThat(response.device).isUUID("00000000-0000-0000-0000-000000000002") + assertThat(response.id).isEqualToUuid("00000000-0000-0000-0000-000000000003") + assertThat(response.client).isEqualToUuid("00000000-0000-0000-0000-000000000001") + assertThat(response.device).isEqualToUuid("00000000-0000-0000-0000-000000000002") assertThat(response.name).isEqualTo("test") } } diff --git a/src/test/kotlin/ltd/hlaeja/controller/TypeControllerTest.kt b/src/test/kotlin/ltd/hlaeja/controller/TypeControllerTest.kt index 8aa153d..2355a68 100644 --- a/src/test/kotlin/ltd/hlaeja/controller/TypeControllerTest.kt +++ b/src/test/kotlin/ltd/hlaeja/controller/TypeControllerTest.kt @@ -2,20 +2,16 @@ package ltd.hlaeja.controller import io.mockk.coEvery import io.mockk.coVerify -import io.mockk.every import io.mockk.mockk -import io.mockk.verify import java.time.LocalDateTime import java.time.ZoneId import java.time.ZonedDateTime import java.util.UUID -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.single import kotlinx.coroutines.test.runTest import ltd.hlaeja.entity.TypeEntity import ltd.hlaeja.library.deviceRegistry.Type import ltd.hlaeja.service.TypeService -import ltd.hlaeja.assertj.assertThat +import ltd.hlaeja.test.isEqualToUuid import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -36,22 +32,7 @@ class TypeControllerTest { } @Test - fun `get all types`() = runTest { - // given - every { service.getTypes() } returns flowOf(TypeEntity(id, timestamp, "name")) - - // when - val response = controller.getTypes().single() - - // then - verify(exactly = 1) { service.getTypes() } - - assertThat(response.id).isUUID("00000000-0000-0000-0000-000000000000") - assertThat(response.name).isEqualTo("name") - } - - @Test - fun `add types`() = runTest { + fun `add type`() = runTest { // given val request = Type.Request("name") coEvery { service.addType(any()) } returns TypeEntity(id, timestamp, "name") @@ -62,7 +43,7 @@ class TypeControllerTest { // then coVerify(exactly = 1) { service.addType(any()) } - assertThat(response.id).isUUID("00000000-0000-0000-0000-000000000000") + assertThat(response.id).isEqualToUuid("00000000-0000-0000-0000-000000000000") assertThat(response.name).isEqualTo("name") } } diff --git a/src/test/kotlin/ltd/hlaeja/controller/TypesControllerTest.kt b/src/test/kotlin/ltd/hlaeja/controller/TypesControllerTest.kt new file mode 100644 index 0000000..874d1a3 --- /dev/null +++ b/src/test/kotlin/ltd/hlaeja/controller/TypesControllerTest.kt @@ -0,0 +1,49 @@ +package ltd.hlaeja.controller + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import java.time.LocalDateTime +import java.time.ZoneId +import java.time.ZonedDateTime +import java.util.UUID +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.single +import kotlinx.coroutines.test.runTest +import ltd.hlaeja.entity.TypeEntity +import ltd.hlaeja.service.TypeService +import ltd.hlaeja.test.isEqualToUuid +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class TypesControllerTest { + companion object { + val id = UUID.fromString("00000000-0000-0000-0000-000000000000") + val timestamp = ZonedDateTime.of(LocalDateTime.of(2000, 1, 1, 0, 0, 0, 1), ZoneId.of("UTC")) + } + + val service: TypeService = mockk() + + lateinit var controller: TypesController + + @BeforeEach + fun setUp() { + controller = TypesController(service) + } + + @Test + fun `get all types`() = runTest { + // given + every { service.getTypes(any(), any(), any()) } returns flowOf(TypeEntity(id, timestamp, "name")) + + // when + val response = controller.getTypes().single() + + // then + verify(exactly = 1) { service.getTypes(0, 25, null) } + + assertThat(response.id).isEqualToUuid("00000000-0000-0000-0000-000000000000") + assertThat(response.name).isEqualTo("name") + } +} diff --git a/src/test/kotlin/ltd/hlaeja/service/TypeServiceTest.kt b/src/test/kotlin/ltd/hlaeja/service/TypeServiceTest.kt index 8884bcc..2641c17 100644 --- a/src/test/kotlin/ltd/hlaeja/service/TypeServiceTest.kt +++ b/src/test/kotlin/ltd/hlaeja/service/TypeServiceTest.kt @@ -37,13 +37,27 @@ class TypeServiceTest { @Test fun `get all types`() { // given - every { repository.findAll() } returns flowOf(mockk()) + every { repository.findAll(any(), any()) } returns flowOf(mockk()) // when - service.getTypes() + service.getTypes(1, 10, null) // then - verify(exactly = 1) { repository.findAll() } + verify(exactly = 1) { repository.findAll(1, 10) } + verify(exactly = 0) { repository.findAllContaining(any(), any(), any()) } + } + + @Test + fun `get all types with filter`() { + // given + every { repository.findAllContaining(any(), any(), any()) } returns flowOf(mockk()) + + // when + service.getTypes(1, 10, "abc") + + // then + verify(exactly = 1) { repository.findAllContaining("%abc%", 1, 10) } + verify(exactly = 0) { repository.findAll(any(), any()) } } @Test diff --git a/src/test/kotlin/ltd/hlaeja/util/MappingKtTest.kt b/src/test/kotlin/ltd/hlaeja/util/MappingKtTest.kt index 6ee5f9b..f04b40c 100644 --- a/src/test/kotlin/ltd/hlaeja/util/MappingKtTest.kt +++ b/src/test/kotlin/ltd/hlaeja/util/MappingKtTest.kt @@ -8,11 +8,11 @@ import java.time.ZoneId import java.time.ZonedDateTime import java.util.UUID import kotlin.test.Test -import ltd.hlaeja.assertj.assertThat import ltd.hlaeja.entity.NodeEntity import ltd.hlaeja.entity.TypeEntity -import ltd.hlaeja.library.deviceRegistry.Type import ltd.hlaeja.library.deviceRegistry.Node +import ltd.hlaeja.library.deviceRegistry.Type +import ltd.hlaeja.test.isEqualToUuid import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertThrows @@ -68,7 +68,7 @@ class MappingKtTest { val response = entity.toTypeResponse() // then - assertThat(response.id).isUUID("00000000-0000-0000-0000-000000000000") + assertThat(response.id).isEqualToUuid("00000000-0000-0000-0000-000000000000") assertThat(response.name).isEqualTo("name") } @@ -119,9 +119,9 @@ class MappingKtTest { val result = entity.toNodeResponse() // then - assertThat(result.id).isUUID("00000000-0000-0000-0000-000000000001") - assertThat(result.client).isUUID("00000000-0000-0000-0000-000000000002") - assertThat(result.device).isUUID("00000000-0000-0000-0000-000000000003") + assertThat(result.id).isEqualToUuid("00000000-0000-0000-0000-000000000001") + assertThat(result.client).isEqualToUuid("00000000-0000-0000-0000-000000000002") + assertThat(result.device).isEqualToUuid("00000000-0000-0000-0000-000000000003") assertThat(result.name).isEqualTo("test") } @@ -164,9 +164,9 @@ class MappingKtTest { val result = entity.toIdentityResponse() // then - assertThat(result.node).isUUID("00000000-0000-0000-0000-000000000001") - assertThat(result.client).isUUID("00000000-0000-0000-0000-000000000002") - assertThat(result.device).isUUID("00000000-0000-0000-0000-000000000003") + assertThat(result.node).isEqualToUuid("00000000-0000-0000-0000-000000000001") + assertThat(result.client).isEqualToUuid("00000000-0000-0000-0000-000000000002") + assertThat(result.device).isEqualToUuid("00000000-0000-0000-0000-000000000003") } @Test