diff --git a/backend/emm-sale/src/docs/asciidoc/index.adoc b/backend/emm-sale/src/docs/asciidoc/index.adoc index da7e10a12..a1ab36ae5 100644 --- a/backend/emm-sale/src/docs/asciidoc/index.adoc +++ b/backend/emm-sale/src/docs/asciidoc/index.adoc @@ -133,6 +133,14 @@ include::{snippets}/participate-event/http-request.adoc[] .HTTP response include::{snippets}/participate-event/http-response.adoc[] +=== `DELETE` : 컨퍼런스에 함께가기 요청 취소(컨퍼런스에 함께 가는 멤버에서 삭제) + +.HTTP request +include::{snippets}/participate-event-cancel/http-request.adoc[] + +.HTTP response +include::{snippets}/participate-event-cancel/http-response.adoc[] + === `GET`: 행사 목록 조회 .HTTP request diff --git a/backend/emm-sale/src/main/java/com/emmsale/event/api/EventApi.java b/backend/emm-sale/src/main/java/com/emmsale/event/api/EventApi.java index 3781f1fb8..3398a4663 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/event/api/EventApi.java +++ b/backend/emm-sale/src/main/java/com/emmsale/event/api/EventApi.java @@ -46,17 +46,24 @@ public ResponseEntity participateEvent( @RequestBody final EventParticipateRequest request, final Member member ) { - final Long participantId = eventService.participate( - eventId, - request.getMemberId(), - member - ); + final Long participantId = eventService.participate(eventId, request.getMemberId(), member); return ResponseEntity .created(create(format("/events/%s/participants/%s", eventId, participantId))) .build(); } + @DeleteMapping("/{eventId}/participants") + public ResponseEntity cancelParticipateEvent( + @PathVariable final Long eventId, + @RequestBody final EventParticipateRequest request, + final Member member + ) { + eventService.cancelParticipate(eventId, request.getMemberId(), member); + + return ResponseEntity.noContent().build(); + } + @GetMapping("/{id}/participants") public ResponseEntity> findParticipants(@PathVariable final Long id) { final List responses = eventService.findParticipants(id); diff --git a/backend/emm-sale/src/main/java/com/emmsale/event/application/EventService.java b/backend/emm-sale/src/main/java/com/emmsale/event/application/EventService.java index b1713d577..f8d9da25e 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/event/application/EventService.java +++ b/backend/emm-sale/src/main/java/com/emmsale/event/application/EventService.java @@ -74,6 +74,21 @@ public Long participate(final Long eventId, final Long memberId, final Member me return participant.getId(); } + public void cancelParticipate(final Long eventId, final Long memberId, final Member member) { + validateMemberNotAllowed(memberId, member); + if (!eventRepository.existsById(eventId)) { + throw new EventException(NOT_FOUND_EVENT); + } + + participantRepository + .findByMemberIdAndEventId(memberId, eventId) + .ifPresentOrElse( + participant -> participantRepository.deleteById(participant.getId()), + () -> { + throw new EventException(EventExceptionType.NOT_FOUND_PARTICIPANT); + }); + } + @Transactional(readOnly = true) public List findEvents(final EventType categoryName, final LocalDate nowDate, final Integer year, final Integer month, diff --git a/backend/emm-sale/src/main/java/com/emmsale/event/domain/repository/ParticipantRepository.java b/backend/emm-sale/src/main/java/com/emmsale/event/domain/repository/ParticipantRepository.java index fa5f5e606..d0cf2b299 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/event/domain/repository/ParticipantRepository.java +++ b/backend/emm-sale/src/main/java/com/emmsale/event/domain/repository/ParticipantRepository.java @@ -1,10 +1,12 @@ package com.emmsale.event.domain.repository; import com.emmsale.event.domain.Participant; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface ParticipantRepository extends JpaRepository { + Optional findByMemberIdAndEventId(final Long memberId, final Long eventId); } diff --git a/backend/emm-sale/src/main/java/com/emmsale/event/exception/EventExceptionType.java b/backend/emm-sale/src/main/java/com/emmsale/event/exception/EventExceptionType.java index 0a6311e87..abd9b9623 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/event/exception/EventExceptionType.java +++ b/backend/emm-sale/src/main/java/com/emmsale/event/exception/EventExceptionType.java @@ -9,6 +9,7 @@ public enum EventExceptionType implements BaseExceptionType { NOT_FOUND_EVENT(HttpStatus.NOT_FOUND, "해당하는 행사를 찾을 수 없습니다."), FORBIDDEN_PARTICIPATE_EVENT(HttpStatus.FORBIDDEN, "참가하려는 사용자와 로그인된 사용자가 다릅니다."), + NOT_FOUND_PARTICIPANT(HttpStatus.NOT_FOUND, "해당 행사에 등록되지 않은 사용자입니다."), ALREADY_PARTICIPATED(HttpStatus.BAD_REQUEST, "이미 참가신청한 멤버입니다."), INVALID_STATUS( HttpStatus.BAD_REQUEST, diff --git a/backend/emm-sale/src/main/resources/http/event.http b/backend/emm-sale/src/main/resources/http/event.http index 9e366bc7e..c055e3041 100644 --- a/backend/emm-sale/src/main/resources/http/event.http +++ b/backend/emm-sale/src/main/resources/http/event.http @@ -35,5 +35,14 @@ Authorization: bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaWF0IjoxNjkwMTk2OTY5L "memberId": 1 } +### Event 참여자 목록에서 멤버 삭제 +DELETE http://localhost:8080/events/1/participants +Content-Type: application/json +Authorization: bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaWF0IjoxNjkwMTk2OTY5LCJleHAiOjE2OTM3OTY5Njl9.yahaEBvKBA7xelNuykx8TROhemnzJAsu1Sv5rrSfCM0 + +{ + "memberId": 1 +} + ### 행사 참여자 목록 조회 GET http://localhost:8080/events/1/participants diff --git a/backend/emm-sale/src/test/java/com/emmsale/event/api/EventApiTest.java b/backend/emm-sale/src/test/java/com/emmsale/event/api/EventApiTest.java index d034d44e2..85e0aef82 100644 --- a/backend/emm-sale/src/test/java/com/emmsale/event/api/EventApiTest.java +++ b/backend/emm-sale/src/test/java/com/emmsale/event/api/EventApiTest.java @@ -117,6 +117,28 @@ void participateEvent() throws Exception { .andDo(document("participate-event", requestFields)); } + @Test + @DisplayName("Event에 사용자를 참여자 목록에서 제거할 수 있다.") + void cancelParticipateEvent() throws Exception { + //given + final Long eventId = 1L; + final Long memberId = 2L; + final EventParticipateRequest request = new EventParticipateRequest(memberId); + final String fakeAccessToken = "Bearer accessToken"; + + final RequestFieldsSnippet requestFields = requestFields( + fieldWithPath("memberId").type(JsonFieldType.NUMBER).description("멤버 식별자") + ); + + //when + mockMvc.perform(delete(format("/events/%s/participants", eventId)) + .header("Authorization", fakeAccessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isNoContent()) + .andDo(document("participate-event-cancel", requestFields)); + } + @Test @DisplayName("특정 카테고리의 행사 목록을 조회할 수 있으면 200 OK를 반환한다.") void findEvents() throws Exception { diff --git a/backend/emm-sale/src/test/java/com/emmsale/event/application/EventServiceTest.java b/backend/emm-sale/src/test/java/com/emmsale/event/application/EventServiceTest.java index d10dc650d..d7be4eadc 100644 --- a/backend/emm-sale/src/test/java/com/emmsale/event/application/EventServiceTest.java +++ b/backend/emm-sale/src/test/java/com/emmsale/event/application/EventServiceTest.java @@ -16,6 +16,7 @@ import static com.emmsale.event.exception.EventExceptionType.INVALID_YEAR; import static com.emmsale.event.exception.EventExceptionType.INVALID_YEAR_AND_MONTH; import static com.emmsale.event.exception.EventExceptionType.NOT_FOUND_EVENT; +import static com.emmsale.event.exception.EventExceptionType.NOT_FOUND_PARTICIPANT; import static com.emmsale.event.exception.EventExceptionType.NOT_FOUND_TAG; import static com.emmsale.event.exception.EventExceptionType.START_DATE_TIME_AFTER_END_DATE_TIME; import static com.emmsale.tag.TagFixture.AI; @@ -37,8 +38,10 @@ import com.emmsale.event.domain.Event; import com.emmsale.event.domain.EventTag; import com.emmsale.event.domain.EventType; +import com.emmsale.event.domain.Participant; import com.emmsale.event.domain.repository.EventRepository; import com.emmsale.event.domain.repository.EventTagRepository; +import com.emmsale.event.domain.repository.ParticipantRepository; import com.emmsale.event.exception.EventException; import com.emmsale.helper.ServiceIntegrationTestHelper; import com.emmsale.member.domain.Member; @@ -51,6 +54,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.junit.jupiter.api.BeforeEach; @@ -92,6 +96,8 @@ class EventServiceTest extends ServiceIntegrationTestHelper { @Autowired private EventTagRepository eventTagRepository; @Autowired + private ParticipantRepository participantRepository; + @Autowired private TagRepository tagRepository; @BeforeEach @@ -221,6 +227,65 @@ void fail_alreadyParticipate() { } } + @Nested + @DisplayName("event 참가자 목록에서 멤버를 삭제할 수 있다.") + class CancelParticipate { + + @Test + @DisplayName("정상적으로 멤버를 삭제한다.") + void cancelParticipate_success() { + //given + final Long memberId = 1L; + final Member member = memberRepository.findById(memberId).get(); + final Event 인프콘 = eventRepository.save(eventFixture()); + + final Long participantId = eventService.participate(인프콘.getId(), memberId, member); + + // when + eventService.cancelParticipate(인프콘.getId(), memberId, member); + final Optional actual = participantRepository.findById(participantId); + + // then + assertThat(actual).isEmpty(); + } + + @Test + @DisplayName("존재하지 않는 행사면 예외가 발생한다.") + void cancelParticipate_not_found_event() { + // given + final Long memberId = 1L; + final Member member = memberRepository.findById(memberId).get(); + + final Long invalidEventId = 999L; + + // when + final ThrowingCallable actual = () -> eventService.cancelParticipate(invalidEventId, memberId, + member); + + // then + assertThatThrownBy(actual).isInstanceOf(EventException.class) + .hasMessage(NOT_FOUND_EVENT.errorMessage()); + } + + @Test + @DisplayName("존재하지 않는 참여자면 예외가 발생한다.") + void cancelParticipate_not_found_participant() { + // given + final Long memberId = 1L; + final Member member = memberRepository.findById(memberId).get(); + + final Long eventId = eventRepository.save(eventFixture()).getId(); + + // when + final ThrowingCallable actual = () -> eventService.cancelParticipate(eventId, memberId, + member); + + // then + assertThatThrownBy(actual).isInstanceOf(EventException.class) + .hasMessage(NOT_FOUND_PARTICIPANT.errorMessage()); + } + } + @Nested @DisplayName("findEvents() : 행사 목록 조회") class findEvents { @@ -458,285 +523,286 @@ void findEvents_status_filter_fail() { .isInstanceOf(EventException.class) .hasMessage(INVALID_STATUS.errorMessage()); } + } + + @Nested + class AddEvent { - @Nested - class AddEvent { + final List tagRequests = List.of( + new TagRequest(IOS().getName()), + new TagRequest(AI().getName()) + ); + private final LocalDateTime beforeDateTime = LocalDateTime.now(); + private final LocalDateTime afterDateTime = beforeDateTime.plusDays(1); + private final String eventName = "새로운 이름"; + private final String eventLocation = "새로운 장소"; + private final String eventInformationUrl = "https://새로운-상세-URL.com"; + private final String imageUrl = "https://image.com"; + private final EventType type = EventType.CONFERENCE; + private final LocalDate now = LocalDate.now(); + @Test + @DisplayName("이벤트를 성공적으로 저장한다.") + void addEventTest() { + //given + final EventDetailRequest request = new EventDetailRequest( + eventName, + eventLocation, + eventInformationUrl, + beforeDateTime, + afterDateTime, + tagRequests, + imageUrl, + type + ); + + //when + final EventDetailResponse response = eventService.addEvent(request, now); + final Event savedEvent = eventRepository.findById(response.getId()).get(); + + //then + assertAll( + () -> assertEquals(eventName, savedEvent.getName()), + () -> assertEquals(eventLocation, savedEvent.getLocation()), + () -> assertEquals(eventInformationUrl, savedEvent.getInformationUrl()), + () -> assertEquals(beforeDateTime, savedEvent.getStartDate()), + () -> assertEquals(afterDateTime, savedEvent.getEndDate()), + () -> assertThat(savedEvent.getTags()).extracting("tag", Tag.class) + .extracting("name", String.class) + .containsAll( + tagRequests.stream() + .map(TagRequest::getName) + .collect(Collectors.toList()) + ) + ); + } + + @Test + @DisplayName("행사 시작 일시가 행사 종료 일시 이후일 경우 EventException이 발생한다.") + void addEventWithStartDateTimeAfterBeforeDateTimeTest() { + //given + final LocalDateTime startDateTime = afterDateTime; + final LocalDateTime endDatetime = beforeDateTime; + + final EventDetailRequest request = new EventDetailRequest( + eventName, + eventLocation, + eventInformationUrl, + startDateTime, + endDatetime, + tagRequests, + imageUrl, + type + ); + + //when & then + final EventException exception = assertThrowsExactly(EventException.class, + () -> eventService.addEvent(request, now)); + + assertEquals(exception.exceptionType(), + START_DATE_TIME_AFTER_END_DATE_TIME); + } + + @Test + @DisplayName("Tag가 존재하지 않을 경우 EventException이 발생한다.") + void addEventWithNotExistTagTest() { + //given final List tagRequests = List.of( - new TagRequest(IOS().getName()), - new TagRequest(AI().getName()) + new TagRequest(백엔드().getName()), + new TagRequest(안드로이드().getName()), + new TagRequest("존재하지 않는 태그") + ); + + final EventDetailRequest request = new EventDetailRequest( + eventName, + eventLocation, + eventInformationUrl, + beforeDateTime, + afterDateTime, + tagRequests, + imageUrl, + type + ); + + //when & then + final EventException exception = assertThrowsExactly(EventException.class, + () -> eventService.addEvent(request, now)); + + assertEquals(exception.exceptionType(), + NOT_FOUND_TAG); + } + } + + @Nested + class UpdateEvent { + + final List newTagRequests = List.of( + new TagRequest(IOS().getName()), + new TagRequest(AI().getName()) + ); + private final LocalDateTime beforeDateTime = LocalDateTime.now(); + private final LocalDateTime afterDateTime = beforeDateTime.plusDays(1); + private final String newName = "새로운 이름"; + private final String newLocation = "새로운 장소"; + private final String newInformationUrl = "https://새로운-상세-URL.com"; + private final String imageUrl = "https://image.com"; + private final LocalDate now = LocalDate.now(); + + @Test + @DisplayName("이벤트를 성공적으로 업데이트한다.") + void updateEventTest() { + //given + final LocalDateTime newStartDateTime = beforeDateTime; + final LocalDateTime newEndDateTime = afterDateTime; + + final EventDetailRequest updateRequest = new EventDetailRequest( + newName, + newLocation, + newInformationUrl, + beforeDateTime, + afterDateTime, + newTagRequests, + imageUrl, + EventType.CONFERENCE + ); + + final Event event = eventRepository.save(인프콘_2023()); + final Long eventId = event.getId(); + + //when + eventService.updateEvent(eventId, updateRequest, now); + final Event updatedEvent = eventRepository.findById(eventId).get(); + + //then + assertAll( + () -> assertEquals(newName, updatedEvent.getName()), + () -> assertEquals(newLocation, updatedEvent.getLocation()), + () -> assertEquals(newStartDateTime, updatedEvent.getStartDate()), + () -> assertEquals(newEndDateTime, updatedEvent.getEndDate()), + () -> assertEquals(newInformationUrl, updatedEvent.getInformationUrl()), + () -> assertThat(updatedEvent.getTags()) + .extracting("tag", Tag.class) + .extracting("name", String.class) + .containsAll( + newTagRequests.stream() + .map(TagRequest::getName) + .collect(Collectors.toList()) + ) + ); + } + + @Test + @DisplayName("업데이트할 이벤트가 존재하지 않을 경우 EventException이 발생한다.") + void updateEventWithNotExistsEventTest() { + //given + final long notExistsEventId = 0L; + + final EventDetailRequest updateRequest = new EventDetailRequest( + newName, + newLocation, + newInformationUrl, + beforeDateTime, + afterDateTime, + newTagRequests, + imageUrl, + EventType.CONFERENCE + ); + + //when & then + final EventException exception = assertThrowsExactly(EventException.class, + () -> eventService.updateEvent(notExistsEventId, updateRequest, now)); + + assertEquals(exception.exceptionType(), NOT_FOUND_EVENT); + } + + @Test + @DisplayName("행사 시작 일시가 행사 종료 일시 이후일 경우 EventException이 발생한다.") + void updateEventWithStartDateTimeAfterBeforeDateTimeTest() { + //given + final LocalDateTime newStartDateTime = afterDateTime; + final LocalDateTime newEndDateTime = beforeDateTime; + + final EventDetailRequest updateRequest = new EventDetailRequest( + newName, + newLocation, + newInformationUrl, + newStartDateTime, + newEndDateTime, + newTagRequests, + imageUrl, + EventType.CONFERENCE ); - private final LocalDateTime beforeDateTime = LocalDateTime.now(); - private final LocalDateTime afterDateTime = beforeDateTime.plusDays(1); - private final String eventName = "새로운 이름"; - private final String eventLocation = "새로운 장소"; - private final String eventInformationUrl = "https://새로운-상세-URL.com"; - private final String imageUrl = "https://image.com"; - private final EventType type = EventType.CONFERENCE; - private final LocalDate now = LocalDate.now(); - - @Test - @DisplayName("이벤트를 성공적으로 저장한다.") - void addEventTest() { - //given - final EventDetailRequest request = new EventDetailRequest( - eventName, - eventLocation, - eventInformationUrl, - beforeDateTime, - afterDateTime, - tagRequests, - imageUrl, - type - ); - - //when - final EventDetailResponse response = eventService.addEvent(request, now); - final Event savedEvent = eventRepository.findById(response.getId()).get(); - - //then - assertAll( - () -> assertEquals(eventName, savedEvent.getName()), - () -> assertEquals(eventLocation, savedEvent.getLocation()), - () -> assertEquals(eventInformationUrl, savedEvent.getInformationUrl()), - () -> assertEquals(beforeDateTime, savedEvent.getStartDate()), - () -> assertEquals(afterDateTime, savedEvent.getEndDate()), - () -> assertThat(savedEvent.getTags()).extracting("tag", Tag.class) - .extracting("name", String.class) - .containsAll( - tagRequests.stream() - .map(TagRequest::getName) - .collect(Collectors.toList()) - ) - ); - } - - @Test - @DisplayName("행사 시작 일시가 행사 종료 일시 이후일 경우 EventException이 발생한다.") - void addEventWithStartDateTimeAfterBeforeDateTimeTest() { - //given - final LocalDateTime startDateTime = afterDateTime; - final LocalDateTime endDatetime = beforeDateTime; - - final EventDetailRequest request = new EventDetailRequest( - eventName, - eventLocation, - eventInformationUrl, - startDateTime, - endDatetime, - tagRequests, - imageUrl, - type - ); - - //when & then - final EventException exception = assertThrowsExactly(EventException.class, - () -> eventService.addEvent(request, now)); - - assertEquals(exception.exceptionType(), - START_DATE_TIME_AFTER_END_DATE_TIME); - } - - @Test - @DisplayName("Tag가 존재하지 않을 경우 EventException이 발생한다.") - void addEventWithNotExistTagTest() { - //given - final List tagRequests = List.of( - new TagRequest(백엔드().getName()), - new TagRequest(안드로이드().getName()), - new TagRequest("존재하지 않는 태그") - ); - - final EventDetailRequest request = new EventDetailRequest( - eventName, - eventLocation, - eventInformationUrl, - beforeDateTime, - afterDateTime, - tagRequests, - imageUrl, - type - ); - - //when & then - final EventException exception = assertThrowsExactly(EventException.class, - () -> eventService.addEvent(request, now)); - - assertEquals(exception.exceptionType(), - NOT_FOUND_TAG); - } - } - - @Nested - class UpdateEvent { + final Event event = eventRepository.save(인프콘_2023()); + final Long eventId = event.getId(); + + //when & then + final EventException exception = assertThrowsExactly(EventException.class, + () -> eventService.updateEvent(eventId, updateRequest, now)); + + assertEquals(exception.exceptionType(), START_DATE_TIME_AFTER_END_DATE_TIME); + } + + @Test + @DisplayName("Tag가 존재하지 않을 경우 EventException이 발생한다.") + void updateEventWithNotExistTagTest() { + //given final List newTagRequests = List.of( - new TagRequest(IOS().getName()), - new TagRequest(AI().getName()) + new TagRequest("존재하지 않는 태그") ); - private final LocalDateTime beforeDateTime = LocalDateTime.now(); - private final LocalDateTime afterDateTime = beforeDateTime.plusDays(1); - private final String newName = "새로운 이름"; - private final String newLocation = "새로운 장소"; - private final String newInformationUrl = "https://새로운-상세-URL.com"; - private final String imageUrl = "https://image.com"; - private final LocalDate now = LocalDate.now(); - - @Test - @DisplayName("이벤트를 성공적으로 업데이트한다.") - void updateEventTest() { - //given - final LocalDateTime newStartDateTime = beforeDateTime; - final LocalDateTime newEndDateTime = afterDateTime; - - final EventDetailRequest updateRequest = new EventDetailRequest( - newName, - newLocation, - newInformationUrl, - beforeDateTime, - afterDateTime, - newTagRequests, - imageUrl, - EventType.CONFERENCE - ); - - final Event event = eventRepository.save(인프콘_2023()); - final Long eventId = event.getId(); - - //when - eventService.updateEvent(eventId, updateRequest, now); - final Event updatedEvent = eventRepository.findById(eventId).get(); - - //then - assertAll( - () -> assertEquals(newName, updatedEvent.getName()), - () -> assertEquals(newLocation, updatedEvent.getLocation()), - () -> assertEquals(newStartDateTime, updatedEvent.getStartDate()), - () -> assertEquals(newEndDateTime, updatedEvent.getEndDate()), - () -> assertEquals(newInformationUrl, updatedEvent.getInformationUrl()), - () -> assertThat(updatedEvent.getTags()) - .extracting("tag", Tag.class) - .extracting("name", String.class) - .containsAll( - newTagRequests.stream() - .map(TagRequest::getName) - .collect(Collectors.toList()) - ) - ); - } - - @Test - @DisplayName("업데이트할 이벤트가 존재하지 않을 경우 EventException이 발생한다.") - void updateEventWithNotExistsEventTest() { - //given - final long notExistsEventId = 0L; - - final EventDetailRequest updateRequest = new EventDetailRequest( - newName, - newLocation, - newInformationUrl, - beforeDateTime, - afterDateTime, - newTagRequests, - imageUrl, - EventType.CONFERENCE - ); - - //when & then - final EventException exception = assertThrowsExactly(EventException.class, - () -> eventService.updateEvent(notExistsEventId, updateRequest, now)); - - assertEquals(exception.exceptionType(), NOT_FOUND_EVENT); - } - - @Test - @DisplayName("행사 시작 일시가 행사 종료 일시 이후일 경우 EventException이 발생한다.") - void updateEventWithStartDateTimeAfterBeforeDateTimeTest() { - //given - final LocalDateTime newStartDateTime = afterDateTime; - final LocalDateTime newEndDateTime = beforeDateTime; - - final EventDetailRequest updateRequest = new EventDetailRequest( - newName, - newLocation, - newInformationUrl, - newStartDateTime, - newEndDateTime, - newTagRequests, - imageUrl, - EventType.CONFERENCE - ); - - final Event event = eventRepository.save(인프콘_2023()); - final Long eventId = event.getId(); - - //when & then - final EventException exception = assertThrowsExactly(EventException.class, - () -> eventService.updateEvent(eventId, updateRequest, now)); - - assertEquals(exception.exceptionType(), START_DATE_TIME_AFTER_END_DATE_TIME); - } - - @Test - @DisplayName("Tag가 존재하지 않을 경우 EventException이 발생한다.") - void updateEventWithNotExistTagTest() { - //given - final List newTagRequests = List.of( - new TagRequest("존재하지 않는 태그") - ); - - final EventDetailRequest updateRequest = new EventDetailRequest( - newName, - newLocation, - newInformationUrl, - beforeDateTime, - afterDateTime, - newTagRequests, - imageUrl, - EventType.CONFERENCE - ); - - final Event event = eventRepository.save(인프콘_2023()); - final Long eventId = event.getId(); - - //when & then - final EventException exception = assertThrowsExactly(EventException.class, - () -> eventService.updateEvent(eventId, updateRequest, now)); - - assertEquals(exception.exceptionType(), NOT_FOUND_TAG); - } - } - - @Nested - class DeleteEvent { - - @Test - @DisplayName("이벤트를 성공적으로 삭제한다.") - void deleteEventTest() { - //given - final Event event = eventRepository.save(인프콘_2023()); - final Long eventId = event.getId(); - - //when - eventService.deleteEvent(eventId); - - //then - assertFalse(eventRepository.findById(eventId).isPresent()); - } - - @Test - @DisplayName("삭제할 이벤트가 존재하지 않을 경우 EventException이 발생한다.") - void deleteEventWithNotExistsEventTest() { - //given - final long notExistsEventId = 0L; - - //when & then - final EventException exception = assertThrowsExactly(EventException.class, - () -> eventService.deleteEvent(notExistsEventId)); - - assertEquals(exception.exceptionType(), NOT_FOUND_EVENT); - } + + final EventDetailRequest updateRequest = new EventDetailRequest( + newName, + newLocation, + newInformationUrl, + beforeDateTime, + afterDateTime, + newTagRequests, + imageUrl, + EventType.CONFERENCE + ); + + final Event event = eventRepository.save(인프콘_2023()); + final Long eventId = event.getId(); + + //when & then + final EventException exception = assertThrowsExactly(EventException.class, + () -> eventService.updateEvent(eventId, updateRequest, now)); + + assertEquals(exception.exceptionType(), NOT_FOUND_TAG); } + } + + @Nested + class DeleteEvent { + @Test + @DisplayName("이벤트를 성공적으로 삭제한다.") + void deleteEventTest() { + //given + final Event event = eventRepository.save(인프콘_2023()); + final Long eventId = event.getId(); + + //when + eventService.deleteEvent(eventId); + + //then + assertFalse(eventRepository.findById(eventId).isPresent()); + } + + @Test + @DisplayName("삭제할 이벤트가 존재하지 않을 경우 EventException이 발생한다.") + void deleteEventWithNotExistsEventTest() { + //given + final long notExistsEventId = 0L; + + //when & then + final EventException exception = assertThrowsExactly(EventException.class, + () -> eventService.deleteEvent(notExistsEventId)); + + assertEquals(exception.exceptionType(), NOT_FOUND_EVENT); + } } + } +