Skip to content

Commit

Permalink
fix: ✏️ Fix Entity By ChatMember's Name Domain Rule (#208)
Browse files Browse the repository at this point in the history
* fix: delete name field from chat_member

* fix: update query for receiving chat_member's name field from user table

* fix: update query-dsl for receiving chat_member's name field from user table

* test: read member query dao test

* fix: add find user step in chatroom_with_participants_search_service

* fix: change name parameter source from chat_member to user_name in chat_member_join_service

* test: add given clauses in chatroom-with-participant-search-service-test
  • Loading branch information
psychology50 authored Nov 28, 2024
1 parent 3387c97 commit fc333f5
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public Triple<ChatRoom, Integer, Long> execute(Long userId, Long chatRoomId, Int
ChatMember member = chatMemberService.createMember(user, chatRoom);
Long unreadMessageCount = chatMessageService.countUnreadMessages(chatRoomId, 0L);

eventPublisher.publishEvent(ChatRoomJoinEvent.of(chatRoomId, member.getName()));
eventPublisher.publishEvent(ChatRoomJoinEvent.of(chatRoomId, user.getName()));

return ImmutableTriple.of(chatRoom, currentMemberCount.intValue() + 1, unreadMessageCount);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import kr.co.pennyway.api.apis.chat.dto.ChatRoomRes;
import kr.co.pennyway.api.apis.chat.mapper.ChatRoomMapper;
import kr.co.pennyway.domain.context.account.service.UserService;
import kr.co.pennyway.domain.context.chat.service.ChatMemberService;
import kr.co.pennyway.domain.context.chat.service.ChatMessageService;
import kr.co.pennyway.domain.domains.member.domain.ChatMember;
Expand All @@ -10,6 +11,7 @@
import kr.co.pennyway.domain.domains.member.exception.ChatMemberErrorException;
import kr.co.pennyway.domain.domains.member.type.ChatMemberRole;
import kr.co.pennyway.domain.domains.message.domain.ChatMessage;
import kr.co.pennyway.domain.domains.user.domain.User;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
Expand All @@ -26,15 +28,19 @@
public class ChatRoomWithParticipantsSearchService {
private static final int MESSAGE_LIMIT = 15;

private final UserService userService;
private final ChatMemberService chatMemberService;
private final ChatMessageService chatMessageService;

@Transactional(readOnly = true)
public ChatRoomRes.RoomWithParticipants execute(Long userId, Long chatRoomId) {
// 내 정보 조회
User me = userService.readUser(userId)
.orElseThrow(() -> new ChatMemberErrorException(ChatMemberErrorCode.NOT_FOUND));

ChatMember myInfo = chatMemberService.readChatMember(userId, chatRoomId)
.orElseThrow(() -> new ChatMemberErrorException(ChatMemberErrorCode.NOT_FOUND));
ChatMemberResult.Detail myDetail = new ChatMemberResult.Detail(myInfo.getId(), myInfo.getName(), myInfo.getRole(), myInfo.isNotifyEnabled(), userId, myInfo.getCreatedAt());
ChatMemberResult.Detail myDetail = new ChatMemberResult.Detail(myInfo.getId(), me.getName(), myInfo.getRole(), myInfo.isNotifyEnabled(), userId, myInfo.getCreatedAt());

// 최근 메시지 조회 (15건)
List<ChatMessage> chatMessages = chatMessageService.readRecentMessages(chatRoomId, MESSAGE_LIMIT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import kr.co.pennyway.api.config.fixture.ChatMemberFixture;
import kr.co.pennyway.api.config.fixture.ChatRoomFixture;
import kr.co.pennyway.api.config.fixture.UserFixture;
import kr.co.pennyway.domain.context.account.service.UserService;
import kr.co.pennyway.domain.context.chat.service.ChatMemberService;
import kr.co.pennyway.domain.context.chat.service.ChatMessageService;
import kr.co.pennyway.domain.domains.chatroom.domain.ChatRoom;
Expand Down Expand Up @@ -45,6 +46,8 @@ public class ChatRoomWithParticipantsSearchServiceTest {
@InjectMocks
private ChatRoomWithParticipantsSearchService service;
@Mock
private UserService userService;
@Mock
private ChatMemberService chatMemberService;
@Mock
private ChatMessageService chatMessageService;
Expand All @@ -63,6 +66,7 @@ public void successToRetrieveChatRoomWithParticipantsAndRecentMessages() {
List<ChatMemberResult.Detail> recentParticipants = createRecentParticipantDetails();
List<ChatMemberResult.Summary> otherParticipants = createOtherParticipantSummaries();

given(userService.readUser(userId)).willReturn(Optional.of(UserFixture.GENERAL_USER.toUser()));
given(chatMemberService.readChatMember(userId, chatRoom.getId())).willReturn(Optional.of(myInfo));
given(chatMessageService.readRecentMessages(eq(chatRoom.getId()), anyInt())).willReturn(recentMessages);
given(chatMemberService.readChatMembersByUserIds(eq(chatRoom.getId()), anySet())).willReturn(recentParticipants);
Expand All @@ -82,6 +86,7 @@ public void successToRetrieveChatRoomWithParticipantsAndRecentMessages() {
);

// verify
verify(userService).readUser(userId);
verify(chatMemberService).readChatMember(userId, chatRoom.getId());
verify(chatMessageService).readRecentMessages(eq(chatRoom.getId()), anyInt());
verify(chatMemberService).readChatMembersByUserIds(eq(chatRoom.getId()), anySet());
Expand All @@ -99,6 +104,7 @@ public void memberSuccessToRetrieveChatRoomWithParticipantsIncludingAdmin() {
List<ChatMemberResult.Detail> recentParticipants = createRecentParticipantDetails();
List<ChatMemberResult.Summary> otherParticipants = createOtherParticipantSummaries();

given(userService.readUser(userId)).willReturn(Optional.of(UserFixture.GENERAL_USER.toUser()));
given(chatMemberService.readChatMember(userId, chatRoom.getId())).willReturn(Optional.of(myInfo));
given(chatMessageService.readRecentMessages(eq(chatRoom.getId()), eq(15))).willReturn(recentMessages);
given(chatMemberService.readChatMembersByUserIds(eq(chatRoom.getId()), anySet())).willReturn(recentParticipants);
Expand Down Expand Up @@ -127,6 +133,7 @@ public void memberSuccessToRetrieveChatRoomWithParticipantsIncludingAdmin() {
@DisplayName("존재하지 않는 채팅방 멤버 조회 시 예외가 발생한다")
void throwExceptionWhenChatMemberNotFound() {
// given
given(userService.readUser(userId)).willReturn(Optional.of(UserFixture.GENERAL_USER.toUser()));
given(chatMemberService.readChatMember(userId, chatRoom.getId())).willReturn(Optional.empty());

// when
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.SQLDelete;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Objects;
Expand All @@ -29,8 +28,6 @@ public class ChatMember extends DateAuditable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;

@Convert(converter = ChatMemberRoleConverter.class)
private ChatMemberRole role;

Expand All @@ -51,10 +48,9 @@ public class ChatMember extends DateAuditable {
private ChatRoom chatRoom;

@Builder
protected ChatMember(String name, User user, ChatRoom chatRoom, ChatMemberRole role) {
validate(name, user, chatRoom, role);
protected ChatMember(User user, ChatRoom chatRoom, ChatMemberRole role) {
validate(user, chatRoom, role);

this.name = name;
this.user = user;
this.chatRoom = chatRoom;
this.role = role;
Expand All @@ -63,18 +59,13 @@ protected ChatMember(String name, User user, ChatRoom chatRoom, ChatMemberRole r

public static ChatMember of(User user, ChatRoom chatRoom, ChatMemberRole role) {
return ChatMember.builder()
.name(user.getName())
.user(user)
.chatRoom(chatRoom)
.role(role)
.build();
}

private void validate(String name, User user, ChatRoom chatRoom, ChatMemberRole role) {
if (!StringUtils.hasText(name)) {
throw new IllegalArgumentException("name은 null이거나 빈 문자열이 될 수 없습니다.");
}

private void validate(User user, ChatRoom chatRoom, ChatMemberRole role) {
Objects.requireNonNull(user, "user는 null이 될 수 없습니다.");
Objects.requireNonNull(chatRoom, "chatRoom은 null이 될 수 없습니다.");
Objects.requireNonNull(role, "role은 null이 될 수 없습니다.");
Expand Down Expand Up @@ -115,7 +106,6 @@ public void ban() {
public String toString() {
return "ChatMember{" +
"id=" + id +
", name='" + name + '\'' +
", banned=" + banned +
", notifyEnabled=" + notifyEnabled +
", deletedAt=" + deletedAt +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public Optional<ChatMemberResult.Detail> findAdminByChatRoomId(Long chatRoomId)
Projections.constructor(
ChatMemberResult.Detail.class,
chatMember.id,
chatMember.name,
chatMember.user.name,
chatMember.role,
chatMember.notifyEnabled,
chatMember.user.id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public List<ChatMemberResult.Detail> readChatMembersByIdIn(Long chatRoomId, Set<

Map<String, Expression<?>> bindings = new LinkedHashMap<>();
bindings.put("id", qChatMember.id);
bindings.put("name", qChatMember.name);
bindings.put("name", qChatMember.user.name);
bindings.put("role", qChatMember.role);
bindings.put("notification", qChatMember.notifyEnabled);
bindings.put("userId", qChatMember.user.id);
Expand All @@ -87,7 +87,7 @@ public List<ChatMemberResult.Detail> readChatMembersByUserIdIn(Long chatRoomId,

Map<String, Expression<?>> bindings = new LinkedHashMap<>();
bindings.put("id", qChatMember.id);
bindings.put("name", qChatMember.name);
bindings.put("name", qChatMember.user.name);
bindings.put("role", qChatMember.role);
bindings.put("notification", qChatMember.notifyEnabled);
bindings.put("userId", qChatMember.user.id);
Expand All @@ -104,7 +104,7 @@ public List<ChatMemberResult.Summary> readChatMemberIdsByUserIdNotIn(Long chatRo

Map<String, Expression<?>> bindings = new LinkedHashMap<>();
bindings.put("id", qChatMember.id);
bindings.put("name", qChatMember.name);
bindings.put("name", qChatMember.user.name);

return chatMemberRepository.selectList(predicate, ChatMemberResult.Summary.class, bindings, null, null);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package kr.co.pennyway.domain.member.service;

import kr.co.pennyway.domain.common.fixture.ChatRoomFixture;
import kr.co.pennyway.domain.common.fixture.UserFixture;
import kr.co.pennyway.domain.config.ContainerMySqlTestConfig;
import kr.co.pennyway.domain.config.JpaConfig;
import kr.co.pennyway.domain.config.JpaTestConfig;
import kr.co.pennyway.domain.domains.chatroom.domain.ChatRoom;
import kr.co.pennyway.domain.domains.chatroom.repository.ChatRoomRepository;
import kr.co.pennyway.domain.domains.member.domain.ChatMember;
import kr.co.pennyway.domain.domains.member.dto.ChatMemberResult;
import kr.co.pennyway.domain.domains.member.repository.ChatMemberRepository;
import kr.co.pennyway.domain.domains.member.service.ChatMemberRdbService;
import kr.co.pennyway.domain.domains.member.type.ChatMemberRole;
import kr.co.pennyway.domain.domains.user.domain.User;
import kr.co.pennyway.domain.domains.user.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@Slf4j
@DataJpaTest(properties = {"spring.jpa.hibernate.ddl-auto=create"})
@ContextConfiguration(classes = {JpaConfig.class, ChatMemberRdbService.class})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ActiveProfiles("test")
@Import({JpaTestConfig.class})
public class ChatMemberNameSearchTest extends ContainerMySqlTestConfig {
@Autowired
private ChatMemberRdbService chatMemberRdbService;

@Autowired
private ChatMemberRepository chatMemberRepository;

@Autowired
private UserRepository userRepository;

@Autowired
private ChatRoomRepository chatRoomRepository;

@Test
@Transactional
@DisplayName("채팅방 멤버 단일 조회에 성공한다.")
public void successReadChatMember() {
// given
User user = userRepository.save(UserFixture.GENERAL_USER.toUser());
ChatRoom chatRoom = chatRoomRepository.save(ChatRoomFixture.PUBLIC_CHAT_ROOM.toEntity());
ChatMember chatMember = chatMemberRepository.save(ChatMember.of(user, chatRoom, ChatMemberRole.MEMBER));

// when
Optional<ChatMember> result = chatMemberRdbService.readChatMember(user.getId(), chatRoom.getId());

// then
log.debug("result: {}", result);
assertNotNull(result.get());
assertEquals(chatMember.getId(), result.get().getId());
}

@Test
@Transactional
@DisplayName("채팅방 관리자 조회에 성공한다.")
public void successReadAdmin() {
// given
User user = userRepository.save(UserFixture.GENERAL_USER.toUser());
ChatRoom chatRoom = chatRoomRepository.save(ChatRoomFixture.PUBLIC_CHAT_ROOM.toEntity());
ChatMember chatMember = chatMemberRepository.save(ChatMember.of(user, chatRoom, ChatMemberRole.ADMIN));

// when
Optional<ChatMemberResult.Detail> result = chatMemberRdbService.readAdmin(chatRoom.getId());

// then
log.debug("result: {}", result);
assertNotNull(result.get());
assertEquals(chatMember.getId(), result.get().id());
}

@Test
@Transactional
@DisplayName("멤버 아이디 리스트로 멤버 조회에 성공한다.")
public void successReadChatMembersByIdIn() {
// given
User user = userRepository.save(UserFixture.GENERAL_USER.toUser());
ChatRoom chatRoom = chatRoomRepository.save(ChatRoomFixture.PUBLIC_CHAT_ROOM.toEntity());
ChatMember chatMember1 = chatMemberRepository.save(ChatMember.of(user, chatRoom, ChatMemberRole.ADMIN));

User user2 = userRepository.save(UserFixture.GENERAL_USER.toUser());
ChatMember chatMember2 = chatMemberRepository.save(ChatMember.of(user2, chatRoom, ChatMemberRole.MEMBER));

Set<Long> chatMemberIds = Set.of(chatMember1.getId(), chatMember2.getId());

// when
List<ChatMemberResult.Detail> result = chatMemberRdbService.readChatMembersByIdIn(chatRoom.getId(), chatMemberIds);

// then
log.debug("result: {}", result);
assertEquals(2, result.size());
}

@Test
@Transactional
@DisplayName("사용자 아이디 리스트로 멤버 조회에 성공한다.")
public void successReadChatMembersByUserIds() {
// given
User user = userRepository.save(UserFixture.GENERAL_USER.toUser());
ChatRoom chatRoom = chatRoomRepository.save(ChatRoomFixture.PUBLIC_CHAT_ROOM.toEntity());
ChatMember chatMember1 = chatMemberRepository.save(ChatMember.of(user, chatRoom, ChatMemberRole.ADMIN));

User user2 = userRepository.save(UserFixture.GENERAL_USER.toUser());
ChatMember chatMember2 = chatMemberRepository.save(ChatMember.of(user2, chatRoom, ChatMemberRole.MEMBER));

Set<Long> userIds = Set.of(user.getId(), user2.getId());

// when
List<ChatMemberResult.Detail> result = chatMemberRdbService.readChatMembersByUserIdIn(chatRoom.getId(), userIds);

// then
log.debug("result: {}", result);
assertEquals(2, result.size());
}
}

0 comments on commit fc333f5

Please sign in to comment.