diff --git a/src/main/java/com/example/mate/domain/mate/controller/MateController.java b/src/main/java/com/example/mate/domain/mate/controller/MateController.java index 1f656353..470bc380 100644 --- a/src/main/java/com/example/mate/domain/mate/controller/MateController.java +++ b/src/main/java/com/example/mate/domain/mate/controller/MateController.java @@ -2,6 +2,7 @@ import com.example.mate.common.response.ApiResponse; import com.example.mate.common.response.PageResponse; +import com.example.mate.common.security.auth.AuthMember; import com.example.mate.common.validator.ValidPageable; import com.example.mate.domain.constant.Gender; import com.example.mate.domain.mate.dto.request.*; @@ -18,6 +19,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -33,12 +35,12 @@ public class MateController { @PostMapping @Operation(summary = "메이트 구인글 등록", description = "메이트 구인글 페이지에서 등록합니다.") - public ResponseEntity> createMatePost( - @Parameter(description = "구인글 등록 데이터", required = true) @Valid @RequestPart(value = "data") MatePostCreateRequest request, - @Parameter(description = "구인글 대표사진", required = true) @RequestPart(value = "file", required = false) MultipartFile file - ) { - //TODO - member 정보를 request가 아니라 @AuthenticationPrincipal Long memberId로 받도록 변경 - MatePostResponse response = mateService.createMatePost(request, file); + public ResponseEntity> createMatePost(@Parameter(description = "구인글 등록 데이터", required = true) + @Valid @RequestPart(value = "data") MatePostCreateRequest request, + @Parameter(description = "구인글 대표사진", required = true) + @RequestPart(value = "file", required = false) MultipartFile file, + @AuthenticationPrincipal AuthMember member) { + MatePostResponse response = mateService.createMatePost(request, file, member.getMemberId()); return ResponseEntity.ok(ApiResponse.success(response)); } @@ -52,15 +54,21 @@ public ResponseEntity>> getMainPagePos @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "메이트 구인글 페이징 조회", description = "메이트 구인글 페이지에서 팀/카테고리 기준으로 페이징 조회합니다.") - public ResponseEntity>> getMatePagePosts( - @Parameter(description = "팀 ID") @RequestParam(required = false) Long teamId, - @Parameter(description = "정렬 기준") @RequestParam(required = false) String sortType, - @Parameter(description = "연령대 카테고리") @RequestParam(required = false) String age, - @Parameter(description = "성별 카테고리") @RequestParam(required = false) String gender, - @Parameter(description = "모집인원 수") @RequestParam(required = false) Integer maxParticipants, - @Parameter(description = "이동수단 카테고리") @RequestParam(required = false) String transportType, - @Parameter(description = "페이징 정보") @ValidPageable Pageable pageable - ) { + public ResponseEntity>> getMatePagePosts(@Parameter(description = "팀 ID") + @RequestParam(required = false) Long teamId, + @Parameter(description = "정렬 기준") + @RequestParam(required = false) String sortType, + @Parameter(description = "연령대 카테고리") + @RequestParam(required = false) String age, + @Parameter(description = "성별 카테고리") + @RequestParam(required = false) String gender, + @Parameter(description = "모집인원 수") + @RequestParam(required = false) Integer maxParticipants, + @Parameter(description = "이동수단 카테고리") + @RequestParam(required = false) String transportType, + @Parameter(description = "페이징 정보") + @ValidPageable Pageable pageable) { + MatePostSearchRequest request = MatePostSearchRequest.builder() .teamId(teamId) .sortType(sortType != null ? SortType.from(sortType) : null) @@ -83,65 +91,66 @@ public ResponseEntity> getMatePostDetail(@Pa return ResponseEntity.ok(ApiResponse.success(response)); } - @PatchMapping("/{memberId}/{postId}") + @PutMapping("/{postId}") @Operation(summary = "메이트 구인글 수정", description = "메이트 구인글 상세 페이지에서 수정합니다.") - public ResponseEntity> updateMatePost( - @Parameter(description = "작성자 ID (삭제 예정)", required = true) @PathVariable Long memberId, - @Parameter(description = "구인글 ID", required = true) @PathVariable Long postId, - @Parameter(description = "수정할 구인글 데이터", required = true) @Valid @RequestPart(value = "data") MatePostUpdateRequest request, - @Parameter(description = "수정할 대표사진 파일 ", required = true) @RequestPart(value = "file", required = false) MultipartFile file - ) { - MatePostResponse response = mateService.updateMatePost(memberId, postId, request, file); + public ResponseEntity> updateMatePost( @AuthenticationPrincipal AuthMember member, + @Parameter(description = "구인글 ID", required = true) + @PathVariable Long postId, + @Parameter(description = "수정할 구인글 데이터", required = true) + @Valid @RequestPart(value = "data") MatePostUpdateRequest request, + @Parameter(description = "수정할 대표사진 파일 ", required = true) + @RequestPart(value = "file", required = false) MultipartFile file) { + + MatePostResponse response = mateService.updateMatePost(member.getMemberId(), postId, request, file); return ResponseEntity.ok(ApiResponse.success(response)); } - // TODO: @PathVariable Long memberId -> @AuthenticationPrincipal 로 변경 // 메이트 게시글 모집 상태 변경 - @PatchMapping("/{memberId}/{postId}/status") + @PatchMapping("/{postId}/status") @Operation(summary = "메이트 구인글 모집상태 변경", description = "메이트 구인글 채팅방에서 모집상태를 변경합니다.") - public ResponseEntity> updateMatePostStatus( - @Parameter(description = "작성자 ID (삭제 예정)", required = true) @PathVariable(value = "memberId") Long memberId, - @Parameter(description = "구인글 ID", required = true) @PathVariable(value = "postId") Long postId, - @Parameter(description = "변경할 모집상태와 현재 참여자 리스트 ID", required = true) @Valid @RequestBody MatePostStatusRequest request - ) { - MatePostResponse response = mateService.updateMatePostStatus(memberId, postId, request); + public ResponseEntity> updateMatePostStatus( @AuthenticationPrincipal AuthMember member, + @Parameter(description = "구인글 ID", required = true) + @PathVariable(value = "postId") Long postId, + @Parameter(description = "변경할 모집상태와 현재 참여자 리스트 ID", required = true) + @Valid @RequestBody MatePostStatusRequest request) { + + MatePostResponse response = mateService.updateMatePostStatus(member.getMemberId(), postId, request); return ResponseEntity.ok(ApiResponse.success(response)); } - // TODO: @PathVariable Long memberId -> @AuthenticationPrincipal 로 변경 - @DeleteMapping("/{memberId}/{postId}") + @DeleteMapping("/{postId}") @Operation(summary = "메이트 구인글 삭제", description = "메이트 구인글 상세 페이지에서 삭제합니다.") - public ResponseEntity deleteMatePost(@Parameter(description = "작성자 ID (삭제 예정)", required = true) - @PathVariable Long memberId, - @Parameter(description = "삭제할 구인글 ID", required = true) - @PathVariable Long postId) { + public ResponseEntity deleteMatePost( @AuthenticationPrincipal AuthMember member, + @Parameter(description = "삭제할 구인글 ID", required = true) + @PathVariable Long postId) { - mateService.deleteMatePost(memberId, postId); + mateService.deleteMatePost(member.getMemberId(), postId); return ResponseEntity.noContent().build(); } - // TODO: @PathVariable Long memberId -> @AuthenticationPrincipal 로 변경 - @PatchMapping("/{memberId}/{postId}/complete") + @PatchMapping("/{postId}/complete") @Operation(summary = "직관완료 처리", description = "메이트 구인글 채팅방에서 직관완료 처리를 진행합니다.") - public ResponseEntity> completeVisit( - @Parameter(description = "작성자 ID (삭제 예정)", required = true) @PathVariable Long memberId, - @Parameter(description = "구인글 ID", required = true) @PathVariable Long postId, - @Parameter(description = "실제 직관 참여자 리스트 ID", required = true) @Valid @RequestBody MatePostCompleteRequest request - ) { - MatePostCompleteResponse response = mateService.completeVisit(memberId, postId, request); + public ResponseEntity> completeVisit( @AuthenticationPrincipal AuthMember member, + @Parameter(description = "구인글 ID", required = true) + @PathVariable Long postId, + @Parameter(description = "실제 직관 참여자 리스트 ID", required = true) + @Valid @RequestBody MatePostCompleteRequest request) { + + MatePostCompleteResponse response = mateService.completeVisit(member.getMemberId(), postId, request); return ResponseEntity.ok(ApiResponse.success(response)); } - // TODO: @PathVariable Long memberId -> @AuthenticationPrincipal 로 변경 - @PostMapping("/{memberId}/{postId}/reviews") + @PostMapping("/{postId}/reviews") @Operation(summary = "메이트 직관 후기 등록", description = "직관 타임라인 페이지에서 메이트에 대한 후기를 등록합니다.") - public ResponseEntity> createMateReview( - @Parameter(description = "작성자 ID (삭제 예정)", required = true) @PathVariable Long memberId, - @Parameter(description = "구인글 ID", required = true) @PathVariable Long postId, - @Parameter(description = "리뷰 대상자 ID와 평점 및 코멘트", required = true) @Valid @RequestBody MateReviewCreateRequest request + public ResponseEntity> createMateReview( @AuthenticationPrincipal AuthMember member, + @Parameter(description = "구인글 ID", required = true) + @PathVariable Long postId, + @Parameter(description = "리뷰 대상자 ID와 평점 및 코멘트", required = true) + @Valid @RequestBody MateReviewCreateRequest request ) { - MateReviewCreateResponse response = mateService.createReview(postId, memberId, request); + + MateReviewCreateResponse response = mateService.createReview(postId, member.getMemberId(), request); return ResponseEntity.ok(ApiResponse.success(response)); } } \ No newline at end of file diff --git a/src/main/java/com/example/mate/domain/mate/dto/request/MatePostCreateRequest.java b/src/main/java/com/example/mate/domain/mate/dto/request/MatePostCreateRequest.java index 3748d003..77f593e9 100644 --- a/src/main/java/com/example/mate/domain/mate/dto/request/MatePostCreateRequest.java +++ b/src/main/java/com/example/mate/domain/mate/dto/request/MatePostCreateRequest.java @@ -19,7 +19,6 @@ @NoArgsConstructor @AllArgsConstructor public class MatePostCreateRequest { - private Long memberId; @NotNull(message = "팀 ID는 필수 입력 값입니다.") @Min(value = 0, message = "팀 ID는 0 이상이어야 합니다.") diff --git a/src/main/java/com/example/mate/domain/mate/service/MateService.java b/src/main/java/com/example/mate/domain/mate/service/MateService.java index 245d7619..95b6caa3 100644 --- a/src/main/java/com/example/mate/domain/mate/service/MateService.java +++ b/src/main/java/com/example/mate/domain/mate/service/MateService.java @@ -41,8 +41,8 @@ public class MateService { private final MateReviewRepository mateReviewRepository; private final FileService fileService; - public MatePostResponse createMatePost(MatePostCreateRequest request, MultipartFile file) { - Member author = findMemberById(request.getMemberId()); + public MatePostResponse createMatePost(MatePostCreateRequest request, MultipartFile file, Long memberId) { + Member author = findMemberById(memberId); Match match = findMatchById(request.getMatchId()); diff --git a/src/test/java/com/example/mate/domain/mate/controller/MateControllerTest.java b/src/test/java/com/example/mate/domain/mate/controller/MateControllerTest.java index 19c84865..74b2c882 100644 --- a/src/test/java/com/example/mate/domain/mate/controller/MateControllerTest.java +++ b/src/test/java/com/example/mate/domain/mate/controller/MateControllerTest.java @@ -21,6 +21,7 @@ import com.example.mate.common.error.ErrorCode; import com.example.mate.common.response.PageResponse; import com.example.mate.common.security.util.JwtUtil; +import com.example.mate.config.WithAuthMember; import com.example.mate.domain.constant.Gender; import com.example.mate.domain.mate.dto.request.MatePostCreateRequest; import com.example.mate.domain.mate.dto.request.MatePostUpdateRequest; @@ -31,6 +32,7 @@ import com.example.mate.domain.mate.entity.Status; import com.example.mate.domain.mate.entity.TransportType; import com.example.mate.domain.mate.service.MateService; +import com.example.mate.domain.member.service.LogoutRedisService; import com.fasterxml.jackson.databind.ObjectMapper; import java.time.LocalDateTime; import java.util.List; @@ -39,6 +41,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; @@ -48,10 +51,11 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -//@WebMvcTest(MateController.class) -@SpringBootTest + +@WebMvcTest(MateController.class) @MockBean(JpaMetamodelMappingContext.class) @AutoConfigureMockMvc(addFilters = false) +@WithAuthMember class MateControllerTest { @Autowired @@ -66,6 +70,9 @@ class MateControllerTest { @MockBean private JwtUtil jwtUtil; + @MockBean + private LogoutRedisService logoutRedisService; + private MatePostSummaryResponse createMatePostSummaryResponse() { return MatePostSummaryResponse.builder() .imageUrl("test-image.jpg") @@ -87,7 +94,6 @@ class CreateMatePost { private MatePostCreateRequest createMatePostRequest() { return MatePostCreateRequest.builder() - .memberId(1L) .teamId(1L) .matchId(1L) .title("테스트 제목") @@ -127,7 +133,7 @@ void createMatePost_success() throws Exception { "test image content".getBytes() ); - given(mateService.createMatePost(any(MatePostCreateRequest.class), any())) + given(mateService.createMatePost(any(MatePostCreateRequest.class), any(), any())) .willReturn(response); // when & then @@ -146,6 +152,7 @@ void createMatePost_success() throws Exception { @DisplayName("메이트 게시글 작성 성공 - 이미지 없음") void createMatePost_successWithoutImage() throws Exception { // given + Long memberId = 1L; MatePostCreateRequest request = createMatePostRequest(); MatePostResponse response = createMatePostResponse(); @@ -156,7 +163,7 @@ void createMatePost_successWithoutImage() throws Exception { objectMapper.writeValueAsBytes(request) ); - given(mateService.createMatePost(any(MatePostCreateRequest.class), any())) + given(mateService.createMatePost(any(MatePostCreateRequest.class), any(), any())) .willReturn(response); // when & then @@ -468,7 +475,6 @@ private MatePostResponse createMatePostResponse() { @DisplayName("메이트 게시글 수정 성공") void updateMatePost_Success() throws Exception { // given - Long memberId = 1L; Long postId = 1L; MatePostUpdateRequest request = createMatePostUpdateRequest(); MatePostResponse response = createMatePostResponse(); @@ -487,12 +493,12 @@ void updateMatePost_Success() throws Exception { "test image content".getBytes() ); - given(mateService.updateMatePost(eq(memberId), eq(postId), any(MatePostUpdateRequest.class), any())) + given(mateService.updateMatePost(any(), eq(postId), any(MatePostUpdateRequest.class), any())) .willReturn(response); // when & then mockMvc.perform(MockMvcRequestBuilders - .multipart(HttpMethod.PATCH, "/api/mates/{memberId}/{postId}", memberId, postId) + .multipart(HttpMethod.PUT, "/api/mates/{postId}", postId) .file(file) .file(data)) .andDo(print()) @@ -502,14 +508,13 @@ void updateMatePost_Success() throws Exception { .andExpect(jsonPath("$.data.status").value("모집중")) .andExpect(jsonPath("$.code").value(200)); - verify(mateService).updateMatePost(eq(memberId), eq(postId), any(MatePostUpdateRequest.class), any()); + verify(mateService).updateMatePost(any(), eq(postId), any(MatePostUpdateRequest.class), any()); } @Test @DisplayName("메이트 게시글 수정 성공 - 이미지 없음") void updateMatePost_SuccessWithoutImage() throws Exception { // given - Long memberId = 1L; Long postId = 1L; MatePostUpdateRequest request = createMatePostUpdateRequest(); MatePostResponse response = createMatePostResponse(); @@ -521,12 +526,12 @@ void updateMatePost_SuccessWithoutImage() throws Exception { objectMapper.writeValueAsBytes(request) ); - given(mateService.updateMatePost(eq(memberId), eq(postId), any(MatePostUpdateRequest.class), isNull())) + given(mateService.updateMatePost(any(), eq(postId), any(MatePostUpdateRequest.class), isNull())) .willReturn(response); // when & then mockMvc.perform(MockMvcRequestBuilders - .multipart(HttpMethod.PATCH, "/api/mates/{memberId}/{postId}", memberId, postId) + .multipart(HttpMethod.PUT, "/api/mates/{postId}", postId) .file(data)) .andDo(print()) .andExpect(status().isOk()) @@ -535,14 +540,13 @@ void updateMatePost_SuccessWithoutImage() throws Exception { .andExpect(jsonPath("$.data.status").value("모집중")) .andExpect(jsonPath("$.code").value(200)); - verify(mateService).updateMatePost(eq(memberId), eq(postId), any(MatePostUpdateRequest.class), isNull()); + verify(mateService).updateMatePost(any(), eq(postId), any(MatePostUpdateRequest.class), isNull()); } @Test @DisplayName("메이트 게시글 수정 실패 - 유효하지 않은 요청 데이터") void updateMatePost_FailWithInvalidRequest() throws Exception { // given - Long memberId = 1L; Long postId = 1L; MatePostUpdateRequest request = MatePostUpdateRequest.builder() .teamId(null) // 필수 값 누락 @@ -564,7 +568,7 @@ void updateMatePost_FailWithInvalidRequest() throws Exception { // when & then mockMvc.perform(MockMvcRequestBuilders - .multipart(HttpMethod.PATCH, "/api/mates/{memberId}/{postId}", memberId, postId) + .multipart(HttpMethod.PUT, "/api/mates/{postId}", postId) .file(data)) .andDo(print()) .andExpect(status().isBadRequest()); @@ -576,7 +580,6 @@ void updateMatePost_FailWithInvalidRequest() throws Exception { @DisplayName("메이트 게시글 수정 실패 - 존재하지 않는 게시글") void updateMatePost_FailWithPostNotFound() throws Exception { // given - Long memberId = 1L; Long postId = 999L; MatePostUpdateRequest request = createMatePostUpdateRequest(); @@ -592,7 +595,7 @@ void updateMatePost_FailWithPostNotFound() throws Exception { // when & then mockMvc.perform(MockMvcRequestBuilders - .multipart(HttpMethod.PATCH, "/api/mates/{memberId}/{postId}", memberId, postId) + .multipart(HttpMethod.PUT, "/api/mates/{postId}", postId) .file(data)) .andDo(print()) .andExpect(status().isNotFound()) @@ -604,7 +607,6 @@ void updateMatePost_FailWithPostNotFound() throws Exception { @DisplayName("메이트 게시글 수정 실패 - 권한 없음") void updateMatePost_FailWithUnauthorized() throws Exception { // given - Long memberId = 999L; Long postId = 1L; MatePostUpdateRequest request = createMatePostUpdateRequest(); @@ -620,7 +622,7 @@ void updateMatePost_FailWithUnauthorized() throws Exception { // when & then mockMvc.perform(MockMvcRequestBuilders - .multipart(HttpMethod.PATCH, "/api/mates/{memberId}/{postId}", memberId, postId) + .multipart(HttpMethod.PUT, "/api/mates/{postId}", postId) .file(data)) .andDo(print()) .andExpect(status().isForbidden()) @@ -632,7 +634,6 @@ void updateMatePost_FailWithUnauthorized() throws Exception { @DisplayName("메이트 게시글 수정 실패 - 이미 완료된 게시글") void updateMatePost_FailWithCompletedPost() throws Exception { // given - Long memberId = 1L; Long postId = 1L; MatePostUpdateRequest request = createMatePostUpdateRequest(); @@ -648,7 +649,7 @@ void updateMatePost_FailWithCompletedPost() throws Exception { // when & then mockMvc.perform(MockMvcRequestBuilders - .multipart(HttpMethod.PATCH, "/api/mates/{memberId}/{postId}", memberId, postId) + .multipart(HttpMethod.PUT, "/api/mates/{postId}", postId) .file(data)) .andDo(print()) .andExpect(status().isForbidden()) @@ -669,7 +670,7 @@ void deleteMatePost_success() throws Exception { Long postId = 1L; // when & then - mockMvc.perform(delete("/api/mates/{memberId}/{postId}", memberId, postId) + mockMvc.perform(delete("/api/mates/{postId}", postId) .contentType(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isNoContent()); @@ -689,7 +690,7 @@ void deleteMatePost_failPostNotFound() throws Exception { .deleteMatePost(memberId, nonExistentPostId); // when & then - mockMvc.perform(delete("/api/mates/{memberId}/{postId}", memberId, nonExistentPostId) + mockMvc.perform(delete("/api/mates/{postId}", nonExistentPostId) .contentType(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isNotFound()) @@ -700,6 +701,7 @@ void deleteMatePost_failPostNotFound() throws Exception { @Test @DisplayName("메이트 게시글 삭제 실패 - 삭제 권한 없음") + @WithAuthMember(memberId = 2L) void deleteMatePost_failNotAllowed() throws Exception { // given Long memberId = 2L; // 작성자가 아닌 다른 사용자 @@ -710,7 +712,7 @@ void deleteMatePost_failNotAllowed() throws Exception { .deleteMatePost(memberId, postId); // when & then - mockMvc.perform(delete("/api/mates/{memberId}/{postId}", memberId, postId) + mockMvc.perform(delete("/api/mates/{postId}", postId) .contentType(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isForbidden()) diff --git a/src/test/java/com/example/mate/domain/mate/controller/MateReviewControllerTest.java b/src/test/java/com/example/mate/domain/mate/controller/MateReviewControllerTest.java index f6bb84ab..d72da3ff 100644 --- a/src/test/java/com/example/mate/domain/mate/controller/MateReviewControllerTest.java +++ b/src/test/java/com/example/mate/domain/mate/controller/MateReviewControllerTest.java @@ -8,6 +8,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.example.mate.common.security.filter.JwtCheckFilter; +import com.example.mate.config.WithAuthMember; import com.example.mate.domain.constant.Rating; import com.example.mate.domain.mate.dto.request.MateReviewCreateRequest; import com.example.mate.domain.mate.dto.response.MateReviewCreateResponse; @@ -27,6 +28,7 @@ @WebMvcTest(MateController.class) @MockBean(JpaMetamodelMappingContext.class) @AutoConfigureMockMvc(addFilters = false) +@WithAuthMember class MateReviewControllerTest { @Autowired @@ -68,7 +70,6 @@ private MateReviewCreateResponse createMateReviewResponse() { @DisplayName("메이트 직관 후기 작성 성공") void createMateReview_success() throws Exception { // given - Long memberId = 1L; Long postId = 1L; MateReviewCreateRequest request = createMateReviewRequest(); MateReviewCreateResponse response = createMateReviewResponse(); @@ -77,7 +78,7 @@ void createMateReview_success() throws Exception { .willReturn(response); // when & then - mockMvc.perform(post("/api/mates/{memberId}/{postId}/reviews", memberId, postId) + mockMvc.perform(post("/api/mates/{postId}/reviews", postId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -96,7 +97,6 @@ void createMateReview_success() throws Exception { @DisplayName("메이트 직관 후기 작성 실패 - 리뷰 대상자 ID 누락") void createMateReview_failWithoutRevieweeId() throws Exception { // given - Long memberId = 1L; Long postId = 1L; MateReviewCreateRequest request = MateReviewCreateRequest.builder() .rating(Rating.GOOD) @@ -104,7 +104,7 @@ void createMateReview_failWithoutRevieweeId() throws Exception { .build(); // when & then - mockMvc.perform(post("/api/mates/{memberId}/{postId}/reviews", memberId, postId) + mockMvc.perform(post("/api/mates/{postId}/reviews", postId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -128,7 +128,7 @@ void createMateReview_failWithLongContent() throws Exception { .build(); // when & then - mockMvc.perform(post("/api/mates/{memberId}/{postId}/reviews", memberId, postId) + mockMvc.perform(post("/api/mates/{postId}/reviews", memberId, postId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) diff --git a/src/test/java/com/example/mate/domain/mate/controller/MateStatusControllerTest.java b/src/test/java/com/example/mate/domain/mate/controller/MateStatusControllerTest.java index 33be6016..e80b18db 100644 --- a/src/test/java/com/example/mate/domain/mate/controller/MateStatusControllerTest.java +++ b/src/test/java/com/example/mate/domain/mate/controller/MateStatusControllerTest.java @@ -20,6 +20,7 @@ import com.example.mate.common.error.CustomException; import com.example.mate.common.error.ErrorCode; import com.example.mate.common.security.filter.JwtCheckFilter; +import com.example.mate.config.WithAuthMember; import com.example.mate.domain.mate.dto.request.MatePostCompleteRequest; import com.example.mate.domain.mate.dto.request.MatePostStatusRequest; import com.example.mate.domain.mate.dto.response.MatePostCompleteResponse; @@ -42,6 +43,7 @@ @WebMvcTest(MateController.class) @MockBean(JpaMetamodelMappingContext.class) @AutoConfigureMockMvc(addFilters = false) +@WithAuthMember class MateStatusControllerTest { @Autowired @@ -64,7 +66,6 @@ class UpdateMatePostStatus { @DisplayName("메이트 게시글 상태 변경 성공 - OPEN 상태로 변경") void updateMatePostStatus_successToOpen() throws Exception { // given - Long memberId = 1L; Long postId = 1L; List participantIds = List.of(2L, 3L); MatePostStatusRequest request = new MatePostStatusRequest(Status.OPEN, participantIds); @@ -73,11 +74,11 @@ void updateMatePostStatus_successToOpen() throws Exception { .status(Status.OPEN) .build(); - given(mateService.updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class))) + given(mateService.updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class))) .willReturn(response); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", memberId, postId) + mockMvc.perform(patch("/api/mates/{postId}/status", postId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -87,14 +88,13 @@ void updateMatePostStatus_successToOpen() throws Exception { .andExpect(jsonPath("$.data.status").value("모집중")) .andExpect(jsonPath("$.code").value(200)); - verify(mateService).updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class)); + verify(mateService).updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class)); } @Test @DisplayName("메이트 게시글 상태 변경 성공 - CLOSED 상태로 변경") void updateMatePostStatus_successToClosed() throws Exception { // given - Long memberId = 1L; Long postId = 1L; List participantIds = List.of(2L, 3L, 4L); MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); @@ -103,11 +103,11 @@ void updateMatePostStatus_successToClosed() throws Exception { .status(Status.CLOSED) .build(); - given(mateService.updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class))) + given(mateService.updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class))) .willReturn(response); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", memberId, postId) + mockMvc.perform(patch("/api/mates/{postId}/status", postId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -117,24 +117,23 @@ void updateMatePostStatus_successToClosed() throws Exception { .andExpect(jsonPath("$.data.status").value("모집완료")) .andExpect(jsonPath("$.code").value(200)); - verify(mateService).updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class)); + verify(mateService).updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class)); } @Test @DisplayName("메이트 게시글 상태 변경 실패 - 존재하지 않는 게시글") void updateMatePostStatus_failPostNotFound() throws Exception { // given - Long memberId = 1L; Long nonExistentPostId = 999L; List participantIds = List.of(2L, 3L); MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); - given(mateService.updateMatePostStatus(eq(memberId), eq(nonExistentPostId), + given(mateService.updateMatePostStatus(any(), eq(nonExistentPostId), any(MatePostStatusRequest.class))) .willThrow(new CustomException(MATE_POST_NOT_FOUND_BY_ID)); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", memberId, nonExistentPostId) + mockMvc.perform(patch("/api/mates/{postId}/status", nonExistentPostId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -143,49 +142,23 @@ void updateMatePostStatus_failPostNotFound() throws Exception { .andExpect(jsonPath("$.message").exists()) .andExpect(jsonPath("$.code").value(404)); - verify(mateService).updateMatePostStatus(eq(memberId), eq(nonExistentPostId), + verify(mateService).updateMatePostStatus(any(), eq(nonExistentPostId), any(MatePostStatusRequest.class)); } - @Test - @DisplayName("메이트 게시글 상태 변경 실패 - 권한 없음") - void updateMatePostStatus_failNotAuthorized() throws Exception { - // given - Long memberId = 2L; - Long postId = 1L; - List participantIds = List.of(2L, 3L); - MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); - - given(mateService.updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class))) - .willThrow(new CustomException(ErrorCode.MATE_POST_UPDATE_NOT_ALLOWED)); - - // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", memberId, postId) - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(request))) - .andDo(print()) - .andExpect(status().isForbidden()) - .andExpect(jsonPath("$.status").value("ERROR")) - .andExpect(jsonPath("$.message").exists()) - .andExpect(jsonPath("$.code").value(403)); - - verify(mateService).updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class)); - } - @Test @DisplayName("메이트 게시글 상태 변경 실패 - VISIT_COMPLETE로 변경 시도") void updateMatePostStatus_failWithCompleteStatus() throws Exception { // given - Long memberId = 1L; Long postId = 1L; List participantIds = List.of(2L, 3L); MatePostStatusRequest request = new MatePostStatusRequest(Status.VISIT_COMPLETE, participantIds); - given(mateService.updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class))) + given(mateService.updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class))) .willThrow(new CustomException(ALREADY_COMPLETED_POST)); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", memberId, postId) + mockMvc.perform(patch("/api/mates/{postId}/status", postId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -194,23 +167,22 @@ void updateMatePostStatus_failWithCompleteStatus() throws Exception { .andExpect(jsonPath("$.message").exists()) .andExpect(jsonPath("$.code").value(403)); - verify(mateService).updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class)); + verify(mateService).updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class)); } @Test @DisplayName("메이트 게시글 상태 변경 실패 - 이미 완료된 게시글") void updateMatePostStatus_failAlreadyCompleted() throws Exception { // given - Long memberId = 1L; Long postId = 1L; List participantIds = List.of(2L, 3L); MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); - given(mateService.updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class))) + given(mateService.updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class))) .willThrow(new CustomException(ALREADY_COMPLETED_POST)); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", memberId, postId) + mockMvc.perform(patch("/api/mates/{postId}/status", postId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -219,24 +191,23 @@ void updateMatePostStatus_failAlreadyCompleted() throws Exception { .andExpect(jsonPath("$.message").exists()) .andExpect(jsonPath("$.code").value(403)); - verify(mateService).updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class)); + verify(mateService).updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class)); } @Test @DisplayName("메이트 게시글 상태 변경 실패 - 참여자 수 초과") void updateMatePostStatus_failMaxParticipantsExceeded() throws Exception { // given - Long memberId = 1L; Long postId = 1L; // @Size(max = 9) 제약조건을 통과하도록 9명으로 수정 List participantIds = List.of(2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L); MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); - given(mateService.updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class))) + given(mateService.updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class))) .willThrow(new CustomException(MATE_POST_MAX_PARTICIPANTS_EXCEEDED)); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", memberId, postId) + mockMvc.perform(patch("/api/mates/{postId}/status", postId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -245,21 +216,20 @@ void updateMatePostStatus_failMaxParticipantsExceeded() throws Exception { .andExpect(jsonPath("$.message").value(MATE_POST_MAX_PARTICIPANTS_EXCEEDED.getMessage())) .andExpect(jsonPath("$.code").value(400)); - verify(mateService).updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class)); + verify(mateService).updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class)); } @Test @DisplayName("메이트 게시글 상태 변경 실패 - 참여자 수 validation 실패") void updateMatePostStatus_failMaxParticipantsValidation() throws Exception { // given - Long memberId = 1L; Long postId = 1L; // @Size(max = 9) 제약조건을 초과하는 10명 List participantIds = List.of(2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L); MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", memberId, postId) + mockMvc.perform(patch("/api/mates/{postId}/status", postId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -276,16 +246,15 @@ void updateMatePostStatus_failMaxParticipantsValidation() throws Exception { @DisplayName("메이트 게시글 상태 변경 실패 - 잘못된 참여자 ID") void updateMatePostStatus_failInvalidParticipantIds() throws Exception { // given - Long memberId = 1L; Long postId = 1L; List participantIds = List.of(999L, 998L); // 존재하지 않는 참여자 ID MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); - given(mateService.updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class))) + given(mateService.updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class))) .willThrow(new CustomException(INVALID_MATE_POST_PARTICIPANT_IDS)); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", memberId, postId) + mockMvc.perform(patch("/api/mates/{postId}/status", postId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -294,7 +263,7 @@ void updateMatePostStatus_failInvalidParticipantIds() throws Exception { .andExpect(jsonPath("$.message").exists()) .andExpect(jsonPath("$.code").value(400)); - verify(mateService).updateMatePostStatus(eq(memberId), eq(postId), any(MatePostStatusRequest.class)); + verify(mateService).updateMatePostStatus(any(), eq(postId), any(MatePostStatusRequest.class)); } } @@ -327,7 +296,7 @@ void completeVisit_success() throws Exception { .willReturn(response); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", MEMBER_ID, POST_ID) + mockMvc.perform(patch("/api/mates/{postId}/complete", POST_ID) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -352,7 +321,7 @@ void completeVisit_failPostNotFound() throws Exception { .willThrow(new CustomException(MATE_POST_NOT_FOUND_BY_ID)); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", MEMBER_ID, POST_ID) + mockMvc.perform(patch("/api/mates/{postId}/complete", POST_ID) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -372,7 +341,7 @@ void completeVisit_failNotAuthorized() throws Exception { .willThrow(new CustomException(MATE_POST_UPDATE_NOT_ALLOWED)); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", MEMBER_ID, POST_ID) + mockMvc.perform(patch("/api/mates/{postId}/complete", POST_ID) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -392,7 +361,7 @@ void completeVisit_failBeforeMatchTime() throws Exception { .willThrow(new CustomException(MATE_POST_COMPLETE_TIME_NOT_ALLOWED)); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", MEMBER_ID, POST_ID) + mockMvc.perform(patch("/api/mates/{postId}/complete", POST_ID) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -412,7 +381,7 @@ void completeVisit_failNotClosedStatus() throws Exception { .willThrow(new CustomException(NOT_CLOSED_STATUS_FOR_COMPLETION)); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", MEMBER_ID, POST_ID) + mockMvc.perform(patch("/api/mates/{postId}/complete", POST_ID) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -432,7 +401,7 @@ void completeVisit_failExceededParticipants() throws Exception { .willThrow(new CustomException(MATE_POST_MAX_PARTICIPANTS_EXCEEDED)); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", MEMBER_ID, POST_ID) + mockMvc.perform(patch("/api/mates/{postId}/complete", POST_ID) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andDo(print()) @@ -442,4 +411,4 @@ void completeVisit_failExceededParticipants() throws Exception { .andExpect(jsonPath("$.code").value(400)); } } -} +} \ No newline at end of file diff --git a/src/test/java/com/example/mate/domain/mate/integration/MateIntegrationTest.java b/src/test/java/com/example/mate/domain/mate/integration/MateIntegrationTest.java index 12a13a7c..8f3d4a66 100644 --- a/src/test/java/com/example/mate/domain/mate/integration/MateIntegrationTest.java +++ b/src/test/java/com/example/mate/domain/mate/integration/MateIntegrationTest.java @@ -1,6 +1,7 @@ package com.example.mate.domain.mate.integration; import com.example.mate.common.security.util.JwtUtil; +import com.example.mate.config.WithAuthMember; import com.example.mate.domain.constant.Gender; import com.example.mate.domain.match.entity.Match; import com.example.mate.domain.match.repository.MatchRepository; @@ -24,6 +25,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.domain.PageRequest; import org.springframework.http.MediaType; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; @@ -60,6 +62,9 @@ public class MateIntegrationTest { @Autowired private MateRepository mateRepository; + @Autowired + private JdbcTemplate jdbcTemplate; + @MockBean private JwtUtil jwtUtil; @@ -78,6 +83,8 @@ void setUp() { matchRepository.deleteAll(); memberRepository.deleteAll(); + jdbcTemplate.execute("ALTER TABLE member ALTER COLUMN id RESTART WITH 1"); + // 테스트 멤버 생성 testMember = createTestMember(); @@ -151,10 +158,10 @@ class CreateMatePost { @Test @DisplayName("메이트 게시글 작성 성공") + @WithAuthMember void createMatePost_Success() throws Exception { // given MatePostCreateRequest request = MatePostCreateRequest.builder() - .memberId(testMember.getId()) .teamId(1L) .matchId(futureMatch.getId()) .title("통합 테스트 제목") @@ -198,36 +205,11 @@ void createMatePost_Success() throws Exception { assertThat(savedPost.getTransport()).isEqualTo(request.getTransportType()); } - @Test - @DisplayName("존재하지 않는 회원으로 메이트 게시글 작성 시 실패") - void createMatePost_WithInvalidMember() throws Exception { - MatePostCreateRequest request = MatePostCreateRequest.builder() - .memberId(999L) - .teamId(1L) - .matchId(futureMatch.getId()) - .title("통합 테스트 제목") - .content("통합 테스트 내용") - .age(Age.TWENTIES) - .maxParticipants(4) - .gender(Gender.FEMALE) - .transportType(TransportType.PUBLIC) - .build(); - - MockMultipartFile data = new MockMultipartFile( - "data", - "", - MediaType.APPLICATION_JSON_VALUE, - objectMapper.writeValueAsBytes(request) - ); - - performErrorTest(data, MEMBER_NOT_FOUND_BY_ID.getMessage(), 404); - } - @Test @DisplayName("존재하지 않는 경기로 메이트 게시글 작성 시 실패") + @WithAuthMember void createMatePost_WithInvalidMatch() throws Exception { MatePostCreateRequest request = MatePostCreateRequest.builder() - .memberId(testMember.getId()) .teamId(1L) .matchId(999L) .title("통합 테스트 제목") @@ -584,9 +566,10 @@ class DeleteMatePost { @Test @DisplayName("메이트 게시글 삭제 성공") + @WithAuthMember void deleteMatePost_Success() throws Exception { // when & then - mockMvc.perform(delete("/api/mates/{memberId}/{postId}", testMember.getId(), openPost.getId()) + mockMvc.perform(delete("/api/mates/{postId}", openPost.getId()) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()) .andDo(print()); @@ -597,9 +580,10 @@ void deleteMatePost_Success() throws Exception { @Test @DisplayName("메이트 게시글 삭제 실패 - 존재하지 않는 게시글") + @WithAuthMember void deleteMatePost_NotFound() throws Exception { // when & then - mockMvc.perform(delete("/api/mates/{memberId}/{postId}", testMember.getId(), 999L) + mockMvc.perform(delete("/api/mates/{postId}", 999L) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()) .andExpect(jsonPath("$.status").value("ERROR")) @@ -610,51 +594,5 @@ void deleteMatePost_NotFound() throws Exception { // DB 검증 - 기존 게시글들은 여전히 존재 assertThat(mateRepository.findAll()).hasSize(3); } - - @Test - @DisplayName("메이트 게시글 삭제 실패 - 권한 없음") - void deleteMatePost_NotAllowed() throws Exception { - // given - Member otherMember = memberRepository.save(Member.builder() - .name("다른유저") - .email("other@test.com") - .nickname("다른계정") - .imageUrl("other.jpg") - .gender(Gender.MALE) - .age(30) - .manner(0.3f) - .build()); - - // when & then - mockMvc.perform(delete("/api/mates/{memberId}/{postId}", otherMember.getId(), openPost.getId()) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isForbidden()) - .andExpect(jsonPath("$.status").value("ERROR")) - .andExpect(jsonPath("$.message").value(MATE_POST_UPDATE_NOT_ALLOWED.getMessage())) - .andExpect(jsonPath("$.code").value(403)) - .andDo(print()); - - // DB 검증 - 게시글이 삭제되지 않음 - assertThat(mateRepository.findById(openPost.getId())).isPresent(); - } -// -// @Test -// @DisplayName("직관 완료된 게시글 삭제 시 Visit 엔티티와 연관관계 제거") -// void deleteMatePost_WithCompletedStatus() throws Exception { -// // given -// MatePost post = createMatePost(futureMatch, 1L, Status.CLOSED); // CLOSED 상태로 생성 -// post.completeVisit(List.of(testMember.getId())); // completeVisit 호출하여 COMPLETE로 변경 -// Visit visit = post.getVisit(); -// -// // when -// mockMvc.perform(delete("/api/mates/{memberId}/{postId}", testMember.getId(), post.getId()) -// .contentType(MediaType.APPLICATION_JSON)) -// .andExpect(status().isNoContent()) -// .andDo(print()); -// -// // then -// assertThat(mateRepository.findById(post.getId())).isEmpty(); -// assertThat(visit.getPost()).isNull(); -// } } } \ No newline at end of file diff --git a/src/test/java/com/example/mate/domain/mate/integration/MateStatusIntegrationTest.java b/src/test/java/com/example/mate/domain/mate/integration/MateStatusIntegrationTest.java index a62c9faf..2ba68d03 100644 --- a/src/test/java/com/example/mate/domain/mate/integration/MateStatusIntegrationTest.java +++ b/src/test/java/com/example/mate/domain/mate/integration/MateStatusIntegrationTest.java @@ -18,6 +18,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.example.mate.common.security.util.JwtUtil; +import com.example.mate.config.WithAuthMember; import com.example.mate.domain.constant.Gender; import com.example.mate.domain.match.entity.Match; import com.example.mate.domain.match.repository.MatchRepository; @@ -44,6 +45,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; @@ -51,6 +53,7 @@ @SpringBootTest @AutoConfigureMockMvc(addFilters = false) @Transactional +@WithAuthMember public class MateStatusIntegrationTest { @Autowired @@ -68,6 +71,9 @@ public class MateStatusIntegrationTest { @Autowired private MateRepository mateRepository; + @Autowired + private JdbcTemplate jdbcTemplate; + private Member testMember; private Member participant1; private Member participant2; @@ -87,6 +93,8 @@ void setUp() { matchRepository.deleteAll(); memberRepository.deleteAll(); + jdbcTemplate.execute("ALTER TABLE member ALTER COLUMN id RESTART WITH 1"); + // 테스트 멤버와 참여자들 생성 testMember = createTestMember("testMember"); participant1 = createTestMember("part1"); @@ -151,7 +159,7 @@ void updateMatePostStatus_OpenToClosed_Success() throws Exception { MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", testMember.getId(), openPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/status", openPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isOk()) @@ -174,7 +182,7 @@ void updateMatePostStatus_ClosedToOpen_Success() throws Exception { MatePostStatusRequest request = new MatePostStatusRequest(Status.OPEN, participantIds); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", testMember.getId(), closedPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/status", closedPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isOk()) @@ -197,7 +205,7 @@ void updateMatePostStatus_ToComplete_Failure() throws Exception { MatePostStatusRequest request = new MatePostStatusRequest(Status.VISIT_COMPLETE, participantIds); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", testMember.getId(), openPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/status", openPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isForbidden()) @@ -219,7 +227,7 @@ void updateMatePostStatus_AlreadyCompleted_Failure() throws Exception { MatePostStatusRequest request = new MatePostStatusRequest(Status.OPEN, participantIds); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", testMember.getId(), completedPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/status", completedPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isForbidden()) @@ -233,30 +241,6 @@ void updateMatePostStatus_AlreadyCompleted_Failure() throws Exception { assertThat(unchangedPost.getStatus()).isEqualTo(Status.VISIT_COMPLETE); } - @Test - @DisplayName("게시글 작성자가 아닌 사용자가 상태 변경 시도시 실패") - void updateMatePostStatus_NotAuthor_Failure() throws Exception { - // given - Member otherMember = createTestMember("otherMem"); - List participantIds = Arrays.asList(participant1.getId(), participant2.getId()); - MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); - - // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", otherMember.getId(), openPost.getId()) - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(request))) - .andExpect(status().isForbidden()) - .andExpect(jsonPath("$.status").value("ERROR")) - .andExpect(jsonPath("$.message").value(MATE_POST_UPDATE_NOT_ALLOWED.getMessage())) - .andExpect(jsonPath("$.code").value(403)) - .andDo(print()); - - // DB 검증 - MatePost unchangedPost = mateRepository.findById(openPost.getId()).orElseThrow(); - assertThat(unchangedPost.getStatus()).isEqualTo(Status.OPEN); - } - - @Test @DisplayName("존재하지 않는 게시글의 상태 변경 시도시 실패") void updateMatePostStatus_PostNotFound_Failure() throws Exception { @@ -265,7 +249,7 @@ void updateMatePostStatus_PostNotFound_Failure() throws Exception { MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", testMember.getId(), 999L) + mockMvc.perform(patch("/api/mates/{postId}/status", 999L) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isNotFound()) @@ -288,7 +272,7 @@ void updateMatePostStatus_ExceedMaxParticipants_Failure() throws Exception { MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", testMember.getId(), openPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/status", openPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isBadRequest()) @@ -310,7 +294,7 @@ void updateMatePostStatus_InvalidParticipantId_Failure() throws Exception { MatePostStatusRequest request = new MatePostStatusRequest(Status.CLOSED, participantIds); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/status", testMember.getId(), openPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/status", openPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isBadRequest()) @@ -338,8 +322,8 @@ void completeVisit_Success() throws Exception { ); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", - testMember.getId(), closedPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/complete", + closedPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsBytes(request))) .andExpect(status().isOk()) @@ -362,6 +346,7 @@ void completeVisit_Success() throws Exception { @Test @DisplayName("직관 완료 처리 실패 - 권한 없음") + @WithAuthMember(memberId = 2L) void completeVisit_Fail_NotAuthor() throws Exception { // given MatePostCompleteRequest request = new MatePostCompleteRequest( @@ -369,8 +354,8 @@ void completeVisit_Fail_NotAuthor() throws Exception { ); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", - participant1.getId(), closedPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/complete" + ,closedPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsBytes(request))) .andExpect(status().isForbidden()) @@ -395,8 +380,8 @@ void completeVisit_Fail_NotClosedStatus() throws Exception { ); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", - testMember.getId(), openPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/complete", + openPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsBytes(request))) .andExpect(status().isBadRequest()) @@ -421,8 +406,8 @@ void completeVisit_Fail_BeforeMatchTime() throws Exception { ); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", - testMember.getId(), futureClosedPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/complete", + futureClosedPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsBytes(request))) .andExpect(status().isForbidden()) @@ -447,8 +432,8 @@ void completeVisit_Fail_InvalidParticipant() throws Exception { ); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", - testMember.getId(), closedPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/complete", + closedPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsBytes(request))) .andExpect(status().isBadRequest()) @@ -473,8 +458,8 @@ void completeVisit_Fail_ExceedMaxParticipants() throws Exception { ); // when & then - mockMvc.perform(patch("/api/mates/{memberId}/{postId}/complete", - testMember.getId(), closedPost.getId()) + mockMvc.perform(patch("/api/mates/{postId}/complete", + closedPost.getId()) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsBytes(request))) .andExpect(status().isBadRequest()) @@ -488,4 +473,4 @@ void completeVisit_Fail_ExceedMaxParticipants() throws Exception { assertThat(unchangedPost.getStatus()).isEqualTo(Status.CLOSED); assertThat(unchangedPost.getVisit()).isNull(); } -} +} \ No newline at end of file diff --git a/src/test/java/com/example/mate/domain/mate/service/MateServiceTest.java b/src/test/java/com/example/mate/domain/mate/service/MateServiceTest.java index e0df0e6d..8eb5c642 100644 --- a/src/test/java/com/example/mate/domain/mate/service/MateServiceTest.java +++ b/src/test/java/com/example/mate/domain/mate/service/MateServiceTest.java @@ -95,7 +95,6 @@ void createMatePost_Success() { Match testMatch = createTestMatch(); MatePostCreateRequest request = MatePostCreateRequest.builder() - .memberId(TEST_MEMBER_ID) .teamId(TEST_MATCH_ID) .matchId(1L) .title("테스트 제목") @@ -120,7 +119,7 @@ void createMatePost_Success() { .transport(TransportType.PUBLIC) .build(); - given(memberRepository.findById(request.getMemberId())) + given(memberRepository.findById(TEST_MEMBER_ID)) .willReturn(Optional.of(testMember)); given(matchRepository.findById(request.getMatchId())) .willReturn(Optional.of(testMatch)); @@ -128,7 +127,7 @@ void createMatePost_Success() { .willReturn(matePost); // when - MatePostResponse response = mateService.createMatePost(request, null); + MatePostResponse response = mateService.createMatePost(request, null, TEST_MEMBER_ID); // then assertThat(response.getStatus()).isEqualTo(Status.OPEN); @@ -142,7 +141,6 @@ void createMatePost_Success() { void createMatePost_FailWithInvalidMember() { // given MatePostCreateRequest request = MatePostCreateRequest.builder() - .memberId(TEST_MEMBER_ID) .teamId(TEST_MATCH_ID) .matchId(1L) .title("테스트 제목") @@ -153,11 +151,11 @@ void createMatePost_FailWithInvalidMember() { .transportType(TransportType.PUBLIC) .build(); - given(memberRepository.findById(request.getMemberId())) + given(memberRepository.findById(TEST_MEMBER_ID)) .willReturn(Optional.empty()); // when & then - assertThatThrownBy(() -> mateService.createMatePost(request, null)) + assertThatThrownBy(() -> mateService.createMatePost(request, null, TEST_MEMBER_ID)) .isInstanceOf(CustomException.class) .hasFieldOrPropertyWithValue("errorCode", MEMBER_NOT_FOUND_BY_ID); @@ -172,7 +170,6 @@ void createMatePost_FailWithInvalidMatch() { // given Member testMember = createTestMember(); MatePostCreateRequest request = MatePostCreateRequest.builder() - .memberId(TEST_MEMBER_ID) .teamId(TEST_MATCH_ID) .matchId(1L) .title("테스트 제목") @@ -183,13 +180,13 @@ void createMatePost_FailWithInvalidMatch() { .transportType(TransportType.PUBLIC) .build(); - given(memberRepository.findById(request.getMemberId())) + given(memberRepository.findById(TEST_MEMBER_ID)) .willReturn(Optional.of(testMember)); given(matchRepository.findById(request.getMatchId())) .willReturn(Optional.empty()); // when & then - assertThatThrownBy(() -> mateService.createMatePost(request, null)) + assertThatThrownBy(() -> mateService.createMatePost(request, null, TEST_MEMBER_ID)) .isInstanceOf(CustomException.class) .hasFieldOrPropertyWithValue("errorCode", MATCH_NOT_FOUND_BY_ID); diff --git a/src/test/java/com/example/mate/domain/mate/service/MateStatusServiceTest.java b/src/test/java/com/example/mate/domain/mate/service/MateStatusServiceTest.java index 9424d08e..cc4db709 100644 --- a/src/test/java/com/example/mate/domain/mate/service/MateStatusServiceTest.java +++ b/src/test/java/com/example/mate/domain/mate/service/MateStatusServiceTest.java @@ -585,4 +585,4 @@ void completeVisit_FailExceedMaxParticipants() { verify(memberRepository).findAllById(participantIds); } } -} +} \ No newline at end of file