refactor: Moved exceptions into package `exceptions` - Aligned Code
[demos/kafka/chat] / src / test / java / de / juplo / kafka / chat / backend / api / ChatBackendControllerTest.java
index 2f120ae..f831dba 100644 (file)
@@ -1,6 +1,9 @@
 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.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;
@@ -20,13 +23,18 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.*;
 
 
-@SpringBootTest(properties = "spring.main.allow-bean-definition-overriding=true")
+@SpringBootTest(properties = {
+    "spring.main.allow-bean-definition-overriding=true",
+    })
 @AutoConfigureWebTestClient
 @Slf4j
 public class ChatBackendControllerTest
 {
+  @Autowired
+  ChatBackendProperties properties;
+
   @MockBean
-  ChatHomeService chatHomeService;
+  ChatHome chatHome;
   @MockBean
   ChatRoomService chatRoomService;
 
@@ -36,12 +44,12 @@ public class ChatBackendControllerTest
   {
     // Given
     UUID chatroomId = UUID.randomUUID();
-    when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
+    when(chatHome.getChatRoomData(eq(chatroomId))).thenThrow(new UnknownChatroomException(chatroomId));
 
     // When
     WebTestClient.ResponseSpec responseSpec = client
         .get()
-        .uri("/list/{chatroomId}", chatroomId)
+        .uri("/{chatroomId}/list", chatroomId)
         .accept(MediaType.APPLICATION_JSON)
         .exchange();
 
@@ -56,12 +64,12 @@ public class ChatBackendControllerTest
   {
     // Given
     UUID chatroomId = UUID.randomUUID();
-    when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
+    when(chatHome.getChatRoomInfo(eq(chatroomId))).thenThrow(new UnknownChatroomException(chatroomId));
 
     // When
     WebTestClient.ResponseSpec responseSpec = client
         .get()
-        .uri("/get/{chatroomId}", chatroomId)
+        .uri("/{chatroomId}", chatroomId)
         .accept(MediaType.APPLICATION_JSON)
         .exchange();
 
@@ -77,13 +85,13 @@ public class ChatBackendControllerTest
     UUID chatroomId = UUID.randomUUID();
     String username = "foo";
     Long messageId = 66l;
-    when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
+    when(chatHome.getChatRoomData(eq(chatroomId))).thenThrow(new UnknownChatroomException(chatroomId));
 
     // When
     WebTestClient.ResponseSpec responseSpec = client
         .put()
         .uri(
-            "/put/{chatroomId}/{username}/{messageId}",
+            "/{chatroomId}/{username}/{messageId}",
             chatroomId,
             username,
             messageId)
@@ -103,13 +111,13 @@ public class ChatBackendControllerTest
     UUID chatroomId = UUID.randomUUID();
     String username = "foo";
     Long messageId = 66l;
-    when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
+    when(chatHome.getChatRoomData(eq(chatroomId))).thenThrow(new UnknownChatroomException(chatroomId));
 
     // When
     WebTestClient.ResponseSpec responseSpec = client
         .get()
         .uri(
-            "/get/{chatroomId}/{username}/{messageId}",
+            "/{chatroomId}/{username}/{messageId}",
             chatroomId,
             username,
             messageId)
@@ -126,12 +134,12 @@ public class ChatBackendControllerTest
   {
     // Given
     UUID chatroomId = UUID.randomUUID();
-    when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.empty());
+    when(chatHome.getChatRoomData(eq(chatroomId))).thenThrow(new UnknownChatroomException(chatroomId));
 
     // When
     WebTestClient.ResponseSpec responseSpec = client
         .get()
-        .uri("/listen/{chatroomId}", chatroomId)
+        .uri("/{chatroomId}/listen", chatroomId)
         // .accept(MediaType.TEXT_EVENT_STREAM, MediaType.APPLICATION_JSON) << TODO: Does not work!
         .exchange();
 
@@ -152,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();
@@ -164,12 +172,11 @@ public class ChatBackendControllerTest
     LocalDateTime timeExistingMessage = LocalDateTime.parse(timeExistingMessageAsString);
     String textExistingMessage = "Existing";
     String textMutatedMessage = "Mutated!";
-    ChatRoom chatRoom = new ChatRoom(
-        chatroomId,
-        "Test-ChatRoom",
+    ChatRoomData chatRoomData = new ChatRoomData(
         Clock.systemDefaultZone(),
-        chatRoomService, 8);
-    when(chatHomeService.getChatRoom(any(UUID.class))).thenReturn(Mono.just(chatRoom));
+        chatRoomService,
+        8);
+    when(chatHome.getChatRoomData(eq(chatroomId))).thenReturn(Mono.just(chatRoomData));
     Message existingMessage = new Message(
         key,
         serialNumberExistingMessage,
@@ -179,13 +186,13 @@ public class ChatBackendControllerTest
         .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));
+        .thenReturn(Mono.just(mock(Message.class)));
 
     // When
     client
         .put()
         .uri(
-            "/put/{chatroomId}/{username}/{messageId}",
+            "/{chatroomId}/{username}/{messageId}",
             chatroomId,
             user,
             messageId)
@@ -204,4 +211,169 @@ public class ChatBackendControllerTest
         .jsonPath("$.mutatedText").isEqualTo(textMutatedMessage);
     verify(chatRoomService, 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)
+  {
+    // Given
+    UUID chatroomId = UUID.randomUUID();
+    String user = "Foo";
+    Long messageId = 66l;
+    Message.MessageKey key = Message.MessageKey.of(user, messageId);
+    String textMessage = "Hallo Welt";
+    ChatRoomData chatRoomData = new ChatRoomData(
+        Clock.systemDefaultZone(),
+        chatRoomService,
+        8);
+    when(chatHome.getChatRoomData(any(UUID.class)))
+        .thenReturn(Mono.just(chatRoomData));
+    when(chatRoomService.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(Mono.just(mock(Message.class)));
+
+    // When
+    client
+        .put()
+        .uri(
+            "/{chatroomId}/{username}/{messageId}",
+            chatroomId,
+            user,
+            messageId)
+        .bodyValue(textMessage)
+        .accept(MediaType.APPLICATION_JSON)
+        .exchange()
+        // Then
+        .expectStatus().is4xxClientError()
+        .expectBody()
+        .jsonPath("$.type").isEqualTo("/problem/invalid-username")
+        .jsonPath("$.username").isEqualTo(user);
+    verify(chatRoomService, 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();
+    int shard = 666;
+    when(chatHome.getChatRoomInfo(eq(chatroomId))).thenThrow(new ShardNotOwnedException(shard));
+
+    // When
+    WebTestClient.ResponseSpec responseSpec = client
+        .get()
+        .uri("/{chatroomId}", chatroomId)
+        .accept(MediaType.APPLICATION_JSON)
+        .exchange();
+
+    // Then
+    assertProblemDetailsForShardNotOwnedException(responseSpec, shard);
+  }
+
+  @Test
+  @DisplayName("Assert expected problem-details for not owned shard on GET /list/{chatroomId}")
+  void testShardNotOwnedExceptionForListChatroom(@Autowired WebTestClient client)
+  {
+    // Given
+    UUID chatroomId = UUID.randomUUID();
+    int shard = 666;
+    when(chatHome.getChatRoomData(eq(chatroomId))).thenThrow(new ShardNotOwnedException(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;
+    int shard = 666;
+    when(chatHome.getChatRoomData(eq(chatroomId))).thenThrow(new ShardNotOwnedException(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;
+    int shard = 666;
+    when(chatHome.getChatRoomData(eq(chatroomId))).thenThrow(new ShardNotOwnedException(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();
+    int shard = 666;
+    when(chatHome.getChatRoomData(eq(chatroomId))).thenThrow(new ShardNotOwnedException(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);
+  }
 }