From 3270b7c2df63380f0a229ba407dc50d7fffd3f86 Mon Sep 17 00:00:00 2001 From: FunixG Date: Mon, 28 Aug 2023 22:20:54 +0200 Subject: [PATCH 1/4] WIP command type and security, need tests --- .../client/dtos/FunixBotCommandDTO.java | 5 +++ .../client/enums/FunixBotCommandType.java | 9 ++++ .../service/entities/FunixBotCommand.java | 9 +++- .../FunixBotCommandRepository.java | 4 +- .../services/FunixBotCommandsService.java | 43 +++++++++++++++++++ .../migration/V3__funixbot_command_type.sql | 3 ++ .../FunixBotCommandResourceTest.java | 3 ++ 7 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 modules/funixbot/client/src/main/java/fr/funixgaming/api/funixbot/client/enums/FunixBotCommandType.java create mode 100644 modules/funixbot/service/src/main/resources/db/migration/V3__funixbot_command_type.sql diff --git a/modules/funixbot/client/src/main/java/fr/funixgaming/api/funixbot/client/dtos/FunixBotCommandDTO.java b/modules/funixbot/client/src/main/java/fr/funixgaming/api/funixbot/client/dtos/FunixBotCommandDTO.java index 663ec88..e174732 100644 --- a/modules/funixbot/client/src/main/java/fr/funixgaming/api/funixbot/client/dtos/FunixBotCommandDTO.java +++ b/modules/funixbot/client/src/main/java/fr/funixgaming/api/funixbot/client/dtos/FunixBotCommandDTO.java @@ -1,7 +1,9 @@ package fr.funixgaming.api.funixbot.client.dtos; import com.funixproductions.core.crud.dtos.ApiDTO; +import fr.funixgaming.api.funixbot.client.enums.FunixBotCommandType; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; @@ -11,6 +13,9 @@ public class FunixBotCommandDTO extends ApiDTO { @NotBlank private String command; + @NotNull + private FunixBotCommandType type; + @NotBlank private String message; } diff --git a/modules/funixbot/client/src/main/java/fr/funixgaming/api/funixbot/client/enums/FunixBotCommandType.java b/modules/funixbot/client/src/main/java/fr/funixgaming/api/funixbot/client/enums/FunixBotCommandType.java new file mode 100644 index 0000000..81f84c2 --- /dev/null +++ b/modules/funixbot/client/src/main/java/fr/funixgaming/api/funixbot/client/enums/FunixBotCommandType.java @@ -0,0 +1,9 @@ +package fr.funixgaming.api.funixbot.client.enums; + +public enum FunixBotCommandType { + INFO, + VIEWER, + MODERATION, + FUN, + OTHER +} diff --git a/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/entities/FunixBotCommand.java b/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/entities/FunixBotCommand.java index fc80c40..6fba435 100644 --- a/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/entities/FunixBotCommand.java +++ b/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/entities/FunixBotCommand.java @@ -1,8 +1,11 @@ package fr.funixgaming.api.funixbot.service.entities; import com.funixproductions.core.crud.entities.ApiEntity; +import fr.funixgaming.api.funixbot.client.enums.FunixBotCommandType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import lombok.Getter; import lombok.Setter; @@ -13,6 +16,10 @@ public class FunixBotCommand extends ApiEntity { @Column(nullable = false, unique = true, length = 30) private String command; - @Column(nullable = false) + @Enumerated(EnumType.STRING) + @Column(nullable = false, columnDefinition = "varchar(200) DEFAULT 'OTHER'") + private FunixBotCommandType type; + + @Column(nullable = false, length = 500) private String message; } diff --git a/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/repositories/FunixBotCommandRepository.java b/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/repositories/FunixBotCommandRepository.java index 2682696..75fae10 100644 --- a/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/repositories/FunixBotCommandRepository.java +++ b/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/repositories/FunixBotCommandRepository.java @@ -4,9 +4,7 @@ import fr.funixgaming.api.funixbot.service.entities.FunixBotCommand; import org.springframework.stereotype.Repository; -import java.util.Optional; - @Repository public interface FunixBotCommandRepository extends ApiRepository { - Optional findByCommand(String command); + boolean existsByCommand(String command); } diff --git a/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/services/FunixBotCommandsService.java b/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/services/FunixBotCommandsService.java index 4a12149..7c18261 100644 --- a/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/services/FunixBotCommandsService.java +++ b/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/services/FunixBotCommandsService.java @@ -1,18 +1,61 @@ package fr.funixgaming.api.funixbot.service.services; import com.funixproductions.core.crud.services.ApiService; +import com.funixproductions.core.exceptions.ApiBadRequestException; import fr.funixgaming.api.funixbot.client.dtos.FunixBotCommandDTO; import fr.funixgaming.api.funixbot.service.entities.FunixBotCommand; import fr.funixgaming.api.funixbot.service.mappers.FunixBotCommandMapper; import fr.funixgaming.api.funixbot.service.repositories.FunixBotCommandRepository; +import lombok.NonNull; import org.springframework.stereotype.Service; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + @Service public class FunixBotCommandsService extends ApiService { + private static final int MAX_LEN_MESSAGE = 500; + private static final int MAX_LEN_COMMAND = 30; + private static final String ERROR_MESSAGE_COMMAND_MAX_LEN = String.format("La commande ne peut pas dépasser %d caractères.", MAX_LEN_COMMAND); + private static final String ERROR_MESSAGE_MAX_LEN = String.format("Le message de la commande ne peut pas dépasser %d caractères.", MAX_LEN_MESSAGE); + private static final String ERROR_MESSAGE_NOT_ALPHANUMERIC = "La commande ne peut contenir que des caractères alphanumériques."; + private final Pattern pattern = Pattern.compile("^[a-zA-Z0-9]+$"); + public FunixBotCommandsService(FunixBotCommandRepository repository, FunixBotCommandMapper mapper) { super(repository, mapper); } + @Override + public void beforeSavingEntity(@NonNull Iterable entity) { + for (FunixBotCommand command : entity) { + if (command.getMessage().length() > MAX_LEN_MESSAGE) { + throw new ApiBadRequestException(ERROR_MESSAGE_MAX_LEN); + } + + if (command.getCommand().startsWith("!")) { + command.setCommand(command.getCommand().substring(1)); + } + if (command.getCommand().length() > MAX_LEN_COMMAND) { + throw new ApiBadRequestException(ERROR_MESSAGE_COMMAND_MAX_LEN); + } + + if (!isAlphanumeric(command.getCommand())) { + throw new ApiBadRequestException(ERROR_MESSAGE_NOT_ALPHANUMERIC); + } + + if (super.getRepository().existsByCommand(command.getCommand())) { + throw new ApiBadRequestException(String.format("La commande '%s' existe déjà.", command.getCommand())); + } + + command.setCommand(command.getCommand().toLowerCase()); + } + } + + private boolean isAlphanumeric(String input) { + Matcher matcher = pattern.matcher(input); + return matcher.matches(); + } + } diff --git a/modules/funixbot/service/src/main/resources/db/migration/V3__funixbot_command_type.sql b/modules/funixbot/service/src/main/resources/db/migration/V3__funixbot_command_type.sql new file mode 100644 index 0000000..8949121 --- /dev/null +++ b/modules/funixbot/service/src/main/resources/db/migration/V3__funixbot_command_type.sql @@ -0,0 +1,3 @@ +ALTER TABLE funixbot_commands ADD COLUMN type VARCHAR(200) DEFAULT 'OTHER' NOT NULL; + +ALTER TABLE funixbot_commands ALTER COLUMN message TYPE VARCHAR(500); diff --git a/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java b/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java index e39a938..8b51559 100644 --- a/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java +++ b/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java @@ -16,6 +16,9 @@ class FunixBotCommandResourceTest { @Autowired private MockMvc mockMvc; + @Autowired + private + @Test void testGetCommands() throws Exception { mockMvc.perform(get("/funixbot/command")) From 338652b48efecf9033bf11877f34054b45e5a32b Mon Sep 17 00:00:00 2001 From: FunixG Date: Mon, 28 Aug 2023 22:54:32 +0200 Subject: [PATCH 2/4] done tests --- .../FunixBotCommandResourceTest.java | 128 +++++++++++++++++- .../FunixBotUserExperienceResourceTest.java | 92 ++++++++++++- 2 files changed, 217 insertions(+), 3 deletions(-) diff --git a/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java b/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java index 8b51559..1a9c2ab 100644 --- a/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java +++ b/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java @@ -1,12 +1,26 @@ package fr.funixgaming.api.funixbot.service.resources; +import com.funixproductions.api.user.client.clients.UserAuthClient; +import com.funixproductions.api.user.client.dtos.UserDTO; +import com.funixproductions.api.user.client.enums.UserRole; +import com.funixproductions.core.test.beans.JsonHelper; +import fr.funixgaming.api.funixbot.client.dtos.FunixBotCommandDTO; +import fr.funixgaming.api.funixbot.client.enums.FunixBotCommandType; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest @@ -17,7 +31,10 @@ class FunixBotCommandResourceTest { private MockMvc mockMvc; @Autowired - private + private JsonHelper jsonHelper; + + @MockBean + private UserAuthClient userAuthClient; @Test void testGetCommands() throws Exception { @@ -25,4 +42,111 @@ void testGetCommands() throws Exception { .andExpect(status().isOk()); } + @Test + void testCreateCommandNoAccess() throws Exception { + final UserDTO userDTO = new UserDTO(); + userDTO.setRole(UserRole.USER); + userDTO.setUsername(UUID.randomUUID().toString()); + userDTO.setEmail(UUID.randomUUID().toString()); + userDTO.setId(UUID.randomUUID()); + userDTO.setValid(true); + when(userAuthClient.current(any())).thenReturn(userDTO); + + mockMvc.perform(post("/funixbot/command")) + .andExpect(status().isUnauthorized()); + + mockMvc.perform(post("/funixbot/command") + .header("Authorization", "Bearer " + UUID.randomUUID())) + .andExpect(status().isForbidden()); + + mockMvc.perform(patch("/funixbot/command") + .header("Authorization", "Bearer " + UUID.randomUUID())) + .andExpect(status().isForbidden()); + } + + @Test + void testCreateAndEditCommand() throws Exception { + final UserDTO userDTO = new UserDTO(); + userDTO.setRole(UserRole.MODERATOR); + userDTO.setUsername(UUID.randomUUID().toString()); + userDTO.setEmail(UUID.randomUUID().toString()); + userDTO.setId(UUID.randomUUID()); + userDTO.setValid(true); + when(userAuthClient.current(any())).thenReturn(userDTO); + + final String commandName = "tEst1"; + final FunixBotCommandDTO commandDTO = new FunixBotCommandDTO(); + commandDTO.setCommand("!" + commandName); + commandDTO.setMessage("testMessage"); + commandDTO.setType(FunixBotCommandType.FUN); + + MvcResult mvcResult = mockMvc.perform(post("/funixbot/command") + .header("Authorization", "Bearer " + UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(commandDTO))) + .andExpect(status().isOk()).andReturn(); + final FunixBotCommandDTO createdCommand = jsonHelper.fromJson(mvcResult.getResponse().getContentAsString(), FunixBotCommandDTO.class); + assertEquals(commandName, createdCommand.getCommand()); + createdCommand.setCommand("test2"); + + mvcResult = mockMvc.perform(patch("/funixbot/command") + .header("Authorization", "Bearer " + UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(createdCommand))) + .andExpect(status().isOk()).andReturn(); + final FunixBotCommandDTO editedCommand = jsonHelper.fromJson(mvcResult.getResponse().getContentAsString(), FunixBotCommandDTO.class); + assertEquals(createdCommand.getCommand(), editedCommand.getCommand()); + } + + @Test + void testCreateCommandWithCommandTooLong() throws Exception { + final FunixBotCommandDTO commandDTO = new FunixBotCommandDTO(); + commandDTO.setCommand("testdfgldfskghdflkghdflskgjhdfslkgjhdflkgjhdskflhfghdgfhdgfhdfghdfghfdghfdgh"); + commandDTO.setMessage("testMessage"); + commandDTO.setType(FunixBotCommandType.FUN); + + handleBadRequest(commandDTO); + } + + @Test + void testCreateCommandWithMessageTooLong() throws Exception { + final FunixBotCommandDTO commandDTO = new FunixBotCommandDTO(); + commandDTO.setCommand("test"); + commandDTO.setMessage("testdfgldfskghdflkghdflskgjhdfslkgjhdflkgjhdskflhfghdgfhdgfhdfghdfghfdghfdghtestdfgldfskghdflkghdflskgjhdfslkgjhdflkgjhdskflhfghdgfhdgfhdfghdfghfdghfdghtestdfgldfskghdflkghdflskgjhdfslkgjhdflkgjhdskflhfghdgfhdgfhdfghdfghfdghfdghtestdfgldfskghdflkghdflskgjhdfslkgjhdflkgjhdskflhfghdgfhdgfhdfghdfghfdghfdghtestdfgldfskghdflkghdflskgjhdfslkgjhdflkgjhdskflhfghdgfhdgfhdfghdfghfdghfdghtestdfgldfskghdflkghdflskgjhdfslkgjhdflkgjhdskflhfghdgfhdgfhdfghdfghfdghfdghtestdfgldfskghdflkghdflskgjhdfslkgjhdflkgjhdskflhfghdgfhdgfhdfghdfghfdghfdghtestdfgldfskghdflkghdflskgjhdfslkgjhdflkgjhdskflhfghdgfhdgfhdfghdfghfdghfdgh"); + commandDTO.setType(FunixBotCommandType.FUN); + + handleBadRequest(commandDTO); + } + + @Test + void testCreateCommandNotAlphanumeric() throws Exception { + final FunixBotCommandDTO commandDTO = new FunixBotCommandDTO(); + commandDTO.setCommand("test!"); + commandDTO.setMessage("testMessage"); + commandDTO.setType(FunixBotCommandType.FUN); + + handleBadRequest(commandDTO); + + commandDTO.setCommand("test@"); + handleBadRequest(commandDTO); + commandDTO.setCommand("test#"); + handleBadRequest(commandDTO); + } + + private void handleBadRequest(final FunixBotCommandDTO commandDTO) throws Exception { + final UserDTO userDTO = new UserDTO(); + userDTO.setRole(UserRole.MODERATOR); + userDTO.setUsername(UUID.randomUUID().toString()); + userDTO.setEmail(UUID.randomUUID().toString()); + userDTO.setId(UUID.randomUUID()); + userDTO.setValid(true); + when(userAuthClient.current(any())).thenReturn(userDTO); + + mockMvc.perform(post("/funixbot/command") + .header("Authorization", "Bearer " + UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(commandDTO))) + .andExpect(status().isBadRequest()); + } + } diff --git a/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotUserExperienceResourceTest.java b/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotUserExperienceResourceTest.java index ae22171..8453c2a 100644 --- a/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotUserExperienceResourceTest.java +++ b/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotUserExperienceResourceTest.java @@ -1,12 +1,25 @@ package fr.funixgaming.api.funixbot.service.resources; +import com.funixproductions.api.user.client.clients.UserAuthClient; +import com.funixproductions.api.user.client.dtos.UserDTO; +import com.funixproductions.api.user.client.enums.UserRole; +import com.funixproductions.core.test.beans.JsonHelper; +import fr.funixgaming.api.funixbot.client.dtos.FunixBotUserExperienceDTO; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest @@ -16,10 +29,87 @@ class FunixBotUserExperienceResourceTest { @Autowired private MockMvc mockMvc; + @Autowired + private JsonHelper jsonHelper; + + @MockBean + private UserAuthClient userAuthClient; + @Test void testGetExp() throws Exception { mockMvc.perform(get("/funixbot/user/exp")) .andExpect(status().isOk()); } + @Test + void testCreateNoPermissions() throws Exception { + final UserDTO userDTO = new UserDTO(); + userDTO.setRole(UserRole.USER); + userDTO.setUsername(UUID.randomUUID().toString()); + userDTO.setEmail(UUID.randomUUID().toString()); + userDTO.setId(UUID.randomUUID()); + userDTO.setValid(true); + + when(userAuthClient.current(any())).thenReturn(userDTO); + + mockMvc.perform(post("/funixbot/user/exp") + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(new FunixBotUserExperienceDTO()))) + .andExpect(status().isUnauthorized()); + + mockMvc.perform(post("/funixbot/user/exp") + .header("Authorization", "Bearer " + UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(new FunixBotUserExperienceDTO()))) + .andExpect(status().isForbidden()); + + mockMvc.perform(patch("/funixbot/user/exp") + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(new FunixBotUserExperienceDTO()))) + .andExpect(status().isUnauthorized()); + + mockMvc.perform(patch("/funixbot/user/exp") + .header("Authorization", "Bearer " + UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(new FunixBotUserExperienceDTO()))) + .andExpect(status().isForbidden()); + } + + @Test + void testCreateAndUpdateExp() throws Exception { + final UserDTO userDTO = new UserDTO(); + userDTO.setRole(UserRole.MODERATOR); + userDTO.setUsername(UUID.randomUUID().toString()); + userDTO.setEmail(UUID.randomUUID().toString()); + userDTO.setId(UUID.randomUUID()); + userDTO.setValid(true); + + when(userAuthClient.current(any())).thenReturn(userDTO); + + final FunixBotUserExperienceDTO experienceDTO = new FunixBotUserExperienceDTO(); + experienceDTO.setXp(10); + experienceDTO.setLevel(1); + experienceDTO.setLastMessageDateSeconds(1L); + experienceDTO.setTwitchUserId("qsd"); + experienceDTO.setXpNextLevel(100); + + MvcResult mvcResult = this.mockMvc.perform(post("/funixbot/user/exp") + .header("Authorization", "Bearer " + UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(experienceDTO))) + .andExpect(status().isOk()) + .andReturn(); + final FunixBotUserExperienceDTO createdDTO = jsonHelper.fromJson(mvcResult.getResponse().getContentAsString(), FunixBotUserExperienceDTO.class); + assertEquals(experienceDTO.getXp(), createdDTO.getXp()); + createdDTO.setLevel(10); + + mvcResult = this.mockMvc.perform(patch("/funixbot/user/exp") + .header("Authorization", "Bearer " + UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(createdDTO))) + .andExpect(status().isOk()).andReturn(); + final FunixBotUserExperienceDTO updatedDTO = jsonHelper.fromJson(mvcResult.getResponse().getContentAsString(), FunixBotUserExperienceDTO.class); + assertEquals(createdDTO.getLevel(), updatedDTO.getLevel()); + } + } From aba66db2673030e13860bce6fcab5196753631bd Mon Sep 17 00:00:00 2001 From: FunixG Date: Mon, 28 Aug 2023 22:55:21 +0200 Subject: [PATCH 3/4] done tests --- .../funixbot/service/resources/FunixBotCommandResourceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java b/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java index 1a9c2ab..7509cbc 100644 --- a/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java +++ b/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java @@ -86,7 +86,7 @@ void testCreateAndEditCommand() throws Exception { .content(jsonHelper.toJson(commandDTO))) .andExpect(status().isOk()).andReturn(); final FunixBotCommandDTO createdCommand = jsonHelper.fromJson(mvcResult.getResponse().getContentAsString(), FunixBotCommandDTO.class); - assertEquals(commandName, createdCommand.getCommand()); + assertEquals(commandName.toLowerCase(), createdCommand.getCommand()); createdCommand.setCommand("test2"); mvcResult = mockMvc.perform(patch("/funixbot/command") From bee36dd90cf74c649436f0b3fdc60cfaaa4f95e3 Mon Sep 17 00:00:00 2001 From: FunixG Date: Mon, 28 Aug 2023 23:05:55 +0200 Subject: [PATCH 4/4] done tests and fix tests --- .../FunixBotCommandRepository.java | 2 +- .../services/FunixBotCommandsService.java | 6 ++-- .../FunixBotCommandResourceTest.java | 31 ++++++++++++++++++- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/repositories/FunixBotCommandRepository.java b/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/repositories/FunixBotCommandRepository.java index 75fae10..4ef7a4c 100644 --- a/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/repositories/FunixBotCommandRepository.java +++ b/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/repositories/FunixBotCommandRepository.java @@ -6,5 +6,5 @@ @Repository public interface FunixBotCommandRepository extends ApiRepository { - boolean existsByCommand(String command); + boolean existsFunixBotCommandByCommandContainsIgnoreCase(String command); } diff --git a/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/services/FunixBotCommandsService.java b/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/services/FunixBotCommandsService.java index 7c18261..d086a03 100644 --- a/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/services/FunixBotCommandsService.java +++ b/modules/funixbot/service/src/main/java/fr/funixgaming/api/funixbot/service/services/FunixBotCommandsService.java @@ -28,8 +28,8 @@ public FunixBotCommandsService(FunixBotCommandRepository repository, } @Override - public void beforeSavingEntity(@NonNull Iterable entity) { - for (FunixBotCommand command : entity) { + public void beforeMappingToEntity(@NonNull Iterable request) { + for (FunixBotCommandDTO command : request) { if (command.getMessage().length() > MAX_LEN_MESSAGE) { throw new ApiBadRequestException(ERROR_MESSAGE_MAX_LEN); } @@ -45,7 +45,7 @@ public void beforeSavingEntity(@NonNull Iterable entity) { throw new ApiBadRequestException(ERROR_MESSAGE_NOT_ALPHANUMERIC); } - if (super.getRepository().existsByCommand(command.getCommand())) { + if (super.getRepository().existsFunixBotCommandByCommandContainsIgnoreCase(command.getCommand())) { throw new ApiBadRequestException(String.format("La commande '%s' existe déjà.", command.getCommand())); } diff --git a/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java b/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java index 7509cbc..00f8a27 100644 --- a/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java +++ b/modules/funixbot/service/src/test/java/fr/funixgaming/api/funixbot/service/resources/FunixBotCommandResourceTest.java @@ -87,7 +87,7 @@ void testCreateAndEditCommand() throws Exception { .andExpect(status().isOk()).andReturn(); final FunixBotCommandDTO createdCommand = jsonHelper.fromJson(mvcResult.getResponse().getContentAsString(), FunixBotCommandDTO.class); assertEquals(commandName.toLowerCase(), createdCommand.getCommand()); - createdCommand.setCommand("test2"); + createdCommand.setCommand("test2patched"); mvcResult = mockMvc.perform(patch("/funixbot/command") .header("Authorization", "Bearer " + UUID.randomUUID()) @@ -133,6 +133,35 @@ void testCreateCommandNotAlphanumeric() throws Exception { handleBadRequest(commandDTO); } + @Test + void testCreateDuplicateCommands() throws Exception { + final FunixBotCommandDTO commandDTO = new FunixBotCommandDTO(); + commandDTO.setCommand("testDupplicateCmd"); + commandDTO.setMessage("testMessage"); + commandDTO.setType(FunixBotCommandType.FUN); + + final UserDTO userDTO = new UserDTO(); + userDTO.setRole(UserRole.MODERATOR); + userDTO.setUsername(UUID.randomUUID().toString()); + userDTO.setEmail(UUID.randomUUID().toString()); + userDTO.setId(UUID.randomUUID()); + userDTO.setValid(true); + when(userAuthClient.current(any())).thenReturn(userDTO); + + mockMvc.perform(post("/funixbot/command") + .header("Authorization", "Bearer " + UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(commandDTO))) + .andExpect(status().isOk()); + + commandDTO.setId(null); + mockMvc.perform(post("/funixbot/command") + .header("Authorization", "Bearer " + UUID.randomUUID()) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonHelper.toJson(commandDTO))) + .andExpect(status().isBadRequest()); + } + private void handleBadRequest(final FunixBotCommandDTO commandDTO) throws Exception { final UserDTO userDTO = new UserDTO(); userDTO.setRole(UserRole.MODERATOR);