update project

This commit is contained in:
2025-07-29 09:51:49 +02:00
committed by swordsteel
parent cf8ca86c32
commit 5d735ccfbe
17 changed files with 25 additions and 22 deletions

View File

@@ -0,0 +1,10 @@
package ltd.hlaeja
@org.springframework.boot.test.context.SpringBootTest
class ApplicationTests {
@org.junit.jupiter.api.Test
fun contextLoads() {
// place holder
}
}

View File

@@ -0,0 +1,96 @@
package ltd.hlaeja.controller
import java.util.UUID
import ltd.hlaeja.library.deviceRegistry.Device
import ltd.hlaeja.test.compareToFile
import ltd.hlaeja.test.container.PostgresContainer
import ltd.hlaeja.test.isEqualToUuid
import org.assertj.core.api.SoftAssertions
import org.assertj.core.api.junit.jupiter.InjectSoftAssertions
import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
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)
@ExtendWith(SoftAssertionsExtension::class)
class DeviceEndpoint {
@InjectSoftAssertions
lateinit var softly: SoftAssertions
@LocalServerPort
var port: Int = 0
lateinit var webClient: WebTestClient
@BeforeEach
fun setup() {
webClient = WebTestClient.bindToServer().baseUrl("http://localhost:$port").build()
}
@Nested
inner class GetDevice {
@Test
fun `get account - success valid uuid`() {
// given
val uuid = UUID.fromString("00000000-0000-0000-0002-000000000001")
// when
val result = webClient.get().uri("/device-$uuid").exchange()
// then
result.expectStatus().isOk()
.expectBody<Device.Response>()
.consumeWith {
softly.assertThat(it.responseBody?.id).isEqualTo(uuid)
softly.assertThat(it.responseBody?.type).isEqualToUuid("00000000-0000-0000-0001-000000000001")
softly.assertThat(it.responseBody?.identity).compareToFile("identity/first-device.data")
}
}
@Test
fun `get account - fail non-existent uuid`() {
// given
val uuid = UUID.fromString("00000000-0000-0000-0002-000000000000")
// when
val result = webClient.get().uri("/device-$uuid").exchange()
// then
result.expectStatus().isNotFound
}
}
@Nested
inner class CreateDevice {
@Test
fun `added device - success`() {
// given
val uuid = UUID.fromString("00000000-0000-0000-0001-000000000003")
val request = Device.Request(
type = uuid,
)
// when
val result = webClient.post().uri("/device").bodyValue(request).exchange()
// then
result.expectStatus().isOk()
.expectBody<Device.Response>()
.consumeWith {
softly.assertThat(it.responseBody?.id?.version()).isEqualTo(7)
softly.assertThat(it.responseBody?.type).isEqualTo(uuid)
}
}
}
}

View File

@@ -0,0 +1,79 @@
package ltd.hlaeja.controller
import java.util.UUID
import ltd.hlaeja.library.deviceRegistry.Identity
import ltd.hlaeja.test.container.PostgresContainer
import ltd.hlaeja.test.isEqualToUuid
import org.assertj.core.api.SoftAssertions
import org.assertj.core.api.junit.jupiter.InjectSoftAssertions
import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
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)
@ExtendWith(SoftAssertionsExtension::class)
class IdentityEndpoint {
@InjectSoftAssertions
lateinit var softly: SoftAssertions
@LocalServerPort
var port: Int = 0
lateinit var webClient: WebTestClient
@BeforeEach
fun setup() {
webClient = WebTestClient.bindToServer().baseUrl("http://localhost:$port").build()
}
@Test
fun `get identity - success`() {
// given
val device = UUID.fromString("00000000-0000-0000-0002-000000000002")
// when
val result = webClient.get().uri("/identity/device-$device").exchange()
// then
result.expectStatus()
.isOk
.expectBody<Identity.Response>()
.consumeWith {
softly.assertThat(it.responseBody?.client).isEqualToUuid("00000000-0000-0000-0000-000000000000")
softly.assertThat(it.responseBody?.node).isEqualToUuid("00000000-0000-0000-0003-000000000001")
softly.assertThat(it.responseBody?.device).isEqualTo(device)
}
}
@Test
fun `get identity - fail device exist but not a node`() {
// given
val device = UUID.fromString("00000000-0000-0000-0002-000000000001")
// when
val result = webClient.get().uri("/identity/device-$device").exchange()
// then
result.expectStatus().isNotFound
}
@Test
fun `get identity - fail device dont exist`() {
// given
val device = UUID.fromString("00000000-0000-0000-0002-000000000000")
// when
val result = webClient.get().uri("/identity/device-$device").exchange()
// then
result.expectStatus().isNotFound
}
}

