diff --git a/src/main/java/com/example/solidconnection/auth/service/EmailSignInService.java b/src/main/java/com/example/solidconnection/auth/service/EmailSignInService.java index bbbb4f85c..3e26309a5 100644 --- a/src/main/java/com/example/solidconnection/auth/service/EmailSignInService.java +++ b/src/main/java/com/example/solidconnection/auth/service/EmailSignInService.java @@ -35,7 +35,7 @@ public SignInResponse signIn(EmailSignInRequest signInRequest) { throw new CustomException(USER_NOT_FOUND, "이메일과 비밀번호를 확인해주세요."); } - private void validatePassword(String rawPassword, String encodedPassword) throws CustomException { + private void validatePassword(String rawPassword, String encodedPassword) { if (!passwordEncoder.matches(rawPassword, encodedPassword)) { throw new CustomException(USER_NOT_FOUND, "이메일과 비밀번호를 확인해주세요."); } diff --git a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java index 529430749..4c3cf07ba 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java @@ -83,6 +83,8 @@ public enum ErrorCode { CAN_NOT_UPDATE_DEPRECATED_COMMENT(HttpStatus.BAD_REQUEST.value(), "이미 삭제된 댓글을 수정할 수 없습니다."), INVALID_POST_LIKE(HttpStatus.BAD_REQUEST.value(), "존재하지 않는 게시글 좋아요입니다."), DUPLICATE_POST_LIKE(HttpStatus.BAD_REQUEST.value(), "이미 좋아요한 게시글입니다."), + ALREADY_LIKED_UNIVERSITY(HttpStatus.BAD_REQUEST.value(), "이미 좋아요한 대학입니다."), + NOT_LIKED_UNIVERSITY(HttpStatus.BAD_REQUEST.value(), "좋아요하지 않은 대학입니다."), // score INVALID_GPA_SCORE(HttpStatus.BAD_REQUEST.value(), "존재하지 않는 학점입니다."), diff --git a/src/main/java/com/example/solidconnection/siteuser/controller/SiteUserController.java b/src/main/java/com/example/solidconnection/siteuser/controller/SiteUserController.java index 11c154243..2f43337ed 100644 --- a/src/main/java/com/example/solidconnection/siteuser/controller/SiteUserController.java +++ b/src/main/java/com/example/solidconnection/siteuser/controller/SiteUserController.java @@ -3,24 +3,18 @@ import com.example.solidconnection.custom.resolver.AuthorizedUser; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.dto.MyPageResponse; -import com.example.solidconnection.siteuser.dto.MyPageUpdateResponse; -import com.example.solidconnection.siteuser.dto.NicknameUpdateRequest; -import com.example.solidconnection.siteuser.dto.NicknameUpdateResponse; -import com.example.solidconnection.siteuser.dto.ProfileImageUpdateResponse; import com.example.solidconnection.siteuser.service.SiteUserService; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @RequiredArgsConstructor -@RequestMapping("/my-page") +@RequestMapping("/my") @RestController class SiteUserController { @@ -34,29 +28,13 @@ public ResponseEntity getMyPageInfo( return ResponseEntity.ok(myPageResponse); } - @GetMapping("/update") - public ResponseEntity getMyPageInfoToUpdate( - @AuthorizedUser SiteUser siteUser - ) { - MyPageUpdateResponse myPageUpdateDto = siteUserService.getMyPageInfoToUpdate(siteUser); - return ResponseEntity.ok(myPageUpdateDto); - } - - @PatchMapping("/update/profileImage") - public ResponseEntity updateProfileImage( - @AuthorizedUser SiteUser siteUser, - @RequestParam(value = "file", required = false) MultipartFile imageFile - ) { - ProfileImageUpdateResponse profileImageUpdateResponse = siteUserService.updateProfileImage(siteUser, imageFile); - return ResponseEntity.ok().body(profileImageUpdateResponse); - } - - @PatchMapping("/update/nickname") - public ResponseEntity updateNickname( + @PatchMapping + public ResponseEntity updateMyPageInfo( @AuthorizedUser SiteUser siteUser, - @Valid @RequestBody NicknameUpdateRequest nicknameUpdateRequest + @RequestParam("file") MultipartFile imageFile, + @RequestParam("nickname") String nickname ) { - NicknameUpdateResponse nicknameUpdateResponse = siteUserService.updateNickname(siteUser, nicknameUpdateRequest); - return ResponseEntity.ok().body(nicknameUpdateResponse); + siteUserService.updateMyPageInfo(siteUser, imageFile, nickname); + return ResponseEntity.ok().build(); } } diff --git a/src/main/java/com/example/solidconnection/siteuser/service/SiteUserService.java b/src/main/java/com/example/solidconnection/siteuser/service/SiteUserService.java index c181c2809..30297283a 100644 --- a/src/main/java/com/example/solidconnection/siteuser/service/SiteUserService.java +++ b/src/main/java/com/example/solidconnection/siteuser/service/SiteUserService.java @@ -5,10 +5,6 @@ import com.example.solidconnection.s3.UploadedFileUrlResponse; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.dto.MyPageResponse; -import com.example.solidconnection.siteuser.dto.MyPageUpdateResponse; -import com.example.solidconnection.siteuser.dto.NicknameUpdateRequest; -import com.example.solidconnection.siteuser.dto.NicknameUpdateResponse; -import com.example.solidconnection.siteuser.dto.ProfileImageUpdateResponse; import com.example.solidconnection.siteuser.repository.LikedUniversityRepository; import com.example.solidconnection.siteuser.repository.SiteUserRepository; import com.example.solidconnection.type.ImgType; @@ -48,68 +44,27 @@ public MyPageResponse getMyPageInfo(SiteUser siteUser) { } /* - * 내 정보를 수정하기 위한 마이페이지 정보를 조회한다. (닉네임, 프로필 사진) - * */ - @Transactional(readOnly = true) - public MyPageUpdateResponse getMyPageInfoToUpdate(SiteUser siteUser) { - return MyPageUpdateResponse.from(siteUser); - } - - /* - * 관심 대학교 목록을 조회한다. - * */ - @Transactional(readOnly = true) - public List getWishUniversity(SiteUser siteUser) { - List likedUniversities = likedUniversityRepository.findAllBySiteUser_Id(siteUser.getId()); - return likedUniversities.stream() - .map(likedUniversity -> UniversityInfoForApplyPreviewResponse.from(likedUniversity.getUniversityInfoForApply())) - .toList(); - } - - /* - * 프로필 이미지를 수정한다. + * 마이페이지 정보를 수정한다. * */ @Transactional - public ProfileImageUpdateResponse updateProfileImage(SiteUser siteUser, MultipartFile imageFile) { - validateProfileImage(imageFile); + public void updateMyPageInfo(SiteUser siteUser, MultipartFile imageFile, String nickname) { + validateNicknameUnique(nickname); + validateNicknameNotChangedRecently(siteUser.getNicknameModifiedAt()); + validateProfileImageNotEmpty(imageFile); - // 프로필 이미지를 처음 수정하는 경우에는 deleteExProfile 수행하지 않음 if (!isDefaultProfileImage(siteUser.getProfileImageUrl())) { s3Service.deleteExProfile(siteUser); } - UploadedFileUrlResponse uploadedFileUrlResponse = s3Service.uploadFile(imageFile, ImgType.PROFILE); - siteUser.setProfileImageUrl(uploadedFileUrlResponse.fileUrl()); - siteUserRepository.save(siteUser); - - return ProfileImageUpdateResponse.from(siteUser); - } - - private void validateProfileImage(MultipartFile imageFile) { - if (imageFile == null || imageFile.isEmpty()) { - throw new CustomException(PROFILE_IMAGE_NEEDED); - } - } - private boolean isDefaultProfileImage(String profileImageUrl) { - String prefix = "profile/"; - return profileImageUrl == null || !profileImageUrl.startsWith(prefix); - } + UploadedFileUrlResponse uploadedFile = s3Service.uploadFile(imageFile, ImgType.PROFILE); + String profileImageUrl = uploadedFile.fileUrl(); - /* - * 닉네임을 수정한다. - * */ - @Transactional - public NicknameUpdateResponse updateNickname(SiteUser siteUser, NicknameUpdateRequest nicknameUpdateRequest) { - validateNicknameDuplicated(nicknameUpdateRequest.nickname()); - validateNicknameNotChangedRecently(siteUser.getNicknameModifiedAt()); - - siteUser.setNickname(nicknameUpdateRequest.nickname()); + siteUser.setProfileImageUrl(profileImageUrl); + siteUser.setNickname(nickname); siteUser.setNicknameModifiedAt(LocalDateTime.now()); siteUserRepository.save(siteUser); - - return NicknameUpdateResponse.from(siteUser); } - private void validateNicknameDuplicated(String nickname) { + private void validateNicknameUnique(String nickname) { if (siteUserRepository.existsByNickname(nickname)) { throw new CustomException(NICKNAME_ALREADY_EXISTED); } @@ -125,4 +80,26 @@ private void validateNicknameNotChangedRecently(LocalDateTime lastModifiedAt) { throw new CustomException(CAN_NOT_CHANGE_NICKNAME_YET, formatLastModifiedAt); } } + + private void validateProfileImageNotEmpty(MultipartFile imageFile) { + if (imageFile == null || imageFile.isEmpty()) { + throw new CustomException(PROFILE_IMAGE_NEEDED); + } + } + + private boolean isDefaultProfileImage(String profileImageUrl) { + String prefix = "profile/"; + return profileImageUrl == null || !profileImageUrl.startsWith(prefix); + } + + /* + * 관심 대학교 목록을 조회한다. + * */ + @Transactional(readOnly = true) + public List getWishUniversity(SiteUser siteUser) { + List likedUniversities = likedUniversityRepository.findAllBySiteUser_Id(siteUser.getId()); + return likedUniversities.stream() + .map(likedUniversity -> UniversityInfoForApplyPreviewResponse.from(likedUniversity.getUniversityInfoForApply())) + .toList(); + } } diff --git a/src/main/java/com/example/solidconnection/university/controller/UniversityController.java b/src/main/java/com/example/solidconnection/university/controller/UniversityController.java index 505bfe072..66da87095 100644 --- a/src/main/java/com/example/solidconnection/university/controller/UniversityController.java +++ b/src/main/java/com/example/solidconnection/university/controller/UniversityController.java @@ -14,6 +14,7 @@ import com.example.solidconnection.university.service.UniversityRecommendService; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -24,7 +25,7 @@ import java.util.List; @RequiredArgsConstructor -@RequestMapping("/university") +@RequestMapping("/universities") @RestController public class UniversityController { @@ -33,7 +34,7 @@ public class UniversityController { private final UniversityRecommendService universityRecommendService; private final SiteUserService siteUserService; - @GetMapping("/recommends") + @GetMapping("/recommend") public ResponseEntity getUniversityRecommends( @AuthorizedUser SiteUser siteUser ) { @@ -70,7 +71,16 @@ public ResponseEntity addWishUniversity( return ResponseEntity.ok(likeResultResponse); } - @GetMapping("/detail/{universityInfoForApplyId}") + @DeleteMapping("/{universityInfoForApplyId}/like") + public ResponseEntity cancelWishUniversity( + @AuthorizedUser SiteUser siteUser, + @PathVariable Long universityInfoForApplyId + ) { + LikeResultResponse likeResultResponse = universityLikeService.cancelLikeUniversity(siteUser, universityInfoForApplyId); + return ResponseEntity.ok(likeResultResponse); + } + + @GetMapping("/{universityInfoForApplyId}") public ResponseEntity getUniversityDetails( @PathVariable Long universityInfoForApplyId ) { diff --git a/src/main/java/com/example/solidconnection/university/service/UniversityLikeService.java b/src/main/java/com/example/solidconnection/university/service/UniversityLikeService.java index d926bc516..85971663b 100644 --- a/src/main/java/com/example/solidconnection/university/service/UniversityLikeService.java +++ b/src/main/java/com/example/solidconnection/university/service/UniversityLikeService.java @@ -1,5 +1,6 @@ package com.example.solidconnection.university.service; +import com.example.solidconnection.custom.exception.CustomException; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.repository.LikedUniversityRepository; import com.example.solidconnection.university.domain.LikedUniversity; @@ -14,6 +15,9 @@ import java.util.Optional; +import static com.example.solidconnection.custom.exception.ErrorCode.ALREADY_LIKED_UNIVERSITY; +import static com.example.solidconnection.custom.exception.ErrorCode.NOT_LIKED_UNIVERSITY; + @RequiredArgsConstructor @Service public class UniversityLikeService { @@ -29,16 +33,14 @@ public class UniversityLikeService { /* * 대학교를 '좋아요' 한다. - * - 이미 좋아요가 눌러져있다면, 좋아요를 취소한다. * */ @Transactional public LikeResultResponse likeUniversity(SiteUser siteUser, Long universityInfoForApplyId) { UniversityInfoForApply universityInfoForApply = universityInfoForApplyRepository.getUniversityInfoForApplyById(universityInfoForApplyId); - Optional alreadyLikedUniversity = likedUniversityRepository.findBySiteUserAndUniversityInfoForApply(siteUser, universityInfoForApply); - if (alreadyLikedUniversity.isPresent()) { - likedUniversityRepository.delete(alreadyLikedUniversity.get()); - return new LikeResultResponse(LIKE_CANCELED_MESSAGE); + Optional optionalLikedUniversity = likedUniversityRepository.findBySiteUserAndUniversityInfoForApply(siteUser, universityInfoForApply); + if (optionalLikedUniversity.isPresent()) { + throw new CustomException(ALREADY_LIKED_UNIVERSITY); } LikedUniversity likedUniversity = LikedUniversity.builder() @@ -49,6 +51,22 @@ public LikeResultResponse likeUniversity(SiteUser siteUser, Long universityInfoF return new LikeResultResponse(LIKE_SUCCESS_MESSAGE); } + /* + * 대학교 '좋아요'를 취소한다. + * */ + @Transactional + public LikeResultResponse cancelLikeUniversity(SiteUser siteUser, long universityInfoForApplyId) throws CustomException { + UniversityInfoForApply universityInfoForApply = universityInfoForApplyRepository.getUniversityInfoForApplyById(universityInfoForApplyId); + + Optional optionalLikedUniversity = likedUniversityRepository.findBySiteUserAndUniversityInfoForApply(siteUser, universityInfoForApply); + if (optionalLikedUniversity.isEmpty()) { + throw new CustomException(NOT_LIKED_UNIVERSITY); + } + + likedUniversityRepository.delete(optionalLikedUniversity.get()); + return new LikeResultResponse(LIKE_CANCELED_MESSAGE); + } + /* * '좋아요'한 대학교인지 확인한다. * */ diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 477fc03f5..5ae08770d 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -41,6 +41,11 @@ VALUES ('BN', '브루나이', 'ASIA'), ('MY', '말레이시아', 'ASIA'), ('RU', '러시아', 'EUROPE'); +INSERT INTO site_user (birth, email, nickname, profile_image_url, gender, preparation_stage, role, password, auth_type) +VALUES ('1999-01-01', 'test@test.email', 'yonso','https://github.com/nayonsoso.png', + 'FEMALE', 'CONSIDERING', 'MENTEE', + '$2a$10$psmwlxPfqWnIlq9JrlQJkuXr1XtjRNsyVOgcTWYZub5jFfn0TML76', 'EMAIL'); -- 12341234 + INSERT INTO university(id, country_code, region_code, english_name, format_name, korean_name, accommodation_url, english_course_url, homepage_url, details_for_local, logo_image_url, background_image_url) diff --git a/src/test/java/com/example/solidconnection/e2e/MyPageTest.java b/src/test/java/com/example/solidconnection/e2e/MyPageTest.java index 7a0ae07f4..dd2ce1e3a 100644 --- a/src/test/java/com/example/solidconnection/e2e/MyPageTest.java +++ b/src/test/java/com/example/solidconnection/e2e/MyPageTest.java @@ -44,7 +44,7 @@ public void setUpUserAndToken() { MyPageResponse myPageResponse = RestAssured.given() .header("Authorization", "Bearer " + accessToken) .log().all() - .get("/my-page") + .get("/my") .then().log().all() .statusCode(HttpStatus.OK.value()) .extract().as(MyPageResponse.class); diff --git a/src/test/java/com/example/solidconnection/e2e/MyPageUpdateTest.java b/src/test/java/com/example/solidconnection/e2e/MyPageUpdateTest.java deleted file mode 100644 index b16f3b822..000000000 --- a/src/test/java/com/example/solidconnection/e2e/MyPageUpdateTest.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.example.solidconnection.e2e; - -import com.example.solidconnection.auth.service.AuthTokenProvider; -import com.example.solidconnection.custom.response.ErrorResponse; -import com.example.solidconnection.siteuser.domain.SiteUser; -import com.example.solidconnection.siteuser.dto.MyPageUpdateResponse; -import com.example.solidconnection.siteuser.dto.NicknameUpdateRequest; -import com.example.solidconnection.siteuser.dto.NicknameUpdateResponse; -import com.example.solidconnection.siteuser.repository.SiteUserRepository; -import io.restassured.RestAssured; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; - -import java.time.LocalDateTime; - -import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_CHANGE_NICKNAME_YET; -import static com.example.solidconnection.custom.exception.ErrorCode.NICKNAME_ALREADY_EXISTED; -import static com.example.solidconnection.e2e.DynamicFixture.createSiteUserByEmail; -import static com.example.solidconnection.siteuser.service.SiteUserService.MIN_DAYS_BETWEEN_NICKNAME_CHANGES; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; - -@DisplayName("마이페이지 수정 테스트") -class MyPageUpdateTest extends BaseEndToEndTest { - - @Autowired - private SiteUserRepository siteUserRepository; - - @Autowired - private AuthTokenProvider authTokenProvider; - - private String accessToken; - - private SiteUser siteUser; - - @BeforeEach - public void setUpUserAndToken() { - // setUp - 회원 정보 저장 - siteUser = createSiteUserByEmail("email"); - siteUserRepository.save(siteUser); - - // setUp - 엑세스 토큰 생성과 리프레시 토큰 생성 및 저장 - accessToken = authTokenProvider.generateAccessToken(siteUser); - authTokenProvider.generateAndSaveRefreshToken(siteUser); - } - - @Test - void 수정을_위해_수정_전_정보를_조회한다() { - // request - 요청 - MyPageUpdateResponse myPageUpdateResponse = RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .log().all() - .get("/my-page/update") - .then().log().all() - .statusCode(HttpStatus.OK.value()) - .extract().as(MyPageUpdateResponse.class); - - assertAll("불러온 마이 페이지 정보가 DB의 정보와 일치한다.", - () -> assertThat(myPageUpdateResponse.nickname()).isEqualTo(siteUser.getNickname()), - () -> assertThat(myPageUpdateResponse.profileImageUrl()).isEqualTo(siteUser.getProfileImageUrl())); - } - - @Test - void 닉네임을_수정한다() { - // request - body 생성 및 요청 - NicknameUpdateRequest nicknameUpdateRequest = new NicknameUpdateRequest("newNickname"); - NicknameUpdateResponse nicknameUpdateResponse = RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .log().all() - .body(nicknameUpdateRequest) - .contentType("application/json") - .patch("/my-page/update/nickname") - .then().log().all() - .statusCode(HttpStatus.OK.value()) - .extract().as(NicknameUpdateResponse.class); - - SiteUser updatedSiteUser = siteUserRepository.findById(siteUser.getId()).get(); - assertAll("마이 페이지 정보가 수정된다.", - () -> assertThat(nicknameUpdateResponse.nickname()).isEqualTo(updatedSiteUser.getNickname())); - } - - @Test - void 닉네임을_수정할_때_닉네임이_중복된다면_예외_응답을_반환한다() { - // setUp - 같은 닉네임을 갖는 다른 회원 정보 저장 - SiteUser existUser = createSiteUserByEmail("existUser"); - String duplicateNickname = "duplicateNickname"; - existUser.setNickname(duplicateNickname); - siteUserRepository.save(existUser); - - // request - body 생성 및 요청 - NicknameUpdateRequest nicknameUpdateRequest = new NicknameUpdateRequest("duplicateNickname"); - ErrorResponse response = RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .log().all() - .body(nicknameUpdateRequest) - .contentType("application/json") - .patch("/my-page/update/nickname") - .then().log().all() - .statusCode(HttpStatus.CONFLICT.value()) - .extract().as(ErrorResponse.class); - - assertThat(response.message()) - .isEqualTo(NICKNAME_ALREADY_EXISTED.getMessage()); - } - - @Test - void 닉네임을_수정할_때_닉네임_변경_가능_기한이_지나지않았다면_예외_응답을_반환한다() { - // setUp - 회원 정보 저장 (닉네임 변경 가능 시간이 되기 1분 전) - LocalDateTime nicknameModifiedAt = LocalDateTime.now() - .minusDays(MIN_DAYS_BETWEEN_NICKNAME_CHANGES) - .plusMinutes(1); - siteUser.setNicknameModifiedAt(nicknameModifiedAt); - siteUserRepository.save(siteUser); - - // request - body 생성 및 요청 - NicknameUpdateRequest nicknameUpdateRequest = new NicknameUpdateRequest("newNickname"); - ErrorResponse response = RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .log().all() - .body(nicknameUpdateRequest) - .contentType("application/json") - .patch("/my-page/update/nickname") - .then().log().all() - .statusCode(HttpStatus.BAD_REQUEST.value()) - .extract().as(ErrorResponse.class); - - assertThat(response.message()) - .contains(CAN_NOT_CHANGE_NICKNAME_YET.getMessage()); - } -} diff --git a/src/test/java/com/example/solidconnection/e2e/UniversityDetailTest.java b/src/test/java/com/example/solidconnection/e2e/UniversityDetailTest.java index 01b2b5730..c7a364ebf 100644 --- a/src/test/java/com/example/solidconnection/e2e/UniversityDetailTest.java +++ b/src/test/java/com/example/solidconnection/e2e/UniversityDetailTest.java @@ -45,7 +45,7 @@ public void setUpUserAndToken() { UniversityDetailResponse response = RestAssured.given() .header("Authorization", "Bearer " + accessToken) .log().all() - .get("/university/detail/" + 메이지대학_지원_정보.getId()) + .get("/universities/" + 메이지대학_지원_정보.getId()) .then().log().all() .statusCode(HttpStatus.OK.value()) .extract().as(UniversityDetailResponse.class); diff --git a/src/test/java/com/example/solidconnection/e2e/UniversityLikeTest.java b/src/test/java/com/example/solidconnection/e2e/UniversityLikeTest.java index 3b5733d82..693d6d91b 100644 --- a/src/test/java/com/example/solidconnection/e2e/UniversityLikeTest.java +++ b/src/test/java/com/example/solidconnection/e2e/UniversityLikeTest.java @@ -24,7 +24,6 @@ import static com.example.solidconnection.e2e.DynamicFixture.createLikedUniversity; import static com.example.solidconnection.e2e.DynamicFixture.createSiteUserByEmail; import static com.example.solidconnection.e2e.DynamicFixture.createUniversityForApply; -import static com.example.solidconnection.university.service.UniversityLikeService.LIKE_CANCELED_MESSAGE; import static com.example.solidconnection.university.service.UniversityLikeService.LIKE_SUCCESS_MESSAGE; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; @@ -73,7 +72,7 @@ public void setUpUserAndToken() { List wishUniversities = RestAssured.given() .header("Authorization", "Bearer " + accessToken) .log().all() - .get("/university/like") + .get("/universities/like") .then().log().all() .statusCode(HttpStatus.OK.value()) .extract().jsonPath().getList(".", UniversityInfoForApplyPreviewResponse.class); @@ -92,7 +91,7 @@ public void setUpUserAndToken() { LikeResultResponse response = RestAssured.given() .header("Authorization", "Bearer " + accessToken) .log().all() - .post("/university/" + 괌대학_A_지원_정보.getId() + "/like") + .post("/universities/" + 괌대학_A_지원_정보.getId() + "/like") .then().log().all() .statusCode(HttpStatus.OK.value()) .extract().as(LikeResultResponse.class); @@ -106,28 +105,6 @@ public void setUpUserAndToken() { ); } - @Test - void 이미_좋아요한_대학교에_좋아요를_누른다() { - // setUp - 대학교 좋아요 저장 - likedUniversityRepository.save(createLikedUniversity(siteUser, 괌대학_A_지원_정보)); - - // request - 요청 - LikeResultResponse response = RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .log().all() - .post("/university/" + 괌대학_A_지원_정보.getId() + "/like") - .then().log().all() - .statusCode(HttpStatus.OK.value()) - .extract().as(LikeResultResponse.class); - - Optional likedUniversity - = likedUniversityRepository.findAllBySiteUser_Id(siteUser.getId()).stream().findFirst(); - assertAll("좋아요 누른 대학교를 삭제하고, 좋아요 취소 응답을 반환한다.", - () -> assertThat(likedUniversity).isEmpty(), - () -> assertThat(response.result()).isEqualTo(LIKE_CANCELED_MESSAGE) - ); - } - @Test void 대학의_좋아요_여부를_조회한다() { // setUp - 대학교 좋아요 저장 @@ -136,7 +113,7 @@ public void setUpUserAndToken() { // request - 요청 IsLikeResponse response = RestAssured.given().log().all() .header("Authorization", "Bearer " + accessToken) - .get("/university/" + 괌대학_A_지원_정보.getId() + "/like") + .get("/universities/" + 괌대학_A_지원_정보.getId() + "/like") .then().log().all() .statusCode(HttpStatus.OK.value()) .extract().as(IsLikeResponse.class); diff --git a/src/test/java/com/example/solidconnection/e2e/UniversityRecommendTest.java b/src/test/java/com/example/solidconnection/e2e/UniversityRecommendTest.java index 8e1e8184f..9939d1a54 100644 --- a/src/test/java/com/example/solidconnection/e2e/UniversityRecommendTest.java +++ b/src/test/java/com/example/solidconnection/e2e/UniversityRecommendTest.java @@ -66,7 +66,7 @@ void setUp() { UniversityRecommendsResponse response = RestAssured.given() .header("Authorization", "Bearer " + accessToken) .log().all() - .get("/university/recommends") + .get("/universities/recommend") .then().log().all() .statusCode(HttpStatus.OK.value()) .extract().as(UniversityRecommendsResponse.class); @@ -94,7 +94,7 @@ void setUp() { UniversityRecommendsResponse response = RestAssured.given() .header("Authorization", "Bearer " + accessToken) .log().all() - .get("/university/recommends") + .get("/universities/recommend") .then().log().all() .statusCode(HttpStatus.OK.value()) .extract().as(UniversityRecommendsResponse.class); @@ -121,7 +121,7 @@ void setUp() { UniversityRecommendsResponse response = RestAssured.given() .header("Authorization", "Bearer " + accessToken) .log().all() - .get("/university/recommends") + .get("/universities/recommend") .then().log().all() .statusCode(HttpStatus.OK.value()) .extract().as(UniversityRecommendsResponse.class); @@ -148,7 +148,7 @@ void setUp() { UniversityRecommendsResponse response = RestAssured.given() .header("Authorization", "Bearer " + accessToken) .log().all() - .get("/university/recommends") + .get("/universities/recommend") .then().log().all() .statusCode(HttpStatus.OK.value()) .extract().as(UniversityRecommendsResponse.class); @@ -171,7 +171,7 @@ void setUp() { // request - 요청 UniversityRecommendsResponse response = RestAssured.given() .log().all() - .get("/university/recommends") + .get("/universities/recommend") .then().log().all() .statusCode(HttpStatus.OK.value()) .extract().as(UniversityRecommendsResponse.class); diff --git a/src/test/java/com/example/solidconnection/e2e/UniversitySearchTest.java b/src/test/java/com/example/solidconnection/e2e/UniversitySearchTest.java index 3b508d014..5d4ff71fd 100644 --- a/src/test/java/com/example/solidconnection/e2e/UniversitySearchTest.java +++ b/src/test/java/com/example/solidconnection/e2e/UniversitySearchTest.java @@ -43,7 +43,7 @@ public void setUpUserAndToken() { // request - 요청 List response = RestAssured.given().log().all() .header("Authorization", "Bearer " + accessToken) - .when().get("/university/search") + .when().get("/universities/search") .then().log().all() .statusCode(200) .extract().jsonPath().getList(".", UniversityInfoForApplyPreviewResponse.class); @@ -67,7 +67,7 @@ public void setUpUserAndToken() { // request - 요청 List response = RestAssured.given().log().all() .header("Authorization", "Bearer " + accessToken) - .when().get("/university/search?region=" + 영미권.getCode()) + .when().get("/universities/search?region=" + 영미권.getCode()) .then().log().all() .statusCode(200) .extract().jsonPath().getList(".", UniversityInfoForApplyPreviewResponse.class); @@ -85,7 +85,7 @@ public void setUpUserAndToken() { // request - 요청 List response = RestAssured.given().log().all() .header("Authorization", "Bearer " + accessToken) - .when().get("/university/search?keyword=라") + .when().get("/universities/search?keyword=라") .then().log().all() .statusCode(200) .extract().jsonPath().getList(".", UniversityInfoForApplyPreviewResponse.class); @@ -102,7 +102,7 @@ public void setUpUserAndToken() { // request - 요청 List response = RestAssured.given().log().all() .header("Authorization", "Bearer " + accessToken) - .when().get("/university/search?keyword=라&keyword=일본") + .when().get("/universities/search?keyword=라&keyword=일본") .then().log().all() .statusCode(200) .extract().jsonPath().getList(".", UniversityInfoForApplyPreviewResponse.class); @@ -120,7 +120,7 @@ public void setUpUserAndToken() { // request - 요청 List response = RestAssured.given().log().all() .header("Authorization", "Bearer " + accessToken) - .when().get("/university/search?testType=TOEFL_IBT") + .when().get("/universities/search?testType=TOEFL_IBT") .then().log().all() .statusCode(200) .extract().jsonPath().getList(".", UniversityInfoForApplyPreviewResponse.class); @@ -139,7 +139,7 @@ public void setUpUserAndToken() { // request - 요청 List response = RestAssured.given().log().all() .header("Authorization", "Bearer " + accessToken) - .when().get("/university/search?testType=TOEFL_IBT&testScore=70") + .when().get("/universities/search?testType=TOEFL_IBT&testScore=70") .then().log().all() .statusCode(200) .extract().jsonPath().getList(".", UniversityInfoForApplyPreviewResponse.class); @@ -155,7 +155,7 @@ public void setUpUserAndToken() { // request - 요청 List response = RestAssured.given().log().all() .header("Authorization", "Bearer " + accessToken) - .when().get("/university/search?region=EUROPE&testType=TOEFL_IBT&testScore=70") + .when().get("/universities/search?region=EUROPE&testType=TOEFL_IBT&testScore=70") .then().log().all() .statusCode(200) .extract().jsonPath().getList(".", UniversityInfoForApplyPreviewResponse.class); diff --git a/src/test/java/com/example/solidconnection/siteuser/service/SiteUserServiceTest.java b/src/test/java/com/example/solidconnection/siteuser/service/SiteUserServiceTest.java index 9fc6410d8..cb256bc0f 100644 --- a/src/test/java/com/example/solidconnection/siteuser/service/SiteUserServiceTest.java +++ b/src/test/java/com/example/solidconnection/siteuser/service/SiteUserServiceTest.java @@ -5,10 +5,7 @@ import com.example.solidconnection.s3.UploadedFileUrlResponse; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.dto.MyPageResponse; -import com.example.solidconnection.siteuser.dto.MyPageUpdateResponse; import com.example.solidconnection.siteuser.dto.NicknameUpdateRequest; -import com.example.solidconnection.siteuser.dto.NicknameUpdateResponse; -import com.example.solidconnection.siteuser.dto.ProfileImageUpdateResponse; import com.example.solidconnection.siteuser.repository.LikedUniversityRepository; import com.example.solidconnection.siteuser.repository.SiteUserRepository; import com.example.solidconnection.support.integration.BaseIntegrationTest; @@ -19,6 +16,7 @@ import com.example.solidconnection.university.domain.LikedUniversity; import com.example.solidconnection.university.dto.UniversityInfoForApplyPreviewResponse; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -36,11 +34,11 @@ import static com.example.solidconnection.siteuser.service.SiteUserService.NICKNAME_LAST_CHANGE_DATE_FORMAT; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; -import static org.mockito.BDDMockito.never; import static org.mockito.BDDMockito.any; import static org.mockito.BDDMockito.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.never; +import static org.mockito.BDDMockito.then; @DisplayName("유저 서비스 테스트") class SiteUserServiceTest extends BaseIntegrationTest { @@ -78,21 +76,6 @@ class SiteUserServiceTest extends BaseIntegrationTest { ); } - @Test - void 내_정보를_수정하기_위한_마이페이지_정보를_조회한다() { - // given - SiteUser testUser = createSiteUser(); - - // when - MyPageUpdateResponse response = siteUserService.getMyPageInfoToUpdate(testUser); - - // then - Assertions.assertAll( - () -> assertThat(response.nickname()).isEqualTo(testUser.getNickname()), - () -> assertThat(response.profileImageUrl()).isEqualTo(testUser.getProfileImageUrl()) - ); - } - @Test void 관심_대학교_목록을_조회한다() { // given @@ -126,13 +109,10 @@ class 프로필_이미지_수정_테스트 { .willReturn(new UploadedFileUrlResponse(expectedUrl)); // when - ProfileImageUpdateResponse response = siteUserService.updateProfileImage( - testUser, - imageFile - ); + siteUserService.updateMyPageInfo(testUser, imageFile, "newNickname"); // then - assertThat(response.profileImageUrl()).isEqualTo(expectedUrl); + assertThat(testUser.getProfileImageUrl()).isEqualTo(expectedUrl); } @Test @@ -144,7 +124,7 @@ class 프로필_이미지_수정_테스트 { .willReturn(new UploadedFileUrlResponse("newProfileImageUrl")); // when - siteUserService.updateProfileImage(testUser, imageFile); + siteUserService.updateMyPageInfo(testUser, imageFile, "newNickname"); // then then(s3Service).should(never()).deleteExProfile(any()); @@ -159,7 +139,7 @@ class 프로필_이미지_수정_테스트 { .willReturn(new UploadedFileUrlResponse("newProfileImageUrl")); // when - siteUserService.updateProfileImage(testUser, imageFile); + siteUserService.updateMyPageInfo(testUser, imageFile, "newNickname"); // then then(s3Service).should().deleteExProfile(testUser); @@ -172,7 +152,7 @@ class 프로필_이미지_수정_테스트 { MockMultipartFile emptyFile = createEmptyImageFile(); // when & then - assertThatCode(() -> siteUserService.updateProfileImage(testUser, emptyFile)) + assertThatCode(() -> siteUserService.updateMyPageInfo(testUser, emptyFile, "newNickname")) .isInstanceOf(CustomException.class) .hasMessage(PROFILE_IMAGE_NEEDED.getMessage()); } @@ -181,23 +161,26 @@ class 프로필_이미지_수정_테스트 { @Nested class 닉네임_수정_테스트 { + @BeforeEach + void setUp() { + given(s3Service.uploadFile(any(), eq(ImgType.PROFILE))) + .willReturn(new UploadedFileUrlResponse("newProfileImageUrl")); + } + @Test void 닉네임을_성공적으로_수정한다() { // given SiteUser testUser = createSiteUser(); + MockMultipartFile imageFile = createValidImageFile(); String newNickname = "newNickname"; - NicknameUpdateRequest request = new NicknameUpdateRequest(newNickname); // when - NicknameUpdateResponse response = siteUserService.updateNickname( - testUser, - request - ); + siteUserService.updateMyPageInfo(testUser, imageFile, newNickname); // then SiteUser updatedUser = siteUserRepository.findById(testUser.getId()).get(); assertThat(updatedUser.getNicknameModifiedAt()).isNotNull(); - assertThat(response.nickname()).isEqualTo(newNickname); + assertThat(updatedUser.getNickname()).isEqualTo(newNickname); } @Test @@ -205,10 +188,10 @@ class 닉네임_수정_테스트 { // given createDuplicatedSiteUser(); SiteUser testUser = createSiteUser(); - NicknameUpdateRequest request = new NicknameUpdateRequest("duplicatedNickname"); + MockMultipartFile imageFile = createValidImageFile(); // when & then - assertThatCode(() -> siteUserService.updateNickname(testUser, request)) + assertThatCode(() -> siteUserService.updateMyPageInfo(testUser, imageFile, "duplicatedNickname")) .isInstanceOf(CustomException.class) .hasMessage(NICKNAME_ALREADY_EXISTED.getMessage()); } @@ -217,6 +200,7 @@ class 닉네임_수정_테스트 { void 최소_대기기간이_지나지_않은_상태에서_변경하면_예외_응답을_반환한다() { // given SiteUser testUser = createSiteUser(); + MockMultipartFile imageFile = createValidImageFile(); LocalDateTime modifiedAt = LocalDateTime.now().minusDays(MIN_DAYS_BETWEEN_NICKNAME_CHANGES - 1); testUser.setNicknameModifiedAt(modifiedAt); siteUserRepository.save(testUser); @@ -224,8 +208,7 @@ class 닉네임_수정_테스트 { NicknameUpdateRequest request = new NicknameUpdateRequest("newNickname"); // when & then - assertThatCode(() -> - siteUserService.updateNickname(testUser, request)) + assertThatCode(() -> siteUserService.updateMyPageInfo(testUser, imageFile, "nickname12")) .isInstanceOf(CustomException.class) .hasMessage(createExpectedErrorMessage(modifiedAt)); } diff --git a/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java index 51958ed5d..ec9b704a6 100644 --- a/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java @@ -13,14 +13,18 @@ import com.example.solidconnection.university.dto.IsLikeResponse; import com.example.solidconnection.university.dto.LikeResultResponse; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import static com.example.solidconnection.custom.exception.ErrorCode.ALREADY_LIKED_UNIVERSITY; +import static com.example.solidconnection.custom.exception.ErrorCode.NOT_LIKED_UNIVERSITY; import static com.example.solidconnection.custom.exception.ErrorCode.UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND; import static com.example.solidconnection.university.service.UniversityLikeService.LIKE_CANCELED_MESSAGE; import static com.example.solidconnection.university.service.UniversityLikeService.LIKE_SUCCESS_MESSAGE; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; +import static org.junit.jupiter.api.Assertions.assertAll; @DisplayName("대학교 좋아요 서비스 테스트") class UniversityLikeServiceTest extends BaseIntegrationTest { @@ -34,33 +38,70 @@ class UniversityLikeServiceTest extends BaseIntegrationTest { @Autowired private SiteUserRepository siteUserRepository; - @Test - void 대학_좋아요를_등록한다() { - // given - SiteUser testUser = createSiteUser(); - - // when - LikeResultResponse response = universityLikeService.likeUniversity(testUser, 괌대학_A_지원_정보.getId()); - - // then - assertThat(response.result()).isEqualTo(LIKE_SUCCESS_MESSAGE); - assertThat(likedUniversityRepository.findBySiteUserAndUniversityInfoForApply( - testUser, 괌대학_A_지원_정보)).isPresent(); + @Nested + class 대학_좋아요를_등록한다 { + + @Test + void 성공적으로_좋아요를_등록한다() { + // given + SiteUser testUser = createSiteUser(); + + // when + LikeResultResponse response = universityLikeService.likeUniversity(testUser, 괌대학_A_지원_정보.getId()); + + // then + assertAll( + () -> assertThat(response.result()).isEqualTo(LIKE_SUCCESS_MESSAGE), + () -> assertThat(likedUniversityRepository.findBySiteUserAndUniversityInfoForApply( + testUser, 괌대학_A_지원_정보 + )).isPresent() + ); + } + + @Test + void 이미_좋아요한_대학이면_예외_응답을_반환한다() { + // given + SiteUser testUser = createSiteUser(); + saveLikedUniversity(testUser, 괌대학_A_지원_정보); + + // when & then + assertThatCode(() -> universityLikeService.likeUniversity(testUser, 괌대학_A_지원_정보.getId())) + .isInstanceOf(CustomException.class) + .hasMessage(ALREADY_LIKED_UNIVERSITY.getMessage()); + } } - @Test - void 대학_좋아요를_취소한다() { - // given - SiteUser testUser = createSiteUser(); - saveLikedUniversity(testUser, 괌대학_A_지원_정보); - - // when - LikeResultResponse response = universityLikeService.likeUniversity(testUser, 괌대학_A_지원_정보.getId()); - - // then - assertThat(response.result()).isEqualTo(LIKE_CANCELED_MESSAGE); - assertThat(likedUniversityRepository.findBySiteUserAndUniversityInfoForApply( - testUser, 괌대학_A_지원_정보)).isEmpty(); + @Nested + class 대학_좋아요를_취소한다 { + + @Test + void 성공적으로_좋아요를_취소한다() { + // given + SiteUser testUser = createSiteUser(); + saveLikedUniversity(testUser, 괌대학_A_지원_정보); + + // when + LikeResultResponse response = universityLikeService.cancelLikeUniversity(testUser, 괌대학_A_지원_정보.getId()); + + // then + assertAll( + () -> assertThat(response.result()).isEqualTo(LIKE_CANCELED_MESSAGE), + () -> assertThat(likedUniversityRepository.findBySiteUserAndUniversityInfoForApply( + testUser, 괌대학_A_지원_정보 + )).isEmpty() + ); + } + + @Test + void 좋아요하지_않은_대학이면_예외_응답을_반환한다() { + // given + SiteUser testUser = createSiteUser(); + + // when & then + assertThatCode(() -> universityLikeService.cancelLikeUniversity(testUser, 괌대학_A_지원_정보.getId())) + .isInstanceOf(CustomException.class) + .hasMessage(NOT_LIKED_UNIVERSITY.getMessage()); + } } @Test