Skip to content

Commit

Permalink
refactor: 행사 참여 인원 이름 변경 api 수정 (#268)
Browse files Browse the repository at this point in the history
* refactor: 회원 이름 변경 api 여러명으로 추가

* style: 메소드 순서 변경
  • Loading branch information
Arachneee authored Aug 9, 2024
1 parent 97fc7fb commit 1feb2d6
Show file tree
Hide file tree
Showing 13 changed files with 256 additions and 105 deletions.
11 changes: 10 additions & 1 deletion server/src/docs/asciidoc/event.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ operation::updateEventMemberName[snippets="path-parameters,http-request,request-
[source,json,options="nowrap"]
----
[
{
"code":"MEMBER_NAME_CHANGE_DUPLICATE",
"message":"중복된 참여 인원 이름 변경 요청이 존재합니다."
},
{
"code":"MEMBER_NOT_EXIST",
"message":"현재 참여하고 있지 않는 인원이 존재합니다."
},
{
"code":"REQUEST_EMPTY",
"message":"멤버 이름은 공백일 수 없습니다."
Expand All @@ -128,7 +137,7 @@ operation::updateEventMemberName[snippets="path-parameters,http-request,request-
},
{
"code":"TOKEN_EXPIRED",
"message":"토큰이 존재하지 않습니다."
"message":"만료된 토큰입니다."
},
{
"code":"TOKEN_INVALID",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import server.haengdong.application.request.EventAppRequest;
import server.haengdong.application.request.EventLoginAppRequest;
import server.haengdong.application.request.MemberUpdateAppRequest;
import server.haengdong.application.request.MemberNameUpdateAppRequest;
import server.haengdong.application.request.MemberNamesUpdateAppRequest;
import server.haengdong.application.response.ActionAppResponse;
import server.haengdong.application.response.EventAppResponse;
import server.haengdong.application.response.EventDetailAppResponse;
Expand Down Expand Up @@ -100,22 +102,55 @@ public MembersAppResponse findAllMembers(String token) {
}

@Transactional
public void updateMember(String token, String memberName, MemberUpdateAppRequest request) {
public void updateMember(String token, MemberNamesUpdateAppRequest request) {
Event event = getEvent(token);
String updatedMemberName = request.name();
validateMemberNameUnique(event, updatedMemberName);
List<MemberNameUpdateAppRequest> members = request.members();

memberActionRepository.findAllByAction_EventAndMemberName(event, memberName)
.forEach(memberAction -> memberAction.updateMemberName(updatedMemberName));
validateBeforeNames(members, event);
validateAfterNames(members, event);

members.forEach(member -> updateMemberName(event, member.before(), member.after()));
}

private void validateBeforeNames(List<MemberNameUpdateAppRequest> members, Event event) {
List<String> beforeNames = members.stream()
.map(MemberNameUpdateAppRequest::before)
.toList();
if (beforeNames.size() != Set.copyOf(beforeNames).size()) {
throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_CHANGE_DUPLICATE);
}
beforeNames.forEach(beforeName -> validateBeforeMemberNameExist(event, beforeName));
}

private void validateBeforeMemberNameExist(Event event, String beforeName) {
boolean isMemberNameExist = memberActionRepository.existsByAction_EventAndMemberName(event, beforeName);
if (!isMemberNameExist) {
throw new HaengdongException(HaengdongErrorCode.MEMBER_NOT_EXIST);
}
}

private void validateAfterNames(List<MemberNameUpdateAppRequest> members, Event event) {
List<String> afterNames = members.stream()
.map(MemberNameUpdateAppRequest::after)
.toList();
if (afterNames.size() != Set.copyOf(afterNames).size()) {
throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_CHANGE_DUPLICATE);
}
afterNames.forEach(afterName -> validateAfterMemberNameNotExist(event, afterName));
}

private void validateMemberNameUnique(Event event, String updatedMemberName) {
boolean isMemberNameExist = memberActionRepository.existsByAction_EventAndMemberName(event, updatedMemberName);
private void validateAfterMemberNameNotExist(Event event, String afterName) {
boolean isMemberNameExist = memberActionRepository.existsByAction_EventAndMemberName(event, afterName);
if (isMemberNameExist) {
throw new HaengdongException(HaengdongErrorCode.MEMBER_NAME_DUPLICATE);
}
}

private void updateMemberName(Event event, String beforeName, String afterName) {
memberActionRepository.findAllByAction_EventAndMemberName(event, beforeName)
.forEach(memberAction -> memberAction.updateMemberName(afterName));
}

public void validatePassword(EventLoginAppRequest request) throws HaengdongException {
Event event = getEvent(request.token());
if (event.isSamePassword(request.password())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package server.haengdong.application.request;

public record MemberNameUpdateAppRequest(
String before,
String after
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package server.haengdong.application.request;

import java.util.List;

public record MemberNamesUpdateAppRequest(
List<MemberNameUpdateAppRequest> members
) {
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public enum HaengdongErrorCode {
MEMBER_NAME_DUPLICATE("중복된 행사 참여 인원 이름이 존재합니다."),
MEMBER_NOT_EXIST("현재 참여하고 있지 않는 인원이 존재합니다."),
MEMBER_ALREADY_EXIST("현재 참여하고 있는 인원이 존재합니다."),
MEMBER_NAME_CHANGE_DUPLICATE("중복된 참여 인원 이름 변경 요청이 존재합니다."),

MEMBER_ACTION_NOT_FOUND("존재하지 않는 멤버 액션입니다."),
MEMBER_ACTION_STATUS_INVALID("멤버 액션은 IN, OUT만 가능합니다. 입력한 멤버 액션: %s"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import server.haengdong.infrastructure.auth.CookieProperties;
import server.haengdong.presentation.request.EventLoginRequest;
import server.haengdong.presentation.request.EventSaveRequest;
import server.haengdong.presentation.request.MemberUpdateRequest;
import server.haengdong.presentation.request.MemberNamesUpdateRequest;
import server.haengdong.presentation.response.EventDetailResponse;
import server.haengdong.presentation.response.EventResponse;
import server.haengdong.presentation.response.MembersResponse;
Expand Down Expand Up @@ -69,13 +69,12 @@ public ResponseEntity<MembersResponse> findAllMembers(@PathVariable("eventId") S
return ResponseEntity.ok(response);
}

@PutMapping("/api/events/{eventId}/members/{memberName}")
@PutMapping("/api/events/{eventId}/members/nameChange")
public ResponseEntity<Void> updateMember(
@PathVariable("eventId") String token,
@PathVariable("memberName") String memberName,
@Valid @RequestBody MemberUpdateRequest request
@Valid @RequestBody MemberNamesUpdateRequest request
) {
eventService.updateMember(token, memberName, request.toAppRequest());
eventService.updateMember(token, request.toAppRequest());

return ResponseEntity.ok().build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package server.haengdong.presentation.request;

import jakarta.validation.constraints.NotBlank;
import server.haengdong.application.request.MemberNameUpdateAppRequest;

public record MemberNameUpdateRequest(

@NotBlank(message = "멤버 이름은 공백일 수 없습니다.")
String before,

@NotBlank(message = "멤버 이름은 공백일 수 없습니다.")
String after
) {

public MemberNameUpdateAppRequest toAppRequest() {
return new MemberNameUpdateAppRequest(before, after);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package server.haengdong.presentation.request;

import jakarta.validation.Valid;
import java.util.List;
import server.haengdong.application.request.MemberNamesUpdateAppRequest;

public record MemberNamesUpdateRequest(
@Valid List<MemberNameUpdateRequest> members
) {

public MemberNamesUpdateAppRequest toAppRequest() {
return new MemberNamesUpdateAppRequest(members.stream()
.map(MemberNameUpdateRequest::toAppRequest)
.toList());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import server.haengdong.application.request.EventAppRequest;
import server.haengdong.application.request.MemberUpdateAppRequest;
import server.haengdong.application.request.MemberNameUpdateAppRequest;
import server.haengdong.application.request.MemberNamesUpdateAppRequest;
import server.haengdong.application.response.ActionAppResponse;
import server.haengdong.application.response.EventAppResponse;
import server.haengdong.application.response.EventDetailAppResponse;
Expand Down Expand Up @@ -119,7 +120,7 @@ void findAllMembersTest() {
assertThat(membersAppResponse.memberNames()).containsExactlyInAnyOrder("토다리", "쿠키");
}

@DisplayName("행사 참여 인원의 이름을 변경한다.")
@DisplayName("행사 참여 인원들의 이름을 변경한다.")
@Test
void updateMember() {
Event event = Fixture.EVENT1;
Expand All @@ -134,13 +135,16 @@ void updateMember() {
memberAction1, memberAction2, memberAction3, memberAction4, memberAction5, memberAction6
));

eventService.updateMember(event.getToken(), "쿠키", new MemberUpdateAppRequest("쿡쿡"));
eventService.updateMember(event.getToken(), new MemberNamesUpdateAppRequest(List.of(
new MemberNameUpdateAppRequest("쿠키", "쿡쿡"),
new MemberNameUpdateAppRequest("토다리", "토쟁이")
)));

List<MemberAction> foundMemberActions = memberActionRepository.findAllByEvent(event);
assertThat(foundMemberActions)
.extracting(MemberAction::getId, MemberAction::getMemberName)
.contains(
tuple(memberAction1.getId(), "토다리"),
tuple(memberAction1.getId(), "토쟁이"),
tuple(memberAction2.getId(), "쿡쿡"),
tuple(memberAction3.getId(), "웨디"),
tuple(memberAction4.getId(), "쿡쿡"),
Expand All @@ -149,7 +153,7 @@ void updateMember() {
);
}

@DisplayName("참여 인원 이름을 이미 존재하는 행사 참여 인원과 동일한 이름으로 변경할 수 없다.")
@DisplayName("이미 존재하는 인원의 이름으로 변경할 수 없다.")
@Test
void updateMember1() {
Event event = Fixture.EVENT1;
Expand All @@ -159,7 +163,69 @@ void updateMember1() {
eventRepository.save(event);
memberActionRepository.saveAll(List.of(memberAction1, memberAction2, memberAction3));

assertThatThrownBy(() -> eventService.updateMember(event.getToken(), "쿠키", new MemberUpdateAppRequest("토다리")))
MemberNamesUpdateAppRequest appRequest = new MemberNamesUpdateAppRequest(List.of(
new MemberNameUpdateAppRequest("쿠키", "쿡쿡"),
new MemberNameUpdateAppRequest("웨디", "토다리")
));

assertThatThrownBy(() -> eventService.updateMember(event.getToken(), appRequest))
.isInstanceOf(HaengdongException.class);
}

@DisplayName("존재하지 않는 인원은 변경할 수 없다.")
@Test
void updateMember2() {
Event event = Fixture.EVENT1;
MemberAction memberAction1 = new MemberAction(new Action(event, 1L), "토다리", IN, 1L);
MemberAction memberAction2 = new MemberAction(new Action(event, 2L), "쿠키", IN, 1L);
MemberAction memberAction3 = new MemberAction(new Action(event, 3L), "웨디", IN, 2L);
eventRepository.save(event);
memberActionRepository.saveAll(List.of(memberAction1, memberAction2, memberAction3));

MemberNamesUpdateAppRequest appRequest = new MemberNamesUpdateAppRequest(List.of(
new MemberNameUpdateAppRequest("쿡쿡", "토쟁이"),
new MemberNameUpdateAppRequest("웨디", "말복")
));

assertThatThrownBy(() -> eventService.updateMember(event.getToken(), appRequest))
.isInstanceOf(HaengdongException.class);
}

@DisplayName("변경 전 참여 인원 이름이 중복될 수 없다.")
@Test
void updateMember3() {
Event event = Fixture.EVENT1;
MemberAction memberAction1 = new MemberAction(new Action(event, 1L), "토다리", IN, 1L);
MemberAction memberAction2 = new MemberAction(new Action(event, 2L), "쿠키", IN, 1L);
MemberAction memberAction3 = new MemberAction(new Action(event, 3L), "웨디", IN, 2L);
eventRepository.save(event);
memberActionRepository.saveAll(List.of(memberAction1, memberAction2, memberAction3));

MemberNamesUpdateAppRequest appRequest = new MemberNamesUpdateAppRequest(List.of(
new MemberNameUpdateAppRequest("쿠키", "쿡쿡"),
new MemberNameUpdateAppRequest("쿠키", "토쟁이")
));

assertThatThrownBy(() -> eventService.updateMember(event.getToken(), appRequest))
.isInstanceOf(HaengdongException.class);
}

@DisplayName("변경 후 참여 인원 이름이 중복될 수 없다.")
@Test
void updateMember4() {
Event event = Fixture.EVENT1;
MemberAction memberAction1 = new MemberAction(new Action(event, 1L), "토다리", IN, 1L);
MemberAction memberAction2 = new MemberAction(new Action(event, 2L), "쿠키", IN, 1L);
MemberAction memberAction3 = new MemberAction(new Action(event, 3L), "웨디", IN, 2L);
eventRepository.save(event);
memberActionRepository.saveAll(List.of(memberAction1, memberAction2, memberAction3));

MemberNamesUpdateAppRequest appRequest = new MemberNamesUpdateAppRequest(List.of(
new MemberNameUpdateAppRequest("쿠키", "쿡쿡"),
new MemberNameUpdateAppRequest("토다리", "쿡쿡")
));

assertThatThrownBy(() -> eventService.updateMember(event.getToken(), appRequest))
.isInstanceOf(HaengdongException.class);
}
}
Loading

0 comments on commit 1feb2d6

Please sign in to comment.