View File

@@ -0,0 +1,81 @@
package ltd.hlaeja.controller
import java.util.UUID
import ltd.hlaeja.library.deviceRegistry.Node
import ltd.hlaeja.test.container.PostgresContainer
import org.assertj.core.api.SoftAssertions
import org.assertj.core.api.junit.jupiter.InjectSoftAssertions
import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
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)
@ExtendWith(SoftAssertionsExtension::class)
class NodeEndpoint {
@InjectSoftAssertions
lateinit var softly: SoftAssertions
@LocalServerPort
var port: Int = 0
lateinit var webClient: WebTestClient
@BeforeEach
fun setup() {
webClient = WebTestClient.bindToServer().baseUrl("http://localhost:$port").build()
}
@Test
fun `added node - success`() {
// given
val name = "Node 4"
val device = UUID.fromString("00000000-0000-0000-0002-000000000001")
val client = UUID.fromString("00000000-0000-0000-0000-000000000000")
val request = Node.Request(device = device, client = client, name = name)
// when
val result = webClient.post().uri("/node").bodyValue(request).exchange()
// then
result.expectStatus()
.isCreated
.expectBody<Node.Response>()
.consumeWith {
softly.assertThat(it.responseBody?.id?.version()).isEqualTo(7)
softly.assertThat(it.responseBody?.device).isEqualTo(device)
softly.assertThat(it.responseBody?.client).isEqualTo(client)
softly.assertThat(it.responseBody?.name).isEqualTo(name)
}
}
@ParameterizedTest
@CsvSource(
// not a device
"'00000000-0000-0000-0002-000000000000'",
// already a node
"'00000000-0000-0000-0002-000000000002'",
)
fun `added node - fail`(device: String) {
// given
val name = "Node 5"
val client = UUID.fromString("00000000-0000-0000-0000-000000000000")
val request = Node.Request(device = UUID.fromString(device), client = client, name = name)
// when
val result = webClient.post().uri("/node").bodyValue(request).exchange()
// then
result.expectStatus()
.isBadRequest
}
}

View File

