diff --git a/server/src/main/java/com/usatiuk/tjv/y/server/controller/ChatController.java b/server/src/main/java/com/usatiuk/tjv/y/server/controller/ChatController.java index 0e5407e..90d3499 100644 --- a/server/src/main/java/com/usatiuk/tjv/y/server/controller/ChatController.java +++ b/server/src/main/java/com/usatiuk/tjv/y/server/controller/ChatController.java @@ -3,110 +3,52 @@ package com.usatiuk.tjv.y.server.controller; import com.usatiuk.tjv.y.server.dto.ChatCreateTo; import com.usatiuk.tjv.y.server.dto.ChatTo; import com.usatiuk.tjv.y.server.dto.PersonTo; -import com.usatiuk.tjv.y.server.dto.converters.ChatMapper; -import com.usatiuk.tjv.y.server.dto.converters.PersonMapper; -import com.usatiuk.tjv.y.server.entity.Chat; -import com.usatiuk.tjv.y.server.entity.Person; import com.usatiuk.tjv.y.server.service.ChatService; -import jakarta.persistence.EntityManager; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; -import org.springframework.web.server.ResponseStatusException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Objects; -import java.util.stream.Stream; +import java.util.Collection; @RestController @RequestMapping(value = "/chat", produces = MediaType.APPLICATION_JSON_VALUE) public class ChatController { - private final EntityManager entityManager; private final ChatService chatService; - private final ChatMapper chatMapper; - private final PersonMapper personMapper; - public ChatController(EntityManager entityManager, ChatService chatService, ChatMapper chatMapper, PersonMapper personMapper) { - this.entityManager = entityManager; + public ChatController(ChatService chatService) { this.chatService = chatService; - this.chatMapper = chatMapper; - this.personMapper = personMapper; } @PostMapping public ChatTo create(Authentication authentication, @RequestBody ChatCreateTo chatCreateTo) { - var chat = new Chat(); - - if (Arrays.stream(chatCreateTo.memberUuids()).noneMatch(n -> Objects.equals(n, authentication.getName()))) - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Creator of chat must be its member"); - - if (chatCreateTo.memberUuids().length <= 1) - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Chat must have members other than its creator"); - - chat.setCreator(entityManager.getReference(Person.class, authentication.getName())); - chat.setMembers(Arrays.stream(chatCreateTo.memberUuids()).map( - p -> entityManager.getReference(Person.class, p) - ).toList()); - chat.setName(chatCreateTo.name()); - - chatService.create(chat); - return chatMapper.makeDto(chat); + return chatService.create(authentication, chatCreateTo); } @GetMapping(path = "/by-id/{id}") public ChatTo get(Authentication authentication, @PathVariable Long id) { - var chat = chatService.readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found")); - var userRef = entityManager.getReference(Person.class, authentication.getName()); - if (!chat.getMembers().contains(userRef)) - throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat"); - return chatMapper.makeDto(chat); + return chatService.getById(authentication, id); } @DeleteMapping(path = "/by-id/{id}") @ResponseStatus(HttpStatus.NO_CONTENT) public void delete(Authentication authentication, @PathVariable Long id) { - var chat = chatService.readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found")); - if (!Objects.equals(chat.getCreator().getUuid(), authentication.getName())) - throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't creator of the chat"); - chatService.deleteById(id); + chatService.deleteById(authentication, id); } @PatchMapping(path = "/by-id/{id}") public ChatTo update(Authentication authentication, @PathVariable Long id, @RequestBody ChatCreateTo chatCreateTo) { - var chat = chatService.readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found")); - if (!Objects.equals(chat.getCreator().getUuid(), authentication.getName())) - throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't creator of the chat"); - - if (Arrays.stream(chatCreateTo.memberUuids()).noneMatch(n -> Objects.equals(n, authentication.getName()))) - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Creator of chat must be its member"); - - if (chatCreateTo.memberUuids().length <= 1) - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Chat must have members other than its creator"); - - chat.setMembers(new ArrayList<>(Arrays.stream(chatCreateTo.memberUuids()).map( - p -> entityManager.getReference(Person.class, p) - ).toList())); - chat.setName(chatCreateTo.name()); - - chatService.update(chat); - return chatMapper.makeDto(chat); + return chatService.update(authentication, id, chatCreateTo); } - - + @GetMapping(path = "/my") - public Stream getMy(Authentication authentication) { - return chatService.readByMember(authentication.getName()).stream().map(chatMapper::makeDto); + public Collection getMy(Authentication authentication) { + return chatService.getMy(authentication); } @GetMapping(path = "/by-id/{id}/members") - public Stream getMembers(Authentication authentication, @PathVariable Long id) { - var chat = chatService.readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found")); - var userRef = entityManager.getReference(Person.class, authentication.getName()); - if (!chat.getMembers().contains(userRef)) - throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat"); - return chat.getMembers().stream().map(personMapper::makeDto); + public Collection getMembers(Authentication authentication, @PathVariable Long id) { + return chatService.getMembers(authentication, id); } diff --git a/server/src/main/java/com/usatiuk/tjv/y/server/service/ChatService.java b/server/src/main/java/com/usatiuk/tjv/y/server/service/ChatService.java index 8a6159d..edd90d4 100644 --- a/server/src/main/java/com/usatiuk/tjv/y/server/service/ChatService.java +++ b/server/src/main/java/com/usatiuk/tjv/y/server/service/ChatService.java @@ -1,9 +1,21 @@ package com.usatiuk.tjv.y.server.service; +import com.usatiuk.tjv.y.server.dto.ChatCreateTo; +import com.usatiuk.tjv.y.server.dto.ChatTo; +import com.usatiuk.tjv.y.server.dto.PersonTo; import com.usatiuk.tjv.y.server.entity.Chat; +import org.springframework.security.core.Authentication; import java.util.Collection; public interface ChatService extends CrudService { - Collection readByMember(String memberUuid); + ChatTo create(Authentication authentication, ChatCreateTo chatCreateTo); + ChatTo update(Authentication authentication, Long id, ChatCreateTo chatCreateTo); + + Collection getMy(Authentication authentication); + + ChatTo getById(Authentication authentication, Long id); + void deleteById(Authentication authentication, Long id); + + Collection getMembers(Authentication authentication, Long id); } diff --git a/server/src/main/java/com/usatiuk/tjv/y/server/service/ChatServiceImpl.java b/server/src/main/java/com/usatiuk/tjv/y/server/service/ChatServiceImpl.java index 313ddb6..31eb4a3 100644 --- a/server/src/main/java/com/usatiuk/tjv/y/server/service/ChatServiceImpl.java +++ b/server/src/main/java/com/usatiuk/tjv/y/server/service/ChatServiceImpl.java @@ -1,19 +1,38 @@ package com.usatiuk.tjv.y.server.service; +import com.usatiuk.tjv.y.server.dto.ChatCreateTo; +import com.usatiuk.tjv.y.server.dto.ChatTo; +import com.usatiuk.tjv.y.server.dto.PersonTo; +import com.usatiuk.tjv.y.server.dto.converters.ChatMapper; +import com.usatiuk.tjv.y.server.dto.converters.PersonMapper; import com.usatiuk.tjv.y.server.entity.Chat; +import com.usatiuk.tjv.y.server.entity.Person; import com.usatiuk.tjv.y.server.repository.ChatRepository; +import jakarta.persistence.EntityManager; import org.springframework.data.repository.CrudRepository; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Objects; @Service public class ChatServiceImpl extends CrudServiceImpl implements ChatService { private final ChatRepository chatRepository; + private final ChatMapper chatMapper; + private final PersonMapper personMapper; + private final EntityManager entityManager; - public ChatServiceImpl(ChatRepository chatRepository) { + public ChatServiceImpl(ChatRepository chatRepository, ChatMapper chatMapper, PersonMapper personMapper, EntityManager entityManager) { this.chatRepository = chatRepository; + this.chatMapper = chatMapper; + this.personMapper = personMapper; + this.entityManager = entityManager; } @Override @@ -21,8 +40,77 @@ public class ChatServiceImpl extends CrudServiceImpl implements Chat return chatRepository; } + @Override - public Collection readByMember(String memberUuid) { - return chatRepository.findByMembers_uuid(memberUuid); + public ChatTo create(Authentication authentication, ChatCreateTo chatCreateTo) { + var chat = new Chat(); + + if (Arrays.stream(chatCreateTo.memberUuids()).noneMatch(n -> Objects.equals(n, authentication.getName()))) + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Creator of chat must be its member"); + + if (chatCreateTo.memberUuids().length == 1) + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Chat must have members other than its creator"); + + chat.setCreator(entityManager.getReference(Person.class, authentication.getName())); + chat.setMembers(Arrays.stream(chatCreateTo.memberUuids()).map( + p -> entityManager.getReference(Person.class, p) + ).toList()); + chat.setName(chatCreateTo.name()); + + chatRepository.save(chat); + return chatMapper.makeDto(chat); + } + + @Override + public ChatTo update(Authentication authentication, Long id, ChatCreateTo chatCreateTo) { + var chat = readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found")); + if (!Objects.equals(chat.getCreator().getUuid(), authentication.getName())) + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't creator of the chat"); + + if (Arrays.stream(chatCreateTo.memberUuids()).noneMatch(n -> Objects.equals(n, authentication.getName()))) + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Creator of chat must be its member"); + + if (chatCreateTo.memberUuids().length <= 1) + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Chat must have members other than its creator"); + + chat.setMembers(new ArrayList<>(Arrays.stream(chatCreateTo.memberUuids()).map( + p -> entityManager.getReference(Person.class, p) + ).toList())); + chat.setName(chatCreateTo.name()); + + chatRepository.save(chat); + return chatMapper.makeDto(chat); + } + + @Override + public Collection getMy(Authentication authentication) { + return chatRepository.findByMembers_uuid(authentication.getName()).stream().map(chatMapper::makeDto).toList(); + } + + @Override + public ChatTo getById(Authentication authentication, Long id) { + var chat = readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found")); + var userRef = entityManager.getReference(Person.class, authentication.getName()); + if (!chat.getMembers().contains(userRef)) + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat"); + + return chatMapper.makeDto(chat); + } + + @Override + public void deleteById(Authentication authentication, Long id) { + var chat = readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found")); + if (!Objects.equals(chat.getCreator().getUuid(), authentication.getName())) + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't creator of the chat"); + deleteById(id); + } + + @Override + public Collection getMembers(Authentication authentication, Long id) { + var chat = readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found")); + var userRef = entityManager.getReference(Person.class, authentication.getName()); + if (!chat.getMembers().contains(userRef)) + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat"); + return chat.getMembers().stream().map(personMapper::makeDto).toList(); } } diff --git a/server/src/test/java/com/usatiuk/tjv/y/server/controller/ChatControllerTest.java b/server/src/test/java/com/usatiuk/tjv/y/server/controller/ChatControllerTest.java index 7092b54..2e02486 100644 --- a/server/src/test/java/com/usatiuk/tjv/y/server/controller/ChatControllerTest.java +++ b/server/src/test/java/com/usatiuk/tjv/y/server/controller/ChatControllerTest.java @@ -40,7 +40,7 @@ public class ChatControllerTest extends DemoDataDbTest { Assertions.assertEquals("chatnew", toResponse.name()); Assertions.assertEquals(person1.getUuid(), toResponse.creatorUuid()); - Assertions.assertIterableEquals(Stream.of(person1, person2).map(personMapper::makeDto).toList(), toResponse.members()); + Assertions.assertEquals(2, toResponse.memberCount()); Assertions.assertTrue(chatRepository.findByName("chatnew").isPresent()); }