Skip to content

Commit de56b8b

Browse files
authored
Refactor/좌석테스트 로직분리 (#236)
* Fix: EnableJpaAuditing이 테스트 코드에서 실행되지 않도록 분리 * Refactor: 좌석 조회 성공 컨트롤러 단위 테스트 작성 * Refactor: 좌석 조회 실패 컨트롤러 단위 테스트 작성 * Refactor: 좌석 선택 성공 컨트롤러 단위 테스트 작성 * Refactor: 미지정석 선택 성공 컨트롤러 단위 테스트 작성 * Refactor: 좌석 5개 이상 선택 시 실패 컨트롤러 단위 테스트 작성 * Refactor: 좌석 선택 실패 케이스 모두 작성 * Refactor: 좌석 취소 성공 테스트 케이스 작성 * Refactor: 좌석 취소 실패 테스트 케이스 작성 * Refactor: 예외 처리로 무조건 404 반환하는 버그 해결 * Refactor: 좌석 조회 성공 및 실패 서비스 단위 테스트 작성 * Refactor: 지정석 성공 및 실패 서비스 단위 테스트 작성 * Refactor: 미지정석 성공 및 실패 서비스 단위 테스트 작성 * Refactor: 좌석 취소 성공 및 실패 서비스 단위 테스트 작성 * Refactor: 주석 처리
1 parent 806d9c2 commit de56b8b

File tree

9 files changed

+1160
-569
lines changed

9 files changed

+1160
-569
lines changed

service/main-server/src/main/java/org/codeNbug/mainserver/domain/seat/dto/SeatLayoutResponse.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@
1010
import com.fasterxml.jackson.databind.JsonNode;
1111
import com.fasterxml.jackson.databind.ObjectMapper;
1212

13+
import lombok.AllArgsConstructor;
1314
import lombok.Getter;
1415
import lombok.NoArgsConstructor;
1516

1617
@Getter
18+
@NoArgsConstructor
19+
@AllArgsConstructor
1720
public class SeatLayoutResponse {
18-
19-
private final List<SeatDto> seats;
20-
private final List<List<String>> layout;
21+
private List<SeatDto> seats;
22+
private List<List<String>> layout;
2123

2224
@Getter
2325
@NoArgsConstructor

service/main-server/src/main/java/org/codeNbug/mainserver/domain/seat/service/SeatService.java

+13-12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import org.codeNbug.mainserver.domain.seat.entity.SeatLayout;
1515
import org.codeNbug.mainserver.domain.seat.repository.SeatLayoutRepository;
1616
import org.codeNbug.mainserver.domain.seat.repository.SeatRepository;
17+
import org.codeNbug.mainserver.global.exception.globalException.BadRequestException;
18+
import org.codeNbug.mainserver.global.exception.globalException.ConflictException;
1719
import org.springframework.stereotype.Service;
1820

1921
import jakarta.transaction.Transactional;
@@ -48,7 +50,7 @@ public SeatLayoutResponse getSeatLayout(Long eventId, Long userId) {
4850
throw new IllegalArgumentException("로그인된 사용자가 없습니다.");
4951
}
5052
SeatLayout seatLayout = seatLayoutRepository.findByEvent_EventId(eventId)
51-
.orElseThrow(() -> new IllegalArgumentException("행사가 존재하지 않습니다."));
53+
.orElseThrow(() -> new IllegalArgumentException("해당 이벤트에 좌석 레이아웃이 존재하지 않습니다."));
5254

5355
log.info("SeatLayout ID: {}", seatLayout.getId());
5456

@@ -75,15 +77,18 @@ public SeatSelectResponse selectSeat(Long eventId, SeatSelectRequest seatSelectR
7577
.orElseThrow(() -> new IllegalArgumentException("행사가 존재하지 않습니다."));
7678

7779
List<Long> selectedSeats = seatSelectRequest.getSeatList();
78-
if (selectedSeats.size() > 4) {
79-
throw new IllegalArgumentException("최대 4개의 좌석만 선택할 수 있습니다.");
80-
}
8180

8281
if (event.getSeatSelectable()) {
8382
// 지정석 예매 처리
83+
if (selectedSeats != null && selectedSeats.size() > 4) {
84+
throw new BadRequestException("최대 4개의 좌석만 선택할 수 있습니다.");
85+
}
8486
selectSeats(selectedSeats, userId, eventId, true, seatSelectRequest.getTicketCount());
8587
} else {
8688
// 미지정석 예매 처리
89+
if (selectedSeats != null && !selectedSeats.isEmpty()) {
90+
throw new BadRequestException("[selectSeats] 미지정석 예매 시 좌석 목록은 제공되지 않아야 합니다.");
91+
}
8792
selectSeats(null, userId, eventId, false, seatSelectRequest.getTicketCount());
8893
}
8994

@@ -110,24 +115,20 @@ private void selectSeats(List<Long> selectedSeats, Long userId, Long eventId, bo
110115
.orElseThrow(() -> new IllegalArgumentException("[selectSeats] 좌석이 존재하지 않습니다."));
111116

112117
if (!seat.isAvailable()) {
113-
throw new IllegalStateException("[selectSeats] 이미 예매된 좌석입니다. seatId = " + seatId);
118+
throw new ConflictException("[selectSeats] 이미 예매된 좌석입니다. seatId = " + seatId);
114119
}
115120

116121
reserveSeat(seat, userId, eventId, seatId);
117122
}
118123
} else {
119124
// 미지정석 예매 처리
120-
if (selectedSeats != null && !selectedSeats.isEmpty()) {
121-
throw new IllegalArgumentException("[selectSeats] 미지정석 예매 시 좌석 목록은 제공되지 않아야 합니다.");
122-
}
123-
124125
List<Seat> availableSeats = seatRepository.findAvailableSeatsByEventId(eventId)
125126
.stream()
126127
.limit(ticketCount)
127128
.toList();
128129

129130
if (availableSeats.size() < ticketCount) {
130-
throw new IllegalStateException("[selectSeats] 예매 가능한 좌석 수가 부족합니다.");
131+
throw new ConflictException("[selectSeats] 예매 가능한 좌석 수가 부족합니다.");
131132
}
132133

133134
for (Seat seat : availableSeats) {
@@ -150,7 +151,7 @@ private void reserveSeat(Seat seat, Long userId, Long eventId, Long seatId) {
150151

151152
boolean lockSuccess = redisLockService.tryLock(lockKey, lockValue, Duration.ofMinutes(5));
152153
if (!lockSuccess) {
153-
throw new IllegalStateException("[reserveSeat] 이미 선택된 좌석이 있습니다.");
154+
throw new BadRequestException("[reserveSeat] 이미 선택된 좌석이 있습니다.");
154155
}
155156

156157
seat.reserve();
@@ -177,7 +178,7 @@ public void cancelSeat(Long eventId, SeatCancelRequest seatCancelRequest, Long u
177178
String lockValue = redisLockService.getLockValue(lockKey);
178179

179180
if (!redisLockService.unlock(lockKey, lockValue)) {
180-
throw new IllegalStateException("[cancelSeat] 좌석 락을 해제할 수 없습니다.");
181+
throw new BadRequestException("[cancelSeat] 좌석 락을 해제할 수 없습니다.");
181182
}
182183

183184
Seat seat = seatRepository.findById(seatId)

service/main-server/src/main/java/org/codeNbug/mainserver/global/exception/GlobalExceptionHandler.java

+14
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.codeNbug.mainserver.global.dto.RsData;
44
import org.codeNbug.mainserver.global.exception.globalException.BadRequestException;
5+
import org.codeNbug.mainserver.global.exception.globalException.ConflictException;
56
import org.codeNbug.mainserver.global.exception.globalException.DuplicateEmailException;
67
import org.codenbug.user.security.exception.AuthenticationFailedException;
78
import org.springframework.http.HttpStatus;
@@ -146,6 +147,19 @@ public ResponseEntity<RsData<Object>> handleBadRequestException(BadRequestExcept
146147
.body(new RsData<>("400-BAD_REQUEST", e.getMessage()));
147148
}
148149

150+
/**
151+
* ConflictException 처리
152+
* 리소스 상태가 요청과 충돌할 때 발생하는 예외를 처리합니다.
153+
*
154+
* @param e 예외 객체
155+
* @return API 응답
156+
*/
157+
@ExceptionHandler(ConflictException.class)
158+
public ResponseEntity<RsData<Object>> handleConflictException(ConflictException e) {
159+
return ResponseEntity.status(HttpStatus.CONFLICT)
160+
.body(new RsData<>("409-CONFLICT", e.getMessage()));
161+
}
162+
149163
/**
150164
* 일반 예외 처리
151165
* 위에서 처리되지 않은 모든 예외를 처리합니다.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.codeNbug.mainserver.global.exception.globalException;
2+
3+
public class ConflictException extends RuntimeException {
4+
public ConflictException(String message) {
5+
super(message);
6+
}
7+
}

0 commit comments

Comments
 (0)