Skip to content

Commit

Permalink
feat: 회원 프로필 업데이트 작업 (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
yeongchan1228 authored Sep 15, 2023
1 parent 92348f9 commit 16e2ac9
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 8 deletions.
6 changes: 6 additions & 0 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ operation::auth-rest-controller-test/user-valid-nickname-duplication[snippets='h

operation::user-rest-controller-test/user-get-info-success[snippets='http-request,request-headers,http-response,response-fields']

== *2. 사용자 프로필 변경 API*

=== *2-1* 성공

operation::user-rest-controller-test/user-update-profile-success[snippets='http-request,request-headers,request-parts,http-response']

[[Family-API]]
= *Family API*

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.polzzak.domain.user.controller;

import org.springframework.http.MediaType;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.polzzak.domain.user.dto.MemberResponse;
import com.polzzak.domain.user.service.UserService;
Expand All @@ -24,4 +28,15 @@ public UserRestController(final UserService userService) {
public ResponseEntity<ApiResponse<MemberResponse>> getMemberInfo(final @LoginId Long memberId) {
return ResponseEntity.ok(ApiResponse.ok(userService.getMemberResponse(memberId)));
}

@PatchMapping(path = "/profile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<ApiResponse<MemberResponse>> updateUserProfile(
final @LoginId Long memberId,
final @RequestPart("profile") MultipartFile profile
) {
final String profileKey = userService.uploadProfile(profile);
final String prevProfileKey = userService.updateMemberProfile(memberId, profileKey);
userService.deleteProfile(prevProfileKey);
return ResponseEntity.noContent().build();
}
}
4 changes: 4 additions & 0 deletions src/main/java/com/polzzak/domain/user/entity/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,8 @@ public boolean isKid() {
public boolean isGuardian() {
return memberType.isGuardianType();
}

public void changeProfileKey(final String profileKey) {
this.profileKey = profileKey;
}
}
18 changes: 18 additions & 0 deletions src/main/java/com/polzzak/domain/user/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.polzzak.domain.family.repository.FamilyMapRepository;
import com.polzzak.domain.memberpoint.entity.MemberPoint;
Expand All @@ -11,6 +12,7 @@
import com.polzzak.domain.user.entity.Member;
import com.polzzak.domain.user.repository.MemberRepository;
import com.polzzak.domain.user.repository.UserRepository;
import com.polzzak.global.common.FileType;
import com.polzzak.global.exception.ErrorCode;
import com.polzzak.global.exception.PolzzakException;
import com.polzzak.global.infra.file.FileClient;
Expand Down Expand Up @@ -81,6 +83,22 @@ public Member findMemberByMemberIdWithMemberType(final Long memberId) {
.orElseThrow(() -> new IllegalArgumentException("사용자가 존재하지 않습니다"));
}

@Transactional
public String updateMemberProfile(final Long memberId, final String profileKey) {
final Member member = findMemberByMemberId(memberId);
final String prevProfileKey = member.getProfileKey();
member.changeProfileKey(profileKey);
return prevProfileKey;
}

public String uploadProfile(final MultipartFile profile) {
return fileClient.uploadFile(profile, FileType.PROFILE_IMAGE);
}

public void deleteProfile(final String prevProfileKey) {
fileClient.deleteFile(prevProfileKey);
}

private int getFamilyCount(final Member requestMember) {
if (requestMember.isKid()) {
return familyMapRepository.countByKidId(requestMember.getId());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
package com.polzzak.domain.user.controller;

import static com.polzzak.support.TokenFixtures.*;
import static com.polzzak.support.UserFixtures.*;
import static org.mockito.Mockito.*;
import static org.springframework.restdocs.headers.HeaderDocumentation.*;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static com.polzzak.support.TokenFixtures.TOKEN_TYPE;
import static com.polzzak.support.TokenFixtures.USER_ACCESS_TOKEN;
import static com.polzzak.support.UserFixtures.MEMBER_RESPONSE;
import static com.polzzak.support.UserFixtures.TEST_MEMBER_ID;
import static com.polzzak.support.UserFixtures.TEST_PREV_PROFILE_KEY;
import static com.polzzak.support.UserFixtures.TEST_PROFILE;
import static com.polzzak.support.UserFixtures.TEST_PROFILE_KEY;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
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.mockmvc.RestDocumentationRequestBuilders.multipart;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.request.RequestDocumentation.partWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParts;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import com.polzzak.domain.user.service.UserService;
import com.polzzak.support.test.ControllerTestHelper;
Expand Down Expand Up @@ -53,4 +66,33 @@ class UserRestControllerTest extends ControllerTestHelper {
)
);
}

@Test
void 사용자_프로필_변경_성공() throws Exception {
when(userService.uploadProfile(any())).thenReturn(TEST_PROFILE_KEY);
when(userService.updateMemberProfile(TEST_MEMBER_ID, TEST_PROFILE_KEY)).thenReturn(TEST_PREV_PROFILE_KEY);
doNothing().when(userService).deleteProfile(TEST_PREV_PROFILE_KEY);
mockMvc.perform(
multipart("/api/v1/users/profile")
.file(TEST_PROFILE)
.contentType(MediaType.MULTIPART_FORM_DATA)
.header(HttpHeaders.AUTHORIZATION, TOKEN_TYPE + USER_ACCESS_TOKEN)
.with(request -> {
request.setMethod("PATCH");
return request;
})
)
.andExpect(status().isNoContent())
.andDo(
document(
"{class-name}/user-update-profile-success",
requestHeaders(
headerWithName(HttpHeaders.AUTHORIZATION).description("엑세스 토큰")
),
requestParts(
partWithName("profile").description("수정할 사용자 프로필")
)
)
);
}
}
2 changes: 2 additions & 0 deletions src/test/java/com/polzzak/support/UserFixtures.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class UserFixtures {
public static final Long TEST_TARGET_MEMBER_ID = 1L;
public static final String TEST_USERNAME = "username";
public static final String TEST_NICKNAME = "nickname";
public static final String TEST_PROFILE_KEY = "testProfileKey";
public static final String TEST_PREV_PROFILE_KEY = "testPrevProfileKey";
public static final String TEST_PROFILE_URL = "profileUrl";
public static final String TEST_OAUTH_ACCESS_TOKEN = "oAuthAccessToken";
public static final String TEST_USER_ROLE = UserRole.ROLE_USER.name();
Expand Down

0 comments on commit 16e2ac9

Please sign in to comment.