Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: 공연의 좌석 등급 목록을 조회하는 API를 구현한다. #40

Merged
merged 6 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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());
}
}
}
Loading