diff --git a/src/main/java/org/highmed/numportal/domain/dto/MessageDto.java b/src/main/java/org/highmed/numportal/domain/dto/MessageDto.java new file mode 100644 index 00000000..a99b24c4 --- /dev/null +++ b/src/main/java/org/highmed/numportal/domain/dto/MessageDto.java @@ -0,0 +1,38 @@ +package org.highmed.numportal.domain.dto; + +import org.highmed.numportal.domain.model.MessageType; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Data +@Schema +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class MessageDto { + + @NotNull + Long id; + + private String title; + + @NotNull + @NotEmpty + private String text; + + private LocalDateTime startDate; + + private LocalDateTime endDate; + + @NotNull + private MessageType type; + +} diff --git a/src/main/java/org/highmed/numportal/domain/model/Message.java b/src/main/java/org/highmed/numportal/domain/model/Message.java new file mode 100644 index 00000000..a8aab222 --- /dev/null +++ b/src/main/java/org/highmed/numportal/domain/model/Message.java @@ -0,0 +1,35 @@ +package org.highmed.numportal.domain.model; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Message { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String title; + + private String text; + + private LocalDateTime startDate; + + private LocalDateTime endDate; + + private MessageType type; + +} diff --git a/src/main/java/org/highmed/numportal/domain/model/MessageType.java b/src/main/java/org/highmed/numportal/domain/model/MessageType.java new file mode 100644 index 00000000..2e71d6bd --- /dev/null +++ b/src/main/java/org/highmed/numportal/domain/model/MessageType.java @@ -0,0 +1,7 @@ +package org.highmed.numportal.domain.model; + +public enum MessageType { + INFO, + WARNING, + ERROR +} diff --git a/src/main/java/org/highmed/numportal/domain/repository/MessageRepository.java b/src/main/java/org/highmed/numportal/domain/repository/MessageRepository.java new file mode 100644 index 00000000..0a6419aa --- /dev/null +++ b/src/main/java/org/highmed/numportal/domain/repository/MessageRepository.java @@ -0,0 +1,11 @@ +package org.highmed.numportal.domain.repository; + +import org.highmed.numportal.domain.model.Message; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface MessageRepository extends JpaRepository<Message, Long>, CustomProjectRepository { + +} diff --git a/src/main/java/org/highmed/numportal/mapper/MessageMapper.java b/src/main/java/org/highmed/numportal/mapper/MessageMapper.java new file mode 100644 index 00000000..1b1645cf --- /dev/null +++ b/src/main/java/org/highmed/numportal/mapper/MessageMapper.java @@ -0,0 +1,30 @@ +package org.highmed.numportal.mapper; + +import org.highmed.numportal.domain.dto.MessageDto; +import org.highmed.numportal.domain.model.Message; + +import javax.annotation.PostConstruct; +import lombok.AllArgsConstructor; +import org.modelmapper.ModelMapper; +import org.springframework.stereotype.Component; + +@Component +@AllArgsConstructor +public class MessageMapper { + + private final ModelMapper modelMapper; + + @PostConstruct + private void initialize() { + modelMapper.getConfiguration().setAmbiguityIgnored(true); + } + + public MessageDto convertToDTO(Message message) { + return modelMapper.map(message, MessageDto.class); + + } + + public Message convertToEntity(MessageDto messageDto) { + return modelMapper.map(messageDto, Message.class); + } +} diff --git a/src/main/java/org/highmed/numportal/service/MessageService.java b/src/main/java/org/highmed/numportal/service/MessageService.java new file mode 100644 index 00000000..65a518bd --- /dev/null +++ b/src/main/java/org/highmed/numportal/service/MessageService.java @@ -0,0 +1,33 @@ +package org.highmed.numportal.service; + +import org.highmed.numportal.domain.dto.MessageDto; +import org.highmed.numportal.domain.model.Message; +import org.highmed.numportal.domain.repository.MessageRepository; +import org.highmed.numportal.mapper.MessageMapper; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + + + +@Slf4j +@Service +@AllArgsConstructor +public class MessageService { + + private MessageMapper messageMapper; + private UserDetailsService userDetailsService; + + private MessageRepository messageRepository; + + public MessageDto createUserMessage(MessageDto messageDto, String userId) { + Message message = messageMapper.convertToEntity(messageDto); + userDetailsService.checkIsUserApproved(userId); + + Message savedMessage = messageRepository.save(message); + + return messageMapper.convertToDTO(savedMessage); + } + +} diff --git a/src/main/java/org/highmed/numportal/web/controller/MessageController.java b/src/main/java/org/highmed/numportal/web/controller/MessageController.java new file mode 100644 index 00000000..cfc78734 --- /dev/null +++ b/src/main/java/org/highmed/numportal/web/controller/MessageController.java @@ -0,0 +1,40 @@ +package org.highmed.numportal.web.controller; + +import org.highmed.numportal.domain.dto.MessageDto; +import org.highmed.numportal.service.MessageService; +import org.highmed.numportal.service.logger.ContextLog; +import org.highmed.numportal.web.config.Role; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@AllArgsConstructor +@RequestMapping(value = "/message", produces = "application/json") +@SecurityRequirement(name = "security_auth") +public class MessageController { + + private final MessageService messageService; + + @ContextLog(type = "MessageManagement", description = "Create user message") + @PostMapping() + @Operation( + description = "Creates a message for the users") + @PreAuthorize(Role.CONTENT_ADMIN) + public ResponseEntity<MessageDto> createUserMessage( + @AuthenticationPrincipal @NotNull Jwt principal, + @Valid @NotNull @RequestBody MessageDto messageDto) { + return ResponseEntity.ok(messageService.createUserMessage(messageDto, principal.getSubject())); + } +} diff --git a/src/test/java/org/highmed/numportal/service/MessageServiceTest.java b/src/test/java/org/highmed/numportal/service/MessageServiceTest.java new file mode 100644 index 00000000..6cbaaa6a --- /dev/null +++ b/src/test/java/org/highmed/numportal/service/MessageServiceTest.java @@ -0,0 +1,64 @@ +package org.highmed.numportal.service; + +import org.highmed.numportal.domain.dto.MessageDto; +import org.highmed.numportal.domain.dto.OrganizationDto; +import org.highmed.numportal.domain.model.Message; +import org.highmed.numportal.domain.model.MessageType; +import org.highmed.numportal.domain.repository.MessageRepository; +import org.highmed.numportal.mapper.MessageMapper; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import java.time.LocalDateTime; + +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class MessageServiceTest { + + private static final String USER_ID = "550e8400-e29b-41d4-a716-446655440000"; + + @Mock + private MessageRepository messageRepository; + @Mock + private MessageMapper messageMapper; + @Mock + private UserDetailsService userDetailsService; + + @InjectMocks + private MessageService messageService; + + @Test + public void createUserMessageTest() { + MessageDto messageDto = MessageDto.builder() + .title("Other title") + .text("Hier koennte deine Nachricht stehen") + .startDate(LocalDateTime.now()) + .endDate(LocalDateTime.MAX) + .type(MessageType.INFO).build(); + Message message = Message.builder() + .title("Other title") + .text("Hier koennte deine Nachricht stehen") + .startDate(LocalDateTime.now()) + .endDate(LocalDateTime.MAX) + .type(MessageType.INFO).build(); + + when(messageMapper.convertToEntity(messageDto)).thenReturn(message); + when(messageRepository.save(message)).thenReturn(message); + when(messageMapper.convertToDTO(message)).thenReturn(messageDto); + MessageDto returnMessage = messageService.createUserMessage(messageDto, USER_ID); + + Assert.assertEquals(messageDto, returnMessage); + + Mockito.verify(messageMapper, Mockito.times(1)).convertToEntity(messageDto); + Mockito.verify(messageMapper, Mockito.times(1)).convertToDTO(message); + Mockito.verify(messageRepository, Mockito.times(1)).save(message); + Mockito.verify(userDetailsService, Mockito.times(1)).checkIsUserApproved(USER_ID); + } +}