diff --git a/.github/workflows/ci-trigger.yml b/.github/workflows/ci-trigger.yml deleted file mode 100644 index 8530b18a..00000000 --- a/.github/workflows/ci-trigger.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: CI trigger - -on: - pull_request: - branches: [ dev, main ] - push: - branches: [ dev, main ] - -jobs: - run-CI-workflow: - runs-on: ubuntu-latest - name: run CI workflow - steps: - - name: run - run: echo "this is a dummy workflow that triggers a workflow_run; it's necessary because otherwise the repo secrets will not be in scope for externally forked pull requests" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a950656..16f0e547 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,10 @@ -name: CI triggered by CI trigger +name: CI triggered by PR on: - workflow_run: - workflows: [CI trigger] - types: [completed] + pull_request: + branches: + - dev + - main jobs: ci: @@ -35,4 +36,4 @@ jobs: - name: test run: | chmod +x gradlew - ./gradlew test + ./gradlew test \ No newline at end of file diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index cc318977..1d6f5c54 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -144,6 +144,18 @@ include::{snippets}/validate_nickname/fail/invalid/response-fields.adoc[] include::{snippets}/validate_nickname/fail/duplicate/response-body.adoc[] include::{snippets}/validate_nickname/fail/duplicate/response-fields.adoc[] +=== 내 정보 조회 + +==== GET /api/v1/members/me + +===== 요청 +include::{snippets}/get-my-profile/success/http-request.adoc[] +include::{snippets}/get-my-profile/success/request-headers.adoc[] + +===== 응답 (200) +include::{snippets}/get-my-profile/success/response-body.adoc[] +include::{snippets}/get-my-profile/success/response-fields.adoc[] + === 사용자 정보 수정 ==== PATCH /api/v1/members/me diff --git a/src/main/java/com/stumeet/server/member/adapter/in/web/MemberProfileApi.java b/src/main/java/com/stumeet/server/member/adapter/in/web/MemberProfileApi.java index ee56e226..ac36d990 100644 --- a/src/main/java/com/stumeet/server/member/adapter/in/web/MemberProfileApi.java +++ b/src/main/java/com/stumeet/server/member/adapter/in/web/MemberProfileApi.java @@ -3,6 +3,7 @@ import com.stumeet.server.common.annotation.WebAdapter; import com.stumeet.server.common.auth.model.LoginMember; import com.stumeet.server.common.model.ApiResponse; +import com.stumeet.server.member.adapter.in.web.response.MemberProfileResponse; import com.stumeet.server.member.application.port.in.MemberProfileUseCase; import com.stumeet.server.member.application.port.in.command.MemberUpdateCommand; import jakarta.validation.Valid; @@ -10,6 +11,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -31,4 +33,15 @@ public ResponseEntity> updateMyProfile( HttpStatus.OK ); } + + @GetMapping("/me") + public ResponseEntity> getMyProfile( + @AuthenticationPrincipal LoginMember member + ) { + MemberProfileResponse response = memberProfileUseCase.getProfileById(member.getMember().getId()); + return new ResponseEntity<>( + ApiResponse.success(HttpStatus.OK.value(), "내 프로필 조회에 성공했습니다.", response), + HttpStatus.OK + ); + } } diff --git a/src/main/java/com/stumeet/server/member/adapter/in/web/response/MemberProfileResponse.java b/src/main/java/com/stumeet/server/member/adapter/in/web/response/MemberProfileResponse.java new file mode 100644 index 00000000..1c7e3e61 --- /dev/null +++ b/src/main/java/com/stumeet/server/member/adapter/in/web/response/MemberProfileResponse.java @@ -0,0 +1,15 @@ +package com.stumeet.server.member.adapter.in.web.response; + +import lombok.Builder; + +@Builder +public record MemberProfileResponse( + Long id, + String image, + String nickname, + String region, + String profession, + String rank, + double experience +) { +} diff --git a/src/main/java/com/stumeet/server/member/adapter/out/persistence/MemberJpaEntity.java b/src/main/java/com/stumeet/server/member/adapter/out/persistence/MemberJpaEntity.java index 2fa9754f..e55fa4c3 100644 --- a/src/main/java/com/stumeet/server/member/adapter/out/persistence/MemberJpaEntity.java +++ b/src/main/java/com/stumeet/server/member/adapter/out/persistence/MemberJpaEntity.java @@ -2,6 +2,7 @@ import com.stumeet.server.common.model.BaseTimeEntity; import com.stumeet.server.member.domain.AuthType; +import com.stumeet.server.member.domain.MemberRank; import com.stumeet.server.member.domain.UserRole; import com.stumeet.server.profession.adapter.out.persistence.ProfessionJpaEntity; import jakarta.persistence.*; @@ -36,9 +37,14 @@ public class MemberJpaEntity extends BaseTimeEntity { @Comment("멤버 이미지 URL") private String image; - @Column(name = "sugar_contents", nullable = false) - @Comment("포도알 당도") - private Double sugarContents; + @Column(name = "rank", length = 50, nullable = false) + @Enumerated(EnumType.STRING) + @Comment("등급") + private MemberRank rank; + + @Column(name = "experience", nullable = false) + @Comment("경험치") + private double experience; @Column(name = "region", length = 50) @Comment("지역") diff --git a/src/main/java/com/stumeet/server/member/adapter/out/persistence/MemberPersistenceMapper.java b/src/main/java/com/stumeet/server/member/adapter/out/persistence/MemberPersistenceMapper.java index 3e6daf95..bfc5899e 100644 --- a/src/main/java/com/stumeet/server/member/adapter/out/persistence/MemberPersistenceMapper.java +++ b/src/main/java/com/stumeet/server/member/adapter/out/persistence/MemberPersistenceMapper.java @@ -1,6 +1,7 @@ package com.stumeet.server.member.adapter.out.persistence; import com.stumeet.server.member.domain.Member; +import com.stumeet.server.member.domain.MemberLevel; import com.stumeet.server.profession.adapter.out.persistence.ProfessionPersistenceMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -16,7 +17,8 @@ public MemberJpaEntity toEntity(Member domain) { .id(domain.getId()) .name(domain.getName()) .image(domain.getImage()) - .sugarContents(domain.getSugarContents()) + .rank(domain.getLevel().getRank()) + .experience(domain.getLevel().getExperience()) .region(domain.getRegion()) .profession(professionPersistenceMapper.toEntity(domain.getProfession())) .authType(domain.getAuthType()) @@ -25,11 +27,16 @@ public MemberJpaEntity toEntity(Member domain) { } public Member toDomain(MemberJpaEntity entity) { + MemberLevel level = MemberLevel.builder() + .rank(entity.getRank()) + .experience(entity.getExperience()) + .build(); + return Member.builder() .id(entity.getId()) .name(entity.getName()) .image(entity.getImage()) - .sugarContents(entity.getSugarContents()) + .level(level) .region(entity.getRegion()) .profession(professionPersistenceMapper.toDomain(entity.getProfession())) .authType(entity.getAuthType()) diff --git a/src/main/java/com/stumeet/server/member/application/port/in/MemberProfileUseCase.java b/src/main/java/com/stumeet/server/member/application/port/in/MemberProfileUseCase.java index 821dc99a..73d710ea 100644 --- a/src/main/java/com/stumeet/server/member/application/port/in/MemberProfileUseCase.java +++ b/src/main/java/com/stumeet/server/member/application/port/in/MemberProfileUseCase.java @@ -1,5 +1,6 @@ package com.stumeet.server.member.application.port.in; +import com.stumeet.server.member.adapter.in.web.response.MemberProfileResponse; import com.stumeet.server.member.application.port.in.command.MemberSignupCommand; import com.stumeet.server.member.application.port.in.command.MemberUpdateCommand; import com.stumeet.server.member.domain.Member; @@ -8,4 +9,6 @@ public interface MemberProfileUseCase { void signup(Member member, MemberSignupCommand request); void updateProfile(Member member, MemberUpdateCommand request); + + MemberProfileResponse getProfileById(Long id); } diff --git a/src/main/java/com/stumeet/server/member/application/port/in/mapper/MemberUseCaseMapper.java b/src/main/java/com/stumeet/server/member/application/port/in/mapper/MemberUseCaseMapper.java new file mode 100644 index 00000000..1374cb84 --- /dev/null +++ b/src/main/java/com/stumeet/server/member/application/port/in/mapper/MemberUseCaseMapper.java @@ -0,0 +1,21 @@ +package com.stumeet.server.member.application.port.in.mapper; + +import com.stumeet.server.member.adapter.in.web.response.MemberProfileResponse; +import com.stumeet.server.member.domain.Member; +import org.springframework.stereotype.Component; + +@Component +public class MemberUseCaseMapper { + + public MemberProfileResponse toProfileResponse(Member member) { + return MemberProfileResponse.builder() + .id(member.getId()) + .image(member.getImage()) + .nickname(member.getName()) + .region(member.getRegion()) + .profession(member.getProfession().getName()) + .rank(member.getLevel().getRank().getName()) + .experience(member.getLevel().getExperience()) + .build(); + } +} diff --git a/src/main/java/com/stumeet/server/member/application/service/MemberOAuthService.java b/src/main/java/com/stumeet/server/member/application/service/MemberOAuthService.java index 7e21be90..20133cd8 100644 --- a/src/main/java/com/stumeet/server/member/application/service/MemberOAuthService.java +++ b/src/main/java/com/stumeet/server/member/application/service/MemberOAuthService.java @@ -28,9 +28,13 @@ public Member getMemberOrCreate(OAuthUserProfileResponse response, String provid if (isRegisterUser) { member = memberQueryPort.getByOAuthProviderId(response.id(), oAuthProvider); } else { + MemberLevel initialLevel = MemberLevel.builder() + .rank(MemberRank.SEED) + .experience(0.0) + .build(); member = memberCommandPort.save( Member.builder() - .sugarContents(0.0) + .level(initialLevel) .authType(AuthType.OAUTH) .role(UserRole.FIRST_LOGIN) .build() diff --git a/src/main/java/com/stumeet/server/member/application/service/MemberProfileService.java b/src/main/java/com/stumeet/server/member/application/service/MemberProfileService.java index b1e214e8..4df75290 100644 --- a/src/main/java/com/stumeet/server/member/application/service/MemberProfileService.java +++ b/src/main/java/com/stumeet/server/member/application/service/MemberProfileService.java @@ -2,11 +2,14 @@ import com.stumeet.server.common.annotation.UseCase; import com.stumeet.server.file.application.port.in.FileUploadUseCase; +import com.stumeet.server.member.adapter.in.web.response.MemberProfileResponse; import com.stumeet.server.member.application.port.in.MemberProfileUseCase; import com.stumeet.server.member.application.port.in.command.MemberProfileCommand; import com.stumeet.server.member.application.port.in.command.MemberSignupCommand; import com.stumeet.server.member.application.port.in.command.MemberUpdateCommand; +import com.stumeet.server.member.application.port.in.mapper.MemberUseCaseMapper; import com.stumeet.server.member.application.port.out.MemberCommandPort; +import com.stumeet.server.member.application.port.out.MemberQueryPort; import com.stumeet.server.member.domain.Member; import com.stumeet.server.profession.application.port.in.ProfessionQueryUseCase; import com.stumeet.server.profession.domain.Profession; @@ -21,6 +24,9 @@ public class MemberProfileService implements MemberProfileUseCase { private final ProfessionQueryUseCase professionQueryUseCase; private final FileUploadUseCase fileUploadUseCase; private final MemberCommandPort memberCommandPort; + private final MemberQueryPort memberQueryPort; + private final MemberUseCaseMapper memberUseCaseMapper; + @Override public void signup(Member member, MemberSignupCommand request) { @@ -61,4 +67,10 @@ public void updateProfile(Member member, MemberUpdateCommand request) { memberCommandPort.update(member); } + @Override + public MemberProfileResponse getProfileById(Long id) { + Member member = memberQueryPort.getById(id); + return memberUseCaseMapper.toProfileResponse(member); + } + } diff --git a/src/main/java/com/stumeet/server/member/domain/Member.java b/src/main/java/com/stumeet/server/member/domain/Member.java index 2c058409..3a0e47be 100644 --- a/src/main/java/com/stumeet/server/member/domain/Member.java +++ b/src/main/java/com/stumeet/server/member/domain/Member.java @@ -19,7 +19,7 @@ public class Member { private String image; - private Double sugarContents; + private MemberLevel level; private String region; diff --git a/src/main/java/com/stumeet/server/member/domain/MemberLevel.java b/src/main/java/com/stumeet/server/member/domain/MemberLevel.java new file mode 100644 index 00000000..4012f013 --- /dev/null +++ b/src/main/java/com/stumeet/server/member/domain/MemberLevel.java @@ -0,0 +1,14 @@ +package com.stumeet.server.member.domain; + +import lombok.*; + + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Builder +public class MemberLevel { + + private MemberRank rank; + private double experience; +} diff --git a/src/main/java/com/stumeet/server/member/domain/MemberRank.java b/src/main/java/com/stumeet/server/member/domain/MemberRank.java new file mode 100644 index 00000000..5213b005 --- /dev/null +++ b/src/main/java/com/stumeet/server/member/domain/MemberRank.java @@ -0,0 +1,19 @@ +package com.stumeet.server.member.domain; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public enum MemberRank { + SEED("씨앗"), + SPROUT("새싹"), + LEAF("잎"), + FLOWER("꽃"), + TREE("나무"), + FRUIT("열매"); + + + private final String name; + +} diff --git a/src/main/resources/db/migration/V1.2__modify_member_level.sql b/src/main/resources/db/migration/V1.2__modify_member_level.sql new file mode 100644 index 00000000..35bf898f --- /dev/null +++ b/src/main/resources/db/migration/V1.2__modify_member_level.sql @@ -0,0 +1,8 @@ +ALTER TABLE `member` + DROP COLUMN `sugar_contents`; + +ALTER TABLE `member` + ADD COLUMN `rank` VARCHAR(50) not null comment '등급' AFTER `image`; + +ALTER TABLE `member` + ADD COLUMN `experience` DOUBLE not null comment '경험치' AFTER `rank` ; \ No newline at end of file diff --git a/src/test/java/com/stumeet/server/common/auth/filter/LogoutFilterTest.java b/src/test/java/com/stumeet/server/common/auth/filter/LogoutFilterTest.java index 293c793a..38267141 100644 --- a/src/test/java/com/stumeet/server/common/auth/filter/LogoutFilterTest.java +++ b/src/test/java/com/stumeet/server/common/auth/filter/LogoutFilterTest.java @@ -29,7 +29,6 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@Transactional public class LogoutFilterTest extends ApiTest { @Container @@ -54,11 +53,10 @@ class Logout { @BeforeEach void setUp() { - MemberJpaEntity entity = jpaMemberRepository.save(MemberStub.getMemberEntity()); redisTemplate.opsForValue() .set( JwtUtil.resolveToken(TokenStub.getMockAccessToken()), - jwtTokenProvider.generateRefreshToken(entity.getId()) + jwtTokenProvider.generateRefreshToken(MemberStub.getMember().getId()) ); } diff --git a/src/test/java/com/stumeet/server/common/auth/filter/OAuthAuthenticationFilterTest.java b/src/test/java/com/stumeet/server/common/auth/filter/OAuthAuthenticationFilterTest.java index 161ac529..8a073ce6 100644 --- a/src/test/java/com/stumeet/server/common/auth/filter/OAuthAuthenticationFilterTest.java +++ b/src/test/java/com/stumeet/server/common/auth/filter/OAuthAuthenticationFilterTest.java @@ -29,7 +29,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WireMockTest(httpPort = 8089) -@Transactional class OAuthAuthenticationFilterTest extends ApiTest { @Container diff --git a/src/test/java/com/stumeet/server/member/adapter/in/web/MemberAuthApiTest.java b/src/test/java/com/stumeet/server/member/adapter/in/web/MemberAuthApiTest.java index 21b6f425..f81363f4 100644 --- a/src/test/java/com/stumeet/server/member/adapter/in/web/MemberAuthApiTest.java +++ b/src/test/java/com/stumeet/server/member/adapter/in/web/MemberAuthApiTest.java @@ -34,7 +34,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@Transactional class MemberAuthApiTest extends ApiTest { @Container @@ -61,8 +60,7 @@ class tokenRenew { @BeforeEach void setUp() { - MemberJpaEntity entity = jpaMemberRepository.save(MemberStub.getMemberEntity()); - refreshToken = jwtTokenProvider.generateRefreshToken(entity.getId()); + refreshToken = jwtTokenProvider.generateRefreshToken(MemberStub.getMember().getId()); redisTemplate.opsForValue() .set(TokenStub.getExpiredAccessToken(), refreshToken); } diff --git a/src/test/java/com/stumeet/server/member/adapter/in/web/MemberProfileApiTest.java b/src/test/java/com/stumeet/server/member/adapter/in/web/MemberProfileApiTest.java index f0e38065..694fcd0e 100644 --- a/src/test/java/com/stumeet/server/member/adapter/in/web/MemberProfileApiTest.java +++ b/src/test/java/com/stumeet/server/member/adapter/in/web/MemberProfileApiTest.java @@ -2,23 +2,20 @@ import com.stumeet.server.common.auth.model.AuthenticationHeader; import com.stumeet.server.helper.WithMockMember; -import com.stumeet.server.member.adapter.out.persistence.JpaMemberRepository; import com.stumeet.server.member.application.port.in.command.MemberUpdateCommand; import com.stumeet.server.stub.MemberStub; import com.stumeet.server.stub.TokenStub; import com.stumeet.server.template.ApiTest; -import org.junit.jupiter.api.BeforeEach; 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 org.springframework.mock.web.MockMultipartFile; import org.springframework.test.web.servlet.request.RequestPostProcessor; -import org.springframework.transaction.annotation.Transactional; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; @@ -26,23 +23,14 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@Transactional class MemberProfileApiTest extends ApiTest { - @Autowired - private JpaMemberRepository memberRepository; - @Nested @DisplayName("내 프로필 수정") class UpdateMyProfile { private final String path = "/api/v1/members/me"; - @BeforeEach - void setUp() { - memberRepository.save(MemberStub.getMemberEntity()); - } - @Test @WithMockMember @DisplayName("[성공] 회원 프로필 수정에 성공한다.") @@ -112,4 +100,33 @@ void invalidRequestTest() throws Exception { ))); } } + + @Nested + @DisplayName("내 프로필 조회") + class GetMyProfile { + + @Test + @WithMockMember + @DisplayName("[성공] 회원 프로필 조회에 성공한다.") + void successTest() throws Exception { + mockMvc.perform(get("/api/v1/members/me") + .header(AuthenticationHeader.ACCESS_TOKEN.getName(), TokenStub.getMockAccessToken())) + .andExpect(status().isOk()) + .andDo(document("get-my-profile/success", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders(headerWithName(AuthenticationHeader.ACCESS_TOKEN.getName()).description("서버로부터 전달받은 액세스 토큰")), + responseFields( + fieldWithPath("code").description("응답 상태"), + fieldWithPath("message").description("응답 메시지"), + fieldWithPath("data.id").description("회원 ID"), + fieldWithPath("data.image").description("프로필 이미지 URL"), + fieldWithPath("data.nickname").description("닉네임"), + fieldWithPath("data.region").description("지역"), + fieldWithPath("data.profession").description("분야 이름"), + fieldWithPath("data.rank").description("회원 레벨 - 랭크"), + fieldWithPath("data.experience").description("회원 레벨 - 경험치") + ))); + } + } } \ No newline at end of file diff --git a/src/test/java/com/stumeet/server/member/adapter/in/web/MemberValidApiTest.java b/src/test/java/com/stumeet/server/member/adapter/in/web/MemberValidApiTest.java index b53f8a2c..d6712605 100644 --- a/src/test/java/com/stumeet/server/member/adapter/in/web/MemberValidApiTest.java +++ b/src/test/java/com/stumeet/server/member/adapter/in/web/MemberValidApiTest.java @@ -26,7 +26,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@Transactional class MemberValidApiTest extends ApiTest { @Autowired @@ -37,12 +36,6 @@ class MemberValidApiTest extends ApiTest { class IsDuplicateNickname { private final String path = "/api/v1/members/validate-nickname"; - private MemberJpaEntity member; - - @BeforeEach - void setUp() { - member = jpaMemberRepository.save(MemberStub.getMemberEntity()); - } @Test @WithMockMember @@ -96,7 +89,7 @@ void invalidRequestTest() throws Exception { @WithMockMember @DisplayName("[실패] 닉네임이 중복되면 검증에 실패합니다.") void duplicateNicknameTest() throws Exception { - String nickname = member.getName(); + String nickname = MemberStub.getMember().getName(); mockMvc.perform(get(path) .header(AuthenticationHeader.ACCESS_TOKEN.getName(), TokenStub.getMockAccessToken()) .param("nickname", nickname)) diff --git a/src/test/java/com/stumeet/server/member/application/service/MemberProfileServiceTest.java b/src/test/java/com/stumeet/server/member/application/service/MemberProfileServiceTest.java index 70d64ee1..58e95e52 100644 --- a/src/test/java/com/stumeet/server/member/application/service/MemberProfileServiceTest.java +++ b/src/test/java/com/stumeet/server/member/application/service/MemberProfileServiceTest.java @@ -1,8 +1,11 @@ package com.stumeet.server.member.application.service; import com.stumeet.server.file.application.port.in.FileUploadUseCase; +import com.stumeet.server.member.adapter.in.web.response.MemberProfileResponse; import com.stumeet.server.member.application.port.in.command.MemberUpdateCommand; +import com.stumeet.server.member.application.port.in.mapper.MemberUseCaseMapper; import com.stumeet.server.member.application.port.out.MemberCommandPort; +import com.stumeet.server.member.application.port.out.MemberQueryPort; import com.stumeet.server.member.domain.Member; import com.stumeet.server.profession.application.port.in.ProfessionQueryUseCase; import com.stumeet.server.stub.FileStub; @@ -15,6 +18,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; @@ -33,6 +37,12 @@ class MemberProfileServiceTest extends UnitTest { @Mock private ProfessionQueryUseCase professionQueryUseCase; + @Mock + private MemberQueryPort memberQueryPort; + + @Mock + private MemberUseCaseMapper memberUseCaseMapper; + @Nested @DisplayName("멤버 프로필 업데이트") class UpdateProfile { @@ -54,4 +64,24 @@ void successTest() { } } + @Nested + @DisplayName("프로필 조회") + class GetProfileById { + @Test + @DisplayName("[성공] 멤버 프로필 조회에 성공한다.") + void successTest() { + Member member = MemberStub.getMember(); + MemberProfileResponse want = MemberStub.getMemberProfileResponse(member); + + given(memberQueryPort.getById(member.getId())) + .willReturn(member); + given(memberUseCaseMapper.toProfileResponse(member)) + .willReturn(want); + + MemberProfileResponse got = memberProfileService.getProfileById(member.getId()); + + assertThat(got).usingRecursiveComparison().isEqualTo(want); + } + } + } \ No newline at end of file diff --git a/src/test/java/com/stumeet/server/profession/adapter/in/web/ProfessionQueryApiTest.java b/src/test/java/com/stumeet/server/profession/adapter/in/web/ProfessionQueryApiTest.java index 0bf7a58c..f3f7304f 100644 --- a/src/test/java/com/stumeet/server/profession/adapter/in/web/ProfessionQueryApiTest.java +++ b/src/test/java/com/stumeet/server/profession/adapter/in/web/ProfessionQueryApiTest.java @@ -20,7 +20,6 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@Transactional class ProfessionQueryApiTest extends ApiTest { @Nested diff --git a/src/test/java/com/stumeet/server/stub/MemberStub.java b/src/test/java/com/stumeet/server/stub/MemberStub.java index b602e344..9d801852 100644 --- a/src/test/java/com/stumeet/server/stub/MemberStub.java +++ b/src/test/java/com/stumeet/server/stub/MemberStub.java @@ -1,11 +1,10 @@ package com.stumeet.server.stub; +import com.stumeet.server.member.adapter.in.web.response.MemberProfileResponse; import com.stumeet.server.member.adapter.out.persistence.MemberJpaEntity; import com.stumeet.server.member.application.port.in.command.MemberSignupCommand; import com.stumeet.server.member.application.port.in.command.MemberUpdateCommand; -import com.stumeet.server.member.domain.AuthType; -import com.stumeet.server.member.domain.Member; -import com.stumeet.server.member.domain.UserRole; +import com.stumeet.server.member.domain.*; import com.stumeet.server.helper.WithMockMember; import org.springframework.mock.web.MockMultipartFile; @@ -29,9 +28,13 @@ public static MemberJpaEntity getMemberEntity() { return MemberJpaEntity.builder() .id(1L) .name("test") + .image(FileStub.getFileUrl().url()) + .region("서울") + .profession(ProfessionStub.getProfessionEntity()) .role(UserRole.FIRST_LOGIN) .authType(AuthType.OAUTH) - .sugarContents(0.0) + .rank(MemberRank.SEED) + .experience(0.0) .build(); } @@ -41,28 +44,37 @@ public static MemberSignupCommand getMemberSignupCommand() { } public static Member getMember(WithMockMember annotation) { + MemberLevel level = MemberLevel.builder() + .rank(MemberRank.SEED) + .experience(0.0) + .build(); + return Member.builder() .id(1L) .name("test") .role(annotation.authority()) .authType(AuthType.OAUTH) - .sugarContents(0.0) - .profession(null) - .region(null) - .image(null) + .level(level) + .profession(ProfessionStub.getProfession()) + .region("서울") + .image(FileStub.getFileUrl().url()) .build(); } public static Member getMember() { + MemberLevel level = MemberLevel.builder() + .rank(MemberRank.SEED) + .experience(0.0) + .build(); return Member.builder() .id(1L) .name("test") .role(UserRole.MEMBER) .authType(AuthType.OAUTH) - .sugarContents(0.0) - .profession(null) - .region(null) - .image(null) + .level(level) + .profession(ProfessionStub.getProfession()) + .region("서울") + .image(FileStub.getFileUrl().url()) .build(); } @@ -75,4 +87,16 @@ public static MemberUpdateCommand getInvalidMemberUpdateCommand() { MockMultipartFile invalidImage = new MockMultipartFile("image", "test.jpa", "plain/text", "test".getBytes()); return new MemberUpdateCommand(invalidImage, "닉", " ", -1L); } + + public static MemberProfileResponse getMemberProfileResponse(Member member) { + return MemberProfileResponse.builder() + .id(member.getId()) + .image(member.getImage()) + .nickname(member.getName()) + .region(member.getRegion()) + .profession(member.getProfession().getName()) + .rank(member.getLevel().getRank().getName()) + .experience(member.getLevel().getExperience()) + .build(); + } } diff --git a/src/test/java/com/stumeet/server/stub/ProfessionStub.java b/src/test/java/com/stumeet/server/stub/ProfessionStub.java index 0c6b53ca..81c3283a 100644 --- a/src/test/java/com/stumeet/server/stub/ProfessionStub.java +++ b/src/test/java/com/stumeet/server/stub/ProfessionStub.java @@ -1,5 +1,6 @@ package com.stumeet.server.stub; +import com.stumeet.server.profession.adapter.out.persistence.ProfessionJpaEntity; import com.stumeet.server.profession.domain.Profession; public class ProfessionStub { @@ -14,4 +15,12 @@ public static Profession getProfession() { .parent(null) .build(); } + + public static ProfessionJpaEntity getProfessionEntity() { + return ProfessionJpaEntity.builder() + .id(1L) + .name("경영사무") + .parent(null) + .build(); + } } diff --git a/src/test/java/com/stumeet/server/template/ApiTest.java b/src/test/java/com/stumeet/server/template/ApiTest.java index ecbaf37b..3a833e22 100644 --- a/src/test/java/com/stumeet/server/template/ApiTest.java +++ b/src/test/java/com/stumeet/server/template/ApiTest.java @@ -11,6 +11,7 @@ import org.springframework.restdocs.RestDocumentationContextProvider; import org.springframework.restdocs.RestDocumentationExtension; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; @@ -23,6 +24,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; @SpringBootTest +@Sql(scripts = "classpath:db/setup.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +@Sql(scripts = "classpath:db/teardown.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) @ExtendWith(RestDocumentationExtension.class) @ActiveProfiles("test") @Import({TestAwsS3Config.class}) diff --git a/src/test/resources/db/setup.sql b/src/test/resources/db/setup.sql new file mode 100644 index 00000000..649cb84e --- /dev/null +++ b/src/test/resources/db/setup.sql @@ -0,0 +1,3 @@ +INSERT INTO member (id, name, image, region, profession_id, role, auth_type, rank, experience, is_deleted, deleted_at) +VALUES (1, 'test', 'http://localhost:4572/user/1/profile/2024030416531039839905-b7e8-4ad3-9552-7d9cbc01cb14-test.jpg', + '서울', 1, 'FIRST_LOGIN', 'OAUTH', 'SEED', 0.0, false, null); \ No newline at end of file diff --git a/src/test/resources/db/teardown.sql b/src/test/resources/db/teardown.sql new file mode 100644 index 00000000..816158a4 --- /dev/null +++ b/src/test/resources/db/teardown.sql @@ -0,0 +1,6 @@ +SET FOREIGN_KEY_CHECKS = 0; + +TRUNCATE TABLE member; +TRUNCATE TABLE oauth_login; + +SET FOREIGN_KEY_CHECKS = 1; \ No newline at end of file