@@ -0,0 +1,291 @@
package ltd.hlaeja.controller
import ltd.hlaeja.library.deviceRegistry.Type
import ltd.hlaeja.test.container.PostgresContainer
import ltd.hlaeja.test.isEqualToUuid
import org.assertj.core.api.SoftAssertions
import org.assertj.core.api.junit.jupiter.InjectSoftAssertions
import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
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.http.HttpStatus.ACCEPTED
import org.springframework.http.HttpStatus.CONFLICT
import org.springframework.http.MediaType.APPLICATION_JSON
import org.springframework.test.web.reactive.server.WebTestClient
import org.springframework.test.web.reactive.server.expectBody
@PostgresContainer
@SpringBootTest(webEnvironment = RANDOM_PORT)
@ExtendWith(SoftAssertionsExtension::class)
class TypeEndpoint {
@InjectSoftAssertions
lateinit var softly: SoftAssertions
@LocalServerPort
var port: Int = 0
lateinit var webClient: WebTestClient
@BeforeEach
fun setup() {
webClient = WebTestClient.bindToServer().baseUrl("http://localhost:$port").build()
}
@Nested
inner class CreateType {
@Test
fun `added type - success`() {
// given
val name = "Thing 5 v1"
val description = "Thing 5 description"
val request = Type.Request(
name = name,
description = description,
)
// when
val result = webClient.post().uri("/type").bodyValue(request).exchange()
// then
result.expectStatus()
.isCreated
.expectBody<Type.Response>()
.consumeWith {
softly.assertThat(it.responseBody?.id?.version()).isEqualTo(7)
softly.assertThat(it.responseBody?.name).isEqualTo(name)
softly.assertThat(it.responseBody?.description).isEqualTo(description)
}
}
@Test
fun `added type - fail name take`() {
// given
val request = Type.Request(
name = "Thing 1 v1",
description = "Thing 1 description",
)
// when
val result = webClient.post().uri("/type").bodyValue(request).exchange()
// then
result.expectStatus().isEqualTo(CONFLICT)
}
@ParameterizedTest
@CsvSource(
value = [
"{}",
"{'name': 'Thing 0 v1'}",
"{'description': 'Thing 0 description'}",
],
)
fun `added type - fail bad request`(jsonRequest: String) {
// when
val result = webClient.post()
.uri("/type")
.contentType(APPLICATION_JSON) // Set Content-Type header
.bodyValue(jsonRequest) // Send raw JSON string
.exchange()
// then
result.expectStatus().isBadRequest
}
}
@Nested
inner class GetType {
@Test
fun `added type - success`() {
// when
val result = webClient.get().uri("/type-00000000-0000-0000-0001-000000000001").exchange()
// then
result.expectStatus()
.isOk
.expectBody<Type.Response>()
.consumeWith {
softly.assertThat(it.responseBody?.id).isEqualToUuid("00000000-0000-0000-0001-000000000001")
softly.assertThat(it.responseBody?.name).isEqualTo("Thing 1 v1")
softly.assertThat(it.responseBody?.description).isEqualTo("Thing 1 description")
}
}
@Test
fun `get type - fail not found`() {
// when
val result = webClient.get().uri("/type-00000000-0000-0000-0000-000000000000").exchange()
// then
result.expectStatus().isNotFound
}
@ParameterizedTest
@CsvSource(
value = [
"zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
"00000000000000000000000000000000",
"0",
],
)
fun `get type - fail bad request`(uuid: String) {
// when
val result = webClient.get().uri("/type-$uuid").exchange()
// then
result.expectStatus().isBadRequest
}
}
@Nested
inner class UpdateType {
@ParameterizedTest
@CsvSource(
value = [
"Thing 4 v1,Thing 4 description update",
"Thing 4 v1 update,Thing 4 description update",
"Thing 4 v1,Thing 4 description",
],
)
fun `update type - success`(name: String, description: String) {
// given
val request = Type.Request(
name = name,
description = description,
)
// when
val result = webClient.put()
.uri("/type-00000000-0000-0000-0001-000000000004")
.contentType(APPLICATION_JSON)
.bodyValue(request)
.exchange()
// then
result.expectStatus()
.isOk
.expectBody<Type.Response>()
.consumeWith {
softly.assertThat(it.responseBody?.id).isEqualToUuid("00000000-0000-0000-0001-000000000004")
softly.assertThat(it.responseBody?.name).isEqualTo(name)
softly.assertThat(it.responseBody?.description).isEqualTo(description)
}
}
@Test
fun `update type - success no change`() {
// given
val request = Type.Request(
name = "Thing 1 v1",
description = "Thing 1 description",
)
// when
val result = webClient.put()
.uri("/type-00000000-0000-0000-0001-000000000001")
.contentType(APPLICATION_JSON)
.bodyValue(request)
.exchange()
// then
result.expectStatus().isEqualTo(ACCEPTED)
}
@Test
fun `update type - fail invalid id`() {
// given
val request = Type.Request(
name = "Thing 0 v1",
description = "Thing 0 description",
)
// when
val result = webClient.put()
.uri("/type-00000000-0000-0000-0001-000000000000")
.contentType(APPLICATION_JSON)
.bodyValue(request)
.exchange()
// then
result.expectStatus().isNotFound
}
@Test
fun `update type - fail name take`() {
// given
val request = Type.Request(
name = "Thing 2 v1",
description = "Thing 2 description",
)
// when
val result = webClient.put()
.uri("/type-00000000-0000-0000-0001-000000000001")
.contentType(APPLICATION_JSON)
.bodyValue(request)
.exchange()
// then
result.expectStatus().isEqualTo(CONFLICT)
}
@ParameterizedTest
@CsvSource(
value = [
"{}",
"{'name': 'Thing 0 v1'}",
"{'description': 'Thing 0 description'}",
],
)
fun `update type - fail bad data request`(jsonRequest: String) {
// when
val result = webClient.put()
.uri("/type-00000000-0000-0000-0001-000000000001")
.contentType(APPLICATION_JSON)
.bodyValue(jsonRequest)
.exchange()
// then
result.expectStatus().isBadRequest
}
@ParameterizedTest
@CsvSource(
value = [
"zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
"00000000000000000000000000000000",
"0",
],
)
fun `update type - fail bad id request`(uuid: String) {
// given
val request = Type.Request(
name = "Thing 0 v1",
description = "Thing 0 description",
)
// when
val result = webClient.put()
.uri("/type-$uuid")
.contentType(APPLICATION_JSON)
.bodyValue(request)
.exchange()
// then
result.expectStatus().isBadRequest
}
}
}

View File

@@ -0,0 +1,210 @@
package ltd.hlaeja.controller
import ltd.hlaeja.library.deviceRegistry.Types
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<List<Types.Response>>()
.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<List<Types.Response>>()
.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<List<Types.Response>>()
.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<List<Types.Response>>()
.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<List<Types.Response>>()
.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<List<Types.Response>>()
.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
}
}