Skip to content

Commit

Permalink
Merge pull request #124 from depromeet/feature/94-member-update
Browse files Browse the repository at this point in the history
feat: νšŒμ› 이름 μˆ˜μ • API κ΅¬ν˜„
  • Loading branch information
ywonchae1 authored Jul 31, 2024
2 parents 4d5f08a + afa37c7 commit 9d10d89
Show file tree
Hide file tree
Showing 21 changed files with 285 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ public Member updateGoal(Integer goal) {
this.goal = goal;
return this;
}

public Member updateName(String name) {
this.name = name;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.depromeet.member.port.in.usecase;

import com.depromeet.member.domain.Member;

public interface NameUpdateUseCase {
Member updateName(Long memberId, String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public interface MemberPersistencePort {
void updateRefresh(Long memberId, String refreshToken);

Optional<Member> updateGoal(Long memberId, Integer goal);

Optional<Member> updateName(Long memberId, String name);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.depromeet.member.service;

import com.depromeet.exception.BadRequestException;
import com.depromeet.exception.InternalServerException;
import com.depromeet.exception.NotFoundException;
import com.depromeet.member.domain.Member;
import com.depromeet.member.domain.MemberRole;
import com.depromeet.member.port.in.command.SocialMemberCommand;
import com.depromeet.member.port.in.usecase.GoalUpdateUseCase;
import com.depromeet.member.port.in.usecase.MemberUseCase;
import com.depromeet.member.port.in.usecase.NameUpdateUseCase;
import com.depromeet.member.port.out.persistence.MemberPersistencePort;
import com.depromeet.type.member.MemberErrorType;
import lombok.RequiredArgsConstructor;
Expand All @@ -16,7 +18,7 @@
@Service
@Transactional
@RequiredArgsConstructor
public class MemberService implements MemberUseCase, GoalUpdateUseCase {
public class MemberService implements MemberUseCase, GoalUpdateUseCase, NameUpdateUseCase {
private final MemberPersistencePort memberPersistencePort;

@Override
Expand Down Expand Up @@ -49,4 +51,14 @@ public Member updateGoal(Long memberId, Integer goal) {
.updateGoal(memberId, goal)
.orElseThrow(() -> new InternalServerException(MemberErrorType.UPDATE_GOAL_FAILED));
}

@Override
public Member updateName(Long memberId, String name) {
if (name == null || name.isBlank()) {
throw new BadRequestException(MemberErrorType.NAME_CANNOT_BE_BLANK);
}
return memberPersistencePort
.updateName(memberId, name)
.orElseThrow(() -> new InternalServerException(MemberErrorType.UPDATE_NAME_FAILED));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,15 @@ public Optional<Member> updateGoal(Long memberId, Integer goal) {
return member;
});
}

@Override
public Optional<Member> updateName(Long memberId, String name) {
return findById(memberId)
.map(
item -> {
Member member = item.updateName(name);
save(member);
return member;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.depromeet.service;

import com.depromeet.member.domain.Member;
import com.depromeet.member.domain.MemberRole;
import com.depromeet.member.port.out.persistence.MemberPersistencePort;
import com.depromeet.member.service.MemberService;
import com.depromeet.mock.FakeMemberRepository;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class MemberServiceTest {
private MemberPersistencePort fakeMemberRepository;

private MemberService memberService;

private Long userId = 1L;
private Member member;

@BeforeEach
void init() {
fakeMemberRepository = new FakeMemberRepository();

// Member create
member =
Member.builder()
.id(userId)
.name("member1")
.email("[email protected]")
.role(MemberRole.USER)
.build();
fakeMemberRepository.save(member);

memberService = new MemberService(fakeMemberRepository);
}

@Test
void νšŒμ›μ˜_이름을_μˆ˜μ •ν• _수_μžˆλ‹€() {
// given
Long memberId = 1L;
String newName = "ν…ŒμŠ€νŠΈ";

// when
Member member1 = memberService.updateName(memberId, newName);

// then
Assertions.assertThat(member1.getName()).isEqualTo(newName);
}

@Test
void νšŒμ›μ˜_이름은_곡백을_ν—ˆμš©ν•˜μ§€_μ•ŠλŠ”λ‹€() {
// given
Long memberId = 1L;
String newName = "";

// when

// then
Assertions.assertThatThrownBy(() -> memberService.updateName(memberId, newName))
.hasMessage("λ©€λ²„μ˜ 이름은 곡백이 ν—ˆμš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

public enum MemberErrorType implements ErrorType {
NOT_FOUND("MEMBER_1", "멀버가 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€"),
UPDATE_GOAL_FAILED("MEMBER_2", "λ©€λ²„μ˜ λͺ©ν‘œ μˆ˜μ •μ— μ‹€νŒ¨ν•˜μ˜€μŠ΅λ‹ˆλ‹€");
UPDATE_GOAL_FAILED("MEMBER_2", "λ©€λ²„μ˜ λͺ©ν‘œ μˆ˜μ •μ— μ‹€νŒ¨ν•˜μ˜€μŠ΅λ‹ˆλ‹€"),
UPDATE_NAME_FAILED("MEMBER_3", "λ©€λ²„μ˜ 이름 μˆ˜μ •μ— μ‹€νŒ¨ν•˜μ˜€μŠ΅λ‹ˆλ‹€"),
NAME_CANNOT_BE_BLANK("MEMBER_4", "λ©€λ²„μ˜ 이름은 곡백이 ν—ˆμš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€");

private final String code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
public enum MemberSuccessType implements SuccessType {
GET_SUCCESS("MEMBER_1", "멀버 μ‘°νšŒμ— μ„±κ³΅ν•˜μ˜€μŠ΅λ‹ˆλ‹€"),
UPDATE_GOAL_SUCCESS("MEMBER_2", "멀버 λͺ©ν‘œ μˆ˜μ •μ— μ„±κ³΅ν•˜μ˜€μŠ΅λ‹ˆλ‹€"),
GET_GOAL_SUCCESS("MEMBER_3", "멀버 λͺ©ν‘œ μ‘°νšŒμ— μ„±κ³΅ν•˜μ˜€μŠ΅λ‹ˆλ‹€");
GET_GOAL_SUCCESS("MEMBER_3", "멀버 λͺ©ν‘œ μ‘°νšŒμ— μ„±κ³΅ν•˜μ˜€μŠ΅λ‹ˆλ‹€"),
UPDATE_NAME_SUCCESS("MEMBER_4", "멀버 이름 μˆ˜μ •μ— μ„±κ³΅ν•˜μ˜€μŠ΅λ‹ˆλ‹€");

private final String code;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,9 @@ public MemberEntity updateGoal(Integer goal) {
this.goal = goal;
return this;
}

public MemberEntity updateName(String name) {
this.name = name;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,11 @@ public Optional<Member> updateGoal(Long memberId, Integer goal) {
.findById(memberId)
.map(memberEntity -> memberEntity.updateGoal(goal).toModel());
}

@Override
public Optional<Member> updateName(Long memberId, String name) {
return memberJpaRepository
.findById(memberId)
.map(memberEntity -> memberEntity.updateName(name).toModel());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic
MemberDto memberDto =
MemberDto.builder()
.id(member.getId())
.name(nickname)
.email(email)
.name(member.getName())
.email(member.getEmail())
.memberRole(member.getRole())
.build();
return new CustomOAuth2User(memberDto);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class AuthFacade {
private final MemberUseCase memberUseCase;
private final SocialUseCase socialUseCase;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
package com.depromeet.member.api;

import com.depromeet.dto.response.ApiResponse;
import com.depromeet.member.annotation.LoginMember;
import com.depromeet.member.dto.request.NameUpdateRequest;
import com.depromeet.member.dto.response.MemberFindOneResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;

@Tag(name = "μ‚¬μš©μž(members)")
public interface MemberApi {
@Operation(summary = "id둜 member 단일 검색")
ApiResponse<MemberFindOneResponse> getMember(@PathVariable("id") Long id);

@Operation(summary = "λ‹‰λ„€μž„ μˆ˜μ •")
ApiResponse<MemberFindOneResponse> updateName(
@LoginMember Long memberId, @Valid @RequestBody NameUpdateRequest updateNameRequest);
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
package com.depromeet.member.api;

import com.depromeet.dto.response.ApiResponse;
import com.depromeet.member.annotation.LoginMember;
import com.depromeet.member.domain.Member;
import com.depromeet.member.dto.request.NameUpdateRequest;
import com.depromeet.member.dto.response.MemberFindOneResponse;
import com.depromeet.member.port.in.usecase.MemberUseCase;
import com.depromeet.member.facade.MemberFacade;
import com.depromeet.type.member.MemberSuccessType;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/member")
public class MemberController implements MemberApi {
private final MemberUseCase memberUseCase;
private final MemberFacade memberFacade;

@GetMapping("/{id}")
public ApiResponse<MemberFindOneResponse> getMember(@PathVariable("id") Long id) {
Member member = memberUseCase.findById(id);
Member member = memberFacade.findById(id);
return ApiResponse.success(MemberSuccessType.GET_SUCCESS, MemberFindOneResponse.of(member));
}

@PatchMapping
public ApiResponse<MemberFindOneResponse> updateName(
@LoginMember Long memberId, @Valid @RequestBody NameUpdateRequest updateNameRequest) {
Member member = memberFacade.updateName(memberId, updateNameRequest.name());
return ApiResponse.success(
MemberSuccessType.UPDATE_NAME_SUCCESS, MemberFindOneResponse.of(member));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.depromeet.member.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

@Schema(name = "이름 μˆ˜μ • 정보 μž…λ ₯")
public record NameUpdateRequest(@NotBlank String name) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.depromeet.member.facade;

import com.depromeet.member.domain.Member;
import com.depromeet.member.port.in.command.SocialMemberCommand;
import com.depromeet.member.port.in.usecase.MemberUseCase;
import com.depromeet.member.port.in.usecase.NameUpdateUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MemberFacade {
private final MemberUseCase memberUseCase;
private final NameUpdateUseCase nameUpdateUseCase;

public Member findById(Long memberId) {
return memberUseCase.findById(memberId);
}

public Member findOrCreateMemberBy(SocialMemberCommand command) {
return memberUseCase.findOrCreateMemberBy(command);
}

public Member updateName(Long memberId, String name) {
return nameUpdateUseCase.updateName(memberId, name);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.depromeet.memory.config;
package com.depromeet.config;

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;
Expand Down
Loading

0 comments on commit 9d10d89

Please sign in to comment.