X-Git-Url: https://juplo.de/gitweb/?a=blobdiff_plain;f=src%2Ftest%2Fjava%2Fde%2Fjuplo%2Fkafka%2Fchat%2Fbackend%2Fapi%2FChatBackendControllerTest.java;h=01de390c6b53deab10766227b8c468ba36d08615;hb=f70bb25f9b0769068028348995a78ece2130cd35;hp=5ebd08d1e9209a28d2d25485e271d4781aa42e7a;hpb=3526be7c01fa286f4253c96fd7f6c35abf3694ef;p=demos%2Fkafka%2Fchat diff --git a/src/test/java/de/juplo/kafka/chat/backend/api/ChatBackendControllerTest.java b/src/test/java/de/juplo/kafka/chat/backend/api/ChatBackendControllerTest.java index 5ebd08d1..01de390c 100644 --- a/src/test/java/de/juplo/kafka/chat/backend/api/ChatBackendControllerTest.java +++ b/src/test/java/de/juplo/kafka/chat/backend/api/ChatBackendControllerTest.java @@ -2,23 +2,21 @@ package de.juplo.kafka.chat.backend.api; import de.juplo.kafka.chat.backend.ChatBackendProperties; import de.juplo.kafka.chat.backend.domain.*; -import de.juplo.kafka.chat.backend.persistence.inmemory.InMemoryChatHomeService; +import de.juplo.kafka.chat.backend.domain.exceptions.ShardNotOwnedException; +import de.juplo.kafka.chat.backend.domain.exceptions.UnknownChatroomException; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Bean; import org.springframework.http.MediaType; import org.springframework.test.web.reactive.server.WebTestClient; import reactor.core.publisher.Mono; import java.time.Clock; import java.time.LocalDateTime; -import java.util.Arrays; import java.util.UUID; import static org.mockito.ArgumentMatchers.any; @@ -27,15 +25,18 @@ import static org.mockito.Mockito.*; @SpringBootTest(properties = { "spring.main.allow-bean-definition-overriding=true", - "chat.backend.inmemory.owned-shards=0,1,2,3,4,5,6,7,8,9" }) + }) @AutoConfigureWebTestClient @Slf4j public class ChatBackendControllerTest { + @Autowired + ChatBackendProperties properties; + @MockBean - InMemoryChatHomeService chatHomeService; + ChatHomeService chatHomeService; @MockBean - ChatRoomService chatRoomService; + ChatMessageService chatMessageService; @Test @DisplayName("Assert expected problem-details for unknown chatroom on GET /list/{chatroomId}") @@ -43,7 +44,7 @@ public class ChatBackendControllerTest { // Given UUID chatroomId = UUID.randomUUID(); - when(chatHomeService.getChatRoom(anyInt(), any(UUID.class))).thenReturn(Mono.empty()); + when(chatHomeService.getChatRoomData(eq(chatroomId))).thenThrow(new UnknownChatroomException(chatroomId)); // When WebTestClient.ResponseSpec responseSpec = client @@ -63,7 +64,7 @@ public class ChatBackendControllerTest { // Given UUID chatroomId = UUID.randomUUID(); - when(chatHomeService.getChatRoom(anyInt(), any(UUID.class))).thenReturn(Mono.empty()); + when(chatHomeService.getChatRoomInfo(eq(chatroomId))).thenThrow(new UnknownChatroomException(chatroomId)); // When WebTestClient.ResponseSpec responseSpec = client @@ -84,7 +85,7 @@ public class ChatBackendControllerTest UUID chatroomId = UUID.randomUUID(); String username = "foo"; Long messageId = 66l; - when(chatHomeService.getChatRoom(anyInt(), any(UUID.class))).thenReturn(Mono.empty()); + when(chatHomeService.getChatRoomData(eq(chatroomId))).thenThrow(new UnknownChatroomException(chatroomId)); // When WebTestClient.ResponseSpec responseSpec = client @@ -110,7 +111,7 @@ public class ChatBackendControllerTest UUID chatroomId = UUID.randomUUID(); String username = "foo"; Long messageId = 66l; - when(chatHomeService.getChatRoom(anyInt(), any(UUID.class))).thenReturn(Mono.empty()); + when(chatHomeService.getChatRoomData(eq(chatroomId))).thenThrow(new UnknownChatroomException(chatroomId)); // When WebTestClient.ResponseSpec responseSpec = client @@ -133,7 +134,7 @@ public class ChatBackendControllerTest { // Given UUID chatroomId = UUID.randomUUID(); - when(chatHomeService.getChatRoom(anyInt(), any(UUID.class))).thenReturn(Mono.empty()); + when(chatHomeService.getChatRoomData(eq(chatroomId))).thenThrow(new UnknownChatroomException(chatroomId)); // When WebTestClient.ResponseSpec responseSpec = client @@ -159,7 +160,7 @@ public class ChatBackendControllerTest @Test @DisplayName("Assert expected problem-details for message mutation on PUT /put/{chatroomId}/{username}/{messageId}") - void testMessageMutationException(@Autowired WebTestClient client) throws Exception + void testMessageMutationException(@Autowired WebTestClient client) { // Given UUID chatroomId = UUID.randomUUID(); @@ -171,23 +172,21 @@ public class ChatBackendControllerTest LocalDateTime timeExistingMessage = LocalDateTime.parse(timeExistingMessageAsString); String textExistingMessage = "Existing"; String textMutatedMessage = "Mutated!"; - ChatRoom chatRoom = new ChatRoom( - chatroomId, - "Test-ChatRoom", - 0, + ChatRoomData chatRoomData = new ChatRoomData( Clock.systemDefaultZone(), - chatRoomService, 8); - when(chatHomeService.getChatRoom(anyInt(), any(UUID.class))).thenReturn(Mono.just(chatRoom)); + chatMessageService, + 8); + when(chatHomeService.getChatRoomData(eq(chatroomId))).thenReturn(Mono.just(chatRoomData)); Message existingMessage = new Message( key, serialNumberExistingMessage, timeExistingMessage, textExistingMessage); - when(chatRoomService.getMessage(any(Message.MessageKey.class))) + when(chatMessageService.getMessage(any(Message.MessageKey.class))) .thenReturn(Mono.just(existingMessage)); // Needed for readable error-reports, in case of a bug that leads to according unwanted call - when(chatRoomService.persistMessage(any(Message.MessageKey.class), any(LocalDateTime.class), any(String.class))) - .thenReturn(mock(Message.class)); + when(chatMessageService.persistMessage(any(Message.MessageKey.class), any(LocalDateTime.class), any(String.class))) + .thenReturn(Mono.just(mock(Message.class))); // When client @@ -210,12 +209,12 @@ public class ChatBackendControllerTest .jsonPath("$.existingMessage.user").isEqualTo(user) .jsonPath("$.existingMessage.text").isEqualTo(textExistingMessage) .jsonPath("$.mutatedText").isEqualTo(textMutatedMessage); - verify(chatRoomService, never()).persistMessage(eq(key), any(LocalDateTime.class), any(String.class)); + verify(chatMessageService, never()).persistMessage(eq(key), any(LocalDateTime.class), any(String.class)); } @Test @DisplayName("Assert expected problem-details for invalid username on PUT /put/{chatroomId}/{username}/{messageId}") - void testInvalidUsernameException(@Autowired WebTestClient client) throws Exception + void testInvalidUsernameException(@Autowired WebTestClient client) { // Given UUID chatroomId = UUID.randomUUID(); @@ -223,19 +222,17 @@ public class ChatBackendControllerTest Long messageId = 66l; Message.MessageKey key = Message.MessageKey.of(user, messageId); String textMessage = "Hallo Welt"; - ChatRoom chatRoom = new ChatRoom( - chatroomId, - "Test-ChatRoom", - 0, + ChatRoomData chatRoomData = new ChatRoomData( Clock.systemDefaultZone(), - chatRoomService, 8); - when(chatHomeService.getChatRoom(anyInt(), any(UUID.class))) - .thenReturn(Mono.just(chatRoom)); - when(chatRoomService.getMessage(any(Message.MessageKey.class))) + chatMessageService, + 8); + when(chatHomeService.getChatRoomData(any(UUID.class))) + .thenReturn(Mono.just(chatRoomData)); + when(chatMessageService.getMessage(any(Message.MessageKey.class))) .thenReturn(Mono.empty()); // Needed for readable error-reports, in case of a bug that leads to according unwanted call - when(chatRoomService.persistMessage(any(Message.MessageKey.class), any(LocalDateTime.class), any(String.class))) - .thenReturn(mock(Message.class)); + when(chatMessageService.persistMessage(any(Message.MessageKey.class), any(LocalDateTime.class), any(String.class))) + .thenReturn(Mono.just(mock(Message.class))); // When client @@ -253,22 +250,135 @@ public class ChatBackendControllerTest .expectBody() .jsonPath("$.type").isEqualTo("/problem/invalid-username") .jsonPath("$.username").isEqualTo(user); - verify(chatRoomService, never()).persistMessage(eq(key), any(LocalDateTime.class), any(String.class)); + verify(chatMessageService, never()).persistMessage(eq(key), any(LocalDateTime.class), any(String.class)); + } + + @Test + @DisplayName("Assert expected problem-details for not owned shard on GET /{chatroomId}") + void testShardNotOwnedExceptionForGetChatroom(@Autowired WebTestClient client) + { + // Given + UUID chatroomId = UUID.randomUUID(); + String instanceId = "peter"; + int shard = 666; + when(chatHomeService.getChatRoomInfo(eq(chatroomId))).thenThrow(new ShardNotOwnedException(instanceId, shard)); + + // When + WebTestClient.ResponseSpec responseSpec = client + .get() + .uri("/{chatroomId}", chatroomId) + .accept(MediaType.APPLICATION_JSON) + .exchange(); + + // Then + assertProblemDetailsForShardNotOwnedException(responseSpec, shard); } - @TestConfiguration - static class Config + @Test + @DisplayName("Assert expected problem-details for not owned shard on GET /list/{chatroomId}") + void testShardNotOwnedExceptionForListChatroom(@Autowired WebTestClient client) { - @Bean - ChatHome[] chatHomes( - ChatBackendProperties properties, - InMemoryChatHomeService service) - { - ChatHome[] chatHomes = new ChatHome[properties.getInmemory().getNumShards()]; - Arrays - .stream(properties.getInmemory().getOwnedShards()) - .forEach(i -> chatHomes[i] = new ChatHome(service, i)); - return chatHomes; - } + // Given + UUID chatroomId = UUID.randomUUID(); + String instanceId = "peter"; + int shard = 666; + when(chatHomeService.getChatRoomData(eq(chatroomId))).thenThrow(new ShardNotOwnedException(instanceId, shard)); + + // When + WebTestClient.ResponseSpec responseSpec = client + .get() + .uri("/{chatroomId}/list", chatroomId) + .accept(MediaType.APPLICATION_JSON) + .exchange(); + + // Then + assertProblemDetailsForShardNotOwnedException(responseSpec, shard); + } + + @Test + @DisplayName("Assert expected problem-details for not owned shard on PUT /put/{chatroomId}/{username}/{messageId}") + void testShardNotOwnedExceptionForPutMessage(@Autowired WebTestClient client) + { + // Given + UUID chatroomId = UUID.randomUUID(); + String username = "foo"; + Long messageId = 66l; + String instanceId = "peter"; + int shard = 666; + when(chatHomeService.getChatRoomData(eq(chatroomId))).thenThrow(new ShardNotOwnedException(instanceId, shard)); + + // When + WebTestClient.ResponseSpec responseSpec = client + .put() + .uri( + "/{chatroomId}/{username}/{messageId}", + chatroomId, + username, + messageId) + .bodyValue("bar") + .accept(MediaType.APPLICATION_JSON) + .exchange(); + + // Then + assertProblemDetailsForShardNotOwnedException(responseSpec, shard); + } + + @Test + @DisplayName("Assert expected problem-details for not owned shard on GET /get/{chatroomId}/{username}/{messageId}") + void testShardNotOwnedExceptionForGetMessage(@Autowired WebTestClient client) + { + // Given + UUID chatroomId = UUID.randomUUID(); + String username = "foo"; + Long messageId = 66l; + String instanceId = "peter"; + int shard = 666; + when(chatHomeService.getChatRoomData(eq(chatroomId))).thenThrow(new ShardNotOwnedException(instanceId, shard)); + + // When + WebTestClient.ResponseSpec responseSpec = client + .get() + .uri( + "/{chatroomId}/{username}/{messageId}", + chatroomId, + username, + messageId) + .accept(MediaType.APPLICATION_JSON) + .exchange(); + + // Then + assertProblemDetailsForShardNotOwnedException(responseSpec, shard); + } + + @Test + @DisplayName("Assert expected problem-details for not owned shard on GET /listen/{chatroomId}") + void testShardNotOwnedExceptionForListenChatroom(@Autowired WebTestClient client) + { + // Given + UUID chatroomId = UUID.randomUUID(); + String instanceId = "peter"; + int shard = 666; + when(chatHomeService.getChatRoomData(eq(chatroomId))).thenThrow(new ShardNotOwnedException(instanceId, shard)); + + // When + WebTestClient.ResponseSpec responseSpec = client + .get() + .uri("/{chatroomId}/listen", chatroomId) + // .accept(MediaType.TEXT_EVENT_STREAM, MediaType.APPLICATION_JSON) << TODO: Does not work! + .exchange(); + + // Then + assertProblemDetailsForShardNotOwnedException(responseSpec, shard); + } + + private void assertProblemDetailsForShardNotOwnedException( + WebTestClient.ResponseSpec responseSpec, + int shard) + { + responseSpec + .expectStatus().isNotFound() + .expectBody() + .jsonPath("$.type").isEqualTo("/problem/shard-not-owned") + .jsonPath("$.shard").isEqualTo(shard); } }