Skip to content

Commit

Permalink
Feature: 공연의 좌석 등급 목록을 조회하는 API를 구현한다. (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
seminchoi authored Aug 14, 2024
2 parents 5fed00a + 1512010 commit b648350
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 12 deletions.
14 changes: 12 additions & 2 deletions src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,21 @@ operation::admin-seat-controller-test/create-seat-grades[snippets='http-response

=== request

operation::seat-controller-test/get-zones[snippets='http-request,path-parameters']
operation::seat-controller-test/get-seats[snippets='http-request,path-parameters']

=== response

operation::seat-controller-test/get-zones[snippets='http-response,response-fields']
operation::seat-controller-test/get-seats[snippets='http-response,response-fields']

== 공연의 좌석 등급 목록 조회

=== request

operation::seat-controller-test/get-seat-grades[snippets='http-request,path-parameters']

=== response

operation::seat-controller-test/get-seat-grades[snippets='http-response,response-fields']

= 티켓(Ticket)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ public class ItemResult<T> {
private List<T> items;

public static <T> ItemResult<T> of(List<T> items) {
return new ItemResult<T>(items);
return new ItemResult<>(items);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.thirdparty.ticketing.domain.ItemResult;
import com.thirdparty.ticketing.domain.seat.dto.response.SeatElement;
import com.thirdparty.ticketing.domain.seat.dto.response.SeatGradeElement;
import com.thirdparty.ticketing.domain.seat.service.SeatService;

import lombok.RequiredArgsConstructor;
Expand All @@ -23,4 +24,11 @@ public ResponseEntity<ItemResult<SeatElement>> getSeats(@PathVariable("zoneId")
ItemResult<SeatElement> seats = seatService.getSeats(zoneId);
return ResponseEntity.ok().body(seats);
}

@GetMapping("/performances/{performanceId}/grades")
public ResponseEntity<ItemResult<SeatGradeElement>> getSeatGrades(
@PathVariable("performanceId") long performanceId) {
ItemResult<SeatGradeElement> seatGrades = seatService.getSeatGrades(performanceId);
return ResponseEntity.ok().body(seatGrades);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.thirdparty.ticketing.domain.seat.dto.response;

import com.thirdparty.ticketing.domain.seat.SeatGrade;

import lombok.Data;

@Data
public class SeatGradeElement {
private final Long gradeId;
private final String gradeName;
private final Long price;

public static SeatGradeElement of(SeatGrade seatGrade) {
return new SeatGradeElement(
seatGrade.getSeatGradeId(), seatGrade.getGradeName(), seatGrade.getPrice());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.thirdparty.ticketing.domain.performance.Performance;
import com.thirdparty.ticketing.domain.seat.SeatGrade;

public interface SeatGradeRepository extends JpaRepository<SeatGrade, Integer> {
Expand All @@ -18,4 +19,6 @@ public interface SeatGradeRepository extends JpaRepository<SeatGrade, Integer> {
""")
List<SeatGrade> findByPerformanceIdAndGradeNames(
@Param("performanceId") long performanceId, @Param("gradeIds") List<Long> gradeIds);

List<SeatGrade> findAllByPerformance(Performance performance);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

import com.thirdparty.ticketing.domain.ItemResult;
import com.thirdparty.ticketing.domain.common.TicketingException;
import com.thirdparty.ticketing.domain.performance.Performance;
import com.thirdparty.ticketing.domain.performance.repository.PerformanceRepository;
import com.thirdparty.ticketing.domain.seat.dto.response.SeatElement;
import com.thirdparty.ticketing.domain.seat.dto.response.SeatGradeElement;
import com.thirdparty.ticketing.domain.seat.repository.SeatGradeRepository;
import com.thirdparty.ticketing.domain.seat.repository.SeatRepository;
import com.thirdparty.ticketing.domain.zone.Zone;
import com.thirdparty.ticketing.domain.zone.repository.ZoneRepository;
Expand All @@ -17,7 +21,9 @@
@Service
@RequiredArgsConstructor
public class SeatService {
private final PerformanceRepository performanceRepository;
private final ZoneRepository zoneRepository;
private final SeatGradeRepository seatGradeRepository;
private final SeatRepository seatRepository;

@Transactional(readOnly = true)
Expand All @@ -28,4 +34,18 @@ public ItemResult<SeatElement> getSeats(Long zoneId) {

return ItemResult.of(seats);
}

@Transactional(readOnly = true)
public ItemResult<SeatGradeElement> getSeatGrades(Long performanceId) {
Performance performance =
performanceRepository
.findById(performanceId)
.orElseThrow(() -> new TicketingException(("")));
List<SeatGradeElement> seatGrades =
seatGradeRepository.findAllByPerformance(performance).stream()
.map(SeatGradeElement::of)
.toList();

return ItemResult.of(seatGrades);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.thirdparty.ticketing.domain.seat.controller;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.BDDMockito.given;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
Expand All @@ -9,7 +9,6 @@
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.Collections;
import java.util.List;

import org.junit.jupiter.api.DisplayName;
Expand All @@ -21,6 +20,7 @@

import com.thirdparty.ticketing.domain.ItemResult;
import com.thirdparty.ticketing.domain.seat.dto.response.SeatElement;
import com.thirdparty.ticketing.domain.seat.dto.response.SeatGradeElement;
import com.thirdparty.ticketing.domain.seat.service.SeatService;
import com.thirdparty.ticketing.support.BaseControllerTest;

Expand All @@ -30,15 +30,15 @@ public class SeatControllerTest extends BaseControllerTest {

@Test
@DisplayName("구역의 좌석 목록을 조회한다.")
void getZones() throws Exception {
void getSeats() throws Exception {
// Given
long performanceId = 1L;
long zoneId = 2L;

List<SeatElement> seatElements =
Collections.singletonList(new SeatElement(1L, "A01", true));
List.of(new SeatElement(1L, "A01", true), new SeatElement(2L, "B01", false));

given(seatService.getSeats(any())).willReturn(ItemResult.of(seatElements));
given(seatService.getSeats(anyLong())).willReturn(ItemResult.of(seatElements));

// When
ResultActions result =
Expand Down Expand Up @@ -70,4 +70,44 @@ void getZones() throws Exception {
.type(JsonFieldType.BOOLEAN)
.description("좌석 선택 가능 여부"))));
}

@Test
@DisplayName("공연의 좌석 등급 목록을 조회한다.")
void getSeatGrades() throws Exception {
// Given
long performanceId = 1L;

List<SeatGradeElement> seatGradeElements =
List.of(
new SeatGradeElement(1L, "Grade1", 10000L),
new SeatGradeElement(2L, "Grade2", 20000L));

given(seatService.getSeatGrades(anyLong())).willReturn(ItemResult.of(seatGradeElements));

// When
ResultActions result =
mockMvc.perform(
get("/api/performances/{performanceId}/grades", performanceId)
.header(AUTHORIZATION_HEADER, adminBearerToken));

// Then
result.andExpect(status().isOk())
.andDo(
restDocs.document(
pathParameters(
parameterWithName("performanceId").description("공연 ID")),
responseFields(
fieldWithPath("items")
.type(JsonFieldType.ARRAY)
.description("좌석 등급 목록"),
fieldWithPath("items[].gradeId")
.type(JsonFieldType.NUMBER)
.description("좌석 등급 ID"),
fieldWithPath("items[].gradeName")
.type(JsonFieldType.STRING)
.description("좌석 등급 이름"),
fieldWithPath("items[].price")
.type(JsonFieldType.NUMBER)
.description("좌석 등급 가격"))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,23 @@
import com.thirdparty.ticketing.domain.member.Member;
import com.thirdparty.ticketing.domain.member.MemberRole;
import com.thirdparty.ticketing.domain.performance.Performance;
import com.thirdparty.ticketing.domain.performance.repository.PerformanceRepository;
import com.thirdparty.ticketing.domain.seat.Seat;
import com.thirdparty.ticketing.domain.seat.SeatGrade;
import com.thirdparty.ticketing.domain.seat.dto.response.SeatElement;
import com.thirdparty.ticketing.domain.seat.dto.response.SeatGradeElement;
import com.thirdparty.ticketing.domain.seat.repository.SeatGradeRepository;
import com.thirdparty.ticketing.domain.seat.repository.SeatRepository;
import com.thirdparty.ticketing.domain.zone.Zone;
import com.thirdparty.ticketing.domain.zone.repository.ZoneRepository;

@DataJpaTest
public class SeatServiceTest {
@Autowired private TestEntityManager testEntityManager;
@Autowired private SeatRepository seatRepository;
@Autowired private PerformanceRepository performanceRepository;
@Autowired private ZoneRepository zoneRepository;
@Autowired private SeatGradeRepository seatGradeRepository;
@Autowired private SeatRepository seatRepository;

private SeatService seatService;

Expand All @@ -41,7 +46,9 @@ public class SeatServiceTest {

@BeforeEach
void setUpBase() {
seatService = new SeatService(zoneRepository, seatRepository);
seatService =
new SeatService(
performanceRepository, zoneRepository, seatGradeRepository, seatRepository);
setUpMember();
setUpPerformance();
setUpZone();
Expand Down Expand Up @@ -100,7 +107,7 @@ private void setUpSeatGrades() {
}

@Nested
@DisplayName("getZones 메서드를 호출할 때")
@DisplayName("getSeats 메소드를 호출할 때")
class GetZonesTest {
private Seat seat1;
private Seat seat2;
Expand All @@ -125,7 +132,7 @@ void setUp() {
}

@Test
@DisplayName("좌석 등급이 성공적으로 생성된다.")
@DisplayName("좌석 목록이 성공적으로 생성된다.")
void getZones_success() {
// Given
testEntityManager.persistAndFlush(seat1);
Expand All @@ -149,4 +156,36 @@ private void assertSeatElement(SeatElement seatElement, Seat expectedSeat) {
assertThat(seatElement.getSeatCode()).isEqualTo(expectedSeat.getSeatCode());
}
}

@Nested
@DisplayName("getSeatGrades 메소드를 호출할 때")
class GetSeatGradesTest {

@Test
@DisplayName("좌석 등급 목록이 성공적으로 반환된다.")
void getSeatGrades_success() {
// Given
Long performanceId = performance.getPerformanceId();

// When
ItemResult<SeatGradeElement> seatGradesResult =
seatService.getSeatGrades(performanceId);

// Then
List<SeatGradeElement> seatGradeElements = seatGradesResult.getItems();
SeatGradeElement seatGradeElement1 = seatGradeElements.get(0);
SeatGradeElement seatGradeElement2 = seatGradeElements.get(1);

assertThat(seatGradeElements).hasSize(2);
assertSeatGradeElement(seatGradeElement1, seatGrade1);
assertSeatGradeElement(seatGradeElement2, seatGrade2);
}

private void assertSeatGradeElement(
SeatGradeElement seatGradeElement, SeatGrade expectedSeatGrade) {
assertThat(seatGradeElement.getGradeId()).isEqualTo(expectedSeatGrade.getSeatGradeId());
assertThat(seatGradeElement.getGradeName()).isEqualTo(expectedSeatGrade.getGradeName());
assertThat(seatGradeElement.getPrice()).isEqualTo(expectedSeatGrade.getPrice());
}
}
}

0 comments on commit b648350

Please sign in to comment.