Implement server state handling in ChatController and ChatService, add ServerStateMapper utility, and create/update server state unit tests.
This commit is contained in:
parent
b61b117f41
commit
65d0118e3d
|
|
@ -28,7 +28,7 @@ public class ChatController implements ChatApi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<Void> updateServerStates(ServerStateDto serverStateDto) {
|
public ResponseEntity<Void> updateServerStates(ServerStateDto serverStateDto) {
|
||||||
//TODO [Stijn] [2026-07-18]: Implement handling server state updates (push to listeners)
|
chatService.updateServerState(serverStateDto);
|
||||||
throw new UnsupportedOperationException("Not implemented");
|
return new ResponseEntity<>(HttpStatus.ACCEPTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.alttd.altitudeweb.controllers.chat;
|
||||||
|
|
||||||
|
import com.alttd.altitudeweb.model.ServerStateDto;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class ServerStateMapper {
|
||||||
|
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
|
||||||
|
.registerModule(new JavaTimeModule())
|
||||||
|
.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||||
|
.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
|
||||||
|
|
||||||
|
public static String toJson(ServerStateDto serverStateDto) {
|
||||||
|
try {
|
||||||
|
return OBJECT_MAPPER.writeValueAsString(serverStateDto);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new IllegalStateException("Failed to serialize ServerStateDto to JSON", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,11 +2,14 @@ package com.alttd.altitudeweb.services.chat;
|
||||||
|
|
||||||
import com.alttd.altitudeweb.controllers.chat.ChatMessage;
|
import com.alttd.altitudeweb.controllers.chat.ChatMessage;
|
||||||
import com.alttd.altitudeweb.controllers.chat.ChatMessageMapper;
|
import com.alttd.altitudeweb.controllers.chat.ChatMessageMapper;
|
||||||
|
import com.alttd.altitudeweb.controllers.chat.ServerStateMapper;
|
||||||
import com.alttd.altitudeweb.database.Databases;
|
import com.alttd.altitudeweb.database.Databases;
|
||||||
import com.alttd.altitudeweb.database.chat.ChatLogMapper;
|
import com.alttd.altitudeweb.database.chat.ChatLogMapper;
|
||||||
import com.alttd.altitudeweb.database.web_db.chat_session.ChatSession;
|
import com.alttd.altitudeweb.database.web_db.chat_session.ChatSession;
|
||||||
import com.alttd.altitudeweb.database.web_db.chat_session.ChatSessionMapper;
|
import com.alttd.altitudeweb.database.web_db.chat_session.ChatSessionMapper;
|
||||||
import com.alttd.altitudeweb.model.PermissionClaimDto;
|
import com.alttd.altitudeweb.model.PermissionClaimDto;
|
||||||
|
import com.alttd.altitudeweb.model.ServerDto;
|
||||||
|
import com.alttd.altitudeweb.model.ServerStateDto;
|
||||||
import com.alttd.altitudeweb.services.chat.event_publisher.EventPublisher;
|
import com.alttd.altitudeweb.services.chat.event_publisher.EventPublisher;
|
||||||
import com.alttd.altitudeweb.services.chat.event_publisher.EventUser;
|
import com.alttd.altitudeweb.services.chat.event_publisher.EventUser;
|
||||||
import com.alttd.altitudeweb.services.chat.event_publisher.MessageForUser;
|
import com.alttd.altitudeweb.services.chat.event_publisher.MessageForUser;
|
||||||
|
|
@ -121,6 +124,20 @@ public class ChatService {
|
||||||
sendMessagesToListeners(chatMessageList);
|
sendMessagesToListeners(chatMessageList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateServerState(ServerStateDto serverStateDto) {
|
||||||
|
sendToUsers("server-state", (eventUser) -> {
|
||||||
|
if (eventUser.hasPermission(PermissionClaimDto.HEAD_MOD)) {
|
||||||
|
return ServerStateMapper.toJson(serverStateDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ServerDto> filteredServers = serverStateDto.getServers().stream()
|
||||||
|
.filter(serverDto -> Arrays.asList(allowedServers).contains(serverDto.getName()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return ServerStateMapper.toJson(new ServerStateDto().servers(filteredServers));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void sendMessagesToListeners(List<ChatMessage> chatMessageList) {
|
private void sendMessagesToListeners(List<ChatMessage> chatMessageList) {
|
||||||
Map<ChatMessage, String> jsonCache = new HashMap<>();
|
Map<ChatMessage, String> jsonCache = new HashMap<>();
|
||||||
for (ChatMessage message : chatMessageList) {
|
for (ChatMessage message : chatMessageList) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.alttd.altitudeweb.controllers.chat;
|
||||||
|
|
||||||
|
import com.alttd.altitudeweb.model.ServerStateDto;
|
||||||
|
import com.alttd.altitudeweb.services.chat.ChatService;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class ChatControllerTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ChatService chatService;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private ChatController chatController;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUpdateServerStatesDelegatesToService() {
|
||||||
|
ServerStateDto serverStateDto = new ServerStateDto();
|
||||||
|
|
||||||
|
ResponseEntity<Void> response = chatController.updateServerStates(serverStateDto);
|
||||||
|
|
||||||
|
verify(chatService).updateServerState(serverStateDto);
|
||||||
|
assertEquals(HttpStatus.ACCEPTED, response.getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,8 @@ package com.alttd.altitudeweb.services.chat;
|
||||||
import com.alttd.altitudeweb.controllers.chat.ChatMessage;
|
import com.alttd.altitudeweb.controllers.chat.ChatMessage;
|
||||||
import com.alttd.altitudeweb.controllers.chat.ChatMessageType;
|
import com.alttd.altitudeweb.controllers.chat.ChatMessageType;
|
||||||
import com.alttd.altitudeweb.model.PermissionClaimDto;
|
import com.alttd.altitudeweb.model.PermissionClaimDto;
|
||||||
|
import com.alttd.altitudeweb.model.ServerDto;
|
||||||
|
import com.alttd.altitudeweb.model.ServerStateDto;
|
||||||
import com.alttd.altitudeweb.services.chat.event_publisher.EventPublisher;
|
import com.alttd.altitudeweb.services.chat.event_publisher.EventPublisher;
|
||||||
import com.alttd.altitudeweb.services.chat.event_publisher.EventUser;
|
import com.alttd.altitudeweb.services.chat.event_publisher.EventUser;
|
||||||
import com.alttd.altitudeweb.services.chat.event_publisher.MessageForUser;
|
import com.alttd.altitudeweb.services.chat.event_publisher.MessageForUser;
|
||||||
|
|
@ -18,6 +20,7 @@ import java.util.UUID;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
class ChatServiceTest {
|
class ChatServiceTest {
|
||||||
|
|
@ -152,4 +155,28 @@ class ChatServiceTest {
|
||||||
assertFalse(messageForUser.get(regularUser).contains("blocked message"));
|
assertFalse(messageForUser.get(regularUser).contains("blocked message"));
|
||||||
assertTrue(messageForUser.get(headModUser).contains("blocked message"));
|
assertTrue(messageForUser.get(headModUser).contains("blocked message"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUpdateServerStateFiltering() {
|
||||||
|
ServerStateDto serverStateDto = new ServerStateDto()
|
||||||
|
.addServersItem(new ServerDto().name("server1"))
|
||||||
|
.addServersItem(new ServerDto().name("server2"));
|
||||||
|
|
||||||
|
chatService.updateServerState(serverStateDto);
|
||||||
|
|
||||||
|
ArgumentCaptor<MessageForUser> captor = ArgumentCaptor.forClass(MessageForUser.class);
|
||||||
|
verify(chatService).sendToUsers(eq("server-state"), captor.capture());
|
||||||
|
|
||||||
|
MessageForUser messageForUser = captor.getValue();
|
||||||
|
|
||||||
|
EventUser regularUser = new EventUser(UUID.randomUUID(), List.of(), null);
|
||||||
|
String regularResult = messageForUser.get(regularUser);
|
||||||
|
assertTrue(regularResult.contains("server1"), "Regular user should see allowed server");
|
||||||
|
assertFalse(regularResult.contains("server2"), "Regular user should NOT see non-allowed server");
|
||||||
|
|
||||||
|
EventUser headModUser = new EventUser(UUID.randomUUID(), List.of(PermissionClaimDto.HEAD_MOD.getValue()), null);
|
||||||
|
String headModResult = messageForUser.get(headModUser);
|
||||||
|
assertTrue(headModResult.contains("server1"), "HEAD_MOD should see allowed server");
|
||||||
|
assertTrue(headModResult.contains("server2"), "HEAD_MOD should see non-allowed server");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ components:
|
||||||
- uuid
|
- uuid
|
||||||
- name
|
- name
|
||||||
- styledName
|
- styledName
|
||||||
|
# TODO [Stijn] [2026-07-19]: Add who they ignore and who they are ignored by
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
uuid:
|
uuid:
|
||||||
|
|
@ -140,11 +141,3 @@ components:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: "#/components/schemas/Server"
|
$ref: "#/components/schemas/Server"
|
||||||
parameters:
|
|
||||||
From:
|
|
||||||
name: from
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user