Skip to content

Commit

Permalink
Merge pull request #45 from Ajou-Hertz/feature/#44-get-my-info
Browse files Browse the repository at this point in the history
내 정보 조회 API 구현
  • Loading branch information
tinon1004 authored Feb 23, 2024
2 parents dff2e5b + d64e041 commit 0178082
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.net.URI;

import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -13,12 +14,14 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.ajou.hertz.common.auth.UserPrincipal;
import com.ajou.hertz.common.validator.PhoneNumber;
import com.ajou.hertz.domain.user.dto.UserDto;
import com.ajou.hertz.domain.user.dto.request.SignUpRequest;
import com.ajou.hertz.domain.user.dto.response.UserEmailResponse;
import com.ajou.hertz.domain.user.dto.response.UserExistenceResponse;
import com.ajou.hertz.domain.user.dto.response.UserResponse;
import com.ajou.hertz.domain.user.dto.response.UserWithLinkedAccountInfoResponse;
import com.ajou.hertz.domain.user.service.UserCommandService;
import com.ajou.hertz.domain.user.service.UserQueryService;

Expand All @@ -27,6 +30,7 @@
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
Expand All @@ -43,6 +47,19 @@ public class UserControllerV1 {
private final UserCommandService userCommandService;
private final UserQueryService userQueryService;

@Operation(
summary = "내 정보 조회",
description = "내 정보를 조회합니다.",
security = @SecurityRequirement(name = "access-token")
)
@GetMapping(value = "/me", headers = API_MINOR_VERSION_HEADER_NAME + "=" + 1)
public UserWithLinkedAccountInfoResponse getMyInfoV1_1(
@AuthenticationPrincipal UserPrincipal userPrincipal
) {
UserDto userDto = userQueryService.getDtoById(userPrincipal.getUserId());
return UserWithLinkedAccountInfoResponse.from(userDto);
}

@Operation(
summary = "회원 존재 여부 조회",
description = "전달받은 값들에 일치하는 회원이 존재하는지 확인힙니다."
Expand Down Expand Up @@ -83,13 +100,10 @@ public UserEmailResponse getUserEmailByPhoneV1_1(
)
@ApiResponses({
@ApiResponse(responseCode = "200"),
@ApiResponse(
responseCode = "409", content = @Content,
description = """
<p>[2200] 이미 다른 사용자가 사용 중인 이메일로 신규 회원을 등록하려고 하는 경우.
<p>[2203] 이미 다른 사용자가 사용 중인 전화번호로 신규 회원을 등록하려고 하는 경우.
"""
)
@ApiResponse(responseCode = "409", content = @Content, description = """
<p>[2200] 이미 다른 사용자가 사용 중인 이메일로 신규 회원을 등록하려고 하는 경우.
<p>[2203] 이미 다른 사용자가 사용 중인 전화번호로 신규 회원을 등록하려고 하는 경우.
""")
})
@PostMapping(headers = API_MINOR_VERSION_HEADER_NAME + "=" + 1)
public ResponseEntity<UserResponse> signUpV1_1(
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/com/ajou/hertz/domain/user/dto/UserDto.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.ajou.hertz.domain.user.dto;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Set;

import com.ajou.hertz.domain.user.constant.Gender;
Expand All @@ -25,6 +26,7 @@ public class UserDto {
private Gender gender;
private String phone;
private String contactLink;
private LocalDateTime createdAt;

public static UserDto from(User user) {
return new UserDto(
Expand All @@ -37,7 +39,8 @@ public static UserDto from(User user) {
user.getBirth(),
user.getGender(),
user.getPhone(),
user.getContactLink()
user.getContactLink(),
user.getCreatedAt()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,52 @@
package com.ajou.hertz.domain.user.dto.response;

import java.time.LocalDate;
import java.time.LocalDateTime;

import com.ajou.hertz.domain.user.constant.Gender;
import com.ajou.hertz.domain.user.dto.UserDto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class UserResponse {

@Schema(description = "Id of user", example = "1")
private Long id;

@Schema(description = "이메일", example = "[email protected]")
private String email;

@Schema(description = "프로필 이미지 url", example = "https://user-profile-image")
private String profileImageUrl;

@Schema(description = "생년월일")
private LocalDate birth;

@Schema(description = "성별")
private Gender gender;

@Schema(description = "연락 수단")
private String contactLink;

@Schema(description = "계정 생성일자 (가입일)")
private LocalDateTime createdAt;

public static UserResponse from(UserDto userDto) {
return new UserResponse(
userDto.getId(),
userDto.getEmail(),
userDto.getProfileImageUrl(),
userDto.getBirth(),
userDto.getGender(),
userDto.getContactLink()
userDto.getContactLink(),
userDto.getCreatedAt()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.ajou.hertz.domain.user.dto.response;

import java.time.LocalDate;
import java.time.LocalDateTime;

import org.springframework.util.StringUtils;

import com.ajou.hertz.domain.user.constant.Gender;
import com.ajou.hertz.domain.user.dto.UserDto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public class UserWithLinkedAccountInfoResponse extends UserResponse {

@Schema(description = "카카오 계정 연동 여부", example = "true")
private Boolean isKakaoAccountLinked;

private UserWithLinkedAccountInfoResponse(
Long id,
String email,
String profileImageUrl,
LocalDate birth,
Gender gender,
String contactLink,
LocalDateTime createdAt,
Boolean isKakaoAccountLinked
) {
super(id, email, profileImageUrl, birth, gender, contactLink, createdAt);
this.isKakaoAccountLinked = isKakaoAccountLinked;
}

public static UserWithLinkedAccountInfoResponse from(UserDto userDto) {
return new UserWithLinkedAccountInfoResponse(
userDto.getId(),
userDto.getEmail(),
userDto.getProfileImageUrl(),
userDto.getBirth(),
userDto.getGender(),
userDto.getContactLink(),
userDto.getCreatedAt(),
StringUtils.hasText(userDto.getKakaoUid())
);
}
}
7 changes: 5 additions & 2 deletions src/test/java/com/ajou/hertz/config/TestSecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.lang.reflect.Constructor;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Set;

import org.springframework.boot.test.context.TestConfiguration;
Expand Down Expand Up @@ -46,7 +47,8 @@ public void securitySetUp() throws Exception {
private UserDto createUserDto() throws Exception {
Constructor<UserDto> userResponseConstructor = UserDto.class.getDeclaredConstructor(
Long.class, Set.class, String.class, String.class, String.class,
String.class, LocalDate.class, Gender.class, String.class, String.class
String.class, LocalDate.class, Gender.class, String.class, String.class,
LocalDateTime.class
);
userResponseConstructor.setAccessible(true);
return userResponseConstructor.newInstance(
Expand All @@ -59,7 +61,8 @@ private UserDto createUserDto() throws Exception {
LocalDate.of(2024, 1, 1),
Gender.ETC,
"01012345678",
"https://contack-link"
"https://contack-link",
LocalDateTime.of(2024, 1, 1, 0, 0)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ private JwtTokenInfoDto createJwtTokenInfoDto() {
private UserDto createUserDto(long id) throws Exception {
Constructor<UserDto> userResponseConstructor = UserDto.class.getDeclaredConstructor(
Long.class, Set.class, String.class, String.class, String.class,
String.class, LocalDate.class, Gender.class, String.class, String.class
String.class, LocalDate.class, Gender.class, String.class, String.class,
LocalDateTime.class
);
userResponseConstructor.setAccessible(true);
return userResponseConstructor.newInstance(
Expand All @@ -122,7 +123,8 @@ private UserDto createUserDto(long id) throws Exception {
LocalDate.of(2024, 1, 1),
Gender.ETC,
"01012345678",
"https://contack-link"
"https://contack-link",
LocalDateTime.of(2024, 1, 1, 0, 0)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ private void verifyEveryMocksShouldHaveNoMoreInteractions() {
private UserDto createUserDto(long id) throws Exception {
Constructor<UserDto> userResponseConstructor = UserDto.class.getDeclaredConstructor(
Long.class, Set.class, String.class, String.class, String.class,
String.class, LocalDate.class, Gender.class, String.class, String.class
String.class, LocalDate.class, Gender.class, String.class, String.class,
LocalDateTime.class
);
userResponseConstructor.setAccessible(true);
return userResponseConstructor.newInstance(
Expand All @@ -153,7 +154,8 @@ private UserDto createUserDto(long id) throws Exception {
LocalDate.of(2024, 1, 1),
Gender.ETC,
"01012345678",
"https://contack-link"
"https://contack-link",
LocalDateTime.of(2024, 1, 1, 0, 0)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import static com.ajou.hertz.common.constant.GlobalConstants.*;
import static org.mockito.BDDMockito.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import java.lang.reflect.Constructor;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Set;

import org.junit.jupiter.api.DisplayName;
Expand All @@ -17,6 +19,7 @@
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext;
import org.springframework.http.MediaType;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.test.context.event.annotation.BeforeTestMethod;
import org.springframework.test.web.servlet.MockMvc;

Expand All @@ -26,6 +29,7 @@
import com.ajou.hertz.common.auth.JwtAuthenticationFilter;
import com.ajou.hertz.common.auth.JwtExceptionFilter;
import com.ajou.hertz.common.auth.JwtTokenProvider;
import com.ajou.hertz.common.auth.UserPrincipal;
import com.ajou.hertz.common.config.SecurityConfig;
import com.ajou.hertz.domain.user.constant.Gender;
import com.ajou.hertz.domain.user.constant.RoleType;
Expand Down Expand Up @@ -71,6 +75,25 @@ public void securitySetUp() throws Exception {
given(userQueryService.getDtoById(anyLong())).willReturn(createUserDto());
}

@Test
void 내_정보를_조회한다() throws Exception {
// given
long userId = 1L;
UserDto expectedResult = createUserDto(userId);
given(userQueryService.getDtoById(userId)).willReturn(expectedResult);

// when & then
mvc.perform(
get("/v1/users/me")
.header(API_MINOR_VERSION_HEADER_NAME, 1)
.with(user(createTestUser(userId)))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(expectedResult.getId()));
then(userQueryService).should().getDtoById(userId);
verifyEveryMocksShouldHaveNoMoreInteractions();
}

@Test
void 이메일이_주어지고_주어진_이메일을_사용_중인_회원의_존재_여부를_조회한다() throws Exception {
// given
Expand Down Expand Up @@ -219,7 +242,8 @@ private SignUpRequest createSignUpRequest() throws Exception {
private UserDto createUserDto(long id) throws Exception {
Constructor<UserDto> userResponseConstructor = UserDto.class.getDeclaredConstructor(
Long.class, Set.class, String.class, String.class, String.class,
String.class, LocalDate.class, Gender.class, String.class, String.class
String.class, LocalDate.class, Gender.class, String.class, String.class,
LocalDateTime.class
);
userResponseConstructor.setAccessible(true);
return userResponseConstructor.newInstance(
Expand All @@ -232,11 +256,16 @@ private UserDto createUserDto(long id) throws Exception {
LocalDate.of(2024, 1, 1),
Gender.ETC,
"01012345678",
"https://contack-link"
"https://contack-link",
LocalDateTime.of(2024, 1, 1, 0, 0)
);
}

private UserDto createUserDto() throws Exception {
return createUserDto(1L);
}

private UserDetails createTestUser(Long userId) throws Exception {
return new UserPrincipal(createUserDto(userId));
}
}

0 comments on commit 0178082

Please sign in to comment.