From 89ed4257776c5fb6252b4a2d5231859a009b456c Mon Sep 17 00:00:00 2001 From: Arachne <66822642+Arachneee@users.noreply.github.com> Date: Thu, 26 Sep 2024 17:15:12 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=ED=96=89=EC=82=AC=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=EC=9E=90=20=EC=A0=84=EC=B2=B4=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81=20(#6?= =?UTF-8?q?44)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 행사 참여자 전체 수정 로직 리펙토링 * refactor: 메소드 분리 * refactor: UpdatedMembers 로 변경 * refactor: CurrentMember 쿼리 변경 * refactor: 변수명 변경 * test: 예외 메시지 변경 * style: 메소드 명 변경 * refactor: 배치 사이즈 조절 * refactor: Set 으로 변경 * refactor: 메소드 순서 변경 * refactor: 필요없는 객체 제거 * docs: 운영 배포 워크플로 수정 * docs: 도커 이미지 이름 변경 --- .github/workflows/backend-prod.yml | 25 +++- .../haengdong/application/MemberService.java | 117 ++++------------- .../request/MembersUpdateAppRequest.java | 8 ++ .../domain/bill/BillDetailRepository.java | 16 --- .../haengdong/domain/bill/BillRepository.java | 9 -- .../domain/member/UpdatedMembers.java | 67 ++++++++++ server/src/main/resources/application.yml | 1 + .../application/BillServiceTest.java | 4 - .../application/MemberServiceTest.java | 17 +-- .../domain/member/UpdatedMembersTest.java | 118 ++++++++++++++++++ 10 files changed, 251 insertions(+), 131 deletions(-) delete mode 100644 server/src/main/java/server/haengdong/domain/bill/BillDetailRepository.java create mode 100644 server/src/main/java/server/haengdong/domain/member/UpdatedMembers.java create mode 100644 server/src/test/java/server/haengdong/domain/member/UpdatedMembersTest.java diff --git a/.github/workflows/backend-prod.yml b/.github/workflows/backend-prod.yml index f7daacd33..4134bde1e 100644 --- a/.github/workflows/backend-prod.yml +++ b/.github/workflows/backend-prod.yml @@ -54,9 +54,9 @@ jobs: docker buildx build --platform linux/arm64 -t \ ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_PROD }} --push . - deploy: + deploy-prod-1: needs: build - runs-on: [ self-hosted, backend-prod ] + runs-on: [ self-hosted, backend-prod-1 ] steps: - name: Docker remove run: | @@ -71,4 +71,23 @@ jobs: run: sudo docker pull ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_PROD }} - name: Docker run - run: sudo docker run -d -p 8080:8080 -e SPRING_PROFILES_ACTIVE=prod -v log-volume:/app/logs --name haengdong-backend ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_PROD }} + run: sudo docker run -d -p 80:8080 -e SPRING_PROFILES_ACTIVE=prod -v log-volume:/app/logs --name haengdong-backend ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_DEV }} + + deploy-prod-2: + needs: build + runs-on: [ self-hosted, backend-prod-2 ] + steps: + - name: Docker remove + run: | + CONTAINER_IDS=$(sudo docker ps -qa) + if [ -n "$CONTAINER_IDS" ]; then + sudo docker rm -f $CONTAINER_IDS + else + echo "No running containers found." + fi + + - name: Docker Image pull + run: sudo docker pull ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_PROD }} + + - name: Docker run + run: sudo docker run -d -p 80:8080 -e SPRING_PROFILES_ACTIVE=prod -v log-volume:/app/logs --name haengdong-backend ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_DEV }} diff --git a/server/src/main/java/server/haengdong/application/MemberService.java b/server/src/main/java/server/haengdong/application/MemberService.java index 9da74972a..840c4f769 100644 --- a/server/src/main/java/server/haengdong/application/MemberService.java +++ b/server/src/main/java/server/haengdong/application/MemberService.java @@ -1,29 +1,24 @@ package server.haengdong.application; -import static java.util.stream.Collectors.toMap; - -import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import server.haengdong.application.request.MemberSaveAppRequest; -import server.haengdong.application.request.MemberUpdateAppRequest; import server.haengdong.application.request.MembersSaveAppRequest; import server.haengdong.application.request.MembersUpdateAppRequest; import server.haengdong.application.response.MemberAppResponse; import server.haengdong.application.response.MembersDepositAppResponse; import server.haengdong.application.response.MembersSaveAppResponse; import server.haengdong.domain.bill.Bill; -import server.haengdong.domain.bill.BillDetailRepository; import server.haengdong.domain.bill.BillRepository; import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; import server.haengdong.domain.member.Member; import server.haengdong.domain.member.MemberRepository; +import server.haengdong.domain.member.UpdatedMembers; import server.haengdong.exception.HaengdongErrorCode; import server.haengdong.exception.HaengdongException; @@ -35,7 +30,6 @@ public class MemberService { private final MemberRepository memberRepository; private final EventRepository eventRepository; private final BillRepository billRepository; - private final BillDetailRepository billDetailRepository; @Transactional public MembersSaveAppResponse saveMembers(String token, MembersSaveAppRequest request) { @@ -54,6 +48,21 @@ public MembersSaveAppResponse saveMembers(String token, MembersSaveAppRequest re return MembersSaveAppResponse.of(savedMembers); } + private void validateMemberSave(List memberNames, Event event) { + Set uniqueMemberNames = Set.copyOf(memberNames); + if (memberNames.size() != uniqueMemberNames.size()) { + throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_DUPLICATE, memberNames); + } + if (isDuplicatedMemberNames(uniqueMemberNames, event)) { + throw new HaengdongException(HaengdongErrorCode.MEMBER_ALREADY_EXIST); + } + } + + private boolean isDuplicatedMemberNames(Set uniqueMemberNames, Event event) { + return memberRepository.findAllByEvent(event).stream() + .anyMatch(member -> uniqueMemberNames.contains(member.getName())); + } + public List getCurrentMembers(String token) { Event event = getEvent(token); @@ -65,16 +74,6 @@ public List getCurrentMembers(String token) { .toList(); } - private void validateMemberSave(List memberNames, Event event) { - if (memberNamesDuplicated(memberNames)) { - throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_DUPLICATE, memberNames); - } - if (memberRepository.findAllByEvent(event).stream() - .anyMatch(member -> memberNames.contains(member.getName()))) { - throw new HaengdongException(HaengdongErrorCode.MEMBER_ALREADY_EXIST); - } - } - public MembersDepositAppResponse findAllMembers(String token) { Event event = getEvent(token); @@ -86,80 +85,11 @@ public MembersDepositAppResponse findAllMembers(String token) { @Transactional public void updateMembers(String token, MembersUpdateAppRequest request) { Event event = getEvent(token); - validateMemberUpdate(request); + UpdatedMembers updatedMembers = new UpdatedMembers(request.toMembers(event)); + List originMembers = memberRepository.findAllByEvent(event); - List updatedMembers = request.members().stream() - .map(memberRequest -> memberRequest.toMember(event)) - .toList(); - List eventMembers = memberRepository.findAllByEvent(event); - - validateUpdatedMembersExist(eventMembers, updatedMembers); - validateUpdatedNamesUnique(eventMembers, updatedMembers); - memberRepository.saveAll(updatedMembers); - } - - private Event getEvent(String token) { - return eventRepository.findByToken(token) - .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)); - } - - private void validateMemberUpdate(MembersUpdateAppRequest request) { - validateChangedNameUnique(request.members()); - validateMemberUnique(request.members()); - } - - private void validateChangedNameUnique(List members) { - List memberNames = members.stream() - .map(MemberUpdateAppRequest::name) - .toList(); - if (memberNamesDuplicated(memberNames)) { - throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_CHANGE_DUPLICATE); - } - } - - private boolean memberNamesDuplicated(List memberNames) { - return memberNames.size() != Set.copyOf(memberNames).size(); - } - - private void validateMemberUnique(List members) { - List memberIds = members.stream() - .map(MemberUpdateAppRequest::id) - .distinct() - .toList(); - if (members.size() != memberIds.size()) { - throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_CHANGE_DUPLICATE); - } - } - - private void validateUpdatedMembersExist(List eventMembers, List updatedMembers) { - if (updatedMembers.size() != eventMembers.size()) { - throw new HaengdongException(HaengdongErrorCode.MEMBER_UPDATE_MISMATCH); - } - Set members = new HashSet<>(eventMembers); - - if (!members.containsAll(updatedMembers)) { - throw new HaengdongException(HaengdongErrorCode.MEMBER_UPDATE_MISMATCH); - } - } - - private void validateUpdatedNamesUnique(List eventMembers, List updatedMembers) { - Map eventMemberNames = eventMembers.stream() - .collect(toMap(Member::getId, Member::getName)); - Set existNames = new HashSet<>(eventMemberNames.values()); - - boolean memberNameDuplicated = updatedMembers.stream() - .filter(updatedMember -> isMemberNameUpdated(eventMemberNames, updatedMember)) - .map(Member::getName) - .anyMatch(existNames::contains); - - if (memberNameDuplicated) { - throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_DUPLICATE); - } - } - - private boolean isMemberNameUpdated(Map eventMemberNames, Member updatedMember) { - String prevMemberName = eventMemberNames.get(updatedMember.getId()); - return !updatedMember.hasName(prevMemberName); + updatedMembers.validateUpdatable(originMembers); + memberRepository.saveAll(updatedMembers.getMembers()); } @Transactional @@ -177,7 +107,12 @@ private void deleteMember(String token, Member member) { billRepository.findAllByEvent(event).stream() .filter(bill -> bill.containMember(member)) .forEach(bill -> bill.removeMemberBillDetail(member)); - billDetailRepository.deleteAllByMember(member); + billRepository.flush(); memberRepository.delete(member); } + + private Event getEvent(String token) { + return eventRepository.findByToken(token) + .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)); + } } diff --git a/server/src/main/java/server/haengdong/application/request/MembersUpdateAppRequest.java b/server/src/main/java/server/haengdong/application/request/MembersUpdateAppRequest.java index a8ce8b893..aa3253504 100644 --- a/server/src/main/java/server/haengdong/application/request/MembersUpdateAppRequest.java +++ b/server/src/main/java/server/haengdong/application/request/MembersUpdateAppRequest.java @@ -1,6 +1,14 @@ package server.haengdong.application.request; import java.util.List; +import server.haengdong.domain.event.Event; +import server.haengdong.domain.member.Member; public record MembersUpdateAppRequest(List members) { + + public List toMembers(Event event) { + return members.stream() + .map(memberRequest -> memberRequest.toMember(event)) + .toList(); + } } diff --git a/server/src/main/java/server/haengdong/domain/bill/BillDetailRepository.java b/server/src/main/java/server/haengdong/domain/bill/BillDetailRepository.java deleted file mode 100644 index 7d656783b..000000000 --- a/server/src/main/java/server/haengdong/domain/bill/BillDetailRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package server.haengdong.domain.bill; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; -import server.haengdong.domain.member.Member; - -@Repository -public interface BillDetailRepository extends JpaRepository { - - @Modifying - @Query("delete from BillDetail bd where bd.member = :member") - void deleteAllByMember(@Param("member") Member member); -} diff --git a/server/src/main/java/server/haengdong/domain/bill/BillRepository.java b/server/src/main/java/server/haengdong/domain/bill/BillRepository.java index bbafbb4db..23efe487c 100644 --- a/server/src/main/java/server/haengdong/domain/bill/BillRepository.java +++ b/server/src/main/java/server/haengdong/domain/bill/BillRepository.java @@ -19,14 +19,5 @@ public interface BillRepository extends JpaRepository { """) List findAllByEvent(Event event); - @Query(""" - select b - from Bill b - join fetch b.billDetails bd - join fetch bd.member - where b.event = :event - order by b.id desc - limit 1 - """) Optional findFirstByEventOrderByIdDesc(Event event); } diff --git a/server/src/main/java/server/haengdong/domain/member/UpdatedMembers.java b/server/src/main/java/server/haengdong/domain/member/UpdatedMembers.java new file mode 100644 index 000000000..3a588c077 --- /dev/null +++ b/server/src/main/java/server/haengdong/domain/member/UpdatedMembers.java @@ -0,0 +1,67 @@ +package server.haengdong.domain.member; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import server.haengdong.exception.HaengdongErrorCode; +import server.haengdong.exception.HaengdongException; + +public class UpdatedMembers { + + private final Set members; + + public UpdatedMembers(List members) { + validateMemberUnique(members); + validateNameUnique(members); + this.members = new HashSet<>(members); + } + + private void validateMemberUnique(List members) { + if (members.size() != Set.copyOf(members).size()) { + throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_CHANGE_DUPLICATE); + } + } + + private void validateNameUnique(List members) { + Set uniqueNames = members.stream() + .map(Member::getName) + .collect(Collectors.toSet()); + if (members.size() != uniqueNames.size()) { + throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_CHANGE_DUPLICATE); + } + } + + public void validateUpdatable(List originMembers) { + Set uniqueMembers = Set.copyOf(originMembers); + validateUpdatedMembersExist(uniqueMembers); + validateUpdatedNamesUnique(uniqueMembers); + } + + private void validateUpdatedMembersExist(Set originMembers) { + if (!this.members.equals(originMembers)) { + throw new HaengdongException(HaengdongErrorCode.MEMBER_UPDATE_MISMATCH); + } + } + + private void validateUpdatedNamesUnique(Set originMembers) { + boolean duplicated = originMembers.stream() + .anyMatch(this::isMemberNameUpdated); + + if (duplicated) { + throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_DUPLICATE); + } + } + + private boolean isMemberNameUpdated(Member originMembers) { + return this.members.stream() + .filter(member -> !member.getId().equals(originMembers.getId())) + .anyMatch(member -> member.hasName(originMembers.getName())); + } + + public List getMembers() { + return members.stream().toList(); + } +} + + diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml index 2ae503547..22c337545 100644 --- a/server/src/main/resources/application.yml +++ b/server/src/main/resources/application.yml @@ -15,6 +15,7 @@ spring: ddl-auto: create properties: hibernate: + default_batch_fetch_size: 30 format_sql: true jdbc.time_zone: Asia/Seoul show-sql: true diff --git a/server/src/test/java/server/haengdong/application/BillServiceTest.java b/server/src/test/java/server/haengdong/application/BillServiceTest.java index 347e6712a..6d2b7aa8d 100644 --- a/server/src/test/java/server/haengdong/application/BillServiceTest.java +++ b/server/src/test/java/server/haengdong/application/BillServiceTest.java @@ -20,7 +20,6 @@ import server.haengdong.application.response.StepAppResponse; import server.haengdong.domain.bill.Bill; import server.haengdong.domain.bill.BillDetail; -import server.haengdong.domain.bill.BillDetailRepository; import server.haengdong.domain.bill.BillRepository; import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; @@ -40,9 +39,6 @@ class BillServiceTest extends ServiceTestSupport { @Autowired private BillRepository billRepository; - @Autowired - private BillDetailRepository billDetailRepository; - @Autowired private MemberRepository memberRepository; diff --git a/server/src/test/java/server/haengdong/application/MemberServiceTest.java b/server/src/test/java/server/haengdong/application/MemberServiceTest.java index 099326317..662156a33 100644 --- a/server/src/test/java/server/haengdong/application/MemberServiceTest.java +++ b/server/src/test/java/server/haengdong/application/MemberServiceTest.java @@ -29,7 +29,6 @@ import server.haengdong.application.response.MembersSaveAppResponse; import server.haengdong.domain.bill.Bill; import server.haengdong.domain.bill.BillDetail; -import server.haengdong.domain.bill.BillDetailRepository; import server.haengdong.domain.bill.BillRepository; import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; @@ -51,9 +50,6 @@ class MemberServiceTest extends ServiceTestSupport { @Autowired private BillRepository billRepository; - @Autowired - private BillDetailRepository billDetailRepository; - @DisplayName("행사에 참여자를 추가한다.") @Test void saveMembersTest() { @@ -171,12 +167,15 @@ void deleteMemberTest2() { billRepository.save(bill); memberService.deleteMember(event1.getToken(), member1.getId()); + Bill bill1 = billRepository.findAllByEvent(event1).get(0); + List bill1Details = bill1.getBillDetails(); assertAll( () -> assertThat(memberRepository.findById(member1.getId())).isEmpty(), - () -> assertThat(billDetailRepository.findById(billDetail1.getId())).isEmpty(), + () -> assertThat(bill1Details).doesNotContain(billDetail1), () -> { - BillDetail foundDetail = billDetailRepository.findById(billDetail2.getId()).orElseThrow(); + BillDetail foundDetail = bill1Details.stream() + .filter(billDetail -> billDetail.isSameId(billDetail2.getId())).findFirst().get(); assertThat(foundDetail.getPrice()).isEqualTo(10000L); assertThat(foundDetail.isFixed()).isEqualTo(false); } @@ -362,10 +361,12 @@ void getCurrentMembersTest() { Member member1 = MEMBER1; Member member2 = MEMBER2; Member member3 = MEMBER3; - Bill bill = Bill.create(event, "title", 100000L, List.of(member1, member2, member3)); + Bill bill1 = Bill.create(event, "title1", 100000L, List.of(member1)); + Bill bill2 = Bill.create(event, "title2", 200000L, List.of(member1, member2, member3)); + Bill bill3 = Bill.create(event, "title2", 200000L, List.of(member1, member2, member3)); eventRepository.save(event); memberRepository.saveAll(List.of(member1, member2, member3)); - billRepository.save(bill); + billRepository.saveAll(List.of(bill1, bill2, bill3)); List currentMembers = memberService.getCurrentMembers(event.getToken()); diff --git a/server/src/test/java/server/haengdong/domain/member/UpdatedMembersTest.java b/server/src/test/java/server/haengdong/domain/member/UpdatedMembersTest.java new file mode 100644 index 000000000..9f0338ffb --- /dev/null +++ b/server/src/test/java/server/haengdong/domain/member/UpdatedMembersTest.java @@ -0,0 +1,118 @@ +package server.haengdong.domain.member; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import server.haengdong.domain.event.Event; +import server.haengdong.exception.HaengdongException; + +class UpdatedMembersTest { + + @DisplayName("이벤트 이름들은 중복될 수 없다.") + @Test + void validateNameUnique() { + Event event = new Event("행동대장 회식", "1234", "1231415jaksdf"); + List members = List.of( + new Member(1L, event, "고구마", false), + new Member(2L, event, "감자", false), + new Member(3L, event, "감자", false) + ); + + assertThatThrownBy(() -> new UpdatedMembers(members)) + .isInstanceOf(HaengdongException.class) + .hasMessage("중복된 참여 인원 이름 변경 요청이 존재합니다."); + } + + @DisplayName("이벤트 회원들은 중복될 수 없다.") + @Test + void validateMemberUnique() { + Event event = new Event("행동대장 회식", "1234", "1231415jaksdf"); + Member member1 = new Member(1L, event, "고구마", false); + Member member2 = new Member(2L, event, "감자", false); + List members = List.of(member1, member2, member2); + + + assertThatThrownBy(() -> new UpdatedMembers(members)) + .isInstanceOf(HaengdongException.class) + .hasMessage("중복된 참여 인원 이름 변경 요청이 존재합니다."); + } + + @DisplayName("이벤트 이름들로 이벤트 참여자들을 생성한다.") + @Test + void create() { + Event event = new Event("행동대장 회식", "1234", "1231415jaksdf"); + Member member1 = new Member(1L, event, "고구마", false); + Member member2 = new Member(2L, event, "감자", false); + Member member3 = new Member(3L, event, "당근", false); + List members = List.of(member1, member2, member3); + + UpdatedMembers eventUpdatedMembers = new UpdatedMembers(members); + assertThat(eventUpdatedMembers.getMembers()).hasSize(3) + .containsExactlyInAnyOrder(member1, member2, member3); + } + + @DisplayName("이벤트의 참여자들 전체가 존재하지 않으면 업데이트할 수 없다.") + @Test + void validateUpdatedMembersExist() { + Event event = new Event("행동대장 회식", "1234", "1231415jaksdf"); + Member member1 = new Member(1L, event, "고구마", false); + Member member2 = new Member(2L, event, "감자", false); + Member member3 = new Member(3L, event, "당근", false); + Member member4 = new Member(4L, event, "양파", false); + List members = List.of(member1, member2, member3, member4); + + Member updateMember1 = new Member(1L, event, "토다리", false); + Member updateMember2 = new Member(2L, event, "쿠키", false); + Member updateMember3 = new Member(3L, event, "백호", false); + UpdatedMembers updatedMembers = new UpdatedMembers(List.of(updateMember1, updateMember2, updateMember3)); + + assertThatThrownBy(() -> updatedMembers.validateUpdatable(members)) + .isInstanceOf(HaengdongException.class) + .hasMessage("업데이트 요청된 참여자 ID 목록과 기존 행사 참여자 ID 목록이 일치하지 않습니다."); + } + + @DisplayName("업데이트할 이름 중에 기존 이벤트의 참여자들의 이름과 중복되면 업데이트할 수 없다.") + @Test + void validateUpdatedNamesUnique() { + Event event = new Event("행동대장 회식", "1234", "1231415jaksdf"); + Member member1 = new Member(1L, event, "고구마", false); + Member member2 = new Member(2L, event, "감자", false); + Member member3 = new Member(3L, event, "당근", false); + Member member4 = new Member(4L, event, "양파", false); + List members = List.of(member1, member2, member3, member4); + + Member updateMember1 = new Member(1L, event, "토다리", false); + Member updateMember2 = new Member(2L, event, "쿠키", false); + Member updateMember3 = new Member(3L, event, "백호", false); + Member updateMember4 = new Member(4L, event, "감자", false); + UpdatedMembers updatedMembers = new UpdatedMembers(List.of(updateMember1, updateMember2, updateMember3, updateMember4)); + + assertThatThrownBy(() -> updatedMembers.validateUpdatable(members)) + .isInstanceOf(HaengdongException.class) + .hasMessage("행사에 중복된 참여자 이름이 존재합니다."); + } + + @DisplayName("이벤트의 참여자들 전체를 업데이트 검증한다.") + @Test + void validateUpdatable() { + Event event = new Event("행동대장 회식", "1234", "1231415jaksdf"); + Member member1 = new Member(1L, event, "고구마", false); + Member member2 = new Member(2L, event, "감자", false); + Member member3 = new Member(3L, event, "당근", false); + Member member4 = new Member(4L, event, "양파", false); + List members = List.of(member1, member2, member3, member4); + + Member updateMember1 = new Member(1L, event, "토다리", false); + Member updateMember2 = new Member(2L, event, "쿠키", false); + Member updateMember3 = new Member(3L, event, "백호", false); + Member updateMember4 = new Member(4L, event, "망쵸", false); + UpdatedMembers updatedMembers = new UpdatedMembers(List.of(updateMember1, updateMember2, updateMember3, updateMember4)); + + assertThatCode(() -> updatedMembers.validateUpdatable(members)) + .doesNotThrowAnyException(); + } +}