diff --git a/build.gradle b/build.gradle index 6d43b49..1e24d72 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' runtimeOnly 'com.h2database:h2' + runtimeOnly 'mysql:mysql-connector-java' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' diff --git a/src/main/java/com/uno/getinline/controller/AdminController.java b/src/main/java/com/uno/getinline/controller/AdminController.java index fff8d3a..e3f1ce3 100644 --- a/src/main/java/com/uno/getinline/controller/AdminController.java +++ b/src/main/java/com/uno/getinline/controller/AdminController.java @@ -74,7 +74,17 @@ public ModelAndView adminEventDetail(@PathVariable Long eventId) { Map map = new HashMap<>(); map.put("event", EventDto.of( eventId, - 1L, + PlaceDto.of( + 1L, + PlaceType.SPORTS, + "배드민턴장", + "서울시 그리구 그래동", + "010-2222-3333", + 33, + null, + LocalDateTime.now(), + LocalDateTime.now() + ), "오후 운동", EventStatus.OPENED, LocalDateTime.of(2021, 1, 1, 13, 0, 0), diff --git a/src/main/java/com/uno/getinline/domain/Admin.java b/src/main/java/com/uno/getinline/domain/Admin.java index 4422d5c..2eb43e3 100644 --- a/src/main/java/com/uno/getinline/domain/Admin.java +++ b/src/main/java/com/uno/getinline/domain/Admin.java @@ -1,16 +1,20 @@ package com.uno.getinline.domain; -import lombok.*; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import javax.persistence.*; import java.time.LocalDateTime; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; @Getter @ToString -@EqualsAndHashCode @Table(indexes = { @Index(columnList = "phoneNumber"), @Index(columnList = "createdAt"), @@ -46,6 +50,12 @@ public class Admin { private String memo; + @ToString.Exclude + @OrderBy("id") + @OneToMany(mappedBy = "admin") + private final Set adminPlaceMaps = new LinkedHashSet<>(); + + @Column(nullable = false, insertable = false, updatable = false, columnDefinition = "datetime default CURRENT_TIMESTAMP") @CreatedDate @@ -71,4 +81,17 @@ public static Admin of(String email, String nickname, String password, String ph return new Admin(email, nickname, password, phoneNumber, memo); } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + return id != null && id.equals(((Admin) obj).getId()); + } + + @Override + public int hashCode() { + return Objects.hash(email, nickname, phoneNumber, createdAt, modifiedAt); + } + } diff --git a/src/main/java/com/uno/getinline/domain/AdminPlaceMap.java b/src/main/java/com/uno/getinline/domain/AdminPlaceMap.java index aca0da5..5392d33 100644 --- a/src/main/java/com/uno/getinline/domain/AdminPlaceMap.java +++ b/src/main/java/com/uno/getinline/domain/AdminPlaceMap.java @@ -1,6 +1,5 @@ package com.uno.getinline.domain; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -10,13 +9,11 @@ import javax.persistence.*; import java.time.LocalDateTime; +import java.util.Objects; @Getter @ToString -@EqualsAndHashCode @Table(indexes = { - @Index(columnList = "adminId"), - @Index(columnList = "placeId"), @Index(columnList = "createdAt"), @Index(columnList = "modifiedAt") }) @@ -30,12 +27,12 @@ public class AdminPlaceMap { @Setter - @Column(nullable = false) - private Long adminId; + @ManyToOne(optional = false) + private Admin admin; @Setter - @Column(nullable = false) - private Long placeId; + @ManyToOne(optional = false) + private Place place; @Column(nullable = false, insertable = false, updatable = false, @@ -51,13 +48,26 @@ public class AdminPlaceMap { protected AdminPlaceMap() {} - protected AdminPlaceMap(Long adminId, Long placeId) { - this.adminId = adminId; - this.placeId = placeId; + protected AdminPlaceMap(Admin admin, Place place) { + this.admin = admin; + this.place = place; } - public static AdminPlaceMap of(Long adminId, Long placeId) { - return new AdminPlaceMap(adminId, placeId); + public static AdminPlaceMap of(Admin admin, Place place) { + return new AdminPlaceMap(admin, place); + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + return id != null && id.equals(((AdminPlaceMap) obj).getId()); + } + + @Override + public int hashCode() { + return Objects.hash(place, admin, createdAt, modifiedAt); } } diff --git a/src/main/java/com/uno/getinline/domain/Event.java b/src/main/java/com/uno/getinline/domain/Event.java index cb5694b..5a21b4f 100644 --- a/src/main/java/com/uno/getinline/domain/Event.java +++ b/src/main/java/com/uno/getinline/domain/Event.java @@ -1,7 +1,9 @@ package com.uno.getinline.domain; import com.uno.getinline.constant.EventStatus; -import lombok.*; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -9,12 +11,11 @@ import javax.persistence.*; import java.time.LocalDateTime; +import java.util.Objects; @Getter @ToString -@EqualsAndHashCode @Table(indexes = { - @Index(columnList = "placeId"), @Index(columnList = "eventName"), @Index(columnList = "eventStartDatetime"), @Index(columnList = "eventEndDatetime"), @@ -31,15 +32,15 @@ public class Event { @Setter - @Column(nullable = false) - private Long placeId; + @ManyToOne(optional = false) + private Place place; @Setter @Column(nullable = false) private String eventName; @Setter - @Column(nullable = false, columnDefinition = "varchar default 'OPENED'") + @Column(nullable = false, columnDefinition = "varchar(20) default 'OPENED'") @Enumerated(EnumType.STRING) private EventStatus eventStatus; @@ -48,16 +49,20 @@ public class Event { @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) private LocalDateTime eventStartDatetime; - @Setter @Column(nullable = false, columnDefinition = "datetime") + @Setter + @Column(nullable = false, columnDefinition = "datetime") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) private LocalDateTime eventEndDatetime; - @Setter @Column(nullable = false, columnDefinition = "integer default 0") + @Setter + @Column(nullable = false, columnDefinition = "integer default 0") private Integer currentNumberOfPeople; - @Setter @Column(nullable = false) + @Setter + @Column(nullable = false) private Integer capacity; + @Setter private String memo; @@ -76,7 +81,7 @@ public class Event { protected Event() {} protected Event( - Long placeId, + Place place, String eventName, EventStatus eventStatus, LocalDateTime eventStartDatetime, @@ -85,7 +90,7 @@ protected Event( Integer capacity, String memo ) { - this.placeId = placeId; + this.place = place; this.eventName = eventName; this.eventStatus = eventStatus; this.eventStartDatetime = eventStartDatetime; @@ -96,7 +101,7 @@ protected Event( } public static Event of( - Long placeId, + Place place, String eventName, EventStatus eventStatus, LocalDateTime eventStartDatetime, @@ -106,7 +111,7 @@ public static Event of( String memo ) { return new Event( - placeId, + place, eventName, eventStatus, eventStartDatetime, @@ -117,4 +122,17 @@ public static Event of( ); } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + return id != null && id.equals(((Event) obj).getId()); + } + + @Override + public int hashCode() { + return Objects.hash(eventName, eventStartDatetime, eventEndDatetime, createdAt, modifiedAt); + } + } diff --git a/src/main/java/com/uno/getinline/domain/Place.java b/src/main/java/com/uno/getinline/domain/Place.java index 4841424..3725df5 100644 --- a/src/main/java/com/uno/getinline/domain/Place.java +++ b/src/main/java/com/uno/getinline/domain/Place.java @@ -1,7 +1,6 @@ package com.uno.getinline.domain; import com.uno.getinline.constant.PlaceType; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -11,10 +10,12 @@ import javax.persistence.*; import java.time.LocalDateTime; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; @Getter @ToString -@EqualsAndHashCode @Table(indexes = { @Index(columnList = "placeName"), @Index(columnList = "address"), @@ -32,7 +33,7 @@ public class Place { @Setter - @Column(nullable = false, columnDefinition = "varchar default 'COMMON'") + @Column(nullable = false, columnDefinition = "varchar(20) default 'COMMON'") @Enumerated(EnumType.STRING) private PlaceType placeType; @@ -68,6 +69,17 @@ public class Place { private LocalDateTime modifiedAt; + @ToString.Exclude + @OrderBy("id") + @OneToMany(mappedBy = "place") + private final Set events = new LinkedHashSet<>(); + + @ToString.Exclude + @OrderBy("id") + @OneToMany(mappedBy = "place") + private final Set adminPlaceMaps = new LinkedHashSet<>(); + + protected Place() {} protected Place( @@ -97,4 +109,17 @@ public static Place of( return new Place(placeType, placeName, address, phoneNumber, capacity, memo); } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + return id != null && id.equals(((Place) obj).getId()); + } + + @Override + public int hashCode() { + return Objects.hash(placeName, address, phoneNumber, createdAt, modifiedAt); + } + } diff --git a/src/main/java/com/uno/getinline/dto/EventDto.java b/src/main/java/com/uno/getinline/dto/EventDto.java index 78d94a5..bca32e3 100644 --- a/src/main/java/com/uno/getinline/dto/EventDto.java +++ b/src/main/java/com/uno/getinline/dto/EventDto.java @@ -2,12 +2,13 @@ import com.uno.getinline.constant.EventStatus; import com.uno.getinline.domain.Event; +import com.uno.getinline.domain.Place; import java.time.LocalDateTime; public record EventDto( Long id, - Long placeId, + PlaceDto placeDto, String eventName, EventStatus eventStatus, LocalDateTime eventStartDatetime, @@ -21,7 +22,7 @@ public record EventDto( public static EventDto of( Long id, - Long placeId, + PlaceDto placeDto, String eventName, EventStatus eventStatus, LocalDateTime eventStartDatetime, @@ -34,7 +35,7 @@ public static EventDto of( ) { return new EventDto( id, - placeId, + placeDto, eventName, eventStatus, eventStartDatetime, @@ -50,7 +51,7 @@ public static EventDto of( public static EventDto of(Event event) { return new EventDto( event.getId(), - event.getPlaceId(), + PlaceDto.of(event.getPlace()), event.getEventName(), event.getEventStatus(), event.getEventStartDatetime(), @@ -63,9 +64,9 @@ public static EventDto of(Event event) { ); } - public Event toEntity() { + public Event toEntity(Place place) { return Event.of( - placeId, + place, eventName, eventStatus, eventStartDatetime, @@ -77,7 +78,6 @@ public Event toEntity() { } public Event updateEntity(Event event) { - if (placeId != null) { event.setPlaceId(placeId); } if (eventName != null) { event.setEventName(eventName); } if (eventStatus != null) { event.setEventStatus(eventStatus); } if (eventStartDatetime != null) { event.setEventStartDatetime(eventStartDatetime); } diff --git a/src/main/java/com/uno/getinline/dto/EventRequest.java b/src/main/java/com/uno/getinline/dto/EventRequest.java index ee3f2e0..790e0a4 100644 --- a/src/main/java/com/uno/getinline/dto/EventRequest.java +++ b/src/main/java/com/uno/getinline/dto/EventRequest.java @@ -44,7 +44,7 @@ public static EventRequest of( public EventDto toDTO() { return EventDto.of( null, - this.placeId(), + null, // TODO: 여기를 반드시 적절히 고쳐야 사용할 수 있음 this.eventName(), this.eventStatus(), this.eventStartDatetime(), diff --git a/src/main/java/com/uno/getinline/dto/EventResponse.java b/src/main/java/com/uno/getinline/dto/EventResponse.java index e460593..93cf204 100644 --- a/src/main/java/com/uno/getinline/dto/EventResponse.java +++ b/src/main/java/com/uno/getinline/dto/EventResponse.java @@ -6,7 +6,7 @@ public record EventResponse( Long id, - Long placeId, + PlaceDto place, String eventName, EventStatus eventStatus, LocalDateTime eventStartDatetime, @@ -18,7 +18,7 @@ public record EventResponse( public static EventResponse of( Long id, - Long placeId, + PlaceDto place, String eventName, EventStatus eventStatus, LocalDateTime eventStartDatetime, @@ -29,7 +29,7 @@ public static EventResponse of( ) { return new EventResponse( id, - placeId, + place, eventName, eventStatus, eventStartDatetime, @@ -44,7 +44,7 @@ public static EventResponse from(EventDto eventDTO) { if (eventDTO == null) { return null; } return EventResponse.of( eventDTO.id(), - eventDTO.placeId(), + eventDTO.placeDto(), eventDTO.eventName(), eventDTO.eventStatus(), eventDTO.eventStartDatetime(), diff --git a/src/main/java/com/uno/getinline/repository/EventRepository.java b/src/main/java/com/uno/getinline/repository/EventRepository.java index 8c3b894..9fa3e34 100644 --- a/src/main/java/com/uno/getinline/repository/EventRepository.java +++ b/src/main/java/com/uno/getinline/repository/EventRepository.java @@ -17,7 +17,8 @@ public interface EventRepository extends @Override default void customize(QuerydslBindings bindings, QEvent root) { bindings.excludeUnlistedProperties(true); - bindings.including(root.placeId, root.eventName, root.eventStatus, root.eventStartDatetime, root.eventEndDatetime); + bindings.including(root.place.placeName, root.eventName, root.eventStatus, root.eventStartDatetime, root.eventEndDatetime); + bindings.bind(root.place.placeName).first(StringExpression::containsIgnoreCase); bindings.bind(root.eventName).first(StringExpression::containsIgnoreCase); bindings.bind(root.eventStartDatetime).first(ComparableExpression::goe); bindings.bind(root.eventEndDatetime).first(ComparableExpression::loe); diff --git a/src/main/java/com/uno/getinline/service/EventService.java b/src/main/java/com/uno/getinline/service/EventService.java index 535ca0a..151e46b 100644 --- a/src/main/java/com/uno/getinline/service/EventService.java +++ b/src/main/java/com/uno/getinline/service/EventService.java @@ -3,9 +3,11 @@ import com.querydsl.core.types.Predicate; import com.uno.getinline.constant.ErrorCode; import com.uno.getinline.constant.EventStatus; +import com.uno.getinline.domain.Place; import com.uno.getinline.dto.EventDto; import com.uno.getinline.exception.GeneralException; import com.uno.getinline.repository.EventRepository; +import com.uno.getinline.repository.PlaceRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -19,6 +21,7 @@ public class EventService { private final EventRepository eventRepository; + private final PlaceRepository placeRepository; public List getEvents(Predicate predicate) { try { @@ -58,7 +61,9 @@ public boolean createEvent(EventDto eventDTO) { return false; } - eventRepository.save(eventDTO.toEntity()); + Place place = placeRepository.findById(eventDTO.placeDto().id()) + .orElseThrow(() -> new GeneralException(ErrorCode.NOT_FOUND)); + eventRepository.save(eventDTO.toEntity(place)); return true; } catch (Exception e) { throw new GeneralException(ErrorCode.DATA_ACCESS_ERROR, e); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 816bbde..d6d5ed5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -13,11 +13,16 @@ spring.thymeleaf3.decoupled-logic=true # Database spring.jpa.defer-datasource-initialization=true -spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.hibernate.ddl-auto=create spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true -spring.h2.console.enabled=true -spring.datasource.url=jdbc:h2:mem:testdb +spring.jpa.properties.hibernate.default_batch_fetch_size=100 +spring.h2.console.enabled=false +spring.datasource.url=jdbc:mysql://localhost:3306/getinline +spring.datasource.username=root +spring.datasource.password= +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.sql.init.mode=always # API spring.data.rest.base-path=/api diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index cf92757..911aa67 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1,6 +1,3 @@ --- noinspection SqlNoDataSourceInspectionForFile --- noinspection SqlResolveForFile - insert into `place` (`place_type`, `place_name`, `address`, `phone_number`, `capacity`, `memo`) values ('SPORTS', '서울 배드민턴장', '경기도 성남시 대왕판교로 999', '010-9999-0000', 20, '판교는 정말 체크남방셔츠 뿐인가'), diff --git a/src/main/resources/templates/event/detail.html b/src/main/resources/templates/event/detail.html index 6a812d0..f881981 100644 --- a/src/main/resources/templates/event/detail.html +++ b/src/main/resources/templates/event/detail.html @@ -11,8 +11,8 @@ - - + + diff --git a/src/main/resources/templates/event/detail.th.xml b/src/main/resources/templates/event/detail.th.xml index e488472..cca7d3f 100644 --- a/src/main/resources/templates/event/detail.th.xml +++ b/src/main/resources/templates/event/detail.th.xml @@ -2,7 +2,7 @@ - + diff --git a/src/main/resources/templates/event/index.html b/src/main/resources/templates/event/index.html index 2bfb268..c211170 100644 --- a/src/main/resources/templates/event/index.html +++ b/src/main/resources/templates/event/index.html @@ -11,7 +11,7 @@
장소 ID?장소명?
이벤트명
- + @@ -23,7 +23,7 @@ - + diff --git a/src/main/resources/templates/event/index.th.xml b/src/main/resources/templates/event/index.th.xml index e45a9ff..5032e79 100644 --- a/src/main/resources/templates/event/index.th.xml +++ b/src/main/resources/templates/event/index.th.xml @@ -4,7 +4,7 @@ - + diff --git a/src/test/java/com/uno/getinline/controller/api/ApiEventControllerTest.java b/src/test/java/com/uno/getinline/controller/api/ApiEventControllerTest.java index 2515a87..3deb033 100644 --- a/src/test/java/com/uno/getinline/controller/api/ApiEventControllerTest.java +++ b/src/test/java/com/uno/getinline/controller/api/ApiEventControllerTest.java @@ -3,8 +3,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.uno.getinline.constant.ErrorCode; import com.uno.getinline.constant.EventStatus; +import com.uno.getinline.constant.PlaceType; import com.uno.getinline.dto.EventDto; import com.uno.getinline.dto.EventResponse; +import com.uno.getinline.dto.PlaceDto; import com.uno.getinline.service.EventService; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; @@ -107,7 +109,7 @@ void givenEvent_whenCreatingAnEvent_thenReturnsSuccessfulStandardResponse() thro // Given EventResponse eventResponse = EventResponse.of( 1L, - 1L, + createPlaceDto(1L), "오후 운동", EventStatus.OPENED, LocalDateTime.of(2021, 1, 1, 13, 0, 0), @@ -139,7 +141,7 @@ void givenWrongEvent_whenCreatingAnEvent_thenReturnsFailedStandardResponse() thr // Given EventResponse eventResponse = EventResponse.of( 1L, - 0L, + createPlaceDto(0L), " ", null, null, @@ -234,7 +236,7 @@ void givenEventIdAndInfo_whenModifyingAnEvent_thenReturnsSuccessfulStandardRespo long eventId = 1L; EventResponse eventResponse = EventResponse.of( eventId, - 1L, + createPlaceDto(1L), "오후 운동", EventStatus.OPENED, LocalDateTime.of(2021, 1, 1, 13, 0, 0), @@ -267,7 +269,7 @@ void givenWrongEventIdAndInfo_whenModifyingAnEvent_thenReturnsSuccessfulStandard long eventId = 0L; EventResponse eventResponse = EventResponse.of( eventId, - 0L, + createPlaceDto(0L), " ", null, null, @@ -329,7 +331,7 @@ void givenWrongEventId_whenDeletingAnEvent_thenReturnsFailedStandardResponse() t private EventDto createEventDTO() { return EventDto.of( 1L, - 1L, + createPlaceDto(1L), "오후 운동", EventStatus.OPENED, LocalDateTime.of(2021, 1, 1, 13, 0, 0), @@ -342,4 +344,18 @@ private EventDto createEventDTO() { ); } + private PlaceDto createPlaceDto(Long placeId) { + return PlaceDto.of( + placeId, + PlaceType.COMMON, + "배드민턴장", + "서울시 가나구 다라동", + "010-1111-2222", + 10, + null, + LocalDateTime.now(), + LocalDateTime.now() + ); + } + } diff --git a/src/test/java/com/uno/getinline/service/EventServiceTest.java b/src/test/java/com/uno/getinline/service/EventServiceTest.java index b7034d4..9ed25af 100644 --- a/src/test/java/com/uno/getinline/service/EventServiceTest.java +++ b/src/test/java/com/uno/getinline/service/EventServiceTest.java @@ -4,16 +4,20 @@ import com.querydsl.core.types.Predicate; import com.uno.getinline.constant.ErrorCode; import com.uno.getinline.constant.EventStatus; +import com.uno.getinline.constant.PlaceType; import com.uno.getinline.domain.Event; +import com.uno.getinline.domain.Place; import com.uno.getinline.dto.EventDto; import com.uno.getinline.exception.GeneralException; import com.uno.getinline.repository.EventRepository; +import com.uno.getinline.repository.PlaceRepository; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; import java.time.LocalDateTime; import java.util.List; @@ -30,6 +34,7 @@ class EventServiceTest { @InjectMocks private EventService sut; @Mock private EventRepository eventRepository; + @Mock private PlaceRepository placeRepository; @DisplayName("이벤트를 검색하면, 결과를 출력하여 보여준다.") @Test @@ -37,8 +42,8 @@ void givenNothing_whenSearchingEvents_thenReturnsEntireEventList() { // Given given(eventRepository.findAll(any(Predicate.class))) .willReturn(List.of( - createEvent(1L, "오전 운동", true), - createEvent(1L, "오후 운동", false) + createEvent("오전 운동", true), + createEvent("오후 운동", false) )); // When @@ -71,7 +76,7 @@ void givenDataRelatedException_whenSearchingEvents_thenThrowsGeneralException() void givenEventId_whenSearchingExistingEvent_thenReturnsEvent() { // Given long eventId = 1L; - Event event = createEvent(1L, "오전 운동", true); + Event event = createEvent("오전 운동", true); given(eventRepository.findById(eventId)).willReturn(Optional.of(event)); // When @@ -118,15 +123,17 @@ void givenDataRelatedException_whenSearchingEvent_thenThrowsGeneralException() { @Test void givenEvent_whenCreating_thenCreatesEventAndReturnsTrue() { // Given - Event event = createEvent(1L, "오후 운동", false); - given(eventRepository.save(event)).willReturn(event); + EventDto eventDto = EventDto.of(createEvent("오후 운동", false)); + given(placeRepository.findById(eventDto.placeDto().id())).willReturn(Optional.of(createPlace())); + given(eventRepository.save(any(Event.class))).willReturn(any()); // When - boolean result = sut.createEvent(EventDto.of(event)); + boolean result = sut.createEvent(eventDto); // Then assertThat(result).isTrue(); - then(eventRepository).should().save(event); + then(placeRepository).should().findById(eventDto.placeDto().id()); + then(eventRepository).should().save(any(Event.class)); } @DisplayName("이벤트 정보를 주지 않으면, 생성 중단하고 결과를 false 로 보여준다.") @@ -139,6 +146,25 @@ void givenNothing_whenCreating_thenAbortCreatingAndReturnsFalse() { // Then assertThat(result).isFalse(); + then(placeRepository).shouldHaveNoInteractions(); + then(eventRepository).shouldHaveNoInteractions(); + } + + @DisplayName("이벤트 생성 중 장소 정보가 틀리거나 없으면, 줄서기 프로젝트 기본 에러로 전환하여 예외 던진다") + @Test + void givenWrongPlaceId_whenCreating_thenThrowsGeneralException() { + // Given + Event event = createEvent(null, false); + given(placeRepository.findById(event.getPlace().getId())).willReturn(Optional.empty()); + + // When + Throwable thrown = catchThrowable(() -> sut.createEvent(EventDto.of(event))); + + // Then + assertThat(thrown) + .isInstanceOf(GeneralException.class) + .hasMessageContaining(ErrorCode.DATA_ACCESS_ERROR.getMessage()); + then(placeRepository).should().findById(event.getPlace().getId()); then(eventRepository).shouldHaveNoInteractions(); } @@ -146,8 +172,9 @@ void givenNothing_whenCreating_thenAbortCreatingAndReturnsFalse() { @Test void givenDataRelatedException_whenCreating_thenThrowsGeneralException() { // Given - Event event = createEvent(0L, null, false); + Event event = createEvent(null, false); RuntimeException e = new RuntimeException("This is test."); + given(placeRepository.findById(event.getPlace().getId())).willReturn(Optional.of(createPlace())); given(eventRepository.save(any())).willThrow(e); // When @@ -157,6 +184,7 @@ void givenDataRelatedException_whenCreating_thenThrowsGeneralException() { assertThat(thrown) .isInstanceOf(GeneralException.class) .hasMessageContaining(ErrorCode.DATA_ACCESS_ERROR.getMessage()); + then(placeRepository).should().findById(event.getPlace().getId()); then(eventRepository).should().save(any()); } @@ -165,8 +193,8 @@ void givenDataRelatedException_whenCreating_thenThrowsGeneralException() { void givenEventIdAndItsInfo_whenModifying_thenModifiesEventAndReturnsTrue() { // Given long eventId = 1L; - Event originalEvent = createEvent(1L, "오후 운동", false); - Event changedEvent = createEvent(1L, "오전 운동", true); + Event originalEvent = createEvent("오후 운동", false); + Event changedEvent = createEvent("오전 운동", true); given(eventRepository.findById(eventId)).willReturn(Optional.of(originalEvent)); given(eventRepository.save(changedEvent)).willReturn(changedEvent); @@ -175,6 +203,10 @@ void givenEventIdAndItsInfo_whenModifying_thenModifiesEventAndReturnsTrue() { // Then assertThat(result).isTrue(); + assertThat(originalEvent.getEventName()).isEqualTo(changedEvent.getEventName()); + assertThat(originalEvent.getEventStartDatetime()).isEqualTo(changedEvent.getEventStartDatetime()); + assertThat(originalEvent.getEventEndDatetime()).isEqualTo(changedEvent.getEventEndDatetime()); + assertThat(originalEvent.getEventStatus()).isEqualTo(changedEvent.getEventStatus()); then(eventRepository).should().findById(eventId); then(eventRepository).should().save(changedEvent); } @@ -183,7 +215,7 @@ void givenEventIdAndItsInfo_whenModifying_thenModifiesEventAndReturnsTrue() { @Test void givenNoEventId_whenModifying_thenAbortModifyingAndReturnsFalse() { // Given - Event event = createEvent(1L, "오후 운동", false); + Event event = createEvent("오후 운동", false); // When boolean result = sut.modifyEvent(null, EventDto.of(event)); @@ -212,8 +244,8 @@ void givenEventIdOnly_whenModifying_thenAbortModifyingAndReturnsFalse() { void givenDataRelatedException_whenModifying_thenThrowsGeneralException() { // Given long eventId = 1L; - Event originalEvent = createEvent(1L, "오후 운동", false); - Event wrongEvent = createEvent(0L, null, false); + Event originalEvent = createEvent("오후 운동", false); + Event wrongEvent = createEvent(null, false); RuntimeException e = new RuntimeException("This is test."); given(eventRepository.findById(eventId)).willReturn(Optional.of(originalEvent)); given(eventRepository.save(any())).willThrow(e); @@ -276,12 +308,13 @@ void givenDataRelatedException_whenDeleting_thenThrowsGeneralException() { } - private Event createEvent(long placeId, String eventName, boolean isMorning) { + private Event createEvent(String eventName, boolean isMorning) { String hourStart = isMorning ? "09" : "13"; String hourEnd = isMorning ? "12" : "16"; return createEvent( - placeId, + 1L, + 1L, eventName, EventStatus.OPENED, LocalDateTime.parse("2021-01-01T%s:00:00".formatted(hourStart)), @@ -290,14 +323,15 @@ private Event createEvent(long placeId, String eventName, boolean isMorning) { } private Event createEvent( + long id, long placeId, String eventName, EventStatus eventStatus, LocalDateTime eventStartDateTime, LocalDateTime eventEndDateTime ) { - return Event.of( - placeId, + Event event = Event.of( + createPlace(placeId), eventName, eventStatus, eventStartDateTime, @@ -306,6 +340,20 @@ private Event createEvent( 24, "마스크 꼭 착용하세요" ); + ReflectionTestUtils.setField(event, "id", id); + + return event; + } + + private Place createPlace() { + return createPlace(1L); + } + + private Place createPlace(long id) { + Place place = Place.of(PlaceType.COMMON, "test place", "test address", "010-1234-1234", 10, null); + ReflectionTestUtils.setField(place, "id", id); + + return place; } } diff --git a/src/test/java/com/uno/getinline/service/PlaceServiceTest.java b/src/test/java/com/uno/getinline/service/PlaceServiceTest.java index 792977d..b7dd7d6 100644 --- a/src/test/java/com/uno/getinline/service/PlaceServiceTest.java +++ b/src/test/java/com/uno/getinline/service/PlaceServiceTest.java @@ -14,6 +14,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; import java.util.List; import java.util.Optional; @@ -118,14 +119,14 @@ void givenDataRelatedException_whenSearchingPlace_thenThrowsGeneralException() { void givenPlace_whenCreating_thenCreatesPlaceAndReturnsTrue() { // Given Place place = createPlace(PlaceType.SPORTS, "체육관"); - given(placeRepository.save(place)).willReturn(place); + given(placeRepository.save(any(Place.class))).willReturn(place); // When boolean result = sut.createPlace(PlaceDto.of(place)); // Then assertThat(result).isTrue(); - then(placeRepository).should().save(place); + then(placeRepository).should().save(any(Place.class)); } @DisplayName("장소 정보를 주지 않으면, 생성 중단하고 결과를 false 로 보여준다.") @@ -275,11 +276,16 @@ void givenDataRelatedException_whenDeleting_thenThrowsGeneralException() { } + private Place createPlace(PlaceType placeType, String placeName) { + return createPlace(1L, placeType, placeName); + } + private Place createPlace( + long id, PlaceType placeType, String placeName ) { - return Place.of( + Place place = Place.of( placeType, placeName, "주소 테스트", @@ -287,6 +293,9 @@ private Place createPlace( 24, "마스크 꼭 착용하세요" ); + ReflectionTestUtils.setField(place, "id", id); + + return place; } }
장소 ID장소명 이벤트명 이벤트 상태 시작 일시
11 테스트 이벤트 OPENED 2021-01-01 09:00:00