Skip to content

Commit

Permalink
feat: 프로필 조회 API (#47)
Browse files Browse the repository at this point in the history
* feat: 내 프로필 조회 로직 추가

* style: 클래스 이름 오타 수정

* feat: 내 프로필 조회 API 추가

* refactor: url 수정

* style: 오타 수정

* test: 존재하지 않는 회원 요청에 대한 테스트 추가
  • Loading branch information
TaeyeonRoyce authored Jan 24, 2024
1 parent 45af80b commit 36293a8
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 1 deletion.
22 changes: 22 additions & 0 deletions src/main/java/com/baro/member/application/MemberService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.baro.member.application;

import com.baro.member.application.dto.GetMemberProfileResult;
import com.baro.member.domain.Member;
import com.baro.member.domain.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional
@Service
public class MemberService {

private final MemberRepository memberRepository;

@Transactional(readOnly = true)
public GetMemberProfileResult getMyProfile(Long id) {
Member member = memberRepository.getById(id);
return GetMemberProfileResult.from(member);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.baro.member.application.dto;

import com.baro.member.domain.Member;

public record GetMemberProfileResult(
Long id,
String name,
String nickname,
String profileImageUrl,
String email,
String oAuthServiceType
) {

public static GetMemberProfileResult from(Member member) {
return new GetMemberProfileResult(
member.getId(),
member.getName(),
member.getNickname(),
member.getProfileImageUrl(),
member.getEmail(),
member.getOAuthServiceType()
);
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/baro/member/presentation/MemberController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.baro.member.presentation;

import com.baro.auth.domain.AuthMember;
import com.baro.member.application.MemberService;
import com.baro.member.application.dto.GetMemberProfileResult;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RequestMapping("/members")
@RestController
public class MemberController {

private final MemberService memberService;

@GetMapping("/profile/me")
public ResponseEntity<GetMemberProfileResult> getMyProfile(
AuthMember authMember
) {
GetMemberProfileResult result = memberService.getMyProfile(authMember.id());
return ResponseEntity.ok().body(result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.baro.common.acceptance.member;

import static com.baro.common.RestApiTest.DEFAULT_REST_DOCS_PATH;
import static com.baro.common.RestApiTest.requestSpec;
import static com.baro.common.acceptance.AcceptanceSteps.예외_응답;
import static com.epages.restdocs.apispec.RestAssuredRestDocumentationWrapper.document;
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;

import com.baro.auth.domain.Token;
import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import org.springframework.http.HttpHeaders;

public class MemberAcceptanceSteps {

public static ExtractableResponse<Response> 내_프로필_조회_요청(Token 토큰) {
return RestAssured.given(requestSpec).log().all()
.filter(document(DEFAULT_REST_DOCS_PATH,
requestHeaders(
headerWithName(HttpHeaders.AUTHORIZATION).description("인증 토큰")
),
responseFields(
fieldWithPath("id").description("회원 ID"),
fieldWithPath("name").description("회원 이름"),
fieldWithPath("nickname").description("회원 닉네임"),
fieldWithPath("email").description("회원 이메일"),
fieldWithPath("profileImageUrl").description("회원 프로필 이미지 URL"),
fieldWithPath("oAuthServiceType").description("OAuth 서비스 타입")
))
)
.header(HttpHeaders.AUTHORIZATION, "Bearer " + 토큰.accessToken())
.when().get("/members/profile/me")
.then().log().all()
.extract();
}

public static ExtractableResponse<Response> 잘못된_프로필_조회_요청(Token 토큰) {
return RestAssured.given(requestSpec).log().all()
.filter(document(DEFAULT_REST_DOCS_PATH,
requestHeaders(
headerWithName(HttpHeaders.AUTHORIZATION).description("인증 토큰")
),
responseFields(예외_응답()))
)
.header(HttpHeaders.AUTHORIZATION, "Bearer " + 토큰.accessToken())
.when().get("/members/profile/me")
.then().log().all()
.extract();
}
}
54 changes: 54 additions & 0 deletions src/test/java/com/baro/member/application/MemberServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.baro.member.application;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import com.baro.member.application.dto.GetMemberProfileResult;
import com.baro.member.domain.Member;
import com.baro.member.domain.MemberRepository;
import com.baro.member.exception.MemberException;
import com.baro.member.exception.MemberExceptionType;
import com.baro.member.fake.FakeMemberRepository;
import com.baro.member.fixture.MemberFixture;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.Test;

@DisplayNameGeneration(ReplaceUnderscores.class)
@SuppressWarnings("NonAsciiCharacters")
class MemberServiceTest {

private MemberService memberService;
private MemberRepository memberRepository;

@BeforeEach
void setUp() {
memberRepository = new FakeMemberRepository();
memberService = new MemberService(memberRepository);
}

@Test
void 사용자_프로필_조회() {
// given
Member savedMember = memberRepository.save(MemberFixture.memberWithNickname("바로"));

// when
GetMemberProfileResult result = memberService.getMyProfile(savedMember.getId());

// then
assertThat(result.nickname()).isEqualTo("바로");
}

@Test
void 존재하지_않는_사용자_조회시_예외_발생() {
// given
Long nonExistMemberId = 1L;

// when & then
assertThatThrownBy(() -> memberService.getMyProfile(nonExistMemberId))
.isInstanceOf(MemberException.class)
.extracting("exceptionType")
.isEqualTo(MemberExceptionType.NOT_EXIST_MEMBER);
}
}
54 changes: 54 additions & 0 deletions src/test/java/com/baro/member/presentation/MemberApiTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.baro.member.presentation;

import static com.baro.auth.fixture.OAuthMemberInfoFixture.태연;
import static com.baro.common.acceptance.AcceptanceSteps.성공;
import static com.baro.common.acceptance.AcceptanceSteps.응답값을_검증한다;
import static com.baro.common.acceptance.AcceptanceSteps.잘못된_요청;
import static com.baro.common.acceptance.member.MemberAcceptanceSteps.내_프로필_조회_요청;
import static com.baro.common.acceptance.member.MemberAcceptanceSteps.잘못된_프로필_조회_요청;
import static org.mockito.BDDMockito.given;

import com.baro.auth.application.TokenTranslator;
import com.baro.auth.domain.Token;
import com.baro.common.RestApiTest;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.SpyBean;

@DisplayNameGeneration(ReplaceUnderscores.class)
@SuppressWarnings("NonAsciiCharacters")
public class MemberApiTest extends RestApiTest {

@SpyBean
private TokenTranslator tokenTranslator;

@Test
void 내_프로필_정보를_조회_한다() {
// given
var 토큰 = 로그인(태연());

// when
var 응답 = 내_프로필_조회_요청(토큰);

// then
응답값을_검증한다(응답, 성공);
}

@Test
void 존재하지_않는_멤버가_프로필을_조회할시_예외를_반환_한다() {
// given
var 토큰 = 로그인(태연());
멤버가_존재하지_않는다(토큰);

// when
var 응답 = 잘못된_프로필_조회_요청(토큰);

// then
응답값을_검증한다(응답, 잘못된_요청);
}

private void 멤버가_존재하지_않는다(Token 토큰) {
given(tokenTranslator.decodeAccessToken("Bearer " + 토큰.accessToken())).willReturn(999L);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

@DisplayNameGeneration(ReplaceUnderscores.class)
@SuppressWarnings("NonAsciiCharacters")
public class TemproalMemoApiTest extends RestApiTest {
public class TemporalMemoApiTest extends RestApiTest {

@Test
void 끄적이는_메모를_작성_한다() {
Expand Down

0 comments on commit 36293a8

Please sign in to comment.