From 96619f4c24537f6eb66f032d1d00f035f442ca2e Mon Sep 17 00:00:00 2001 From: dmytro Date: Tue, 5 Dec 2023 19:23:53 +0200 Subject: [PATCH 1/3] fix: move column is_permitted_sending_private_message from TopicSubscriber to Contact and fix datasets --- .../yourway/controller/ContactController.java | 59 +++++++- .../yourway/controller/TopicController.java | 50 +------ .../java/com/chat/yourway/model/Contact.java | 3 + .../chat/yourway/model/TopicSubscriber.java | 2 - .../yourway/repository/ContactRepository.java | 12 ++ .../yourway/repository/TopicRepository.java | 6 +- .../repository/TopicSubscriberRepository.java | 17 +-- .../yourway/service/ContactServiceImpl.java | 51 ++++++- .../service/TopicSubscriberServiceImpl.java | 35 ----- .../service/interfaces/ContactService.java | 30 ++++ .../interfaces/TopicSubscriberService.java | 16 --- ...rivate_message_column_in_table_contact.sql | 9 ++ .../service/impl/ContactServiceImplTest.java | 129 ++++++++++++++++++ .../impl/TopicSubscriberServiceImplTest.java | 123 ----------------- src/test/resources/dataset/contacts.xml | 2 + .../dataset/favourite-topics-of-contact.xml | 1 + src/test/resources/dataset/mockdb/contact.xml | 2 + ...ssion-sending-message-in-private-topic.xml | 17 ++- .../dataset/popular-topic-dataset.xml | 3 + .../dataset/report-to-message-dataset.xml | 3 + .../dataset/restore-password-dataset.xml | 1 + 21 files changed, 316 insertions(+), 255 deletions(-) create mode 100644 src/main/resources/db/migration/V0025__add_is_permitted_sending_private_message_column_in_table_contact.sql diff --git a/src/main/java/com/chat/yourway/controller/ContactController.java b/src/main/java/com/chat/yourway/controller/ContactController.java index 09c32666..d29eeb2c 100644 --- a/src/main/java/com/chat/yourway/controller/ContactController.java +++ b/src/main/java/com/chat/yourway/controller/ContactController.java @@ -1,13 +1,12 @@ package com.chat.yourway.controller; -import static com.chat.yourway.config.openapi.OpenApiMessages.CONTACT_NOT_FOUND; -import static com.chat.yourway.config.openapi.OpenApiMessages.CONTACT_UNAUTHORIZED; -import static com.chat.yourway.config.openapi.OpenApiMessages.SUCCESSFULLY_UPDATED_CONTACT_PROFILE; +import static com.chat.yourway.config.openapi.OpenApiMessages.*; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import com.chat.yourway.config.openapi.OpenApiExamples; import com.chat.yourway.dto.request.EditContactProfileRequestDto; import com.chat.yourway.dto.response.ApiErrorResponseDto; +import com.chat.yourway.dto.response.ContactProfileResponseDto; import com.chat.yourway.service.interfaces.ContactService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -19,10 +18,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @Tag(name = "Contact") @RestController @@ -51,4 +47,53 @@ public void editContactProfile( contactService.updateContactProfile(editContactProfileRequestDto, userDetails); } + @Operation(summary = "Get contact profile", + responses = { + @ApiResponse(responseCode = "200", description = SUCCESSFULLY_RECEIVED_CONTACT_PROFILE), + @ApiResponse(responseCode = "404", description = CONTACT_NOT_FOUND, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), + @ApiResponse(responseCode = "403", description = CONTACT_UNAUTHORIZED, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) + }) + @GetMapping(path = "/profile", produces = APPLICATION_JSON_VALUE) + public ContactProfileResponseDto getContactProfile( + @AuthenticationPrincipal UserDetails userDetails) { + return contactService.getContactProfile(userDetails); + } + + @Operation( + summary = "Prohibit sending private message", + responses = { + @ApiResponse(responseCode = "200", description = SUCCESSFULLY_PROHIBITED_SENDING_PRIVATE_MESSAGES), + @ApiResponse( + responseCode = "403", + description = CONTACT_UNAUTHORIZED, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), + @ApiResponse( + responseCode = "404", + description = CONTACT_NOT_FOUND, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) + }) + @PatchMapping(path = "/message/send/prohibit") + public void prohibitSendingPrivateMessages(@AuthenticationPrincipal UserDetails userDetails) { + contactService.prohibitSendingPrivateMessages(userDetails); + } + + @Operation( + summary = "Permit sending private message", + responses = { + @ApiResponse(responseCode = "200", description = SUCCESSFULLY_PERMITTED_SENDING_PRIVATE_MESSAGES), + @ApiResponse( + responseCode = "403", + description = CONTACT_UNAUTHORIZED, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), + @ApiResponse( + responseCode = "404", + description = CONTACT_NOT_FOUND, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) + }) + @PatchMapping(path = "/message/send/permit") + public void permitSendingPrivateMessages(@AuthenticationPrincipal UserDetails userDetails) { + contactService.permitSendingPrivateMessages(userDetails); + } } diff --git a/src/main/java/com/chat/yourway/controller/TopicController.java b/src/main/java/com/chat/yourway/controller/TopicController.java index f892e401..9a05b286 100644 --- a/src/main/java/com/chat/yourway/controller/TopicController.java +++ b/src/main/java/com/chat/yourway/controller/TopicController.java @@ -333,59 +333,15 @@ public List findAllFavouriteTopics( return topicService.findAllFavouriteTopics(userDetails); } - @Operation( - summary = "Prohibit sending private message", - responses = { - @ApiResponse(responseCode = "200", description = SUCCESSFULLY_FOUND_TOPIC), - @ApiResponse( - responseCode = "403", - description = CONTACT_UNAUTHORIZED, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), - @ApiResponse( - responseCode = "404", - description = TOPIC_NOT_FOUND, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), - @ApiResponse( - responseCode = "409", - description = USER_DID_NOT_SUBSCRIBED_TO_TOPIC, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) - }) - @GetMapping(path = "/{topic-id}/message/send/prohibit") - public void prohibitSendingPrivateMessages( - @PathVariable("topic-id") int topicId, @AuthenticationPrincipal UserDetails userDetails) { - topicSubscriberService.prohibitSendingPrivateMessages(topicId, userDetails); - } - - @Operation( - summary = "Permit sending private message", - responses = { - @ApiResponse(responseCode = "200", description = SUCCESSFULLY_FOUND_TOPIC), - @ApiResponse( - responseCode = "403", - description = CONTACT_UNAUTHORIZED, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), - @ApiResponse( - responseCode = "404", - description = TOPIC_NOT_FOUND, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), - @ApiResponse( - responseCode = "409", - description = USER_DID_NOT_SUBSCRIBED_TO_TOPIC, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) - }) - @GetMapping(path = "/{topic-id}/message/send/permit") - public void permitSendingPrivateMessages( - @PathVariable("topic-id") int topicId, @AuthenticationPrincipal UserDetails userDetails) { - topicSubscriberService.permitSendingPrivateMessages(topicId, userDetails); - } - @Operation( summary = "List of popular topics", responses = { @ApiResponse(responseCode = "200", description = SUCCESSFULLY_FOUND_TOPIC) }) @GetMapping(path = "/popular/public") - public ListfindAllPopularPublicTopics() { + public List findAllPopularPublicTopics() { return topicService.findPopularPublicTopics(); } + + } diff --git a/src/main/java/com/chat/yourway/model/Contact.java b/src/main/java/com/chat/yourway/model/Contact.java index 14f8f382..f7b5a383 100644 --- a/src/main/java/com/chat/yourway/model/Contact.java +++ b/src/main/java/com/chat/yourway/model/Contact.java @@ -50,6 +50,9 @@ public class Contact implements UserDetails { @Column(name = "role", nullable = false, length = 32) private Role role; + @Column(name = "is_permitted_sending_private_message") + private boolean isPermittedSendingPrivateMessage; + @Override public Collection getAuthorities() { return List.of(new SimpleGrantedAuthority(role.name())); diff --git a/src/main/java/com/chat/yourway/model/TopicSubscriber.java b/src/main/java/com/chat/yourway/model/TopicSubscriber.java index c9d86653..5ab3362f 100644 --- a/src/main/java/com/chat/yourway/model/TopicSubscriber.java +++ b/src/main/java/com/chat/yourway/model/TopicSubscriber.java @@ -52,6 +52,4 @@ public class TopicSubscriber { @Column(name = "is_favourite_topic") private boolean isFavouriteTopic; - @Column(name = "is_permitted_sending_message") - private boolean isPermittedSendingMessage; } diff --git a/src/main/java/com/chat/yourway/repository/ContactRepository.java b/src/main/java/com/chat/yourway/repository/ContactRepository.java index d79cf69f..5ce4d991 100644 --- a/src/main/java/com/chat/yourway/repository/ContactRepository.java +++ b/src/main/java/com/chat/yourway/repository/ContactRepository.java @@ -6,6 +6,8 @@ import org.springframework.data.jpa.repository.Query; import java.util.Optional; + +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository @@ -20,4 +22,14 @@ public interface ContactRepository extends JpaRepository { boolean existsByEmailIgnoreCase(String email); + @Modifying + @Query( + nativeQuery = true, + value = + "UPDATE chat.contact " + + "SET is_permitted_sending_private_message = :isPermittedSendingPrivateMessage " + + "WHERE email = :contactEmail") + void updatePermissionSendingPrivateMessageByContactEmail( + @Param("contactEmail") String contactEmail, + @Param("isPermittedSendingPrivateMessage") boolean isPermittedSendingPrivateMessage); } diff --git a/src/main/java/com/chat/yourway/repository/TopicRepository.java b/src/main/java/com/chat/yourway/repository/TopicRepository.java index 1ce0f2a6..5c0a0b53 100644 --- a/src/main/java/com/chat/yourway/repository/TopicRepository.java +++ b/src/main/java/com/chat/yourway/repository/TopicRepository.java @@ -38,9 +38,9 @@ WHERE to_tsvector('english', t.topic_name) @@ to_tsquery('english', :query) @Query(nativeQuery = true, value = "SELECT t.*, COUNT(ts.id) AS ts_count, COUNT(m.id) AS m_count " + - "FROM topic t " + - "JOIN topic_subscriber ts ON t.id = ts.topic_id " + - "JOIN message m ON t.id = m.topic_id " + + "FROM chat.topic t " + + "JOIN chat.topic_subscriber ts ON t.id = ts.topic_id " + + "JOIN chat.message m ON t.id = m.topic_id " + "WHERE t.is_public = true " + "GROUP BY t.id " + "ORDER BY ts_count DESC, m_count DESC") diff --git a/src/main/java/com/chat/yourway/repository/TopicSubscriberRepository.java b/src/main/java/com/chat/yourway/repository/TopicSubscriberRepository.java index 40516ba9..83a0b4ef 100644 --- a/src/main/java/com/chat/yourway/repository/TopicSubscriberRepository.java +++ b/src/main/java/com/chat/yourway/repository/TopicSubscriberRepository.java @@ -63,23 +63,8 @@ void updateFavouriteTopicStatusByTopicIdAndContactEmail( boolean existsByTopicIdAndTopicCreatedBy(Integer topicId, String topicCreator); - @Modifying - @Query( - nativeQuery = true, - value = - "UPDATE chat.topic_subscriber " - + "SET is_permitted_sending_message = :isPermittedSendingPrivateMessage " - + "FROM chat.contact c " - + "WHERE contact_id = c.id " - + "AND topic_id = :topicId " - + "AND c.email = :contactEmail") - void updatePermissionSendingPrivateMessageByTopicIdAndContactEmail( - @Param("topicId") int topicId, - @Param("contactEmail") String contactEmail, - @Param("isPermittedSendingPrivateMessage") boolean isPermittedSendingPrivateMessage); - @Query( "SELECT CASE WHEN COUNT(ts) > 0 then true else false end from TopicSubscriber ts " + - "where ts.topic.id = :topicId and ts.isPermittedSendingMessage = false") + "where ts.topic.id = :topicId and ts.contact.isPermittedSendingPrivateMessage = false") boolean checkIfExistProhibitionSendingPrivateMessage(@Param("topicId") Integer topicId); } diff --git a/src/main/java/com/chat/yourway/service/ContactServiceImpl.java b/src/main/java/com/chat/yourway/service/ContactServiceImpl.java index c8d288e8..a57826a2 100644 --- a/src/main/java/com/chat/yourway/service/ContactServiceImpl.java +++ b/src/main/java/com/chat/yourway/service/ContactServiceImpl.java @@ -2,9 +2,8 @@ import com.chat.yourway.dto.request.ContactRequestDto; import com.chat.yourway.dto.request.EditContactProfileRequestDto; -import com.chat.yourway.exception.ContactNotFoundException; -import com.chat.yourway.exception.PasswordsAreNotEqualException; -import com.chat.yourway.exception.ValueNotUniqException; +import com.chat.yourway.dto.response.ContactProfileResponseDto; +import com.chat.yourway.exception.*; import com.chat.yourway.model.Contact; import com.chat.yourway.model.Role; import com.chat.yourway.repository.ContactRepository; @@ -90,4 +89,50 @@ public boolean isEmailExists(String email) { return contactRepository.existsByEmailIgnoreCase(email); } + @Override + public ContactProfileResponseDto getContactProfile(UserDetails userDetails) { + String email = userDetails.getUsername(); + Contact contact = + contactRepository + .findByEmailIgnoreCase(email) + .orElseThrow( + () -> new ContactNotFoundException(String.format("Email %s wasn't found", email))); + ContactProfileResponseDto responseDto = new ContactProfileResponseDto(); + + responseDto.setNickname(contact.getNickname()); + responseDto.setAvatarId(contact.getAvatarId()); + responseDto.setEmail(email); + responseDto.setHasPermissionSendingPrivateMessage(contact.isPermittedSendingPrivateMessage()); + + return responseDto; + } + + @Override + @Transactional + public void permitSendingPrivateMessages(UserDetails userDetails) { + boolean isPermittedSendingPrivateMessage = true; + + changePermissionSendingPrivateMessages(userDetails, isPermittedSendingPrivateMessage); + } + + @Override + @Transactional + public void prohibitSendingPrivateMessages(UserDetails userDetails) { + boolean isPermittedSendingPrivateMessage = false; + + changePermissionSendingPrivateMessages(userDetails, isPermittedSendingPrivateMessage); + } + + private void changePermissionSendingPrivateMessages( + UserDetails userDetails, boolean isPermittedSendingPrivateMessage) { + String contactEmail = userDetails.getUsername(); + + if (!contactRepository.existsByEmailIgnoreCase(contactEmail)) { + throw new ContactNotFoundException( + String.format("Contact with email [%s] is not found.", contactEmail)); + } + + contactRepository.updatePermissionSendingPrivateMessageByContactEmail( + contactEmail, isPermittedSendingPrivateMessage); + } } diff --git a/src/main/java/com/chat/yourway/service/TopicSubscriberServiceImpl.java b/src/main/java/com/chat/yourway/service/TopicSubscriberServiceImpl.java index e8ac35e4..f5f36847 100644 --- a/src/main/java/com/chat/yourway/service/TopicSubscriberServiceImpl.java +++ b/src/main/java/com/chat/yourway/service/TopicSubscriberServiceImpl.java @@ -115,47 +115,12 @@ public void removeTopicFromFavourite(Integer topicId, UserDetails userDetails) { topicId, contactEmail, isNotFavouriteTopic); } - @Override - @Transactional - public void permitSendingPrivateMessages(Integer topicId, UserDetails userDetails) { - boolean isPermittedSendingPrivateMessage = true; - - changePermissionSendingPrivateMessages(topicId, userDetails, isPermittedSendingPrivateMessage); - } - - @Override - @Transactional - public void prohibitSendingPrivateMessages(Integer topicId, UserDetails userDetails) { - boolean isPermittedSendingPrivateMessage = false; - - changePermissionSendingPrivateMessages(topicId, userDetails, isPermittedSendingPrivateMessage); - } @Override public boolean hasProhibitionSendingPrivateMessages(Integer topicId) { return topicSubscriberRepository.checkIfExistProhibitionSendingPrivateMessage(topicId); } - private void changePermissionSendingPrivateMessages( - Integer topicId, UserDetails userDetails, boolean isPermittedSendingPrivateMessage) { - String contactEmail = userDetails.getUsername(); - boolean isPublicTopic = false; - - if (!topicRepository.existsById(topicId)) { - throw new TopicNotFoundException(String.format("Topic with id [%d] is not found.", topicId)); - } else if (!topicRepository.existsByIdAndIsPublic(topicId, isPublicTopic)) { - throw new TopicNotFoundException( - String.format("Private topic with id [%d] is not found.", topicId)); - } else if (!topicSubscriberRepository.existsByContactEmailAndTopicIdAndUnsubscribeAtIsNull( - contactEmail, topicId)) { - throw new NotSubscribedTopicException( - "You cannot change permission of sending private messages because you did not subscribe before"); - } - - topicSubscriberRepository.updatePermissionSendingPrivateMessageByTopicIdAndContactEmail( - topicId, contactEmail, isPermittedSendingPrivateMessage); - } - private boolean isTopicCreator(Integer topicId, String topicCreator) { return topicSubscriberRepository.existsByTopicIdAndTopicCreatedBy(topicId, topicCreator); } diff --git a/src/main/java/com/chat/yourway/service/interfaces/ContactService.java b/src/main/java/com/chat/yourway/service/interfaces/ContactService.java index f535ad84..11e01717 100644 --- a/src/main/java/com/chat/yourway/service/interfaces/ContactService.java +++ b/src/main/java/com/chat/yourway/service/interfaces/ContactService.java @@ -2,6 +2,7 @@ import com.chat.yourway.dto.request.ContactRequestDto; import com.chat.yourway.dto.request.EditContactProfileRequestDto; +import com.chat.yourway.dto.response.ContactProfileResponseDto; import com.chat.yourway.exception.ContactNotFoundException; import com.chat.yourway.exception.ValueNotUniqException; import com.chat.yourway.model.Contact; @@ -57,4 +58,33 @@ public interface ContactService { * @return true if contact with email exists in repository */ boolean isEmailExists(String email); + + /** + * Retrieves the contact profile information for a given user. + * + * This method fetches and returns a ContactProfileResponseDto containing details + * such as contact information, preferences, and other relevant data for the specified user. + * + * @param userDetails The UserDetails object representing the user for whom the contact profile + * information is to be retrieved. + * @return A ContactProfileResponseDto containing the contact profile information for the user. + * + * @see UserDetails + * @see ContactProfileResponseDto + */ + ContactProfileResponseDto getContactProfile(UserDetails userDetails); + + /** + * Permits the sending of private messages for private topics to the given user. + * + * @param userDetails the UserDetails object representing the user + */ + void permitSendingPrivateMessages(UserDetails userDetails); + + /** + * Prohibits the sending of private messages for private topics to the given user. + * + * @param userDetails the UserDetails object representing the user + */ + void prohibitSendingPrivateMessages(UserDetails userDetails); } diff --git a/src/main/java/com/chat/yourway/service/interfaces/TopicSubscriberService.java b/src/main/java/com/chat/yourway/service/interfaces/TopicSubscriberService.java index fb3986a0..8939ee04 100644 --- a/src/main/java/com/chat/yourway/service/interfaces/TopicSubscriberService.java +++ b/src/main/java/com/chat/yourway/service/interfaces/TopicSubscriberService.java @@ -67,22 +67,6 @@ public interface TopicSubscriberService { */ void removeTopicFromFavourite(Integer topicId, UserDetails userDetails); - /** - * Permits the sending of private messages for a specific topic to the given user. - * - * @param topicId the ID of the topic for which private message sending is permitted - * @param userDetails the UserDetails object representing the user - */ - void permitSendingPrivateMessages(Integer topicId, UserDetails userDetails); - - /** - * Prohibits the sending of private messages for a specific topic to the given user. - * - * @param topicId the ID of the topic for which private message sending is prohibited - * @param userDetails the UserDetails object representing the user - */ - void prohibitSendingPrivateMessages(Integer topicId, UserDetails userDetails); - /** * Checks if sending private messages for a specific topic is prohibited for the given user. * diff --git a/src/main/resources/db/migration/V0025__add_is_permitted_sending_private_message_column_in_table_contact.sql b/src/main/resources/db/migration/V0025__add_is_permitted_sending_private_message_column_in_table_contact.sql new file mode 100644 index 00000000..cdca629c --- /dev/null +++ b/src/main/resources/db/migration/V0025__add_is_permitted_sending_private_message_column_in_table_contact.sql @@ -0,0 +1,9 @@ +ALTER TABLE chat.contact + ADD is_permitted_sending_private_message boolean DEFAULT true; + +UPDATE chat.contact +SET is_permitted_sending_private_message = true +where id > 0; + +ALTER TABLE chat.topic_subscriber +DROP COLUMN is_permitted_sending_message; \ No newline at end of file diff --git a/src/test/java/com/chat/yourway/integration/service/impl/ContactServiceImplTest.java b/src/test/java/com/chat/yourway/integration/service/impl/ContactServiceImplTest.java index 4ec6601e..6e5c3715 100644 --- a/src/test/java/com/chat/yourway/integration/service/impl/ContactServiceImplTest.java +++ b/src/test/java/com/chat/yourway/integration/service/impl/ContactServiceImplTest.java @@ -104,4 +104,133 @@ public void shouldThrowContactNotFoundException_whenUserIsNotExist() { verify(existingContact, never()).setNickname(anyString()); verify(existingContact, never()).setAvatarId(anyByte()); } + + @Test + @DisplayName("should get contact profile when user is exist") + @DatabaseSetup(value = "/dataset/contacts.xml", type = DatabaseOperation.INSERT) + @DatabaseTearDown(value = "/dataset/contacts.xml", type = DatabaseOperation.DELETE) + public void shouldGetContactProfile_whenUserIsExist() { + // Given + var email = "user@gmail.com"; + var userDetails = Mockito.mock(UserDetails.class); + + when(userDetails.getUsername()).thenReturn(email); + + // When + contactService.getContactProfile(userDetails); + var foundContact = contactRepository.findByEmailIgnoreCase(email).get(); + + // Then + assertAll( + () -> assertThat(foundContact) + .withFailMessage("Expecting nickname is present") + .extracting(Contact::getNickname) + .isNotNull(), + () -> assertThat(foundContact) + .withFailMessage("Expecting avatar id is present") + .extracting(Contact::getAvatarId) + .isNotNull(), + () -> assertThat(foundContact) + .withFailMessage("Expecting permission of sending private message is present") + .extracting(Contact::isPermittedSendingPrivateMessage) + .isNotNull()); + } + + @Test + @DisplayName( + "should throw ContactNotFoundException when contact profile is not exist") + @DatabaseSetup(value = "/dataset/contacts.xml", type = DatabaseOperation.INSERT) + @DatabaseTearDown(value = "/dataset/contacts.xml", type = DatabaseOperation.DELETE) + public void shouldThrowContactNotFoundException_whenContactProfileIsNotExist() { + // Given + var email = "test@example.com"; + var existingContact = Mockito.mock(Contact.class); + var userDetails = Mockito.mock(UserDetails.class); + + when(userDetails.getUsername()).thenReturn(email); + + // When + assertThrows( + ContactNotFoundException.class, + () -> contactService.getContactProfile(userDetails)); + + // Then + verify(existingContact, never()).setNickname(anyString()); + verify(existingContact, never()).setAvatarId(anyByte()); + verify(existingContact, never()).setPermittedSendingPrivateMessage(anyBoolean()); + } + + + @Test + @DatabaseSetup( + value = "/dataset/permission-sending-message-in-private-topic.xml", + type = DatabaseOperation.INSERT) + @DatabaseTearDown( + value = "/dataset/permission-sending-message-in-private-topic.xml", + type = DatabaseOperation.DELETE) + @DisplayName( + "should successfully permit sending private messages when user change permission") + public void shouldSuccessfullyPermitSendingPrivateMessages_whenUserChangePermission() { + // Given + var contactEmail = "vasil299@gmail.com"; + var contact = contactService.findByEmail(contactEmail); + + // When + contactService.permitSendingPrivateMessages(contact); + + // Then + var result = contactService.findByEmail(contactEmail); + + assertThat(result) + .extracting(Contact::isPermittedSendingPrivateMessage) + .isEqualTo(true); + } + + @Test + @DatabaseSetup( + value = "/dataset/permission-sending-message-in-private-topic.xml", + type = DatabaseOperation.INSERT) + @DatabaseTearDown( + value = "/dataset/permission-sending-message-in-private-topic.xml", + type = DatabaseOperation.DELETE) + @DisplayName( + "should successfully prohibit sending private messages when user change permission") + public void shouldSuccessfullyProhibitSendingPrivateMessages_whenUserChangePermission() { + // Given + var contactEmail = "vasil299@gmail.com"; + var contact = contactService.findByEmail(contactEmail); + + // When + contactService.prohibitSendingPrivateMessages(contact); + + // Then + var result = contactService.findByEmail(contactEmail); + + assertThat(result) + .extracting(Contact::isPermittedSendingPrivateMessage) + .isEqualTo(false); + } + + @Test + @DatabaseSetup( + value = "/dataset/permission-sending-message-in-private-topic.xml", + type = DatabaseOperation.INSERT) + @DatabaseTearDown( + value = "/dataset/permission-sending-message-in-private-topic.xml", + type = DatabaseOperation.DELETE) + @DisplayName( + "should throw ContactNotFoundException when user change permission") + public void shouldThrowContactNotFoundException_whenUserChangePermission() { + // Given + var contactEmail = "vasil2929@gmail.com"; + Contact contact = new Contact(); + + contact.setEmail(contactEmail); + + // When + // Then + assertThrows( + ContactNotFoundException.class, + () -> contactService.permitSendingPrivateMessages(contact)); + } } diff --git a/src/test/java/com/chat/yourway/integration/service/impl/TopicSubscriberServiceImplTest.java b/src/test/java/com/chat/yourway/integration/service/impl/TopicSubscriberServiceImplTest.java index b8b36d10..0459ce7d 100644 --- a/src/test/java/com/chat/yourway/integration/service/impl/TopicSubscriberServiceImplTest.java +++ b/src/test/java/com/chat/yourway/integration/service/impl/TopicSubscriberServiceImplTest.java @@ -185,127 +185,4 @@ public void shouldThrowTopicNotFoundException_whenUserMarkTopicAsFavouriteAndTop () -> topicSubscriberService.removeTopicFromFavourite(topicId, contact)); } - @Test - @DatabaseSetup( - value = "/dataset/permission-sending-message-in-private-topic.xml", - type = DatabaseOperation.INSERT) - @DatabaseTearDown( - value = "/dataset/permission-sending-message-in-private-topic.xml", - type = DatabaseOperation.DELETE) - @DisplayName( - "should successfully permit sending private messages when user change permission of topic") - public void shouldSuccessfullyPermitSendingPrivateMessages_whenUserChangePermissionOfTopic() { - // Given - var contactEmail = "vasil299@gmail.com"; - var contact = contactService.findByEmail(contactEmail); - var topicId = 212; - - // When - topicSubscriberService.permitSendingPrivateMessages(topicId, contact); - - // Then - var result = - topicService.findById(topicId).getTopicSubscribers().stream() - .filter(ts -> ts.getContact().getEmail().equals(contactEmail)) - .findFirst() - .orElseThrow(() -> new AssertionError("Expected subscriber of topic is not present.")); - - assertThat(result) - .extracting(TopicSubscriberResponseDto::isPermittedSendingMessage) - .isEqualTo(true); - } - - @Test - @DatabaseSetup( - value = "/dataset/permission-sending-message-in-private-topic.xml", - type = DatabaseOperation.INSERT) - @DatabaseTearDown( - value = "/dataset/permission-sending-message-in-private-topic.xml", - type = DatabaseOperation.DELETE) - @DisplayName( - "should successfully prohibit sending private messages when user change permission of topic") - public void shouldSuccessfullyProhibitSendingPrivateMessages_whenUserChangePermissionOfTopic() { - // Given - var contactEmail = "vasil299@gmail.com"; - var contact = contactService.findByEmail(contactEmail); - var topicId = 211; - - // When - topicSubscriberService.prohibitSendingPrivateMessages(topicId, contact); - - // Then - var result = - topicService.findById(topicId).getTopicSubscribers().stream() - .filter(ts -> ts.getContact().getEmail().equals(contactEmail)) - .findFirst() - .orElseThrow(() -> new AssertionError("Expected subscriber of topic is not present.")); - - assertThat(result) - .extracting(TopicSubscriberResponseDto::isPermittedSendingMessage) - .isEqualTo(false); - } - - @Test - @DatabaseSetup( - value = "/dataset/permission-sending-message-in-private-topic.xml", - type = DatabaseOperation.INSERT) - @DatabaseTearDown( - value = "/dataset/permission-sending-message-in-private-topic.xml", - type = DatabaseOperation.DELETE) - @DisplayName( - "should throw TopicNotFoundException when user change permission of not existed topic") - public void shouldThrowTopicNotFoundException_whenUserChangePermissionOfNotExistedTopic() { - // Given - var contactEmail = "vasil299@gmail.com"; - var contact = contactService.findByEmail(contactEmail); - var topicId = 217; - - // When - // Then - assertThrows( - TopicNotFoundException.class, - () -> topicSubscriberService.permitSendingPrivateMessages(topicId, contact)); - } - - @Test - @DatabaseSetup( - value = "/dataset/permission-sending-message-in-private-topic.xml", - type = DatabaseOperation.INSERT) - @DatabaseTearDown( - value = "/dataset/permission-sending-message-in-private-topic.xml", - type = DatabaseOperation.DELETE) - @DisplayName("should throw TopicNotFoundException when user change permission of public topic") - public void shouldThrowTopicNotFoundException_whenUserChangePermissionOfPublicTopic() { - // Given - var contactEmail = "vasil299@gmail.com"; - var contact = contactService.findByEmail(contactEmail); - var topicId = 213; - - // When - // Then - assertThrows( - TopicNotFoundException.class, - () -> topicSubscriberService.permitSendingPrivateMessages(topicId, contact)); - } - - @Test - @DatabaseSetup( - value = "/dataset/permission-sending-message-in-private-topic.xml", - type = DatabaseOperation.INSERT) - @DatabaseTearDown( - value = "/dataset/permission-sending-message-in-private-topic.xml", - type = DatabaseOperation.DELETE) - @DisplayName("should throw NotSubscribedException when user change permission of topic") - public void shouldThrowNotSubscribedException_whenUserChangePermissionOfTopic() { - // Given - var contactEmail = "anton912@gmail.com"; - var contact = contactService.findByEmail(contactEmail); - var topicId = 212; - - // When - // Then - assertThrows( - NotSubscribedTopicException.class, - () -> topicSubscriberService.permitSendingPrivateMessages(topicId, contact)); - } } diff --git a/src/test/resources/dataset/contacts.xml b/src/test/resources/dataset/contacts.xml index 264434a2..308f6be9 100644 --- a/src/test/resources/dataset/contacts.xml +++ b/src/test/resources/dataset/contacts.xml @@ -8,6 +8,7 @@ is_active="true" is_private="true" email="user@gmail.com" + is_permitted_sending_private_message="true" role="USER" /> diff --git a/src/test/resources/dataset/favourite-topics-of-contact.xml b/src/test/resources/dataset/favourite-topics-of-contact.xml index c6c548a3..de5554ce 100644 --- a/src/test/resources/dataset/favourite-topics-of-contact.xml +++ b/src/test/resources/dataset/favourite-topics-of-contact.xml @@ -9,6 +9,7 @@ email="vasil1@gmail.com" role="USER" avatar_id="1" + is_permitted_sending_private_message="true" /> \ No newline at end of file diff --git a/src/test/resources/dataset/permission-sending-message-in-private-topic.xml b/src/test/resources/dataset/permission-sending-message-in-private-topic.xml index 65589d15..213281e3 100644 --- a/src/test/resources/dataset/permission-sending-message-in-private-topic.xml +++ b/src/test/resources/dataset/permission-sending-message-in-private-topic.xml @@ -9,6 +9,7 @@ email="vasil299@gmail.com" role="USER" avatar_id="1" + is_permitted_sending_private_message="true" /> + + \ No newline at end of file diff --git a/src/test/resources/dataset/popular-topic-dataset.xml b/src/test/resources/dataset/popular-topic-dataset.xml index f7f2f469..6c6933e3 100644 --- a/src/test/resources/dataset/popular-topic-dataset.xml +++ b/src/test/resources/dataset/popular-topic-dataset.xml @@ -9,6 +9,7 @@ email="vasil3000@gmail.com" role="USER" avatar_id="1" + is_permitted_sending_private_message="true" /> Date: Tue, 5 Dec 2023 19:24:59 +0200 Subject: [PATCH 2/3] feat: prepare ContactProfileResponseDto and ContactResponseDto with new field --- .../yourway/config/openapi/OpenApiExamples.java | 6 ++++++ .../yourway/config/openapi/OpenApiMessages.java | 5 ++++- .../dto/response/ContactProfileResponseDto.java | 15 +++++++++++++++ .../yourway/dto/response/ContactResponseDto.java | 1 + 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/chat/yourway/dto/response/ContactProfileResponseDto.java diff --git a/src/main/java/com/chat/yourway/config/openapi/OpenApiExamples.java b/src/main/java/com/chat/yourway/config/openapi/OpenApiExamples.java index 74550152..63a1058a 100644 --- a/src/main/java/com/chat/yourway/config/openapi/OpenApiExamples.java +++ b/src/main/java/com/chat/yourway/config/openapi/OpenApiExamples.java @@ -31,4 +31,10 @@ public class OpenApiExamples { "avatarId": 2 }"""; + public static final String GET_CONTACT_PROFILE = """ + { + "nickname": "JohnDoe", + "email": "johndoe@gmail.com", + "avatarId": 2 + }"""; } diff --git a/src/main/java/com/chat/yourway/config/openapi/OpenApiMessages.java b/src/main/java/com/chat/yourway/config/openapi/OpenApiMessages.java index 4fcf819b..d997a8f0 100644 --- a/src/main/java/com/chat/yourway/config/openapi/OpenApiMessages.java +++ b/src/main/java/com/chat/yourway/config/openapi/OpenApiMessages.java @@ -25,6 +25,8 @@ public class OpenApiMessages { "Contact successfully restored password"; public static final String SUCCESSFULLY_UPDATED_CONTACT_PROFILE = "Contact profile successfully updated"; + public static final String SUCCESSFULLY_RECEIVED_CONTACT_PROFILE = + "Contact profile successfully received"; public static final String SUCCESSFULLY_REPORTED_MESSAGE = "Message is reported successfully"; public static final String MESSAGE_NOT_FOUND = "Message wasn't found in repository"; public static final String MESSAGE_HAS_ALREADY_REPORTED = "You have already made report"; @@ -42,7 +44,8 @@ public class OpenApiMessages { public static final String SUCCESSFULLY_UPDATED_TOPIC = "Topic successfully updated"; public static final String INVALID_VALUE = "Invalid value of request object field"; public static final String SUCCESSFULLY_FOUND_MESSAGE = "Message successfully found"; - + public static final String SUCCESSFULLY_PERMITTED_SENDING_PRIVATE_MESSAGES = "Successfully permitted sending private messages"; + public static final String SUCCESSFULLY_PROHIBITED_SENDING_PRIVATE_MESSAGES = "Successfully prohibited sending private messages"; public static final String SUCCESSFULLY_ADD_TOPIC_TO_FAVOURITE = "Topic added to favourite successfully"; diff --git a/src/main/java/com/chat/yourway/dto/response/ContactProfileResponseDto.java b/src/main/java/com/chat/yourway/dto/response/ContactProfileResponseDto.java new file mode 100644 index 00000000..b05dada8 --- /dev/null +++ b/src/main/java/com/chat/yourway/dto/response/ContactProfileResponseDto.java @@ -0,0 +1,15 @@ +package com.chat.yourway.dto.response; + +import lombok.*; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@ToString +public class ContactProfileResponseDto { + private String nickname; + private String email; + private Byte avatarId; + private Boolean hasPermissionSendingPrivateMessage; +} diff --git a/src/main/java/com/chat/yourway/dto/response/ContactResponseDto.java b/src/main/java/com/chat/yourway/dto/response/ContactResponseDto.java index 6647765d..c50ff72c 100644 --- a/src/main/java/com/chat/yourway/dto/response/ContactResponseDto.java +++ b/src/main/java/com/chat/yourway/dto/response/ContactResponseDto.java @@ -25,4 +25,5 @@ public class ContactResponseDto { private Boolean isPrivate; + private boolean isPermittedSendingPrivateMessage; } From 46a482b3794cd998e2d9ab558b9bd231c7ef08c3 Mon Sep 17 00:00:00 2001 From: dmytro Date: Tue, 5 Dec 2023 19:37:22 +0200 Subject: [PATCH 3/3] refactor: upgrade code --- .../config/openapi/OpenApiExamples.java | 7 -- .../yourway/controller/ContactController.java | 113 +++++++++++------- .../service/interfaces/ContactService.java | 1 - .../impl/TopicSubscriberServiceImplTest.java | 1 - 4 files changed, 69 insertions(+), 53 deletions(-) diff --git a/src/main/java/com/chat/yourway/config/openapi/OpenApiExamples.java b/src/main/java/com/chat/yourway/config/openapi/OpenApiExamples.java index 63a1058a..89b0151a 100644 --- a/src/main/java/com/chat/yourway/config/openapi/OpenApiExamples.java +++ b/src/main/java/com/chat/yourway/config/openapi/OpenApiExamples.java @@ -30,11 +30,4 @@ public class OpenApiExamples { "nickname": "editNickname", "avatarId": 2 }"""; - - public static final String GET_CONTACT_PROFILE = """ - { - "nickname": "JohnDoe", - "email": "johndoe@gmail.com", - "avatarId": 2 - }"""; } diff --git a/src/main/java/com/chat/yourway/controller/ContactController.java b/src/main/java/com/chat/yourway/controller/ContactController.java index d29eeb2c..414059ba 100644 --- a/src/main/java/com/chat/yourway/controller/ContactController.java +++ b/src/main/java/com/chat/yourway/controller/ContactController.java @@ -28,70 +28,95 @@ public class ContactController { private final ContactService contactService; - @Operation(summary = "Edit contact profile", + @Operation( + summary = "Edit contact profile", responses = { - @ApiResponse(responseCode = "200", description = SUCCESSFULLY_UPDATED_CONTACT_PROFILE), - @ApiResponse(responseCode = "404", description = CONTACT_NOT_FOUND, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), - @ApiResponse(responseCode = "403", description = CONTACT_UNAUTHORIZED, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) + @ApiResponse(responseCode = "200", description = SUCCESSFULLY_UPDATED_CONTACT_PROFILE), + @ApiResponse( + responseCode = "404", + description = CONTACT_NOT_FOUND, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), + @ApiResponse( + responseCode = "403", + description = CONTACT_UNAUTHORIZED, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) }, - requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody( - content = @Content(schema = @Schema(implementation = EditContactProfileRequestDto.class), - examples = @ExampleObject(value = OpenApiExamples.EDIT_CONTACT_PROFILE, - description = "Edit Contact profile")))) - @PatchMapping(path = "/profile", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) + requestBody = + @io.swagger.v3.oas.annotations.parameters.RequestBody( + content = + @Content( + schema = @Schema(implementation = EditContactProfileRequestDto.class), + examples = + @ExampleObject( + value = OpenApiExamples.EDIT_CONTACT_PROFILE, + description = "Edit Contact profile")))) + @PatchMapping( + path = "/profile", + consumes = APPLICATION_JSON_VALUE, + produces = APPLICATION_JSON_VALUE) public void editContactProfile( @Valid @RequestBody EditContactProfileRequestDto editContactProfileRequestDto, @AuthenticationPrincipal UserDetails userDetails) { contactService.updateContactProfile(editContactProfileRequestDto, userDetails); } - @Operation(summary = "Get contact profile", - responses = { - @ApiResponse(responseCode = "200", description = SUCCESSFULLY_RECEIVED_CONTACT_PROFILE), - @ApiResponse(responseCode = "404", description = CONTACT_NOT_FOUND, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), - @ApiResponse(responseCode = "403", description = CONTACT_UNAUTHORIZED, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) - }) + @Operation( + summary = "Get contact profile", + responses = { + @ApiResponse( + responseCode = "200", + description = SUCCESSFULLY_RECEIVED_CONTACT_PROFILE, + content = @Content(schema = @Schema(implementation = ContactProfileResponseDto.class))), + @ApiResponse( + responseCode = "404", + description = CONTACT_NOT_FOUND, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), + @ApiResponse( + responseCode = "403", + description = CONTACT_UNAUTHORIZED, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) + }) @GetMapping(path = "/profile", produces = APPLICATION_JSON_VALUE) public ContactProfileResponseDto getContactProfile( - @AuthenticationPrincipal UserDetails userDetails) { + @AuthenticationPrincipal UserDetails userDetails) { return contactService.getContactProfile(userDetails); } @Operation( - summary = "Prohibit sending private message", - responses = { - @ApiResponse(responseCode = "200", description = SUCCESSFULLY_PROHIBITED_SENDING_PRIVATE_MESSAGES), - @ApiResponse( - responseCode = "403", - description = CONTACT_UNAUTHORIZED, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), - @ApiResponse( - responseCode = "404", - description = CONTACT_NOT_FOUND, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) - }) + summary = "Prohibit sending private message", + responses = { + @ApiResponse( + responseCode = "200", + description = SUCCESSFULLY_PROHIBITED_SENDING_PRIVATE_MESSAGES), + @ApiResponse( + responseCode = "403", + description = CONTACT_UNAUTHORIZED, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), + @ApiResponse( + responseCode = "404", + description = CONTACT_NOT_FOUND, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) + }) @PatchMapping(path = "/message/send/prohibit") public void prohibitSendingPrivateMessages(@AuthenticationPrincipal UserDetails userDetails) { contactService.prohibitSendingPrivateMessages(userDetails); } @Operation( - summary = "Permit sending private message", - responses = { - @ApiResponse(responseCode = "200", description = SUCCESSFULLY_PERMITTED_SENDING_PRIVATE_MESSAGES), - @ApiResponse( - responseCode = "403", - description = CONTACT_UNAUTHORIZED, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), - @ApiResponse( - responseCode = "404", - description = CONTACT_NOT_FOUND, - content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) - }) + summary = "Permit sending private message", + responses = { + @ApiResponse( + responseCode = "200", + description = SUCCESSFULLY_PERMITTED_SENDING_PRIVATE_MESSAGES), + @ApiResponse( + responseCode = "403", + description = CONTACT_UNAUTHORIZED, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))), + @ApiResponse( + responseCode = "404", + description = CONTACT_NOT_FOUND, + content = @Content(schema = @Schema(implementation = ApiErrorResponseDto.class))) + }) @PatchMapping(path = "/message/send/permit") public void permitSendingPrivateMessages(@AuthenticationPrincipal UserDetails userDetails) { contactService.permitSendingPrivateMessages(userDetails); diff --git a/src/main/java/com/chat/yourway/service/interfaces/ContactService.java b/src/main/java/com/chat/yourway/service/interfaces/ContactService.java index 11e01717..98c22e4e 100644 --- a/src/main/java/com/chat/yourway/service/interfaces/ContactService.java +++ b/src/main/java/com/chat/yourway/service/interfaces/ContactService.java @@ -61,7 +61,6 @@ public interface ContactService { /** * Retrieves the contact profile information for a given user. - * * This method fetches and returns a ContactProfileResponseDto containing details * such as contact information, preferences, and other relevant data for the specified user. * diff --git a/src/test/java/com/chat/yourway/integration/service/impl/TopicSubscriberServiceImplTest.java b/src/test/java/com/chat/yourway/integration/service/impl/TopicSubscriberServiceImplTest.java index 0459ce7d..d9cf4306 100644 --- a/src/test/java/com/chat/yourway/integration/service/impl/TopicSubscriberServiceImplTest.java +++ b/src/test/java/com/chat/yourway/integration/service/impl/TopicSubscriberServiceImplTest.java @@ -1,6 +1,5 @@ package com.chat.yourway.integration.service.impl; -import com.chat.yourway.dto.response.TopicSubscriberResponseDto; import com.chat.yourway.exception.NotSubscribedTopicException; import com.chat.yourway.exception.TopicNotFoundException; import com.chat.yourway.integration.extension.PostgresExtension;