diff --git a/scripts/dev/replace-new-version.sh b/scripts/dev/replace-new-version.sh index 3fd434fb..48f23ebf 100644 --- a/scripts/dev/replace-new-version.sh +++ b/scripts/dev/replace-new-version.sh @@ -19,4 +19,10 @@ fi JAR_FILE=$(ls /home/ubuntu/app/*.jar | head -n 1) -sudo nohup java -Dspring.profiles.active=dev,monitor -Duser.timezone=Asia/Seoul -Dserver.port=8080 -jar "$JAR_FILE" & +sudo nohup java \ + -Dspring.profiles.active=dev,monitor \ + -Duser.timezone=Asia/Seoul \ + -Dserver.port=8080 \ + -Ddd.service=debate-timer \ + -Ddd.env=dev \ + -jar "$JAR_FILE" & diff --git a/scripts/prod/replace-new-version.sh b/scripts/prod/replace-new-version.sh index ea5d2914..c9f3d2b1 100644 --- a/scripts/prod/replace-new-version.sh +++ b/scripts/prod/replace-new-version.sh @@ -19,4 +19,10 @@ fi JAR_FILE=$(ls /home/ubuntu/app/*.jar | head -n 1) -sudo nohup java -Dspring.profiles.active=prod,monitor -Duser.timezone=Asia/Seoul -Dserver.port=8080 -jar "$JAR_FILE" & +sudo nohup java \ + -Dspring.profiles.active=prod,monitor \ + -Duser.timezone=Asia/Seoul \ + -Dserver.port=8080 \ + -Ddd.service=debate-timer \ + -Ddd.env=prod \ + -jar "$JAR_FILE" & diff --git a/src/main/java/com/debatetimer/controller/timebased/TimeBasedController.java b/src/main/java/com/debatetimer/controller/timebased/TimeBasedController.java deleted file mode 100644 index 2e67ca6f..00000000 --- a/src/main/java/com/debatetimer/controller/timebased/TimeBasedController.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.debatetimer.controller.timebased; - -import com.debatetimer.controller.auth.AuthMember; -import com.debatetimer.domain.member.Member; -import com.debatetimer.dto.timebased.request.TimeBasedTableCreateRequest; -import com.debatetimer.dto.timebased.response.TimeBasedTableResponse; -import com.debatetimer.service.timebased.TimeBasedService; -import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequiredArgsConstructor -public class TimeBasedController { - - private final TimeBasedService timeBasedService; - - @PostMapping("/api/table/time-based") - @ResponseStatus(HttpStatus.CREATED) - public TimeBasedTableResponse save( - @Valid @RequestBody TimeBasedTableCreateRequest tableCreateRequest, - @AuthMember Member member - ) { - return timeBasedService.save(tableCreateRequest, member); - } - - @GetMapping("/api/table/time-based/{tableId}") - @ResponseStatus(HttpStatus.OK) - public TimeBasedTableResponse getTable( - @PathVariable Long tableId, - @AuthMember Member member - ) { - return timeBasedService.findTable(tableId, member); - } - - @PutMapping("/api/table/time-based/{tableId}") - @ResponseStatus(HttpStatus.OK) - public TimeBasedTableResponse updateTable( - @Valid @RequestBody TimeBasedTableCreateRequest tableCreateRequest, - @PathVariable Long tableId, - @AuthMember Member member - ) { - return timeBasedService.updateTable(tableCreateRequest, tableId, member); - } - - @PatchMapping("/api/table/time-based/{tableId}/debate") - @ResponseStatus(HttpStatus.OK) - public TimeBasedTableResponse debate( - @PathVariable Long tableId, - @AuthMember Member member - ) { - return timeBasedService.updateUsedAt(tableId, member); - } - - @DeleteMapping("/api/table/time-based/{tableId}") - @ResponseStatus(HttpStatus.NO_CONTENT) - public void deleteTable( - @PathVariable Long tableId, - @AuthMember Member member - ) { - timeBasedService.deleteTable(tableId, member); - } -} diff --git a/src/main/java/com/debatetimer/controller/tool/export/ExcelExportInterceptor.java b/src/main/java/com/debatetimer/controller/tool/export/ExcelExportInterceptor.java index aab2163d..535d21c1 100644 --- a/src/main/java/com/debatetimer/controller/tool/export/ExcelExportInterceptor.java +++ b/src/main/java/com/debatetimer/controller/tool/export/ExcelExportInterceptor.java @@ -16,6 +16,7 @@ public class ExcelExportInterceptor implements HandlerInterceptor { private static final String SPREAD_SHEET_MEDIA_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; private static final String EXCEL_FILE_NAME = "my_debate_template.xlsx"; + @Override public boolean preHandle( HttpServletRequest request, HttpServletResponse response, diff --git a/src/main/java/com/debatetimer/domain/timebased/TimeBasedBoxType.java b/src/main/java/com/debatetimer/domain/timebased/TimeBasedBoxType.java deleted file mode 100644 index 8dfa4ce6..00000000 --- a/src/main/java/com/debatetimer/domain/timebased/TimeBasedBoxType.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.debatetimer.domain.timebased; - -import com.debatetimer.domain.Stance; -import java.util.Set; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public enum TimeBasedBoxType { - - OPENING(Set.of(Stance.PROS, Stance.CONS)), - REBUTTAL(Set.of(Stance.PROS, Stance.CONS)), - CROSS(Set.of(Stance.PROS, Stance.CONS)), - CLOSING(Set.of(Stance.PROS, Stance.CONS)), - TIME_BASED(Set.of(Stance.NEUTRAL)), - LEADING(Set.of(Stance.PROS, Stance.CONS)), - TIME_OUT(Set.of(Stance.NEUTRAL)), - ; - - private final Set availableStances; - - public boolean isAvailable(Stance stance) { - return availableStances.contains(stance); - } - - public boolean isTimeBased() { - return this == TIME_BASED; - } - - public boolean isNotTimeBased() { - return !isTimeBased(); - } -} diff --git a/src/main/java/com/debatetimer/domain/timebased/TimeBasedTable.java b/src/main/java/com/debatetimer/domain/timebased/TimeBasedTable.java deleted file mode 100644 index d3a17a0d..00000000 --- a/src/main/java/com/debatetimer/domain/timebased/TimeBasedTable.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.debatetimer.domain.timebased; - -import com.debatetimer.domain.DebateTable; -import com.debatetimer.domain.member.Member; -import com.debatetimer.dto.member.TableType; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class TimeBasedTable extends DebateTable { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - public TimeBasedTable( - Member member, - String name, - String agenda, - boolean warningBell, - boolean finishBell - ) { - super(member, name, agenda, warningBell, finishBell); - } - - @Override - public long getId() { - return id; - } - - @Override - public TableType getType() { - return TableType.TIME_BASED; - } - - public void update(TimeBasedTable renewTable) { - updateTable(renewTable); - } -} diff --git a/src/main/java/com/debatetimer/domain/timebased/TimeBasedTimeBox.java b/src/main/java/com/debatetimer/domain/timebased/TimeBasedTimeBox.java deleted file mode 100644 index 0995acf0..00000000 --- a/src/main/java/com/debatetimer/domain/timebased/TimeBasedTimeBox.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.debatetimer.domain.timebased; - -import com.debatetimer.domain.DebateTimeBox; -import com.debatetimer.domain.Stance; -import com.debatetimer.exception.custom.DTClientErrorException; -import com.debatetimer.exception.errorcode.ClientErrorCode; -import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.validation.constraints.NotNull; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class TimeBasedTimeBox extends DebateTimeBox { - - public static final int TIME_MULTIPLIER = 2; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @NotNull - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "table_id") - private TimeBasedTable timeBasedTable; - - @NotNull - @Enumerated(EnumType.STRING) - private TimeBasedBoxType type; - - private Integer timePerTeam; - private Integer timePerSpeaking; - - public TimeBasedTimeBox( - TimeBasedTable timeBasedTable, - int sequence, - Stance stance, - TimeBasedBoxType type, - int time, - Integer speaker - ) { - super(sequence, stance, time, String.valueOf(speaker)); - validateStance(stance, type); - validateNotTimeBasedType(type); - - this.timeBasedTable = timeBasedTable; - this.type = type; - } - - public TimeBasedTimeBox( - TimeBasedTable timeBasedTable, - int sequence, - Stance stance, - TimeBasedBoxType type, - int timePerTeam, - int timePerSpeaking, - Integer speaker - ) { - super(sequence, stance, timePerTeam * TIME_MULTIPLIER, String.valueOf(speaker)); - validateTime(timePerTeam, timePerSpeaking); - validateStance(stance, type); - validateTimeBasedType(type); - validateSpeakerNumber(speaker); - - this.timeBasedTable = timeBasedTable; - this.type = type; - this.timePerTeam = timePerTeam; - this.timePerSpeaking = timePerSpeaking; - } - - private void validateTime(int time) { - if (time <= 0) { - throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_TIME); - } - } - - private void validateTime(int timePerTeam, int timePerSpeaking) { - validateTime(timePerTeam); - validateTime(timePerSpeaking); - if (timePerTeam < timePerSpeaking) { - throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BASED_TIME); - } - } - - private void validateStance(Stance stance, TimeBasedBoxType boxType) { - if (!boxType.isAvailable(stance)) { - throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_STANCE); - } - } - - private void validateTimeBasedType(TimeBasedBoxType boxType) { - if (boxType.isNotTimeBased()) { - throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_FORMAT); - } - } - - private void validateNotTimeBasedType(TimeBasedBoxType boxType) { - if (boxType.isTimeBased()) { - throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_FORMAT); - } - } - - private void validateSpeakerNumber(Integer speaker) { - if (speaker != null && speaker <= 0) { - throw new DTClientErrorException(ClientErrorCode.INVALID_TIME_BOX_SPEAKER); - } - } -} diff --git a/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTableCreateRequest.java b/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTableCreateRequest.java deleted file mode 100644 index c051f94c..00000000 --- a/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTableCreateRequest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.debatetimer.dto.timebased.request; - -import com.debatetimer.domain.TimeBoxes; -import com.debatetimer.domain.member.Member; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.domain.timebased.TimeBasedTimeBox; -import jakarta.validation.Valid; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -public record TimeBasedTableCreateRequest( - @Valid TimeBasedTableInfoCreateRequest info, - @Valid List table -) { - - public TimeBasedTable toTable(Member member) { - return info.toTable(member); - } - - public TimeBoxes toTimeBoxes(TimeBasedTable timeBasedTable) { - return IntStream.range(0, table.size()) - .mapToObj(i -> table.get(i).toTimeBox(timeBasedTable, i + 1)) - .collect(Collectors.collectingAndThen(Collectors.toList(), TimeBoxes::new)); - } -} diff --git a/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTableInfoCreateRequest.java b/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTableInfoCreateRequest.java deleted file mode 100644 index 51db8b89..00000000 --- a/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTableInfoCreateRequest.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.debatetimer.dto.timebased.request; - -import com.debatetimer.domain.member.Member; -import com.debatetimer.domain.timebased.TimeBasedTable; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; - -public record TimeBasedTableInfoCreateRequest( - @NotBlank - String name, - - @NotNull - String agenda, - - boolean warningBell, - boolean finishBell -) { - - public TimeBasedTable toTable(Member member) { - return new TimeBasedTable(member, name, agenda, warningBell, finishBell); - } -} diff --git a/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTimeBoxCreateRequest.java b/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTimeBoxCreateRequest.java deleted file mode 100644 index d3da4518..00000000 --- a/src/main/java/com/debatetimer/dto/timebased/request/TimeBasedTimeBoxCreateRequest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.debatetimer.dto.timebased.request; - -import com.debatetimer.domain.Stance; -import com.debatetimer.domain.timebased.TimeBasedBoxType; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.domain.timebased.TimeBasedTimeBox; -import jakarta.validation.constraints.NotNull; - -public record TimeBasedTimeBoxCreateRequest( - @NotNull - Stance stance, - - @NotNull - TimeBasedBoxType type, - - int time, - Integer timePerTeam, - Integer timePerSpeaking, - Integer speakerNumber -) { - - public TimeBasedTimeBox toTimeBox(TimeBasedTable timeBasedTable, int sequence) { - if (type.isTimeBased()) { - return new TimeBasedTimeBox(timeBasedTable, sequence, stance, type, timePerTeam, timePerSpeaking, - speakerNumber); - } - return new TimeBasedTimeBox(timeBasedTable, sequence, stance, type, time, speakerNumber); - } -} diff --git a/src/main/java/com/debatetimer/dto/timebased/response/TimeBasedTableInfoResponse.java b/src/main/java/com/debatetimer/dto/timebased/response/TimeBasedTableInfoResponse.java deleted file mode 100644 index a5e4b935..00000000 --- a/src/main/java/com/debatetimer/dto/timebased/response/TimeBasedTableInfoResponse.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.debatetimer.dto.timebased.response; - -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.dto.member.TableType; - -public record TimeBasedTableInfoResponse( - String name, - TableType type, - String agenda, - boolean warningBell, - boolean finishBell -) { - - public TimeBasedTableInfoResponse(TimeBasedTable timeBasedTable) { - this( - timeBasedTable.getName(), - TableType.TIME_BASED, - timeBasedTable.getAgenda(), - timeBasedTable.isWarningBell(), - timeBasedTable.isFinishBell() - ); - } -} diff --git a/src/main/java/com/debatetimer/dto/timebased/response/TimeBasedTableResponse.java b/src/main/java/com/debatetimer/dto/timebased/response/TimeBasedTableResponse.java deleted file mode 100644 index 1c19a87e..00000000 --- a/src/main/java/com/debatetimer/dto/timebased/response/TimeBasedTableResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.debatetimer.dto.timebased.response; - -import com.debatetimer.domain.TimeBoxes; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.domain.timebased.TimeBasedTimeBox; -import java.util.List; - -public record TimeBasedTableResponse(long id, TimeBasedTableInfoResponse info, List table) { - - public TimeBasedTableResponse( - TimeBasedTable timeBasedTable, - TimeBoxes timeBasedTimeBoxes - ) { - this( - timeBasedTable.getId(), - new TimeBasedTableInfoResponse(timeBasedTable), - toTimeBoxResponses(timeBasedTimeBoxes) - ); - } - - private static List toTimeBoxResponses(TimeBoxes timeBoxes) { - List timeBasedTimeBoxes = timeBoxes.getTimeBoxes(); - return timeBasedTimeBoxes - .stream() - .map(TimeBasedTimeBoxResponse::new) - .toList(); - } -} diff --git a/src/main/java/com/debatetimer/dto/timebased/response/TimeBasedTimeBoxResponse.java b/src/main/java/com/debatetimer/dto/timebased/response/TimeBasedTimeBoxResponse.java deleted file mode 100644 index 587d95ac..00000000 --- a/src/main/java/com/debatetimer/dto/timebased/response/TimeBasedTimeBoxResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.debatetimer.dto.timebased.response; - -import com.debatetimer.domain.Stance; -import com.debatetimer.domain.timebased.TimeBasedBoxType; -import com.debatetimer.domain.timebased.TimeBasedTimeBox; - -public record TimeBasedTimeBoxResponse( - Stance stance, - TimeBasedBoxType type, - Integer time, - Integer timePerTeam, - Integer timePerSpeaking, - Integer speakerNumber -) { - - public TimeBasedTimeBoxResponse(TimeBasedTimeBox timeBasedTimeBox) { - this(timeBasedTimeBox.getStance(), - timeBasedTimeBox.getType(), - timeBasedTimeBox.getTime(), - timeBasedTimeBox.getTimePerTeam(), - timeBasedTimeBox.getTimePerSpeaking(), - getSpeakerNumber(timeBasedTimeBox) - ); - } - - private static Integer getSpeakerNumber(TimeBasedTimeBox timeBasedTimeBox) { - if (timeBasedTimeBox.getSpeaker() == null || timeBasedTimeBox.getSpeaker().equals("null")) { - return null; - } - return Integer.parseInt(timeBasedTimeBox.getSpeaker()); - } -} diff --git a/src/main/java/com/debatetimer/exception/errorcode/ClientErrorCode.java b/src/main/java/com/debatetimer/exception/errorcode/ClientErrorCode.java index 72e772c7..9f7da726 100644 --- a/src/main/java/com/debatetimer/exception/errorcode/ClientErrorCode.java +++ b/src/main/java/com/debatetimer/exception/errorcode/ClientErrorCode.java @@ -47,7 +47,6 @@ public enum ClientErrorCode implements ResponseErrorCode { NOT_TABLE_OWNER(HttpStatus.UNAUTHORIZED, "테이블을 소유한 회원이 아닙니다."), UNAUTHORIZED_MEMBER(HttpStatus.UNAUTHORIZED, "접근 권한이 없습니다"), EXPIRED_TOKEN(HttpStatus.UNAUTHORIZED, "토큰 기한이 만료되었습니다"), - EMPTY_COOKIE(HttpStatus.UNAUTHORIZED, "쿠키에 값이 없습니다"), MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 회원이 존재하지 않습니다"), diff --git a/src/main/java/com/debatetimer/exception/handler/GlobalExceptionHandler.java b/src/main/java/com/debatetimer/exception/handler/GlobalExceptionHandler.java index ee411661..aa9627d4 100644 --- a/src/main/java/com/debatetimer/exception/handler/GlobalExceptionHandler.java +++ b/src/main/java/com/debatetimer/exception/handler/GlobalExceptionHandler.java @@ -8,6 +8,7 @@ import com.debatetimer.exception.errorcode.ResponseErrorCode; import com.debatetimer.exception.errorcode.ServerErrorCode; import jakarta.validation.ConstraintViolationException; +import java.io.IOException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.catalina.connector.ClientAbortException; @@ -19,6 +20,7 @@ import org.springframework.web.bind.MissingRequestCookieException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.async.AsyncRequestNotUsableException; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import org.springframework.web.servlet.resource.NoResourceFoundException; @@ -31,34 +33,50 @@ public class GlobalExceptionHandler { @ExceptionHandler(BindException.class) public ResponseEntity handleBindingException(BindException exception) { - log.warn("message: {}", exception.getMessage()); + logClientError(exception); return toResponse(ClientErrorCode.FIELD_ERROR); } @ExceptionHandler(ConstraintViolationException.class) public ResponseEntity handleConstraintViolationException(ConstraintViolationException exception) { - log.warn("message: {}", exception.getMessage()); + logClientError(exception); return toResponse(ClientErrorCode.URL_PARAMETER_ERROR); } @ExceptionHandler(MethodArgumentTypeMismatchException.class) public ResponseEntity handleMethodArgumentTypeMismatchException( MethodArgumentTypeMismatchException exception) { - log.warn("message: {}", exception.getMessage()); + logClientError(exception); return toResponse(ClientErrorCode.METHOD_ARGUMENT_TYPE_MISMATCH); } @ExceptionHandler(ClientAbortException.class) public ResponseEntity handleClientAbortException(ClientAbortException exception) { - log.warn("message: {}", exception.getMessage()); + logClientError(exception); return toResponse(ClientErrorCode.ALREADY_DISCONNECTED); } + @ExceptionHandler(AsyncRequestNotUsableException.class) + public ResponseEntity handleAsyncError(AsyncRequestNotUsableException exception) { + if (isClientDisconnect(exception.getCause())) { + logClientError(exception); + return toResponse(ClientErrorCode.ALREADY_DISCONNECTED); + } + logServerError(exception); + return toResponse(ServerErrorCode.INTERNAL_SERVER_ERROR); + } + + private boolean isClientDisconnect(Throwable cause) { + return cause instanceof IOException + && cause.getMessage() != null + && cause.getMessage().contains("Broken pipe"); + } + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) public ResponseEntity handleHttpRequestMethodNotSupportedException( HttpRequestMethodNotSupportedException exception ) { - log.warn("message: {}", exception.getMessage()); + logClientError(exception); return toResponse(ClientErrorCode.METHOD_NOT_SUPPORTED); } @@ -66,40 +84,49 @@ public ResponseEntity handleHttpRequestMethodNotSupportedExceptio public ResponseEntity handleHttpMediaTypeNotSupportedException( HttpMediaTypeNotSupportedException exception ) { - log.warn("message: {}", exception.getMessage()); + logClientError(exception); return toResponse(ClientErrorCode.MEDIA_TYPE_NOT_SUPPORTED); } @ExceptionHandler(NoResourceFoundException.class) public ResponseEntity handleNoResourceFoundException(NoResourceFoundException exception) { + logClientError(exception); return toResponse(ClientErrorCode.NO_RESOURCE_FOUND); } @ExceptionHandler(MissingRequestCookieException.class) public ResponseEntity handleMissingRequestCookieException(MissingRequestCookieException exception) { + logClientError(exception); return toResponse(ClientErrorCode.NO_COOKIE_FOUND); } @ExceptionHandler(DTClientErrorException.class) public ResponseEntity handleClientException(DTClientErrorException exception) { - log.warn("message: {}", exception.getMessage()); + logClientError(exception); return toResponse(exception.getHttpStatus(), exception.getMessage()); } @ExceptionHandler(DTServerErrorException.class) public ResponseEntity handleServerException(DTServerErrorException exception) { - log.error("message: {}", exception.getMessage()); - errorNotifier.sendErrorMessage(exception); + logServerError(exception); return toResponse(exception.getHttpStatus(), exception.getMessage()); } @ExceptionHandler(Exception.class) public ResponseEntity handleException(Exception exception) { - log.error("exception: {}", exception.getMessage()); - errorNotifier.sendErrorMessage(exception); + logServerError(exception); return toResponse(ServerErrorCode.INTERNAL_SERVER_ERROR); } + private void logClientError(Exception exception) { + log.warn("exception message: {}", exception.getMessage()); + } + + private void logServerError(Exception exception) { + log.error("exception message: {}", exception.getMessage()); + errorNotifier.sendErrorMessage(exception); + } + private ResponseEntity toResponse(ResponseErrorCode errorCode) { return toResponse(errorCode.getStatus(), errorCode.getMessage()); } diff --git a/src/main/java/com/debatetimer/repository/timebased/TimeBasedTableRepository.java b/src/main/java/com/debatetimer/repository/timebased/TimeBasedTableRepository.java deleted file mode 100644 index c8a9287e..00000000 --- a/src/main/java/com/debatetimer/repository/timebased/TimeBasedTableRepository.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.debatetimer.repository.timebased; - -import com.debatetimer.domain.member.Member; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.exception.custom.DTClientErrorException; -import com.debatetimer.exception.errorcode.ClientErrorCode; -import java.util.List; -import java.util.Optional; -import org.springframework.data.repository.Repository; - -public interface TimeBasedTableRepository extends Repository { - - TimeBasedTable save(TimeBasedTable timeBasedTable); - - Optional findById(long id); - - default TimeBasedTable getById(long tableId) { - return findById(tableId) - .orElseThrow(() -> new DTClientErrorException(ClientErrorCode.TABLE_NOT_FOUND)); - } - - List findAllByMember(Member member); - - void delete(TimeBasedTable table); -} diff --git a/src/main/java/com/debatetimer/repository/timebased/TimeBasedTimeBoxRepository.java b/src/main/java/com/debatetimer/repository/timebased/TimeBasedTimeBoxRepository.java deleted file mode 100644 index df4bdbf6..00000000 --- a/src/main/java/com/debatetimer/repository/timebased/TimeBasedTimeBoxRepository.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.debatetimer.repository.timebased; - -import com.debatetimer.domain.TimeBoxes; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.domain.timebased.TimeBasedTimeBox; -import java.util.List; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.Repository; -import org.springframework.transaction.annotation.Transactional; - -public interface TimeBasedTimeBoxRepository extends Repository { - - TimeBasedTimeBox save(TimeBasedTimeBox timeBox); - - @Transactional - default List saveAll(List timeBoxes) { - return timeBoxes.stream() - .map(this::save) - .toList(); - } - - List findAllByTimeBasedTable(TimeBasedTable table); - - default TimeBoxes findTableTimeBoxes(TimeBasedTable table) { - List timeBoxes = findAllByTimeBasedTable(table); - return new TimeBoxes<>(timeBoxes); - } - - @Query("DELETE FROM TimeBasedTimeBox tbtb WHERE tbtb IN :timeBoxes") - @Modifying(clearAutomatically = true, flushAutomatically = true) - @Transactional - void deleteAll(List timeBoxes); -} diff --git a/src/main/java/com/debatetimer/service/timebased/TimeBasedService.java b/src/main/java/com/debatetimer/service/timebased/TimeBasedService.java deleted file mode 100644 index f984b7c8..00000000 --- a/src/main/java/com/debatetimer/service/timebased/TimeBasedService.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.debatetimer.service.timebased; - -import com.debatetimer.domain.TimeBoxes; -import com.debatetimer.domain.member.Member; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.domain.timebased.TimeBasedTimeBox; -import com.debatetimer.dto.timebased.request.TimeBasedTableCreateRequest; -import com.debatetimer.dto.timebased.response.TimeBasedTableResponse; -import com.debatetimer.exception.custom.DTClientErrorException; -import com.debatetimer.exception.errorcode.ClientErrorCode; -import com.debatetimer.repository.timebased.TimeBasedTableRepository; -import com.debatetimer.repository.timebased.TimeBasedTimeBoxRepository; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class TimeBasedService { - - private final TimeBasedTableRepository tableRepository; - private final TimeBasedTimeBoxRepository timeBoxRepository; - - @Transactional - public TimeBasedTableResponse save(TimeBasedTableCreateRequest tableCreateRequest, Member member) { - TimeBasedTable table = tableCreateRequest.toTable(member); - TimeBasedTable savedTable = tableRepository.save(table); - - TimeBoxes savedTimeBoxes = saveTimeBoxes(tableCreateRequest, savedTable); - return new TimeBasedTableResponse(savedTable, savedTimeBoxes); - } - - @Transactional(readOnly = true) - public TimeBasedTableResponse findTable(long tableId, Member member) { - TimeBasedTable table = getOwnerTable(tableId, member.getId()); - TimeBoxes timeBoxes = timeBoxRepository.findTableTimeBoxes(table); - return new TimeBasedTableResponse(table, timeBoxes); - } - - @Transactional - public TimeBasedTableResponse updateTable( - TimeBasedTableCreateRequest tableCreateRequest, - long tableId, - Member member - ) { - TimeBasedTable existingTable = getOwnerTable(tableId, member.getId()); - TimeBasedTable renewedTable = tableCreateRequest.toTable(member); - existingTable.update(renewedTable); - - TimeBoxes timeBoxes = timeBoxRepository.findTableTimeBoxes(existingTable); - timeBoxRepository.deleteAll(timeBoxes.getTimeBoxes()); - TimeBoxes savedTimeBoxes = saveTimeBoxes(tableCreateRequest, existingTable); - return new TimeBasedTableResponse(existingTable, savedTimeBoxes); - } - - @Transactional - public TimeBasedTableResponse updateUsedAt(long tableId, Member member) { - TimeBasedTable table = getOwnerTable(tableId, member.getId()); - TimeBoxes timeBoxes = timeBoxRepository.findTableTimeBoxes(table); - table.updateUsedAt(); - - return new TimeBasedTableResponse(table, timeBoxes); - } - - @Transactional - public void deleteTable(long tableId, Member member) { - TimeBasedTable table = getOwnerTable(tableId, member.getId()); - TimeBoxes timeBoxes = timeBoxRepository.findTableTimeBoxes(table); - timeBoxRepository.deleteAll(timeBoxes.getTimeBoxes()); - tableRepository.delete(table); - } - - private TimeBoxes saveTimeBoxes( - TimeBasedTableCreateRequest tableCreateRequest, - TimeBasedTable table - ) { - TimeBoxes timeBoxes = tableCreateRequest.toTimeBoxes(table); - List savedTimeBoxes = timeBoxRepository.saveAll(timeBoxes.getTimeBoxes()); - return new TimeBoxes<>(savedTimeBoxes); - } - - private TimeBasedTable getOwnerTable(long tableId, long memberId) { - TimeBasedTable foundTable = tableRepository.getById(tableId); - validateOwn(foundTable, memberId); - return foundTable; - } - - private void validateOwn(TimeBasedTable table, long memberId) { - if (!table.isOwner(memberId)) { - throw new DTClientErrorException(ClientErrorCode.NOT_TABLE_OWNER); - } - } -} diff --git a/src/test/java/com/debatetimer/controller/BaseControllerTest.java b/src/test/java/com/debatetimer/controller/BaseControllerTest.java index c764dd15..b0f6de9e 100644 --- a/src/test/java/com/debatetimer/controller/BaseControllerTest.java +++ b/src/test/java/com/debatetimer/controller/BaseControllerTest.java @@ -8,12 +8,9 @@ import com.debatetimer.fixture.MemberGenerator; import com.debatetimer.fixture.ParliamentaryTableGenerator; import com.debatetimer.fixture.ParliamentaryTimeBoxGenerator; -import com.debatetimer.fixture.TimeBasedTableGenerator; -import com.debatetimer.fixture.TimeBasedTimeBoxGenerator; import com.debatetimer.fixture.TokenGenerator; import com.debatetimer.repository.customize.CustomizeTableRepository; import com.debatetimer.repository.parliamentary.ParliamentaryTableRepository; -import com.debatetimer.repository.timebased.TimeBasedTableRepository; import io.restassured.RestAssured; import io.restassured.builder.RequestSpecBuilder; import io.restassured.filter.log.RequestLoggingFilter; @@ -33,9 +30,6 @@ public abstract class BaseControllerTest { @Autowired protected ParliamentaryTableRepository parliamentaryTableRepository; - @Autowired - protected TimeBasedTableRepository timeBasedTableRepository; - @Autowired protected CustomizeTableRepository customizeTableRepository; @@ -48,12 +42,6 @@ public abstract class BaseControllerTest { @Autowired protected ParliamentaryTimeBoxGenerator parliamentaryTimeBoxGenerator; - @Autowired - protected TimeBasedTableGenerator timeBasedTableGenerator; - - @Autowired - protected TimeBasedTimeBoxGenerator timeBasedTimeBoxGenerator; - @Autowired protected CustomizeTableGenerator customizeTableGenerator; diff --git a/src/test/java/com/debatetimer/controller/BaseDocumentTest.java b/src/test/java/com/debatetimer/controller/BaseDocumentTest.java index 4e70556f..4a457f05 100644 --- a/src/test/java/com/debatetimer/controller/BaseDocumentTest.java +++ b/src/test/java/com/debatetimer/controller/BaseDocumentTest.java @@ -13,7 +13,6 @@ import com.debatetimer.service.customize.CustomizeService; import com.debatetimer.service.member.MemberService; import com.debatetimer.service.parliamentary.ParliamentaryService; -import com.debatetimer.service.timebased.TimeBasedService; import io.restassured.RestAssured; import io.restassured.builder.RequestSpecBuilder; import io.restassured.filter.log.RequestLoggingFilter; @@ -61,9 +60,6 @@ public abstract class BaseDocumentTest { @MockitoBean protected ParliamentaryService parliamentaryService; - @MockitoBean - protected TimeBasedService timeBasedService; - @MockitoBean protected CustomizeService customizeService; diff --git a/src/test/java/com/debatetimer/controller/timebased/TimeBasedControllerTest.java b/src/test/java/com/debatetimer/controller/timebased/TimeBasedControllerTest.java deleted file mode 100644 index e5d41d4a..00000000 --- a/src/test/java/com/debatetimer/controller/timebased/TimeBasedControllerTest.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.debatetimer.controller.timebased; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; - -import com.debatetimer.controller.BaseControllerTest; -import com.debatetimer.domain.Stance; -import com.debatetimer.domain.member.Member; -import com.debatetimer.domain.timebased.TimeBasedBoxType; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.dto.timebased.request.TimeBasedTableCreateRequest; -import com.debatetimer.dto.timebased.request.TimeBasedTableInfoCreateRequest; -import com.debatetimer.dto.timebased.request.TimeBasedTimeBoxCreateRequest; -import com.debatetimer.dto.timebased.response.TimeBasedTableResponse; -import io.restassured.http.ContentType; -import io.restassured.http.Headers; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -class TimeBasedControllerTest extends BaseControllerTest { - - @Nested - class Save { - - @Test - void 시간총량제_테이블을_생성한다() { - Member bito = memberGenerator.generate("default@gmail.com"); - TimeBasedTableCreateRequest request = new TimeBasedTableCreateRequest( - new TimeBasedTableInfoCreateRequest("비토 테이블", "주제", true, true), - List.of(new TimeBasedTimeBoxCreateRequest(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, - 1), - new TimeBasedTimeBoxCreateRequest(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, - 60, - null))); - Headers headers = headerGenerator.generateAccessTokenHeader(bito); - - TimeBasedTableResponse response = given() - .contentType(ContentType.JSON) - .headers(headers) - .body(request) - .when().post("/api/table/time-based") - .then().statusCode(201) - .extract().as(TimeBasedTableResponse.class); - - assertAll( - () -> assertThat(response.info().name()).isEqualTo(request.info().name()), - () -> assertThat(response.table()).hasSize(request.table().size()) - ); - } - } - - @Nested - class GetTable { - - @Test - void 시간총량제_테이블을_조회한다() { - Member bito = memberGenerator.generate("default@gmail.com"); - TimeBasedTable bitoTable = timeBasedTableGenerator.generate(bito); - timeBasedTimeBoxGenerator.generate(bitoTable, 1); - timeBasedTimeBoxGenerator.generateNotExistSpeaker(bitoTable, 2); - Headers headers = headerGenerator.generateAccessTokenHeader(bito); - - TimeBasedTableResponse response = given() - .contentType(ContentType.JSON) - .pathParam("tableId", bitoTable.getId()) - .headers(headers) - .when().get("/api/table/time-based/{tableId}") - .then().statusCode(200) - .extract().as(TimeBasedTableResponse.class); - - assertAll( - () -> assertThat(response.id()).isEqualTo(bitoTable.getId()), - () -> assertThat(response.table()).hasSize(2) - ); - } - } - - @Nested - class UpdateTable { - - @Test - void 시간총량제_토론_테이블을_업데이트한다() { - Member bito = memberGenerator.generate("default@gmail.com"); - TimeBasedTable bitoTable = timeBasedTableGenerator.generate(bito); - TimeBasedTableCreateRequest renewTableRequest = new TimeBasedTableCreateRequest( - new TimeBasedTableInfoCreateRequest("비토 테이블", "주제", true, true), - List.of(new TimeBasedTimeBoxCreateRequest(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, - 1), - new TimeBasedTimeBoxCreateRequest(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, - 60, - null))); - Headers headers = headerGenerator.generateAccessTokenHeader(bito); - - TimeBasedTableResponse response = given() - .contentType(ContentType.JSON) - .pathParam("tableId", bitoTable.getId()) - .headers(headers) - .body(renewTableRequest) - .when().put("/api/table/time-based/{tableId}") - .then().statusCode(200) - .extract().as(TimeBasedTableResponse.class); - - assertAll( - () -> assertThat(response.id()).isEqualTo(bitoTable.getId()), - () -> assertThat(response.info().name()).isEqualTo(renewTableRequest.info().name()), - () -> assertThat(response.table()).hasSize(renewTableRequest.table().size()) - ); - } - } - - @Nested - class Debate { - - @Test - void 시간총량제_토론을_시작한다() { - Member bito = memberGenerator.generate("default@gmail.com"); - TimeBasedTable bitoTable = timeBasedTableGenerator.generate(bito); - timeBasedTimeBoxGenerator.generate(bitoTable, 1); - timeBasedTimeBoxGenerator.generateNotExistSpeaker(bitoTable, 2); - Headers headers = headerGenerator.generateAccessTokenHeader(bito); - - TimeBasedTableResponse response = given() - .contentType(ContentType.JSON) - .pathParam("tableId", bitoTable.getId()) - .headers(headers) - .when().patch("/api/table/time-based/{tableId}/debate") - .then().statusCode(200) - .extract().as(TimeBasedTableResponse.class); - - assertAll( - () -> assertThat(response.id()).isEqualTo(bitoTable.getId()), - () -> assertThat(response.info().name()).isEqualTo(bitoTable.getName()), - () -> assertThat(response.table()).hasSize(2) - ); - } - } - - @Nested - class DeleteTable { - - @Test - void 시간총량제_토론_테이블을_삭제한다() { - Member bito = memberGenerator.generate("default@gmail.com"); - TimeBasedTable bitoTable = timeBasedTableGenerator.generate(bito); - timeBasedTimeBoxGenerator.generate(bitoTable, 1); - timeBasedTimeBoxGenerator.generateNotExistSpeaker(bitoTable, 2); - Headers headers = headerGenerator.generateAccessTokenHeader(bito); - - given() - .contentType(ContentType.JSON) - .pathParam("tableId", bitoTable.getId()) - .headers(headers) - .when().delete("/api/table/time-based/{tableId}") - .then().statusCode(204); - } - } -} diff --git a/src/test/java/com/debatetimer/controller/timebased/TimeBasedDocumentTest.java b/src/test/java/com/debatetimer/controller/timebased/TimeBasedDocumentTest.java deleted file mode 100644 index 2c1eb608..00000000 --- a/src/test/java/com/debatetimer/controller/timebased/TimeBasedDocumentTest.java +++ /dev/null @@ -1,475 +0,0 @@ -package com.debatetimer.controller.timebased; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; -import static org.springframework.restdocs.payload.JsonFieldType.ARRAY; -import static org.springframework.restdocs.payload.JsonFieldType.BOOLEAN; -import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; -import static org.springframework.restdocs.payload.JsonFieldType.OBJECT; -import static org.springframework.restdocs.payload.JsonFieldType.STRING; -import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; -import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; - -import com.debatetimer.controller.BaseDocumentTest; -import com.debatetimer.controller.RestDocumentationRequest; -import com.debatetimer.controller.RestDocumentationResponse; -import com.debatetimer.controller.Tag; -import com.debatetimer.domain.Stance; -import com.debatetimer.domain.timebased.TimeBasedBoxType; -import com.debatetimer.dto.member.TableType; -import com.debatetimer.dto.timebased.request.TimeBasedTableCreateRequest; -import com.debatetimer.dto.timebased.request.TimeBasedTableInfoCreateRequest; -import com.debatetimer.dto.timebased.request.TimeBasedTimeBoxCreateRequest; -import com.debatetimer.dto.timebased.response.TimeBasedTableInfoResponse; -import com.debatetimer.dto.timebased.response.TimeBasedTableResponse; -import com.debatetimer.dto.timebased.response.TimeBasedTimeBoxResponse; -import com.debatetimer.exception.custom.DTClientErrorException; -import com.debatetimer.exception.errorcode.ClientErrorCode; -import io.restassured.http.ContentType; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; -import org.springframework.http.HttpHeaders; - -public class TimeBasedDocumentTest extends BaseDocumentTest { - - @Nested - class Save { - - private final RestDocumentationRequest requestDocument = request() - .tag(Tag.TIME_BASED_API) - .summary("새로운 시간총량제 토론 시간표 생성") - .requestHeader( - headerWithName(HttpHeaders.AUTHORIZATION).description("액세스 토큰") - ) - .requestBodyField( - fieldWithPath("info").type(OBJECT).description("토론 테이블 정보"), - fieldWithPath("info.name").type(STRING).description("테이블 이름"), - fieldWithPath("info.agenda").type(STRING).description("토론 주제"), - fieldWithPath("info.warningBell").type(BOOLEAN).description("30초 종소리 유무"), - fieldWithPath("info.finishBell").type(BOOLEAN).description("발언 종료 종소리 유무"), - fieldWithPath("table").type(ARRAY).description("토론 테이블 구성"), - fieldWithPath("table[].stance").type(STRING).description("입장"), - fieldWithPath("table[].type").type(STRING).description("발언 유형"), - fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)"), - fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), - fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), - fieldWithPath("table[].speakerNumber").type(NUMBER).description("발언자 번호").optional() - ); - - private final RestDocumentationResponse responseDocument = response() - .responseBodyField( - fieldWithPath("id").type(NUMBER).description("테이블 ID"), - fieldWithPath("info").type(OBJECT).description("토론 테이블 정보"), - fieldWithPath("info.name").type(STRING).description("테이블 이름"), - fieldWithPath("info.type").type(STRING).description("토론 형식"), - fieldWithPath("info.agenda").type(STRING).description("토론 주제"), - fieldWithPath("info.warningBell").type(BOOLEAN).description("30초 종소리 유무"), - fieldWithPath("info.finishBell").type(BOOLEAN).description("발언 종료 종소리 유무"), - fieldWithPath("table").type(ARRAY).description("토론 테이블 구성"), - fieldWithPath("table[].stance").type(STRING).description("입장"), - fieldWithPath("table[].type").type(STRING).description("발언 유형"), - fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)"), - fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), - fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), - fieldWithPath("table[].speakerNumber").type(NUMBER).description("발언자 번호").optional() - ); - - @Test - void 시간총량제_테이블_생성_성공() { - TimeBasedTableCreateRequest request = new TimeBasedTableCreateRequest( - new TimeBasedTableInfoCreateRequest("비토 테이블 1", "토론 주제", true, true), - List.of(new TimeBasedTimeBoxCreateRequest(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, - 1), - new TimeBasedTimeBoxCreateRequest(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, - 60, - 1))); - TimeBasedTableResponse response = new TimeBasedTableResponse( - 5L, - new TimeBasedTableInfoResponse("비토 테이블 1", TableType.PARLIAMENTARY, "토론 주제", true, true), - List.of( - new TimeBasedTimeBoxResponse(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, 1), - new TimeBasedTimeBoxResponse(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, 60, 1) - ) - ); - doReturn(response).when(timeBasedService).save(eq(request), any()); - - var document = document("time_based/post", 201) - .request(requestDocument) - .response(responseDocument) - .build(); - - given(document) - .contentType(ContentType.JSON) - .headers(EXIST_MEMBER_HEADER) - .body(request) - .when().post("/api/table/time-based") - .then().statusCode(201); - } - - @EnumSource( - value = ClientErrorCode.class, - names = { - "INVALID_TABLE_NAME_LENGTH", - "INVALID_TABLE_NAME_FORM", - "INVALID_TABLE_TIME", - "INVALID_TIME_BOX_SEQUENCE", - "INVALID_TIME_BOX_SPEAKER", - "INVALID_TIME_BOX_TIME", - "INVALID_TIME_BOX_STANCE", - "INVALID_TIME_BOX_FORMAT" - } - ) - @ParameterizedTest - void 시간총량제_테이블_생성_실패(ClientErrorCode errorCode) { - TimeBasedTableCreateRequest request = new TimeBasedTableCreateRequest( - new TimeBasedTableInfoCreateRequest("비토 테이블 1", "토론 주제", true, true), - List.of(new TimeBasedTimeBoxCreateRequest(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, - 1), - new TimeBasedTimeBoxCreateRequest(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, - 60, - 1))); - doThrow(new DTClientErrorException(errorCode)).when(timeBasedService).save(eq(request), any()); - - var document = document("time_based/post", errorCode) - .request(requestDocument) - .response(ERROR_RESPONSE) - .build(); - - given(document) - .contentType(ContentType.JSON) - .headers(EXIST_MEMBER_HEADER) - .body(request) - .when().post("/api/table/time-based") - .then().statusCode(errorCode.getStatus().value()); - } - } - - @Nested - class GetTable { - - private final RestDocumentationRequest requestDocument = request() - .summary("시간총량제 토론 시간표 조회") - .tag(Tag.TIME_BASED_API) - .requestHeader( - headerWithName(HttpHeaders.AUTHORIZATION).description("액세스 토큰") - ) - .pathParameter( - parameterWithName("tableId").description("테이블 ID") - ); - - private final RestDocumentationResponse responseDocument = response() - .responseBodyField( - fieldWithPath("id").type(NUMBER).description("테이블 ID"), - fieldWithPath("info").type(OBJECT).description("토론 테이블 정보"), - fieldWithPath("info.name").type(STRING).description("테이블 이름"), - fieldWithPath("info.type").type(STRING).description("토론 형식"), - fieldWithPath("info.agenda").type(STRING).description("토론 주제"), - fieldWithPath("info.warningBell").type(BOOLEAN).description("30초 종소리 유무"), - fieldWithPath("info.finishBell").type(BOOLEAN).description("발언 종료 종소리 유무"), - fieldWithPath("table").type(ARRAY).description("토론 테이블 구성"), - fieldWithPath("table[].stance").type(STRING).description("입장"), - fieldWithPath("table[].type").type(STRING).description("발언 유형"), - fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)"), - fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), - fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), - fieldWithPath("table[].speakerNumber").type(NUMBER).description("발언자 번호").optional() - ); - - @Test - void 시간총량제_테이블_조회_성공() { - long tableId = 5L; - TimeBasedTableResponse response = new TimeBasedTableResponse( - 5L, - new TimeBasedTableInfoResponse("비토 테이블 1", TableType.PARLIAMENTARY, "토론 주제", true, true), - List.of( - new TimeBasedTimeBoxResponse(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, 1), - new TimeBasedTimeBoxResponse(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, 60, 1) - ) - ); - doReturn(response).when(timeBasedService).findTable(eq(tableId), any()); - - var document = document("time_based/get", 200) - .request(requestDocument) - .response(responseDocument) - .build(); - - given(document) - .contentType(ContentType.JSON) - .headers(EXIST_MEMBER_HEADER) - .pathParam("tableId", tableId) - .when().get("/api/table/time-based/{tableId}") - .then().statusCode(200); - } - - @ParameterizedTest - @EnumSource(value = ClientErrorCode.class, names = {"TABLE_NOT_FOUND", "NOT_TABLE_OWNER"}) - void 시간총량제_테이블_조회_실패(ClientErrorCode errorCode) { - long tableId = 5L; - doThrow(new DTClientErrorException(errorCode)).when(timeBasedService).findTable(eq(tableId), any()); - - var document = document("time_based/get", errorCode) - .request(requestDocument) - .response(ERROR_RESPONSE) - .build(); - - given(document) - .contentType(ContentType.JSON) - .headers(EXIST_MEMBER_HEADER) - .pathParam("tableId", tableId) - .when().get("/api/table/time-based/{tableId}") - .then().statusCode(errorCode.getStatus().value()); - } - } - - @Nested - class UpdateTable { - - private final RestDocumentationRequest requestDocument = request() - .tag(Tag.TIME_BASED_API) - .summary("시간총량제 토론 시간표 수정") - .requestHeader( - headerWithName(HttpHeaders.AUTHORIZATION).description("액세스 토큰") - ) - .pathParameter( - parameterWithName("tableId").description("테이블 ID") - ) - .requestBodyField( - fieldWithPath("info").type(OBJECT).description("토론 테이블 정보"), - fieldWithPath("info.name").type(STRING).description("테이블 이름"), - fieldWithPath("info.agenda").type(STRING).description("토론 주제"), - fieldWithPath("info.warningBell").type(BOOLEAN).description("30초 종소리 유무"), - fieldWithPath("info.finishBell").type(BOOLEAN).description("발언 종료 종소리 유무"), - fieldWithPath("table").type(ARRAY).description("토론 테이블 구성"), - fieldWithPath("table[].stance").type(STRING).description("입장"), - fieldWithPath("table[].type").type(STRING).description("발언 유형"), - fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)"), - fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), - fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), - fieldWithPath("table[].speakerNumber").type(NUMBER).description("발언자 번호").optional() - ); - - private final RestDocumentationResponse responseDocument = response() - .responseBodyField( - fieldWithPath("id").type(NUMBER).description("테이블 ID"), - fieldWithPath("info").type(OBJECT).description("토론 테이블 정보"), - fieldWithPath("info.name").type(STRING).description("테이블 이름"), - fieldWithPath("info.type").type(STRING).description("토론 형식"), - fieldWithPath("info.agenda").type(STRING).description("토론 주제"), - fieldWithPath("info.warningBell").type(BOOLEAN).description("30초 종소리 유무"), - fieldWithPath("info.finishBell").type(BOOLEAN).description("발언 종료 종소리 유무"), - fieldWithPath("table").type(ARRAY).description("토론 테이블 구성"), - fieldWithPath("table[].stance").type(STRING).description("입장"), - fieldWithPath("table[].type").type(STRING).description("발언 유형"), - fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)"), - fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), - fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), - fieldWithPath("table[].speakerNumber").type(NUMBER).description("발언자 번호").optional() - ); - - @Test - void 시간총량제_토론_테이블_수정() { - long tableId = 5L; - TimeBasedTableCreateRequest request = new TimeBasedTableCreateRequest( - new TimeBasedTableInfoCreateRequest("비토 테이블 2", "토론 주제 2", true, true), - List.of(new TimeBasedTimeBoxCreateRequest(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, - 1), - new TimeBasedTimeBoxCreateRequest(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, - 60, - 1))); - TimeBasedTableResponse response = new TimeBasedTableResponse( - 5L, - new TimeBasedTableInfoResponse("비토 테이블 2", TableType.PARLIAMENTARY, "토론 주제 2", true, true), - List.of( - new TimeBasedTimeBoxResponse(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, 1), - new TimeBasedTimeBoxResponse(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, 60, 1) - ) - ); - doReturn(response).when(timeBasedService).updateTable(eq(request), eq(tableId), any()); - - var document = document("time_based/patch", 200) - .request(requestDocument) - .response(responseDocument) - .build(); - - given(document) - .contentType(ContentType.JSON) - .headers(EXIST_MEMBER_HEADER) - .pathParam("tableId", tableId) - .body(request) - .when().put("/api/table/time-based/{tableId}") - .then().statusCode(200); - } - - @EnumSource( - value = ClientErrorCode.class, - names = { - "INVALID_TABLE_NAME_LENGTH", - "INVALID_TABLE_NAME_FORM", - "INVALID_TABLE_TIME", - "INVALID_TIME_BOX_SEQUENCE", - "INVALID_TIME_BOX_SPEAKER", - "INVALID_TIME_BOX_TIME", - "INVALID_TIME_BOX_STANCE", - "INVALID_TIME_BOX_FORMAT" - } - ) - @ParameterizedTest - void 시간총량제_테이블_생성_실패(ClientErrorCode errorCode) { - long tableId = 5L; - TimeBasedTableCreateRequest request = new TimeBasedTableCreateRequest( - new TimeBasedTableInfoCreateRequest("비토 테이블 2", "토론 주제 2", true, true), - List.of(new TimeBasedTimeBoxCreateRequest(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, - 1), - new TimeBasedTimeBoxCreateRequest(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, - 60, - 1))); - doThrow(new DTClientErrorException(errorCode)).when(timeBasedService) - .updateTable(eq(request), eq(tableId), any()); - - var document = document("time_based/patch", errorCode) - .request(requestDocument) - .response(ERROR_RESPONSE) - .build(); - - given(document) - .contentType(ContentType.JSON) - .headers(EXIST_MEMBER_HEADER) - .pathParam("tableId", tableId) - .body(request) - .when().put("/api/table/time-based/{tableId}") - .then().statusCode(errorCode.getStatus().value()); - } - } - - @Nested - class Debate { - - private final RestDocumentationRequest requestDocument = request() - .summary("시간총량제 토론 시작") - .tag(Tag.TIME_BASED_API) - .requestHeader( - headerWithName(HttpHeaders.AUTHORIZATION).description("액세스 토큰") - ) - .pathParameter( - parameterWithName("tableId").description("테이블 ID") - ); - - private final RestDocumentationResponse responseDocument = response() - .responseBodyField( - fieldWithPath("id").type(NUMBER).description("테이블 ID"), - fieldWithPath("info").type(OBJECT).description("토론 테이블 정보"), - fieldWithPath("info.name").type(STRING).description("테이블 이름"), - fieldWithPath("info.type").type(STRING).description("토론 형식"), - fieldWithPath("info.agenda").type(STRING).description("토론 주제"), - fieldWithPath("info.warningBell").type(BOOLEAN).description("30초 종소리 유무"), - fieldWithPath("info.finishBell").type(BOOLEAN).description("발언 종료 종소리 유무"), - fieldWithPath("table").type(ARRAY).description("토론 테이블 구성"), - fieldWithPath("table[].stance").type(STRING).description("입장"), - fieldWithPath("table[].type").type(STRING).description("발언 유형"), - fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)"), - fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), - fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), - fieldWithPath("table[].speakerNumber").type(NUMBER).description("발언자 번호").optional() - ); - - @Test - void 시간총량제_토론_진행_성공() { - long tableId = 5L; - TimeBasedTableResponse response = new TimeBasedTableResponse( - 5L, - new TimeBasedTableInfoResponse("비토 테이블 1", TableType.PARLIAMENTARY, "토론 주제", true, true), - List.of( - new TimeBasedTimeBoxResponse(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, 1), - new TimeBasedTimeBoxResponse(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, 60, 1) - ) - ); - doReturn(response).when(timeBasedService).updateUsedAt(eq(tableId), any()); - - var document = document("time_based/patch_debate", 200) - .request(requestDocument) - .response(responseDocument) - .build(); - - given(document) - .contentType(ContentType.JSON) - .headers(EXIST_MEMBER_HEADER) - .pathParam("tableId", tableId) - .when().patch("/api/table/time-based/{tableId}/debate") - .then().statusCode(200); - } - - @ParameterizedTest - @EnumSource(value = ClientErrorCode.class, names = {"TABLE_NOT_FOUND", "NOT_TABLE_OWNER"}) - void 시간총량제_토론_진행_실패(ClientErrorCode errorCode) { - long tableId = 5L; - doThrow(new DTClientErrorException(errorCode)).when(timeBasedService).updateUsedAt(eq(tableId), any()); - - var document = document("time_based/get", errorCode) - .request(requestDocument) - .response(ERROR_RESPONSE) - .build(); - - given(document) - .contentType(ContentType.JSON) - .headers(EXIST_MEMBER_HEADER) - .pathParam("tableId", tableId) - .when().patch("/api/table/time-based/{tableId}/debate") - .then().statusCode(errorCode.getStatus().value()); - } - } - - @Nested - class DeleteTable { - - private final RestDocumentationRequest requestDocument = request() - .tag(Tag.TIME_BASED_API) - .summary("시간총량제 토론 시간표 삭제") - .requestHeader( - headerWithName(HttpHeaders.AUTHORIZATION).description("액세스 토큰") - ) - .pathParameter( - parameterWithName("tableId").description("테이블 ID") - ); - - @Test - void 시간총량제_테이블_삭제_성공() { - long tableId = 5L; - doNothing().when(timeBasedService).deleteTable(eq(tableId), any()); - - var document = document("time_based/delete", 204) - .request(requestDocument) - .build(); - - given(document) - .headers(EXIST_MEMBER_HEADER) - .pathParam("tableId", tableId) - .when().delete("/api/table/time-based/{tableId}") - .then().statusCode(204); - } - - @EnumSource(value = ClientErrorCode.class, names = {"TABLE_NOT_FOUND", "NOT_TABLE_OWNER"}) - @ParameterizedTest - void 시간총량제_테이블_삭제_실패(ClientErrorCode errorCode) { - long tableId = 5L; - doThrow(new DTClientErrorException(errorCode)).when(timeBasedService).deleteTable(eq(tableId), any()); - - var document = document("time_based/delete", errorCode) - .request(requestDocument) - .response(ERROR_RESPONSE) - .build(); - - given(document) - .headers(EXIST_MEMBER_HEADER) - .pathParam("tableId", tableId) - .when().delete("/api/table/time-based/{tableId}") - .then().statusCode(errorCode.getStatus().value()); - } - } -} diff --git a/src/test/java/com/debatetimer/domain/timebased/TimeBasedTableTest.java b/src/test/java/com/debatetimer/domain/timebased/TimeBasedTableTest.java deleted file mode 100644 index 73a7cbcf..00000000 --- a/src/test/java/com/debatetimer/domain/timebased/TimeBasedTableTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.debatetimer.domain.timebased; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.debatetimer.dto.member.TableType; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -class TimeBasedTableTest { - - @Nested - class GetType { - - @Test - void 시간총량제_테이블_타입을_반환한다() { - TimeBasedTable timeBasedTable = new TimeBasedTable(); - - assertThat(timeBasedTable.getType()).isEqualTo(TableType.TIME_BASED); - } - } -} diff --git a/src/test/java/com/debatetimer/domain/timebased/TimeBasedTimeBoxTest.java b/src/test/java/com/debatetimer/domain/timebased/TimeBasedTimeBoxTest.java deleted file mode 100644 index 5ea3b7ae..00000000 --- a/src/test/java/com/debatetimer/domain/timebased/TimeBasedTimeBoxTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.debatetimer.domain.timebased; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.debatetimer.domain.Stance; -import com.debatetimer.exception.custom.DTClientErrorException; -import com.debatetimer.exception.errorcode.ClientErrorCode; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -class TimeBasedTimeBoxTest { - - @Nested - class ValidateStance { - - @Test - void 박스타입에_가능한_입장을_검증한다() { - TimeBasedTable table = new TimeBasedTable(); - - assertThatCode(() -> new TimeBasedTimeBox(table, 1, Stance.CONS, TimeBasedBoxType.OPENING, 10, 1)) - .doesNotThrowAnyException(); - } - - @Test - void 박스타입에_불가한_입장으로_생성을_시도하면_예외를_발생시킨다() { - TimeBasedTable table = new TimeBasedTable(); - - assertThatThrownBy( - () -> new TimeBasedTimeBox(table, 1, Stance.NEUTRAL, TimeBasedBoxType.OPENING, 10, 1)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_TIME_BOX_STANCE.getMessage()); - } - } - - @Nested - class ValidateTimeBased { - - @Test - void 시간총량제_타입은_개인_발언_시간과_팀_발언_시간을_입력해야_한다() { - TimeBasedTable table = new TimeBasedTable(); - TimeBasedBoxType timeBasedBoxType = TimeBasedBoxType.TIME_BASED; - - assertThatCode(() -> new TimeBasedTimeBox(table, 1, Stance.NEUTRAL, timeBasedBoxType, 120, 60, 1)) - .doesNotThrowAnyException(); - } - - @Test - void 시간총량제_타입이_개인_발언_시간과_팀_발언_시간을_입력하지_않을_경우_예외가_발생한다() { - TimeBasedTable table = new TimeBasedTable(); - TimeBasedBoxType timeBasedBoxType = TimeBasedBoxType.TIME_BASED; - - assertThatThrownBy(() -> new TimeBasedTimeBox(table, 1, Stance.NEUTRAL, timeBasedBoxType, 10, 1)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_TIME_BOX_FORMAT.getMessage()); - } - - @Test - void 시간총량제가_아닌_타입이__개인_발언_시간과_팀_발언_시간을_입력할_경우_예외가_발생한다() { - TimeBasedTable table = new TimeBasedTable(); - TimeBasedBoxType notTimeBasedBoxType = TimeBasedBoxType.TIME_OUT; - - assertThatThrownBy( - () -> new TimeBasedTimeBox(table, 1, Stance.NEUTRAL, notTimeBasedBoxType, 120, 60, 1)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_TIME_BOX_FORMAT.getMessage()); - } - - @Test - void 개인_발언_시간은_팀_발언_시간보다_적거나_같아야_한다() { - TimeBasedTable table = new TimeBasedTable(); - int timePerTeam = 60; - int timePerSpeaking = 59; - - assertThatCode( - () -> new TimeBasedTimeBox(table, 1, Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, - timePerTeam, timePerSpeaking, 1)) - .doesNotThrowAnyException(); - } - - @Test - void 개인_발언_시간이_팀_발언_시간보다_길면_예외가_발생한다() { - TimeBasedTable table = new TimeBasedTable(); - int timePerTeam = 60; - int timePerSpeaking = 61; - - assertThatThrownBy( - () -> new TimeBasedTimeBox(table, 1, Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, - timePerTeam, timePerSpeaking, 1)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_TIME_BASED_TIME.getMessage()); - } - } - - @Nested - class ValidateSpeakerNumber { - - @ValueSource(ints = {0, -1}) - @ParameterizedTest - void 시간총량제_타임박스의_발표자_번호는_양수만_가능하다(int speaker) { - TimeBasedTable table = new TimeBasedTable(); - - assertThatThrownBy(() -> new TimeBasedTimeBox(table, 1, Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, - 120, 60, speaker)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_TIME_BOX_SPEAKER.getMessage()); - } - } - - @Nested - class getTime { - - @Test - void 자유_토론_타임_박스의_시간은_팀_당_발언_시간의_배수이어야_한다() { - int timePerTeam = 300; - int timePerSpeaking = 120; - TimeBasedTable table = new TimeBasedTable(); - TimeBasedTimeBox timeBasedTimeBox = new TimeBasedTimeBox(table, 1, Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, - timePerTeam, timePerSpeaking, 1); - - assertThat(timeBasedTimeBox.getTime()).isEqualTo(timePerTeam * TimeBasedTimeBox.TIME_MULTIPLIER); - } - } -} diff --git a/src/test/java/com/debatetimer/fixture/HeaderGenerator.java b/src/test/java/com/debatetimer/fixture/HeaderGenerator.java index 4e641ae5..a8a6b8bb 100644 --- a/src/test/java/com/debatetimer/fixture/HeaderGenerator.java +++ b/src/test/java/com/debatetimer/fixture/HeaderGenerator.java @@ -1,9 +1,8 @@ package com.debatetimer.fixture; +import com.debatetimer.controller.tool.jwt.JwtTokenProvider; import com.debatetimer.domain.member.Member; import com.debatetimer.dto.member.MemberInfo; -import com.debatetimer.controller.tool.jwt.JwtTokenProvider; -import com.debatetimer.controller.tool.cookie.CookieProvider; import io.restassured.http.Header; import io.restassured.http.Headers; import org.springframework.http.HttpHeaders; @@ -13,11 +12,9 @@ public class HeaderGenerator { private final JwtTokenProvider jwtTokenProvider; - private final CookieProvider cookieProvider; - public HeaderGenerator(JwtTokenProvider jwtTokenProvider, CookieProvider cookieProvider) { + public HeaderGenerator(JwtTokenProvider jwtTokenProvider) { this.jwtTokenProvider = jwtTokenProvider; - this.cookieProvider = cookieProvider; } public Headers generateAccessTokenHeader(Member member) { diff --git a/src/test/java/com/debatetimer/fixture/TimeBasedTableGenerator.java b/src/test/java/com/debatetimer/fixture/TimeBasedTableGenerator.java deleted file mode 100644 index 51fd2c2a..00000000 --- a/src/test/java/com/debatetimer/fixture/TimeBasedTableGenerator.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.debatetimer.fixture; - -import com.debatetimer.domain.member.Member; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.repository.timebased.TimeBasedTableRepository; -import org.springframework.stereotype.Component; - -@Component -public class TimeBasedTableGenerator { - - private final TimeBasedTableRepository timeBasedTableRepository; - - public TimeBasedTableGenerator(TimeBasedTableRepository timeBasedTableRepository) { - this.timeBasedTableRepository = timeBasedTableRepository; - } - - public TimeBasedTable generate(Member member) { - TimeBasedTable table = new TimeBasedTable( - member, - "토론 테이블", - "주제", - false, - false - ); - return timeBasedTableRepository.save(table); - } -} diff --git a/src/test/java/com/debatetimer/fixture/TimeBasedTimeBoxGenerator.java b/src/test/java/com/debatetimer/fixture/TimeBasedTimeBoxGenerator.java deleted file mode 100644 index f1df0beb..00000000 --- a/src/test/java/com/debatetimer/fixture/TimeBasedTimeBoxGenerator.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.debatetimer.fixture; - -import com.debatetimer.domain.Stance; -import com.debatetimer.domain.timebased.TimeBasedBoxType; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.domain.timebased.TimeBasedTimeBox; -import com.debatetimer.repository.timebased.TimeBasedTimeBoxRepository; -import org.springframework.stereotype.Component; - -@Component -public class TimeBasedTimeBoxGenerator { - - private final TimeBasedTimeBoxRepository timeBasedTimeBoxRepository; - - public TimeBasedTimeBoxGenerator(TimeBasedTimeBoxRepository timeBasedTimeBoxRepository) { - this.timeBasedTimeBoxRepository = timeBasedTimeBoxRepository; - } - - public TimeBasedTimeBox generate(TimeBasedTable testTable, int sequence) { - TimeBasedTimeBox timeBox = new TimeBasedTimeBox(testTable, sequence, Stance.PROS, - TimeBasedBoxType.OPENING, 180, 1); - return timeBasedTimeBoxRepository.save(timeBox); - } - - public TimeBasedTimeBox generateNotExistSpeaker(TimeBasedTable testTable, int sequence) { - TimeBasedTimeBox timeBox = new TimeBasedTimeBox(testTable, sequence, Stance.PROS, - TimeBasedBoxType.OPENING, 180, null); - return timeBasedTimeBoxRepository.save(timeBox); - } -} diff --git a/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java b/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java index ea98a19a..445e5384 100644 --- a/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java @@ -6,8 +6,6 @@ import com.debatetimer.fixture.MemberGenerator; import com.debatetimer.fixture.ParliamentaryTableGenerator; import com.debatetimer.fixture.ParliamentaryTimeBoxGenerator; -import com.debatetimer.fixture.TimeBasedTableGenerator; -import com.debatetimer.fixture.TimeBasedTimeBoxGenerator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; @@ -17,8 +15,6 @@ MemberGenerator.class, ParliamentaryTableGenerator.class, ParliamentaryTimeBoxGenerator.class, - TimeBasedTableGenerator.class, - TimeBasedTimeBoxGenerator.class, CustomizeTableGenerator.class, CustomizeTimeBoxGenerator.class }) @@ -34,12 +30,6 @@ public abstract class BaseRepositoryTest { @Autowired protected ParliamentaryTimeBoxGenerator parliamentaryTimeBoxGenerator; - @Autowired - protected TimeBasedTableGenerator timeBasedTableGenerator; - - @Autowired - protected TimeBasedTimeBoxGenerator timeBasedTimeBoxGenerator; - @Autowired protected CustomizeTableGenerator customizeTableGenerator; diff --git a/src/test/java/com/debatetimer/repository/timebased/TimeBasedTableRepositoryTest.java b/src/test/java/com/debatetimer/repository/timebased/TimeBasedTableRepositoryTest.java deleted file mode 100644 index 16739d4e..00000000 --- a/src/test/java/com/debatetimer/repository/timebased/TimeBasedTableRepositoryTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.debatetimer.repository.timebased; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import com.debatetimer.domain.member.Member; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.exception.custom.DTClientErrorException; -import com.debatetimer.exception.errorcode.ClientErrorCode; -import com.debatetimer.repository.BaseRepositoryTest; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; - -class TimeBasedTableRepositoryTest extends BaseRepositoryTest { - - @Autowired - private TimeBasedTableRepository tableRepository; - - @Nested - class FindAllByMember { - - @Test - void 특정_회원의_테이블만_조회한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member bito = memberGenerator.generate("default2@gmail.com"); - TimeBasedTable chanTable1 = timeBasedTableGenerator.generate(chan); - TimeBasedTable chanTable2 = timeBasedTableGenerator.generate(chan); - TimeBasedTable bitoTable = timeBasedTableGenerator.generate(bito); - - List foundKeoChanTables = tableRepository.findAllByMember(chan); - - assertThat(foundKeoChanTables).containsExactly(chanTable1, chanTable2); - } - } - - @Nested - class GetById { - - @Test - void 특정_아이디의_테이블을_조회한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - TimeBasedTable chanTable = timeBasedTableGenerator.generate(chan); - - TimeBasedTable foundChanTable = tableRepository.getById(chanTable.getId()); - - assertThat(foundChanTable).usingRecursiveComparison().isEqualTo(chanTable); - } - - @Test - void 특정_아이디의_테이블이_없으면_에러를_발생시킨다() { - assertThatThrownBy(() -> tableRepository.getById(1L)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.TABLE_NOT_FOUND.getMessage()); - } - } -} diff --git a/src/test/java/com/debatetimer/repository/timebased/TimeBasedTimeBoxRepositoryTest.java b/src/test/java/com/debatetimer/repository/timebased/TimeBasedTimeBoxRepositoryTest.java deleted file mode 100644 index 5b5af88e..00000000 --- a/src/test/java/com/debatetimer/repository/timebased/TimeBasedTimeBoxRepositoryTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.debatetimer.repository.timebased; - -import static org.assertj.core.api.Assertions.assertThat; - -import com.debatetimer.domain.member.Member; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.domain.timebased.TimeBasedTimeBox; -import com.debatetimer.repository.BaseRepositoryTest; -import java.util.List; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; - -class TimeBasedTimeBoxRepositoryTest extends BaseRepositoryTest { - - @Autowired - private TimeBasedTimeBoxRepository timeBasedTimeBoxRepository; - - @Nested - class FindAllByParliamentaryTable { - - @Test - void 특정_테이블의_타임박스를_모두_조회한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member bito = memberGenerator.generate("default2@gmail.com"); - TimeBasedTable chanTable = timeBasedTableGenerator.generate(chan); - TimeBasedTable bitoTable = timeBasedTableGenerator.generate(bito); - TimeBasedTimeBox chanBox1 = timeBasedTimeBoxGenerator.generate(chanTable, 1); - TimeBasedTimeBox chanBox2 = timeBasedTimeBoxGenerator.generate(chanTable, 2); - TimeBasedTimeBox bitoBox1 = timeBasedTimeBoxGenerator.generate(bitoTable, 2); - TimeBasedTimeBox bitoBox2 = timeBasedTimeBoxGenerator.generate(bitoTable, 2); - - List foundBoxes = timeBasedTimeBoxRepository.findAllByTimeBasedTable( - chanTable); - - assertThat(foundBoxes).containsExactly(chanBox1, chanBox2); - } - } -} diff --git a/src/test/java/com/debatetimer/service/BaseServiceTest.java b/src/test/java/com/debatetimer/service/BaseServiceTest.java index 69cb79bc..0f93d39c 100644 --- a/src/test/java/com/debatetimer/service/BaseServiceTest.java +++ b/src/test/java/com/debatetimer/service/BaseServiceTest.java @@ -6,15 +6,11 @@ import com.debatetimer.fixture.MemberGenerator; import com.debatetimer.fixture.ParliamentaryTableGenerator; import com.debatetimer.fixture.ParliamentaryTimeBoxGenerator; -import com.debatetimer.fixture.TimeBasedTableGenerator; -import com.debatetimer.fixture.TimeBasedTimeBoxGenerator; import com.debatetimer.repository.customize.CustomizeTableRepository; import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; import com.debatetimer.repository.member.MemberRepository; import com.debatetimer.repository.parliamentary.ParliamentaryTableRepository; import com.debatetimer.repository.parliamentary.ParliamentaryTimeBoxRepository; -import com.debatetimer.repository.timebased.TimeBasedTableRepository; -import com.debatetimer.repository.timebased.TimeBasedTimeBoxRepository; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -32,12 +28,6 @@ public abstract class BaseServiceTest { @Autowired protected ParliamentaryTimeBoxRepository parliamentaryTimeBoxRepository; - @Autowired - protected TimeBasedTableRepository timeBasedTableRepository; - - @Autowired - protected TimeBasedTimeBoxRepository timeBasedTimeBoxRepository; - @Autowired protected CustomizeTableRepository customizeTableRepository; @@ -53,12 +43,6 @@ public abstract class BaseServiceTest { @Autowired protected ParliamentaryTimeBoxGenerator parliamentaryTimeBoxGenerator; - @Autowired - protected TimeBasedTableGenerator timeBasedTableGenerator; - - @Autowired - protected TimeBasedTimeBoxGenerator timeBasedTimeBoxGenerator; - @Autowired protected CustomizeTableGenerator customizeTableGenerator; diff --git a/src/test/java/com/debatetimer/service/timebased/TimeBasedServiceTest.java b/src/test/java/com/debatetimer/service/timebased/TimeBasedServiceTest.java deleted file mode 100644 index be5410fa..00000000 --- a/src/test/java/com/debatetimer/service/timebased/TimeBasedServiceTest.java +++ /dev/null @@ -1,208 +0,0 @@ -package com.debatetimer.service.timebased; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertAll; - -import com.debatetimer.domain.Stance; -import com.debatetimer.domain.member.Member; -import com.debatetimer.domain.timebased.TimeBasedBoxType; -import com.debatetimer.domain.timebased.TimeBasedTable; -import com.debatetimer.domain.timebased.TimeBasedTimeBox; -import com.debatetimer.dto.timebased.request.TimeBasedTableCreateRequest; -import com.debatetimer.dto.timebased.request.TimeBasedTableInfoCreateRequest; -import com.debatetimer.dto.timebased.request.TimeBasedTimeBoxCreateRequest; -import com.debatetimer.dto.timebased.response.TimeBasedTableResponse; -import com.debatetimer.exception.custom.DTClientErrorException; -import com.debatetimer.exception.errorcode.ClientErrorCode; -import com.debatetimer.service.BaseServiceTest; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; - -class TimeBasedServiceTest extends BaseServiceTest { - - @Autowired - private TimeBasedService timeBasedService; - - @Nested - class Save { - - @Test - void 시간총량제_토론_테이블을_생성한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - TimeBasedTableCreateRequest chanTableRequest = new TimeBasedTableCreateRequest( - new TimeBasedTableInfoCreateRequest("커찬의 테이블", "주제", true, true), - List.of(new TimeBasedTimeBoxCreateRequest(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, - 1), - new TimeBasedTimeBoxCreateRequest(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, - 60, - 1))); - - TimeBasedTableResponse savedTableResponse = timeBasedService.save(chanTableRequest, chan); - Optional foundTable = timeBasedTableRepository.findById(savedTableResponse.id()); - List foundTimeBoxes = timeBasedTimeBoxRepository.findAllByTimeBasedTable( - foundTable.get()); - - assertAll( - () -> assertThat(foundTable.get().getName()).isEqualTo(chanTableRequest.info().name()), - () -> assertThat(foundTimeBoxes).hasSize(chanTableRequest.table().size()) - ); - } - } - - @Nested - class FindTable { - - @Test - void 시간총량제_토론_테이블을_조회한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - TimeBasedTable chanTable = timeBasedTableGenerator.generate(chan); - timeBasedTimeBoxGenerator.generate(chanTable, 1); - timeBasedTimeBoxGenerator.generate(chanTable, 2); - - TimeBasedTableResponse foundResponse = timeBasedService.findTable(chanTable.getId(), chan); - - assertAll( - () -> assertThat(foundResponse.id()).isEqualTo(chanTable.getId()), - () -> assertThat(foundResponse.table()).hasSize(2) - ); - } - - @Test - void 회원_소유가_아닌_테이블_조회_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - TimeBasedTable chanTable = timeBasedTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - - assertThatThrownBy(() -> timeBasedService.findTable(chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.NOT_TABLE_OWNER.getMessage()); - } - } - - @Nested - class UpdateTable { - - @Test - void 시간총량제_토론_테이블을_수정한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - TimeBasedTable chanTable = timeBasedTableGenerator.generate(chan); - TimeBasedTableCreateRequest renewTableRequest = new TimeBasedTableCreateRequest( - new TimeBasedTableInfoCreateRequest("커찬의 테이블", "주제", true, true), - List.of(new TimeBasedTimeBoxCreateRequest(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, - 1), - new TimeBasedTimeBoxCreateRequest(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, - 60, - 1))); - - timeBasedService.updateTable(renewTableRequest, chanTable.getId(), chan); - - Optional updatedTable = timeBasedTableRepository.findById(chanTable.getId()); - List updatedTimeBoxes = timeBasedTimeBoxRepository.findAllByTimeBasedTable( - updatedTable.get()); - - assertAll( - () -> assertThat(updatedTable.get().getId()).isEqualTo(chanTable.getId()), - () -> assertThat(updatedTable.get().getName()).isEqualTo(renewTableRequest.info().name()), - () -> assertThat(updatedTimeBoxes).hasSize(renewTableRequest.table().size()) - ); - } - - @Test - void 회원_소유가_아닌_테이블_수정_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - TimeBasedTable chanTable = timeBasedTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - TimeBasedTableCreateRequest renewTableRequest = new TimeBasedTableCreateRequest( - new TimeBasedTableInfoCreateRequest("새로운 테이블", "주제", true, true), - List.of(new TimeBasedTimeBoxCreateRequest(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, - 1), - new TimeBasedTimeBoxCreateRequest(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, - 60, - 1))); - - assertThatThrownBy(() -> timeBasedService.updateTable(renewTableRequest, chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.NOT_TABLE_OWNER.getMessage()); - } - } - - @Nested - class UpdateUsedAt { - - @Test - void 시간총량제_토론_테이블의_사용_시각을_최신화한다() { - Member member = memberGenerator.generate("default@gmail.com"); - TimeBasedTable table = timeBasedTableGenerator.generate(member); - LocalDateTime beforeUsedAt = table.getUsedAt(); - - timeBasedService.updateUsedAt(table.getId(), member); - - Optional updatedTable = timeBasedTableRepository.findById(table.getId()); - assertAll( - () -> assertThat(updatedTable.get().getId()).isEqualTo(table.getId()), - () -> assertThat(updatedTable.get().getUsedAt()).isAfter(beforeUsedAt) - ); - } - - @Test - void 회원_소유가_아닌_테이블_수정_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - TimeBasedTable chanTable = timeBasedTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - TimeBasedTableCreateRequest renewTableRequest = new TimeBasedTableCreateRequest( - new TimeBasedTableInfoCreateRequest("새로운 테이블", "주제", true, true), - List.of(new TimeBasedTimeBoxCreateRequest(Stance.PROS, TimeBasedBoxType.OPENING, 120, null, null, - 1), - new TimeBasedTimeBoxCreateRequest(Stance.NEUTRAL, TimeBasedBoxType.TIME_BASED, 360, 180, - 60, - 1))); - - assertThatThrownBy(() -> timeBasedService.updateTable(renewTableRequest, chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.NOT_TABLE_OWNER.getMessage()); - } - } - - @Nested - class DeleteTable { - - @Test - void 시간총량제_토론_테이블을_삭제한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - TimeBasedTable chanTable = timeBasedTableGenerator.generate(chan); - timeBasedTimeBoxGenerator.generate(chanTable, 1); - timeBasedTimeBoxGenerator.generate(chanTable, 2); - - timeBasedService.deleteTable(chanTable.getId(), chan); - - Optional foundTable = timeBasedTableRepository.findById(chanTable.getId()); - List timeBoxes = timeBasedTimeBoxRepository.findAllByTimeBasedTable( - chanTable); - - assertAll( - () -> assertThat(foundTable).isEmpty(), - () -> assertThat(timeBoxes).isEmpty() - ); - } - - @Test - void 회원_소유가_아닌_테이블_삭제_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - TimeBasedTable chanTable = timeBasedTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - - assertThatThrownBy(() -> timeBasedService.deleteTable(chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.NOT_TABLE_OWNER.getMessage()); - } - } -}