Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,7 @@ public class ChatRoomConverter {

public static ChatRoomResultDTO toChatRoomResultDTO(ChatRoom chatRoom, User user, Post post, Long unreadCount, String thumbnailUrl, boolean isBlocked) {

var opponentUser = opponentUserDTO.builder()
.opponentUserId(user.getId())
.nickname(user.getNickname())
.profileImageUrl(user.getProfile_img() == null ? null : user.getProfile_img())
.emailVerified(user.isEmail_verified())
.blocked(isBlocked)
.build();
var opponentUser = buildOpponentUserDTO(user, isBlocked);

var postInfo = PostInfoDTO.builder()
.postId(post.getId())
Expand All @@ -46,13 +40,7 @@ public static ChatRoomResultDTO toChatRoomResultDTO(ChatRoom chatRoom, User user

public static ChatRoomResultDTO toChatRoomResultDTOFromSnapshot(ChatRoom chatRoom, User opponent, Long unreadCount, boolean isBlocked) {

var opponentUser = opponentUserDTO.builder()
.opponentUserId(opponent.getId())
.nickname(opponent.getNickname())
.profileImageUrl(opponent.getProfile_img())
.emailVerified(opponent.isEmail_verified())
.blocked(isBlocked)
.build();
var opponentUser = buildOpponentUserDTO(opponent, isBlocked);

var postInfo = PostInfoDTO.builder()
.postId(chatRoom.getSourcePostId())
Expand Down Expand Up @@ -86,11 +74,7 @@ public static List<ChatRoomSummaryDTO> toChatRoomSummaryListDTO(List<ChatRoomPar

public static ChatRoomSummaryDTO toChatRoomSummaryDTO(ChatRoomParticipant participant, User contactUser, Map<Long, String> thumbnailMap) {

ContactUserDTO contactUserDTO = ContactUserDTO.builder()
.userId(contactUser.getId())
.nickname(contactUser.getNickname())
.profileImageUrl(contactUser.getProfile_img())
.build();
ContactUserDTO contactUserDTO = buildContactUserDTO(contactUser);

ChatRoom room = participant.getChatRoom();

Expand Down Expand Up @@ -144,6 +128,49 @@ private static boolean isImageMessage(ChatMessage message) {
return message.getMessageType() == MessageType.IMAGE;
}

private static ContactUserDTO buildContactUserDTO(User user) {
boolean withdrawn = user.getDeletedAt() != null;

if (withdrawn) {
return ContactUserDTO.builder()
.userId(user.getId())
.nickname(null)
Comment thread
Yoosejeong marked this conversation as resolved.
.profileImageUrl(null)
.withdrawn(true)
.build();
}

return ContactUserDTO.builder()
.userId(user.getId())
.nickname(user.getNickname())
.profileImageUrl(user.getProfile_img())
.withdrawn(false)
.build();
}

private static opponentUserDTO buildOpponentUserDTO(User user, boolean isBlocked) {
boolean withdrawn = user.getDeletedAt() != null;

if (withdrawn) {
return opponentUserDTO.builder()
.opponentUserId(user.getId())
.nickname(null)
Comment thread
Yoosejeong marked this conversation as resolved.
.profileImageUrl(null)
.emailVerified(false)
.blocked(isBlocked)
.withdrawn(true)
.build();
}

return opponentUserDTO.builder()
.opponentUserId(user.getId())
.nickname(user.getNickname())
.profileImageUrl(user.getProfile_img())
.emailVerified(user.isEmail_verified())
.blocked(isBlocked)
.withdrawn(false)
.build();
}

private ChatRoomConverter() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public static class opponentUserDTO {
private String profileImageUrl;
private boolean emailVerified;
private boolean blocked;
private boolean withdrawn;
}

@Builder
Expand Down Expand Up @@ -83,5 +84,6 @@ public static class ContactUserDTO {
private Long userId;
private String nickname;
private String profileImageUrl;
private boolean withdrawn;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
@Repository
public interface BlockedUserRepository extends JpaRepository<BlockedUser, Long> {
boolean existsByBlockerAndBlocked(User blocker, User blocked);
boolean existsByBlocker_IdAndBlocked_Id(Long blockerId, Long blockedId);
Optional<BlockedUser> findByBlockerAndBlocked(User blocker, User blocked);
List<BlockedUser> findAllByBlocker(User blocker);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,8 @@ private void saveBlockIfNotExists(User blocker, User blocked) {
}

public boolean isBlocked(Long blockerUserId, Long otherUserId) {
User blocker = userRepository.findActiveById(blockerUserId)
.orElseThrow(() -> new GeneralException(ErrorStatus._USER_NOT_FOUND));
User other = userRepository.findActiveById(otherUserId)
.orElseThrow(() -> new GeneralException(ErrorStatus._USER_NOT_FOUND));
// 양방향 중 하나라도 존재하면 차단된 것으로 간주
return blockedUserRepository.existsByBlockerAndBlocked(blocker, other)
|| blockedUserRepository.existsByBlockerAndBlocked(other, blocker);
return blockedUserRepository.existsByBlocker_IdAndBlocked_Id(blockerUserId, otherUserId)
|| blockedUserRepository.existsByBlocker_IdAndBlocked_Id(otherUserId, blockerUserId);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;

import java.time.LocalDateTime;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -197,6 +198,87 @@ void getChatRoomDetail_postHardDeleted_returnsSnapshot() {
assertThat(result.getPostInfo().isDeleted()).isTrue();
}

@Test
@DisplayName("getChatRoomDetail - 상대가 탈퇴한 경우 withdrawn=true, 개인정보는 마스킹된다")
void getChatRoomDetail_opponentWithdrawn_returnsMaskedDto() {
User withdrawnOpponent = User.builder()
.id(2L)
.email("other@test.com")
.nickname("상대")
.profile_img("https://s3.example.com/p.jpg")
.email_verified(true)
.deletedAt(LocalDateTime.now().minusDays(1))
.build();

Post post = mock(Post.class);
given(post.getId()).willReturn(99L);
given(post.getTitle()).willReturn("제목");
given(post.getPostType()).willReturn(PostType.LOST);
given(post.getCategory()).willReturn(Category.WALLET);
given(post.getAddress()).willReturn("서울");
given(post.getPostStatus()).willReturn(PostStatus.SEARCHING);
given(post.isDeleted()).willReturn(false);

ChatRoom chatRoom = mock(ChatRoom.class);
given(chatRoom.getId()).willReturn(10L);
given(chatRoom.isSourcePostDeleted()).willReturn(false);
given(chatRoom.getPost()).willReturn(post);
given(chatRoom.getOtherParticipant(currentUser.getId())).willReturn(withdrawnOpponent);
given(chatRoom.getParticipant(currentUser.getId())).willReturn(participant);

given(chatRoomRepository.findById(10L)).willReturn(Optional.of(chatRoom));
given(postImageService.findThumbnailImageUrl(post)).willReturn(null);
given(blockService.isBlocked(currentUser.getId(), withdrawnOpponent.getId())).willReturn(false);

ChatRoomResultDTO result = chatRoomService.getChatRoomDetail(10L, currentUser);

assertThat(result.getOpponentUser().isWithdrawn()).isTrue();
assertThat(result.getOpponentUser().getOpponentUserId()).isEqualTo(2L);
assertThat(result.getOpponentUser().getNickname()).isNull();
assertThat(result.getOpponentUser().getProfileImageUrl()).isNull();
assertThat(result.getOpponentUser().isEmailVerified()).isFalse();
assertThat(result.getOpponentUser().isBlocked()).isFalse();
}

@Test
@DisplayName("getChatRoomDetail - 상대가 활성 상태면 withdrawn=false, 기존 정보 그대로 반환한다")
void getChatRoomDetail_opponentActive_returnsOriginalDto() {
User activeOpponent = User.builder()
.id(2L)
.email("other@test.com")
.nickname("상대")
.profile_img("https://s3.example.com/p.jpg")
.email_verified(true)
.build();

Post post = mock(Post.class);
given(post.getId()).willReturn(99L);
given(post.getTitle()).willReturn("제목");
given(post.getPostType()).willReturn(PostType.LOST);
given(post.getCategory()).willReturn(Category.WALLET);
given(post.getAddress()).willReturn("서울");
given(post.getPostStatus()).willReturn(PostStatus.SEARCHING);
given(post.isDeleted()).willReturn(false);

ChatRoom chatRoom = mock(ChatRoom.class);
given(chatRoom.getId()).willReturn(10L);
given(chatRoom.isSourcePostDeleted()).willReturn(false);
given(chatRoom.getPost()).willReturn(post);
given(chatRoom.getOtherParticipant(currentUser.getId())).willReturn(activeOpponent);
given(chatRoom.getParticipant(currentUser.getId())).willReturn(participant);

given(chatRoomRepository.findById(10L)).willReturn(Optional.of(chatRoom));
given(postImageService.findThumbnailImageUrl(post)).willReturn(null);
given(blockService.isBlocked(currentUser.getId(), activeOpponent.getId())).willReturn(false);

ChatRoomResultDTO result = chatRoomService.getChatRoomDetail(10L, currentUser);

assertThat(result.getOpponentUser().isWithdrawn()).isFalse();
assertThat(result.getOpponentUser().getNickname()).isEqualTo("상대");
assertThat(result.getOpponentUser().getProfileImageUrl()).isEqualTo("https://s3.example.com/p.jpg");
assertThat(result.getOpponentUser().isEmailVerified()).isTrue();
}

@Test
@DisplayName("getChatRoomDetail - unreadCount가 응답에 포함된다")
void getChatRoomDetail_returnsUnreadCount() {
Expand Down
Loading