Skip to content

Commit

Permalink
feat: 내 사용자 정보 조회 기능 구현 (#60)
Browse files Browse the repository at this point in the history
* chore: 인증 코드 만료 시간 환경 변수명을 VERIFICATION_CODE_EXPIRE_TIME으로 변경

* feat: 내 사용자 정보 조회 기능 구현

* test: 내 사용자 정보 조회 기능 테스트 작성

* chore: static 파일 gitignore에 추가
  • Loading branch information
scv1702 authored May 7, 2024
1 parent fbb737f commit 779490e
Show file tree
Hide file tree
Showing 20 changed files with 210 additions and 36 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,6 @@ Temporary Items
local.sh

# JUnit settings
.run/
.run/

src/main/resources/static/*
5 changes: 5 additions & 0 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,8 @@ include::{docdir}/signup.adoc[]

=== Access Token 및 Refresh Token 재발급


== 사용자

=== 내 사용자 정보 조회
include::{docdir}/member.adoc[]
1 change: 1 addition & 0 deletions src/docs/asciidoc/member.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
operation::/get-my-member/get-my-member[snippets="http-request,http-response,response-fields-data"]
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class SignUpService {
private final MemberService memberService;
private final PasswordEncoder passwordEncoder;

@Transactional
public void sendEmailVerificationCodeForSignUp(String email) {
if (memberService.existsByEmail(email)) {
throw new BusinessLogicException(SignUpErrorCode.DUPLICATED_EMAIL);
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/es/princip/getp/domain/base/BaseTimeEntity.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
package es.princip.getp.domain.base;

import java.time.LocalDateTime;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public abstract class BaseTimeEntity {
@CreatedDate
@Column(columnDefinition = "TIMESTAMP")
private LocalDateTime createdAt;
protected LocalDateTime createdAt;

@LastModifiedDate
@Column(columnDefinition = "TIMESTAMP")
private LocalDateTime updateAt;
protected LocalDateTime updatedAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import es.princip.getp.domain.client.domain.entity.Client;
import es.princip.getp.global.domain.values.Address;
import es.princip.getp.global.domain.values.BankAccount;

import java.time.LocalDateTime;

public record ClientResponse(
Expand All @@ -26,6 +27,6 @@ public static ClientResponse from(final Client client) {
client.getAddress(),
client.getBankAccount(),
client.getCreatedAt(),
client.getUpdateAt());
client.getUpdatedAt());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package es.princip.getp.domain.member.controller;

import es.princip.getp.domain.client.service.ClientService;
import es.princip.getp.domain.member.domain.entity.Member;
import es.princip.getp.domain.member.domain.enums.MemberType;
import es.princip.getp.domain.member.dto.response.MemberResponse;
import es.princip.getp.domain.people.service.PeopleService;
import es.princip.getp.global.security.details.PrincipalDetails;
import es.princip.getp.global.util.ApiResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import static es.princip.getp.global.util.ApiResponse.ApiSuccessResult;

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

private final PeopleService peopleService;
private final ClientService clientService;

@GetMapping("/me")
@PreAuthorize("isAuthenticated()")
public ResponseEntity<ApiSuccessResult<MemberResponse>> getMyMember(
@AuthenticationPrincipal PrincipalDetails principalDetails
) {
Member member = principalDetails.getMember();
Long memberId = member.getMemberId();
String email = member.getEmail();
MemberType memberType = member.getMemberType();
String nickname = memberType.isClient() ? clientService.getByMemberId(memberId).getNickname() :
memberType.isPeople() ? peopleService.getByMemberId(memberId).getNickname() :
email.substring(0, email.indexOf('@'));
return ResponseEntity.ok().body(ApiResponse.success(HttpStatus.OK, MemberResponse.of(member, nickname)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,16 @@
import es.princip.getp.domain.member.domain.enums.MemberType;
import es.princip.getp.domain.member.dto.request.CreateMemberRequest;
import es.princip.getp.domain.serviceTerm.domain.entity.ServiceTermAgreement;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import java.util.ArrayList;
import java.util.List;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
Expand All @@ -47,10 +39,20 @@ public class Member extends BaseTimeEntity {
private List<ServiceTermAgreement> serviceTermAgreements = new ArrayList<>();

@Builder
public Member(String email, String password, MemberType memberType) {
public Member(
Long memberId,
String email,
String password,
MemberType memberType,
LocalDateTime createdAt,
LocalDateTime updatedAt
) {
this.memberId = memberId;
this.email = email;
this.password = password;
this.memberType = memberType;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
}

public static Member from(CreateMemberRequest request) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package es.princip.getp.domain.member.domain.enums;

import com.fasterxml.jackson.annotation.JsonCreator;

import java.util.stream.Stream;

public enum MemberType {
Expand All @@ -13,4 +14,12 @@ public static MemberType parsing(String inputValue) {
.findFirst()
.orElse(null);
}

public boolean isClient() {
return this == ROLE_CLIENT;
}

public boolean isPeople() {
return this == ROLE_PEOPLE;
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,43 @@
package es.princip.getp.domain.member.dto.response;

import com.fasterxml.jackson.annotation.JsonInclude;
import es.princip.getp.domain.member.domain.entity.Member;
import es.princip.getp.domain.member.domain.enums.MemberType;

import java.time.LocalDateTime;

@JsonInclude(JsonInclude.Include.NON_NULL)
public record MemberResponse(
Long memberId,
String email,
String nickname,
MemberType memberType,
LocalDateTime createdAt,
LocalDateTime updatedAt) {
LocalDateTime updatedAt
) {

public static MemberResponse from(final Member member) {
return new MemberResponse(
member.getMemberId(),
member.getEmail(),
null,
member.getMemberType(),
member.getCreatedAt(),
member.getUpdatedAt()
);
}

public static MemberResponse of(
final Member member,
final String nickname
) {
return new MemberResponse(
member.getMemberId(),
member.getEmail(),
nickname,
member.getMemberType(),
member.getCreatedAt(),
member.getUpdateAt());
member.getUpdatedAt()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import es.princip.getp.domain.people.domain.entity.People;
import es.princip.getp.domain.people.domain.enums.PeopleType;

import java.time.LocalDateTime;

public record CreatePeopleResponse(
Expand All @@ -24,7 +25,7 @@ public static CreatePeopleResponse from(People people) {
people.getPeopleType(),
people.getProfileImageUri(),
people.getCreatedAt(),
people.getUpdateAt()
people.getUpdatedAt()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import es.princip.getp.domain.people.domain.entity.People;
import es.princip.getp.domain.people.domain.enums.PeopleType;

import java.time.LocalDateTime;

public record PeopleResponse(
Expand All @@ -24,7 +25,7 @@ public static PeopleResponse from(People people) {
people.getPeopleType(),
people.getProfileImageUri(),
people.getCreatedAt(),
people.getUpdateAt()
people.getUpdatedAt()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import es.princip.getp.domain.people.domain.entity.People;
import es.princip.getp.domain.people.domain.enums.PeopleType;

import java.time.LocalDateTime;

public record UpdatePeopleResponse(
Expand All @@ -24,7 +25,7 @@ public static UpdatePeopleResponse from(People people) {
people.getPeopleType(),
people.getProfileImageUri(),
people.getCreatedAt(),
people.getUpdateAt()
people.getUpdatedAt()
);
}
}
2 changes: 1 addition & 1 deletion src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ spring:

verification-code:
length: ${VERIFICATION_CODE_LENGTH}
expire-time: ${VERIFICATION_CODE_EXPIRATION}
expire-time: ${VERIFICATION_CODE_EXPIRE_TIME}

jwt:
secret: ${JWT_SECRET}
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ spring:

jpa:
hibernate:
ddl-auto: create
ddl-auto: update
properties:
hibernate:
show-sql: true
Expand All @@ -37,7 +37,7 @@ spring:

verification-code:
length: ${VERIFICATION_CODE_LENGTH}
expire-time: ${VERIFICATION_CODE_EXPIRATION}
expire-time: ${VERIFICATION_CODE_EXPIRE_TIME}

jwt:
secret: ${JWT_SECRET}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package es.princip.getp.domain.member.controller;

import es.princip.getp.domain.client.service.ClientService;
import es.princip.getp.domain.member.domain.entity.Member;
import es.princip.getp.domain.member.domain.enums.MemberType;
import es.princip.getp.domain.people.domain.entity.People;
import es.princip.getp.domain.people.service.PeopleService;
import es.princip.getp.fixture.PeopleFixture;
import es.princip.getp.global.mock.WithCustomMockUser;
import es.princip.getp.global.security.details.PrincipalDetails;
import es.princip.getp.global.support.AbstractControllerTest;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;

import static es.princip.getp.global.support.FieldDescriptorHelper.getDescriptor;
import static org.mockito.BDDMockito.given;
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders;
import static org.springframework.restdocs.payload.PayloadDocumentation.beneathPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.snippet.Attributes.key;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(MemberController.class)
class MemberControllerTest extends AbstractControllerTest {

@MockBean
private PeopleService peopleService;



@MockBean
private ClientService clientService;

@Nested
@DisplayName("사용자는")
class GetMyMember {

@DisplayName("내 회원 정보를 조회할 수 있다.")
@WithCustomMockUser(memberType = MemberType.ROLE_PEOPLE)
@Test
void getMyMember(PrincipalDetails principalDetails) throws Exception {
Member member = principalDetails.getMember();
Long memberId = member.getMemberId();
People people = PeopleFixture.createPeople(member);
given(peopleService.getByMemberId(memberId)).willReturn(people);

mockMvc.perform(get("/member/me")
.header("Authorization", "Bearer ${ACCESS_TOKEN}")
)
.andExpect(status().isOk())
.andDo(
restDocs.document(
requestHeaders(
headerWithName("Authorization").description("Bearer ${ACCESS_TOKEN}")
),
responseFields(beneathPath("data").withSubsectionId("data"))
.and(
getDescriptor("memberId", "회원 ID"),
getDescriptor("email", "이메일"),
getDescriptor("nickname", "닉네임"),
getDescriptor("memberType", "회원 유형"),
getDescriptor("createdAt", "회원 가입일")
.attributes(key("format").value("yyyy-MM-dd'T'HH:mm:ss")),
getDescriptor("updatedAt", "회원 정보 수정일")
.attributes(key("format").value("yyyy-MM-dd'T'HH:mm:ss"))
)
)
)
.andDo(print());
}
}
}
Loading

0 comments on commit 779490e

Please sign in to comment.