Skip to content

Commit

Permalink
이벤트 수정 API 추가 (#275)
Browse files Browse the repository at this point in the history
  • Loading branch information
Juhongseok authored Nov 24, 2023
1 parent 67efd5f commit 79bb59b
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 17 deletions.
11 changes: 11 additions & 0 deletions src/docs/asciidoc/mentor.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ include::{snippets}/event/create/request-fields.adoc[]
include::{snippets}/event/create/http-response.adoc[]
include::{snippets}/event/create/response-fields.adoc[]

=== 첨삭 이벤트 수정

*Request*
include::{snippets}/event/update/http-request.adoc[]
include::{snippets}/event/update/request-fields.adoc[]
include::{snippets}/event/update/path-parameters.adoc[]

*Response*
include::{snippets}/event/update/http-response.adoc[]
include::{snippets}/event/update/response-fields.adoc[]

=== 첨삭 이벤트 조회

*Request*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
import org.devcourse.resumeme.business.event.controller.dto.EventPageResponse;
import org.devcourse.resumeme.business.event.controller.dto.EventRejectRequest;
import org.devcourse.resumeme.business.event.controller.dto.EventResponse;
import org.devcourse.resumeme.business.event.controller.dto.EventUpdateRequest;
import org.devcourse.resumeme.business.event.domain.Event;
import org.devcourse.resumeme.business.event.domain.EventPosition;
import org.devcourse.resumeme.business.event.service.EventPositionService;
import org.devcourse.resumeme.business.event.service.EventService;
import org.devcourse.resumeme.business.event.service.vo.AllEventFilter;
import org.devcourse.resumeme.business.event.service.vo.EventReject;
import org.devcourse.resumeme.business.event.service.vo.EventUpdateVo;
import org.devcourse.resumeme.business.user.domain.mentor.Mentor;
import org.devcourse.resumeme.business.user.service.mentor.MentorService;
import org.devcourse.resumeme.common.response.IdResponse;
Expand Down Expand Up @@ -53,6 +55,14 @@ public IdResponse createEvent(@RequestBody EventCreateRequest request, @Authenti
return new IdResponse(eventService.create(event));
}

@PatchMapping("/{eventId}")
public IdResponse updateEvent(@RequestBody EventUpdateRequest request, @PathVariable Long eventId) {
EventUpdateVo updateVo = request.toVo(eventId);
eventService.update(updateVo);

return new IdResponse(eventId);
}

@PatchMapping("/{eventId}/mentee/{menteeId}")
public void rejectApply(@PathVariable Long eventId, @PathVariable Long menteeId, @RequestBody EventRejectRequest request) {
eventService.reject(new EventReject(eventId, menteeId, request.rejectMessage()));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.devcourse.resumeme.business.event.controller.dto;

import org.devcourse.resumeme.business.event.service.vo.EventUpdateVo;
import org.devcourse.resumeme.common.domain.Position;

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

import static org.devcourse.resumeme.common.util.Validator.notNull;

public record EventUpdateRequest(EventInfoRequest info, EventTimeRequest time, List<String> positions) {

public EventUpdateVo toVo(Long eventId) {
notNull(positions);
List<Position> positionEntities = positions.stream()
.map(position -> Position.valueOf(position.toUpperCase()))
.toList();

return new EventUpdateVo(eventId, info.title, info.content, info().maximumAttendee, positionEntities,
time.openDateTime, time.closeDateTime, time.endDate);
}

public record EventInfoRequest(String title, String content, int maximumAttendee) {

}

public record EventTimeRequest(LocalDateTime openDateTime, LocalDateTime closeDateTime, LocalDateTime endDate) {

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import static lombok.AccessLevel.PROTECTED;
import static org.devcourse.resumeme.business.event.domain.EventStatus.FINISH;
import static org.devcourse.resumeme.common.util.Validator.notNull;
import static org.devcourse.resumeme.global.exception.ExceptionCode.APPLICATION_NOT_FOUND;
import static org.devcourse.resumeme.global.exception.ExceptionCode.DUPLICATED_EVENT_OPEN;
import static org.devcourse.resumeme.global.exception.ExceptionCode.DUPLICATE_APPLICATION_EVENT;
import static org.devcourse.resumeme.global.exception.ExceptionCode.MENTEE_NOT_FOUND;
Expand Down Expand Up @@ -134,16 +133,6 @@ public void openReservationEvent(LocalDateTime nowDateTime) {
eventInfo.open();
}

public Long getApplicantId(Long menteeId) {
for (MenteeToEvent applicant : applicants) {
if (applicant.isSameMentee(menteeId)) {
return applicant.getId();
}
}

throw new EventException(APPLICATION_NOT_FOUND);
}

public Mentor getMentor() {
return mentor;
}
Expand Down Expand Up @@ -199,4 +188,27 @@ public int compareTo(Event other) {
return eventTimeInfo.getOpenDateTime().compareTo(other.eventTimeInfo.getOpenDateTime());
}

public void updateInfo(String title, String content, int maximumAttendee) {
this.eventInfo.update(title, content, maximumAttendee);
}

public void updatePosition(List<Position> positions) {
for (int i = 0; i < this.positions.size(); i++) {
this.positions.remove(i--);
}

List<EventPosition> newPositions = getNewPosition(positions);
this.positions.addAll(newPositions);
}

private List<EventPosition> getNewPosition(List<Position> positions) {
return new ArrayList<>(positions.stream()
.map(position -> new EventPosition(position, this))
.toList());
}

public void updateTimeInfo(LocalDateTime openDateTime, LocalDateTime closeDateTime, LocalDateTime endDateTime) {
this.eventTimeInfo.update(openDateTime, closeDateTime, endDateTime);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,12 @@ public boolean isOpen() {
return this.status.isOpen();
}

public void update(String title, String content, int maximumAttendee) {
validateInput(maximumAttendee, title, content);

this.title = title;
this.content = content;
this.maximumAttendee = maximumAttendee;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,12 @@ public boolean isAfterOpenTime(LocalDateTime nowDateTime) {
return nowDateTime.isAfter(this.openDateTime);
}

public void update(LocalDateTime openDateTime, LocalDateTime closeDateTime, LocalDateTime endDateTime) {
validateInput(openDateTime, closeDateTime, endDateTime);

this.openDateTime = openDateTime;
this.closeDateTime = closeDateTime;
this.endDate = endDateTime;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.devcourse.resumeme.business.event.service.vo.AcceptMenteeToEvent;
import org.devcourse.resumeme.business.event.service.vo.AllEventFilter;
import org.devcourse.resumeme.business.event.service.vo.EventReject;
import org.devcourse.resumeme.business.event.service.vo.EventUpdateVo;
import org.devcourse.resumeme.global.exception.CustomException;
import org.devcourse.resumeme.global.exception.ExceptionCode;
import org.springframework.data.domain.Page;
Expand Down Expand Up @@ -121,4 +122,9 @@ public String getOverallReview(Event event, Long resumeId) {
.getOverallReview();
}

public void update(EventUpdateVo updateVo) {
Event event = getOne(updateVo.getEventId());
updateVo.update(event);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.devcourse.resumeme.business.event.service.vo;

import lombok.Getter;
import org.devcourse.resumeme.business.event.domain.Event;
import org.devcourse.resumeme.common.domain.Position;

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

@Getter
public class EventUpdateVo {

private final Long eventId;

private String title;

private String content;

private int maximumAttendee;

private final List<Position> positions;

private final LocalDateTime openDateTime;

private final LocalDateTime closeDateTime;

private final LocalDateTime endDateTime;

public EventUpdateVo(Long eventId, String title, String content, int maximumAttendee, List<Position> positions,
LocalDateTime openDateTime, LocalDateTime closeDateTime, LocalDateTime endDateTime) {
this.eventId = eventId;
this.title = title;
this.content = content;
this.maximumAttendee = maximumAttendee;
this.positions = positions;
this.openDateTime = openDateTime;
this.closeDateTime = closeDateTime;
this.endDateTime = endDateTime;
}

public void update(Event event) {
event.updateInfo(title, content, maximumAttendee);
event.updatePosition(positions);
event.updateTimeInfo(openDateTime, closeDateTime, endDateTime);
}

}
6 changes: 3 additions & 3 deletions src/main/resources/application-endpoint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ endpoint:
role: all
- matcher:
get: /api/v1/mentees/*, /api/v1/user, /api/v1/resumes, /api/v1/results, /api/v1/mentees/*/events, /api/v1/snapshot
post: /api/v1/resumes, /api/v1/results, /api/v1/pdf/resumes/*, /api/v1/resumes/*/**
patch: /api/v1/mentees/*, /api/v1/events/*, /api/v1/resumes/*, /api/v1/resumes/*/**
post: /api/v1/resumes, /api/v1/results, /api/v1/pdf/resumes/*, /api/v1/resumes/*/**, /api/v1/appliments/events/*
patch: /api/v1/mentees/*, /api/v1/resumes/*, /api/v1/resumes/*/**
role: mentee
- matcher:
get: /api/v1/mentors/*, /api/v1/mentees/*, /api/v1/user, /api/v1/resumes/**, /api/v1/results, /api/v1/mentors/*/events
Expand All @@ -21,7 +21,7 @@ endpoint:
- matcher:
get: /api/v1/events/*/resumes/*/comments
post: /api/v1/events/*/resumes/*/comments
patch: /api/v1/events/*/mentee/**, /api/v1/events/*/resumes/**, /api/v1/events/*/resumes/*/comments/*, /api/v2/events/*
patch: /api/v1/events/*/mentee/**, /api/v1/events/*/resumes/**, /api/v1/events/*/resumes/*/comments/*, /api/v1/appliments/events/*, /api/v1/events/*
delete: /api/v1/events/*/resumes/*/comments/*
role: own_mentor
- matcher:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package org.devcourse.resumeme.business.event.controller;

import org.devcourse.resumeme.business.event.controller.dto.ApplyToEventRequest;
import org.devcourse.resumeme.business.event.controller.dto.CompleteEventRequest;
import org.devcourse.resumeme.business.event.controller.dto.EventCreateRequest;
import org.devcourse.resumeme.business.event.controller.dto.EventCreateRequest.EventInfoRequest;
import org.devcourse.resumeme.business.event.controller.dto.EventCreateRequest.EventTimeRequest;
import org.devcourse.resumeme.business.event.controller.dto.EventRejectRequest;
import org.devcourse.resumeme.business.event.controller.dto.EventUpdateRequest;
import org.devcourse.resumeme.business.event.domain.Event;
import org.devcourse.resumeme.business.event.domain.EventInfo;
import org.devcourse.resumeme.business.event.domain.EventPosition;
import org.devcourse.resumeme.business.event.domain.EventTimeInfo;
import org.devcourse.resumeme.business.event.domain.MenteeToEvent;
import org.devcourse.resumeme.business.event.service.vo.AcceptMenteeToEvent;
import org.devcourse.resumeme.business.event.service.vo.AllEventFilter;
import org.devcourse.resumeme.business.event.service.vo.EventReject;
import org.devcourse.resumeme.business.event.service.vo.EventUpdateVo;
import org.devcourse.resumeme.business.resume.domain.Resume;
import org.devcourse.resumeme.business.user.domain.Provider;
import org.devcourse.resumeme.business.user.domain.Role;
Expand Down Expand Up @@ -157,6 +156,53 @@ void setUp() {
);
}

@Test
@WithMockCustomUser
void 첨삭_이벤트_수정에_성공한다() throws Exception {
// given
EventUpdateRequest.EventTimeRequest eventTimeRequest = new EventUpdateRequest.EventTimeRequest(
LocalDateTime.of(2023, 10, 23, 12, 0),
LocalDateTime.of(2023, 10, 24, 12, 0),
LocalDateTime.of(2023, 10, 30, 23, 0)
);
EventUpdateRequest.EventInfoRequest eventInfoRequest = new EventUpdateRequest.EventInfoRequest("title", "content", 3);
EventUpdateRequest eventUpdateRequest = new EventUpdateRequest(eventInfoRequest, eventTimeRequest, List.of("BACK", "FRONT"));
/* 로그인 기능 완료 후 멘토 주입 값 추후 변경 예정 */
EventUpdateVo vo = eventUpdateRequest.toVo(1L);

doNothing().when(eventService).update(vo);

// when
ResultActions result = mvc.perform(patch("/api/v1/events/{eventId}", 1L)
.contentType(MediaType.APPLICATION_JSON)
.content(toJson(eventUpdateRequest)));

// then
result
.andExpect(status().isOk())
.andDo(
document("event/update",
getDocumentRequest(),
getDocumentResponse(),
pathParameters(
parameterWithName("eventId").description("수정할 이벤트 아이디")
),
requestFields(
fieldWithPath("info.title").type(STRING).description("첨삭 이벤트 제목"),
fieldWithPath("info.content").type(STRING).description("첨삭 이벤트 내용"),
fieldWithPath("info.maximumAttendee").type(NUMBER).description("최대 첨삭 이벤트 참여 가능 멘티 인원"),
fieldWithPath("time.openDateTime").type(STRING).description("첨삭 이벤트 신청 오픈 시간").optional().attributes(constraints("이벤트 오픈 예약 시 필수")),
fieldWithPath("time.closeDateTime").type(STRING).description("첨삭 이벤트 신청 마감 시간").attributes(constraints("오픈 시간보다 느리게")),
fieldWithPath("time.endDate").type(STRING).description("첨삭 종료 시간").optional().attributes(constraints("마감 시간보다 늦어야 함")),
fieldWithPath("positions").type(ARRAY).description(generateLinkCode(POSITION))
),
responseFields(
fieldWithPath("id").type(NUMBER).description("생성된 첨삭 이벤트 아이디")
)
)
);
}

@Test
void 첨삭_이벤트_신청을_반려한다() throws Exception {
// given
Expand Down

0 comments on commit 79bb59b

Please sign in to comment.