From 9789c17a92e39d86e319655f73cea9429bd6d5aa Mon Sep 17 00:00:00 2001 From: pparkjs Date: Sat, 12 Jul 2025 12:06:15 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feature:=20=ED=81=AC=EB=A3=A8=EC=9B=90=20?= =?UTF-8?q?=EC=B0=A8=EB=8B=A8=20API=20=EA=B5=AC=ED=98=84=20(#27)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crew/application/in/CrewService.java | 22 ++++++++++ .../in/request/crew/CrewMemberBanRequest.java | 16 ++++++++ .../request/crew/CrewMemberExpelRequest.java | 16 ++++++++ .../in/response/crew/CrewBanListResponse.java | 33 +++++++++++++++ .../in/usecase/ManageCrewUseCase.java | 8 ++++ .../repository/CrewBanMemberRepository.java | 10 +++++ .../com/retrip/crew/domain/entity/Crew.java | 23 +++++++++++ .../crew/domain/entity/CrewBanMember.java | 41 +++++++++++++++++++ .../crew/domain/entity/CrewBanMembers.java | 33 +++++++++++++++ .../crew/domain/entity/CrewMembers.java | 30 ++++++++++++++ .../domain/exception/common/ErrorCode.java | 5 ++- .../in/presentation/rest/CrewController.java | 26 ++++++++++++ 12 files changed, 261 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/retrip/crew/application/in/request/crew/CrewMemberBanRequest.java create mode 100644 src/main/java/com/retrip/crew/application/in/request/crew/CrewMemberExpelRequest.java create mode 100644 src/main/java/com/retrip/crew/application/in/response/crew/CrewBanListResponse.java create mode 100644 src/main/java/com/retrip/crew/application/out/repository/CrewBanMemberRepository.java create mode 100644 src/main/java/com/retrip/crew/domain/entity/CrewBanMember.java create mode 100644 src/main/java/com/retrip/crew/domain/entity/CrewBanMembers.java diff --git a/src/main/java/com/retrip/crew/application/in/CrewService.java b/src/main/java/com/retrip/crew/application/in/CrewService.java index f8e6610..9615ffd 100644 --- a/src/main/java/com/retrip/crew/application/in/CrewService.java +++ b/src/main/java/com/retrip/crew/application/in/CrewService.java @@ -25,6 +25,7 @@ import com.retrip.crew.domain.vo.IntroductionTitle; import com.retrip.crew.infra.adapter.in.presentation.rest.common.ScrollPageResponse; import com.retrip.crew.infra.util.PaginationUtils; +import java.util.List; import lombok.RequiredArgsConstructor; import java.util.UUID; import org.springframework.data.domain.Pageable; @@ -40,6 +41,7 @@ public class CrewService implements ManageCrewUseCase, GetCrewUseCase, ManageInt private final CrewMemberRepository crewMemberRepository; private final CrewQueryRepository crewQueryRepository; private final IntroductionRepository introductionRepository; + private final CrewBanMemberRepository crewBanMemberRepository; private final IntroductionQueryRepository introductionQueryRepository; @Override @@ -154,4 +156,24 @@ public void deleteCrew(UUID crewId, UUID loginMemberId) { Crew crew = findCrewById(crewId); crew.softDelete(loginMemberId); } + + @Override + public void expelMember(UUID loginMemberId, UUID crewId, UUID expellerId) { + Crew crew = findCrewById(crewId); + crew.expelMember(loginMemberId, expellerId); + } + + @Override + public void banMember(UUID loginMemberId, UUID crewId, UUID bannedMemberId) { + Crew crew = findCrewById(crewId); + crew.banMember(loginMemberId, bannedMemberId); + } + + @Override + public CrewBanListResponse getBanMembers(UUID loginMemberId, UUID crewId) { + Crew crew = findCrewById(crewId); + crew.validateCrewLeader(loginMemberId); + List crewBanMembers = crewBanMemberRepository.findAllByCrewId(crewId); + return CrewBanListResponse.from(crewBanMembers); + } } diff --git a/src/main/java/com/retrip/crew/application/in/request/crew/CrewMemberBanRequest.java b/src/main/java/com/retrip/crew/application/in/request/crew/CrewMemberBanRequest.java new file mode 100644 index 0000000..22af0c6 --- /dev/null +++ b/src/main/java/com/retrip/crew/application/in/request/crew/CrewMemberBanRequest.java @@ -0,0 +1,16 @@ +package com.retrip.crew.application.in.request.crew; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.UUID; + +@Schema(description = "크루 회원 차단 Request") +public record CrewMemberBanRequest( + + @Schema(description = "차단할 회원 ID") + @NotNull + UUID memberId +) { +} + + diff --git a/src/main/java/com/retrip/crew/application/in/request/crew/CrewMemberExpelRequest.java b/src/main/java/com/retrip/crew/application/in/request/crew/CrewMemberExpelRequest.java new file mode 100644 index 0000000..848edff --- /dev/null +++ b/src/main/java/com/retrip/crew/application/in/request/crew/CrewMemberExpelRequest.java @@ -0,0 +1,16 @@ +package com.retrip.crew.application.in.request.crew; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.UUID; + +@Schema(description = "크루 멤버 추방 Request") +public record CrewMemberExpelRequest( + + @Schema(description = "추방할 멤버 ID") + @NotNull + UUID memberId +) { +} + + diff --git a/src/main/java/com/retrip/crew/application/in/response/crew/CrewBanListResponse.java b/src/main/java/com/retrip/crew/application/in/response/crew/CrewBanListResponse.java new file mode 100644 index 0000000..765d713 --- /dev/null +++ b/src/main/java/com/retrip/crew/application/in/response/crew/CrewBanListResponse.java @@ -0,0 +1,33 @@ +package com.retrip.crew.application.in.response.crew; + +import com.retrip.crew.domain.entity.CrewBanMember; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +@Schema(description = "크루 차단 리스트 조회 Response") +public record CrewBanListResponse( + @Schema(description = "차단한 회원 리스트") + List banMembers +) { + public static CrewBanListResponse from(List crewBanMembers) { + return new CrewBanListResponse(BanMemberResponse.toList(crewBanMembers)); + } + + public record BanMemberResponse( + @Schema(description = "차단한 회원 ID") + UUID bannedMemberIds + ){ + + public static List toList(List crewBanMembers) { + return crewBanMembers.stream() + .map(BanMemberResponse::from) + .collect(Collectors.toList()); + } + + private static BanMemberResponse from(CrewBanMember crewBanMember) { + return new BanMemberResponse(crewBanMember.getMemberId()); + } + } +} diff --git a/src/main/java/com/retrip/crew/application/in/usecase/ManageCrewUseCase.java b/src/main/java/com/retrip/crew/application/in/usecase/ManageCrewUseCase.java index dfbcc2d..036ff9d 100644 --- a/src/main/java/com/retrip/crew/application/in/usecase/ManageCrewUseCase.java +++ b/src/main/java/com/retrip/crew/application/in/usecase/ManageCrewUseCase.java @@ -4,6 +4,7 @@ import com.retrip.crew.application.in.request.crew.CrewLeaderDelegateRequest; import com.retrip.crew.application.in.request.crew.CrewUpdateRequest; import com.retrip.crew.application.in.request.crew.CrewWithdrawalRequest; +import com.retrip.crew.application.in.response.crew.CrewBanListResponse; import com.retrip.crew.application.in.response.crew.CrewCreateResponse; import com.retrip.crew.application.in.response.crew.CrewLeaderDelegateResponse; import com.retrip.crew.application.in.response.crew.CrewUpdateResponse; @@ -20,4 +21,11 @@ public interface ManageCrewUseCase { CrewLeaderDelegateResponse delegateCrewLeader(UUID crewId, CrewLeaderDelegateRequest request); void deleteCrew(UUID crewId, UUID loginMemberId); + + void expelMember(UUID memberId, UUID crewId, UUID expellerId); + + void banMember(UUID memberId, UUID crewId, UUID bannedMemberId); + + CrewBanListResponse getBanMembers(UUID memberId, UUID crewId); + } diff --git a/src/main/java/com/retrip/crew/application/out/repository/CrewBanMemberRepository.java b/src/main/java/com/retrip/crew/application/out/repository/CrewBanMemberRepository.java new file mode 100644 index 0000000..4da47b1 --- /dev/null +++ b/src/main/java/com/retrip/crew/application/out/repository/CrewBanMemberRepository.java @@ -0,0 +1,10 @@ +package com.retrip.crew.application.out.repository; + +import com.retrip.crew.domain.entity.CrewBanMember; +import java.util.List; +import java.util.UUID; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CrewBanMemberRepository extends JpaRepository { + List findAllByCrewId(UUID crewId); +} diff --git a/src/main/java/com/retrip/crew/domain/entity/Crew.java b/src/main/java/com/retrip/crew/domain/entity/Crew.java index bb2afa7..155ae0f 100644 --- a/src/main/java/com/retrip/crew/domain/entity/Crew.java +++ b/src/main/java/com/retrip/crew/domain/entity/Crew.java @@ -1,6 +1,9 @@ package com.retrip.crew.domain.entity; +import static com.retrip.crew.domain.exception.common.ErrorCode.CREW_MEMBER_BANNED_CANNOT_APPLY; + import com.retrip.crew.domain.exception.NotCrewLeaderException; +import com.retrip.crew.domain.exception.common.BusinessException; import com.retrip.crew.domain.vo.CrewDescription; import com.retrip.crew.domain.vo.CrewTitle; @@ -45,6 +48,8 @@ public class Crew extends BaseEntity { @Embedded private Recruitment recruitment; + @Embedded private CrewBanMembers crewBanMembers; + @Column(name = "is_deleted", nullable = false) private boolean isDeleted = false; @@ -57,6 +62,7 @@ private Crew(String name, String description, int maxMembers, UUID leader, List< this.posts = new Posts(); this.announcements = new Announcements(); this.introductions = new Introductions(); + this.crewBanMembers = new CrewBanMembers(); } public static Crew create(String title, String description, int maxMembers, UUID leader, List questions) { @@ -86,6 +92,7 @@ public void update(CrewTitle title, CrewDescription description) { } public Demand demand(UUID memberId) { + validateAddDemand(this.getId(), memberId); return recruitment.addDemand(memberId, this); } @@ -126,4 +133,20 @@ public void deleteRecruitmentQuestion(UUID memberId, RecruitmentQuestion savedQu validateCrewLeader(memberId); recruitment.deleteRecruitmentQuestion(savedQuestion); } + + public void expelMember(UUID loginMemberId, UUID expellerId) { + this.crewMembers.expelMember(loginMemberId, expellerId); + this.crewBanMembers.banMember(this, expellerId); + } + + public void banMember(UUID loginMemberId, UUID bannedMemberId) { + validateCrewLeader(loginMemberId); + this.crewBanMembers.banMember(this, bannedMemberId); + } + + private void validateAddDemand(UUID crewId, UUID memberId) { + if(this.crewBanMembers.isBan(crewId, memberId)){ + throw new BusinessException(CREW_MEMBER_BANNED_CANNOT_APPLY); + } + } } diff --git a/src/main/java/com/retrip/crew/domain/entity/CrewBanMember.java b/src/main/java/com/retrip/crew/domain/entity/CrewBanMember.java new file mode 100644 index 0000000..414420f --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/CrewBanMember.java @@ -0,0 +1,41 @@ +package com.retrip.crew.domain.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.ForeignKey; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import java.util.UUID; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +@Getter +public class CrewBanMember extends BaseEntity { + + @Id + @Column(columnDefinition = "varbinary(16)") + private UUID id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn( + name = "crew_id", + nullable = false, + columnDefinition = "varbinary(16)", + foreignKey = @ForeignKey(name = "fk_crew_member_to_crew") + ) + private Crew crew; + + @Column(nullable = false) + private UUID memberId; + + public CrewBanMember(Crew crew, UUID bannedMemberId) { + this.id = UUID.randomUUID(); + this.crew = crew; + this.memberId = bannedMemberId; + } +} diff --git a/src/main/java/com/retrip/crew/domain/entity/CrewBanMembers.java b/src/main/java/com/retrip/crew/domain/entity/CrewBanMembers.java new file mode 100644 index 0000000..ac143bf --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/CrewBanMembers.java @@ -0,0 +1,33 @@ +package com.retrip.crew.domain.entity; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Embeddable; +import jakarta.persistence.OneToMany; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +@Embeddable +public class CrewBanMembers { + + @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) + private List values = new ArrayList<>(); + + public void banMember(Crew crew, UUID bannedMemberId) { + this.values.add(createBanMember(crew, bannedMemberId)); + } + + private CrewBanMember createBanMember(Crew crew, UUID bannedMemberId) { + return new CrewBanMember(crew, bannedMemberId); + } + + public boolean isBan(UUID crewId, UUID memberId) { + return this.values.stream() + .anyMatch(member -> crewId.equals(member.getCrew().getId()) && memberId.equals(member.getMemberId())); + } +} diff --git a/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java b/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java index f871150..302e8ba 100644 --- a/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java +++ b/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java @@ -1,8 +1,11 @@ package com.retrip.crew.domain.entity; +import static com.retrip.crew.domain.exception.common.ErrorCode.CREW_MEMBER_NOT_IN_CREW; + import com.retrip.crew.domain.CrewTrip; import com.retrip.crew.domain.exception.ImpossibleWithdrawCrewException; import com.retrip.crew.domain.exception.NotCrewLeaderException; +import com.retrip.crew.domain.exception.common.BusinessException; import com.retrip.crew.domain.exception.common.IllegalStateException; import com.retrip.crew.domain.exception.common.InvalidValueException; import jakarta.persistence.CascadeType; @@ -107,4 +110,31 @@ private void validatePossibleDelegate(CrewMember leader) { throw new NotCrewLeaderException(); } } + + public void expelMember(UUID loginMemberId, UUID expellerId) { + validateCrewLeader(loginMemberId); + validateExistCrewMembers(expellerId); + + CrewMember crewMemberToExpel = values.stream() + .filter(member -> expellerId.equals(member.getMemberId())) + .findFirst() + .orElseThrow(() -> new BusinessException(CREW_MEMBER_NOT_IN_CREW)); + + values.remove(crewMemberToExpel); + } + + private void validateCrewLeader(UUID loginMemberId) { + if(!isLeader(loginMemberId)) { + throw new NotCrewLeaderException(); + } + } + + private void validateExistCrewMembers(UUID expellerId) { + boolean isExist = values.stream() + .anyMatch(member -> expellerId.equals(member.getMemberId())); + + if(!isExist) { + throw new BusinessException(CREW_MEMBER_NOT_IN_CREW); + } + } } diff --git a/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java b/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java index 79fca3f..be7d30c 100644 --- a/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java +++ b/src/main/java/com/retrip/crew/domain/exception/common/ErrorCode.java @@ -29,8 +29,9 @@ public enum ErrorCode { POST_DELETE_FAIL(FORBIDDEN, "Crew-011", "자유 게시글을 삭제할 권한이 없습니다."), QUESTION_UPDATE_FAIL(FORBIDDEN, "Crew-012", "질문 수정 권한이 없습니다."), QUESTION_DELETE_FAIL(FORBIDDEN, "Crew-013", "질문 삭제 권한이 없습니다."), - QUESTION_NOT_FOUND(BAD_REQUEST, "Crew-014", "질문을 찾을 수 없습니다."); - + QUESTION_NOT_FOUND(BAD_REQUEST, "Crew-014", "질문을 찾을 수 없습니다."), + CREW_MEMBER_NOT_IN_CREW(BAD_REQUEST, "Crew-015","차단 대상 멤버가 해당 크루에 포함되어 있지 않습니다."), + CREW_MEMBER_BANNED_CANNOT_APPLY(HttpStatus.BAD_REQUEST, "Crew-016", "차단된 사용자는 해당 크루에 참가 신청할 수 없습니다."), ; private final HttpStatus status; diff --git a/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java index 029a470..d1715de 100644 --- a/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java +++ b/src/main/java/com/retrip/crew/infra/adapter/in/presentation/rest/CrewController.java @@ -147,4 +147,30 @@ public ApiResponse deleteCrew( manageCrewUseCase.deleteCrew(crewId, loginMemberId); return ApiResponse.noContent(); } + + @Schema(description = "크루 멤버 추방") + @DeleteMapping("/{crewId}/members/exile") + public ApiResponse expelMember(@RequestParam("memberId") UUID memberId, //TODO: 추후 로그인 구현되면 이부분은 바뀔 에정 + @PathVariable("crewId") UUID crewId, + @RequestBody CrewMemberExpelRequest request) { + manageCrewUseCase.expelMember(memberId, crewId, request.memberId()); + return ApiResponse.noContent(); + } + + @Schema(description = "크루에서 회원 차단") + @PostMapping("/{crewId}/members/ban") + public ApiResponse banMember(@RequestParam("memberId") UUID memberId, //TODO: 추후 로그인 구현되면 이부분은 바뀔 에정 + @PathVariable("crewId") UUID crewId, + @RequestBody CrewMemberBanRequest request) { + manageCrewUseCase.banMember(memberId, crewId, request.memberId()); + return ApiResponse.noContent(); + } + + @Schema(description = "크루 멤버 차단 목록 조회") + @GetMapping("/{crewId}/members/ban") + public ApiResponse banMember(@RequestParam("memberId") UUID memberId, //TODO: 추후 로그인 구현되면 이부분은 바뀔 에정 + @PathVariable("crewId") UUID crewId) { + CrewBanListResponse banMembers = manageCrewUseCase.getBanMembers(memberId, crewId); + return ApiResponse.ok(banMembers); + } } From 0607619847529ba1bab8f8ef8174c290253274e4 Mon Sep 17 00:00:00 2001 From: pparkjs Date: Sun, 10 Aug 2025 17:28:24 +0900 Subject: [PATCH 2/2] =?UTF-8?q?test:=20=ED=81=AC=EB=A3=A8=EC=9B=90=20?= =?UTF-8?q?=EC=B0=A8=EB=8B=A8,=20=EC=B6=94=EB=B0=A9,=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20=EB=8B=A8=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20(#27)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crew/application/in/CrewService.java | 2 +- .../in/response/crew/CrewBanListResponse.java | 2 +- .../repository/CrewBanMemberRepository.java | 2 +- .../crew/application/in/CrewServiceTest.java | 87 ++++++++++++++++++- .../com/retrip/crew/common/ServiceTest.java | 5 +- 5 files changed, 93 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/retrip/crew/application/in/CrewService.java b/src/main/java/com/retrip/crew/application/in/CrewService.java index 9615ffd..33cfb1e 100644 --- a/src/main/java/com/retrip/crew/application/in/CrewService.java +++ b/src/main/java/com/retrip/crew/application/in/CrewService.java @@ -174,6 +174,6 @@ public CrewBanListResponse getBanMembers(UUID loginMemberId, UUID crewId) { Crew crew = findCrewById(crewId); crew.validateCrewLeader(loginMemberId); List crewBanMembers = crewBanMemberRepository.findAllByCrewId(crewId); - return CrewBanListResponse.from(crewBanMembers); + return CrewBanListResponse.of(crewBanMembers); } } diff --git a/src/main/java/com/retrip/crew/application/in/response/crew/CrewBanListResponse.java b/src/main/java/com/retrip/crew/application/in/response/crew/CrewBanListResponse.java index 765d713..38de456 100644 --- a/src/main/java/com/retrip/crew/application/in/response/crew/CrewBanListResponse.java +++ b/src/main/java/com/retrip/crew/application/in/response/crew/CrewBanListResponse.java @@ -11,7 +11,7 @@ public record CrewBanListResponse( @Schema(description = "차단한 회원 리스트") List banMembers ) { - public static CrewBanListResponse from(List crewBanMembers) { + public static CrewBanListResponse of(List crewBanMembers) { return new CrewBanListResponse(BanMemberResponse.toList(crewBanMembers)); } diff --git a/src/main/java/com/retrip/crew/application/out/repository/CrewBanMemberRepository.java b/src/main/java/com/retrip/crew/application/out/repository/CrewBanMemberRepository.java index 4da47b1..7710fdf 100644 --- a/src/main/java/com/retrip/crew/application/out/repository/CrewBanMemberRepository.java +++ b/src/main/java/com/retrip/crew/application/out/repository/CrewBanMemberRepository.java @@ -5,6 +5,6 @@ import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; -public interface CrewBanMemberRepository extends JpaRepository { +public interface CrewBanMemberRepository extends ReadRepository { List findAllByCrewId(UUID crewId); } diff --git a/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java b/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java index 6b89820..4265967 100644 --- a/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java +++ b/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java @@ -6,6 +6,8 @@ import static com.retrip.crew.common.fixture.CrewFixture.createCrewRequest; import static com.retrip.crew.common.fixture.CrewFixture.createDefaultQuestions; import static com.retrip.crew.common.fixture.CrewFixture.createMultipleCrews; +import static com.retrip.crew.common.fixture.CrewFixture.정수_ID; +import static com.retrip.crew.common.fixture.CrewFixture.홍석_ID; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -16,18 +18,22 @@ import com.retrip.crew.application.in.request.crew.CrewCreateRequest; import com.retrip.crew.application.in.request.crew.CrewOrder; import com.retrip.crew.application.in.request.crew.CrewUpdateRequest; +import com.retrip.crew.application.in.request.demand.CreateDemandRequest; import com.retrip.crew.application.in.response.IntroductionCreateResponse; import com.retrip.crew.application.in.response.IntroductionDetailResponse; +import com.retrip.crew.application.in.response.crew.CrewBanListResponse; import com.retrip.crew.application.in.response.crew.CrewCreateResponse; import com.retrip.crew.application.in.response.crew.CrewDetailResponse; import com.retrip.crew.application.in.response.crew.CrewListResponse; import com.retrip.crew.application.in.response.crew.CrewUpdateResponse; +import com.retrip.crew.application.in.response.demand.CreateDemandResponse; import com.retrip.crew.common.ServiceTest; import com.retrip.crew.domain.entity.Crew; import com.retrip.crew.domain.entity.CrewMemberRole; import com.retrip.crew.domain.entity.Demand; import com.retrip.crew.domain.entity.Introduction; import com.retrip.crew.domain.exception.NotCrewLeaderException; +import com.retrip.crew.domain.exception.common.BusinessException; import com.retrip.crew.domain.exception.common.InvalidAccessException; import com.retrip.crew.infra.adapter.in.presentation.rest.common.ScrollPageResponse; import java.util.List; @@ -301,4 +307,83 @@ class CrewServiceTest extends ServiceTest { // when && then assertThrows(NotCrewLeaderException.class, () -> crewService.deleteCrew(savedCrew.getId(), MEMBER_ID)); } -} + + @Test + void 크루_멤버를_추방하면_멤버에서_제외되고_크루차단대상에_들어간다() { + // given + Crew crew = Crew.create( + "속초 크루원 구함", + "속초 친구 구합니다! 나이는 20~40.. 많은 가입 부탁드립니다.", + 100, + LEADER_ID, + createDefaultQuestions() + ); + Crew savedCrew = crewRepository.save(crew); + Demand demand = savedCrew.demand(정수_ID); + savedCrew.approveDemand(demand); + + //when + crewService.expelMember(LEADER_ID, savedCrew.getId(), 정수_ID); + + //then + assertThat(savedCrew.getCrewBanMembers().getValues().stream().anyMatch(member -> member.getMemberId().equals(정수_ID))).isTrue(); + } + + @Test + void 크루_리더가_특정_회원_차단하면_크루차단대상에_들어간다() { + // given + Crew crew = Crew.create( + "속초 크루원 구함", + "속초 친구 구합니다! 나이는 20~40.. 많은 가입 부탁드립니다.", + 100, + LEADER_ID, + createDefaultQuestions() + ); + Crew savedCrew = crewRepository.save(crew); + + //when + crewService.banMember(LEADER_ID, savedCrew.getId(), 정수_ID); + + //then + assertThat(savedCrew.getCrewBanMembers().getValues().stream().anyMatch(member -> member.getMemberId().equals(정수_ID))).isTrue(); + } + + @Test + void 크루_리더는_크루차단목록을_확인할_수_있다() { + // given + Crew crew = Crew.create( + "속초 크루원 구함", + "속초 친구 구합니다! 나이는 20~40.. 많은 가입 부탁드립니다.", + 100, + LEADER_ID, + createDefaultQuestions() + ); + Crew savedCrew = crewRepository.save(crew); + crewService.banMember(LEADER_ID, savedCrew.getId(), 정수_ID); + crewService.banMember(LEADER_ID, savedCrew.getId(), 홍석_ID); + + //when + CrewBanListResponse banMembers = crewService.getBanMembers(LEADER_ID, savedCrew.getId()); + + //then + assertThat(banMembers.banMembers().stream().allMatch(m -> List.of(정수_ID, 홍석_ID).contains(m.bannedMemberIds()))).isTrue(); + } + + @Test + void 크루_차단목록에_들어가면_크루_가입신청이_불가능_하다() { + // given + Crew crew = Crew.create( + "속초 크루원 구함", + "속초 친구 구합니다! 나이는 20~40.. 많은 가입 부탁드립니다.", + 100, + LEADER_ID, + createDefaultQuestions() + ); + Crew savedCrew = crewRepository.save(crew); + crewService.banMember(LEADER_ID, savedCrew.getId(), 정수_ID); + CreateDemandRequest request = new CreateDemandRequest(정수_ID); + + //when && then + assertThrows(BusinessException.class, () -> demandService.createDemand(savedCrew.getId(), request)); + } +} \ No newline at end of file diff --git a/src/test/java/com/retrip/crew/common/ServiceTest.java b/src/test/java/com/retrip/crew/common/ServiceTest.java index 1fb2aa3..8a9a708 100644 --- a/src/test/java/com/retrip/crew/common/ServiceTest.java +++ b/src/test/java/com/retrip/crew/common/ServiceTest.java @@ -34,6 +34,9 @@ public class ServiceTest { @Autowired protected IntroductionQueryRepository introductionQueryRepository; + @Autowired + protected CrewBanMemberRepository crewBanMemberRepository; + @Autowired protected RecruitmentQuestionQueryRepository recruitmentQuestionQueryRepository; @@ -49,7 +52,7 @@ public class ServiceTest { @BeforeEach void setUp() { - crewService = new CrewService(crewRepository, crewMemberRepository, crewQueryRepository, introductionRepository, introductionQueryRepository); + crewService = new CrewService(crewRepository, crewMemberRepository, crewQueryRepository, introductionRepository, crewBanMemberRepository, introductionQueryRepository); demandService = new DemandService(crewRepository, demandRepository, crewQueryRepository, recruitmentQuestionRepository, recruitmentQuestionQueryRepository); } }