From cb8b6551613ecf0408dac681c2b2b03a46787295 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sat, 26 Jul 2025 14:18:01 +0900 Subject: [PATCH 01/15] =?UTF-8?q?refactor:=20bell=5Ftype=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EC=84=9C=EB=B9=84=EC=8A=A4=20v2?= =?UTF-8?q?=EB=A1=9C=20=EA=B5=90=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../debatetimer/domain/customize/Bell.java | 4 +- .../domain/customize/BellType.java | 9 + .../dto/customize/request/BellRequest.java | 6 +- .../dto/customize/response/BellResponse.java | 4 +- .../entity/customize/BellEntity.java | 14 +- .../service/customize/CustomizeService.java | 62 +++-- .../service/customize/CustomizeServiceV2.java | 98 ------- .../V12__add_bell_type_into_bell.sql | 2 + .../customize/CustomizeDocumentTest.java | 63 +++-- .../domain/customize/BellTest.java | 8 +- .../entity/customize/BellEntityTest.java | 5 +- .../debatetimer/fixture/BellGenerator.java | 5 +- .../customize/BellRepositoryTest.java | 7 +- .../customize/CustomizeServiceTest.java | 45 ++-- .../customize/CustomizeServiceV2Test.java | 243 ------------------ 15 files changed, 153 insertions(+), 422 deletions(-) create mode 100644 src/main/java/com/debatetimer/domain/customize/BellType.java delete mode 100644 src/main/java/com/debatetimer/service/customize/CustomizeServiceV2.java create mode 100644 src/main/resources/db/migration/V12__add_bell_type_into_bell.sql delete mode 100644 src/test/java/com/debatetimer/service/customize/CustomizeServiceV2Test.java diff --git a/src/main/java/com/debatetimer/domain/customize/Bell.java b/src/main/java/com/debatetimer/domain/customize/Bell.java index 58fb4443..9488bef6 100644 --- a/src/main/java/com/debatetimer/domain/customize/Bell.java +++ b/src/main/java/com/debatetimer/domain/customize/Bell.java @@ -9,12 +9,14 @@ public class Bell { public static final int MAX_BELL_COUNT = 3; + private final BellType type; private final int time; private final int count; - public Bell(int time, int count) { + public Bell(BellType type, int time, int count) { validateTime(time); validateCount(count); + this.type = type; this.time = time; this.count = count; } diff --git a/src/main/java/com/debatetimer/domain/customize/BellType.java b/src/main/java/com/debatetimer/domain/customize/BellType.java new file mode 100644 index 00000000..56bc3134 --- /dev/null +++ b/src/main/java/com/debatetimer/domain/customize/BellType.java @@ -0,0 +1,9 @@ +package com.debatetimer.domain.customize; + +public enum BellType { + + AFTER_START, + BEFORE_END, + AFTER_END, + ; +} diff --git a/src/main/java/com/debatetimer/dto/customize/request/BellRequest.java b/src/main/java/com/debatetimer/dto/customize/request/BellRequest.java index fa5f2d88..5142fe8c 100644 --- a/src/main/java/com/debatetimer/dto/customize/request/BellRequest.java +++ b/src/main/java/com/debatetimer/dto/customize/request/BellRequest.java @@ -1,13 +1,17 @@ package com.debatetimer.dto.customize.request; import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.BellType; +import jakarta.validation.constraints.NotNull; public record BellRequest( + @NotNull + BellType type, int time, int count ) { public Bell toDomain() { - return new Bell(time, count); + return new Bell(type, time, count); } } diff --git a/src/main/java/com/debatetimer/dto/customize/response/BellResponse.java b/src/main/java/com/debatetimer/dto/customize/response/BellResponse.java index 0ec2b060..080782d5 100644 --- a/src/main/java/com/debatetimer/dto/customize/response/BellResponse.java +++ b/src/main/java/com/debatetimer/dto/customize/response/BellResponse.java @@ -1,13 +1,15 @@ package com.debatetimer.dto.customize.response; import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.BellType; public record BellResponse( + BellType type, int time, int count ) { public BellResponse(Bell bell) { - this(bell.getTime(), bell.getCount()); + this(bell.getType(), bell.getTime(), bell.getCount()); } } diff --git a/src/main/java/com/debatetimer/entity/customize/BellEntity.java b/src/main/java/com/debatetimer/entity/customize/BellEntity.java index 9c1f9982..81c33816 100644 --- a/src/main/java/com/debatetimer/entity/customize/BellEntity.java +++ b/src/main/java/com/debatetimer/entity/customize/BellEntity.java @@ -1,10 +1,13 @@ package com.debatetimer.entity.customize; import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.exception.custom.DTClientErrorException; import com.debatetimer.exception.errorcode.ClientErrorCode; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -34,21 +37,28 @@ public class BellEntity { @JoinColumn(name = "customize_time_box_id") private CustomizeTimeBoxEntity customizeTimeBox; + @Column(name = "bell_type") + @NotNull + @Enumerated(value = EnumType.STRING) + private BellType type; + @Column(name = "bell_time") private int time; private int count; - public BellEntity(CustomizeTimeBoxEntity customizeTimeBox, int time, int count) { + public BellEntity(CustomizeTimeBoxEntity customizeTimeBox, BellType type, int time, int count) { validateTime(time); validateCount(count); this.customizeTimeBox = customizeTimeBox; + this.type = type; this.time = time; this.count = count; } public BellEntity(CustomizeTimeBoxEntity customizeTimeBox, Bell bell) { this.customizeTimeBox = customizeTimeBox; + this.type = bell.getType(); this.time = bell.getTime(); this.count = bell.getCount(); } @@ -66,7 +76,7 @@ private void validateCount(int count) { } public Bell toDomain() { - return new Bell(time, count); + return new Bell(type, time, count); } public boolean isContained(CustomizeTimeBoxEntity timeBox) { diff --git a/src/main/java/com/debatetimer/service/customize/CustomizeService.java b/src/main/java/com/debatetimer/service/customize/CustomizeService.java index 13b3e44d..02c542ad 100644 --- a/src/main/java/com/debatetimer/service/customize/CustomizeService.java +++ b/src/main/java/com/debatetimer/service/customize/CustomizeService.java @@ -1,15 +1,19 @@ package com.debatetimer.service.customize; import com.debatetimer.domain.customize.CustomizeTable; +import com.debatetimer.domain.customize.CustomizeTimeBox; import com.debatetimer.domain.member.Member; import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; import com.debatetimer.dto.customize.response.CustomizeTableResponse; +import com.debatetimer.entity.customize.BellEntity; import com.debatetimer.entity.customize.CustomizeTableEntity; import com.debatetimer.entity.customize.CustomizeTimeBoxEntities; import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; +import com.debatetimer.repository.customize.BellRepository; import com.debatetimer.repository.customize.CustomizeTableRepository; import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; import java.util.List; +import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -20,21 +24,26 @@ public class CustomizeService { private final CustomizeTableRepository tableRepository; private final CustomizeTimeBoxRepository timeBoxRepository; + private final BellRepository bellRepository; @Transactional public CustomizeTableResponse save(CustomizeTableCreateRequest tableCreateRequest, Member member) { CustomizeTable table = tableCreateRequest.toTable(member); - CustomizeTableEntity savedTable = tableRepository.save(new CustomizeTableEntity(table)); + List timeBoxes = tableCreateRequest.toTimeBoxList(); - CustomizeTimeBoxEntities savedCustomizeTimeBoxes = saveTimeBoxes(tableCreateRequest, savedTable.toDomain()); - return new CustomizeTableResponse(savedTable.toDomain(), savedCustomizeTimeBoxes); + CustomizeTableEntity savedTableEntity = tableRepository.save(new CustomizeTableEntity(table)); + saveTimeBoxes(savedTableEntity, timeBoxes); + return new CustomizeTableResponse(savedTableEntity.toDomain(), timeBoxes); } @Transactional(readOnly = true) public CustomizeTableResponse findTable(long tableId, Member member) { CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - CustomizeTimeBoxEntities timeBoxes = timeBoxRepository.findTableTimeBoxes(tableEntity); - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); + List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); + List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); + CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); + + return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxEntities.toDomain()); } @Transactional @@ -43,38 +52,47 @@ public CustomizeTableResponse updateTable( long tableId, Member member ) { - CustomizeTableEntity existingTable = tableRepository.getByIdAndMember(tableId, member); - CustomizeTable renewedTable = tableCreateRequest.toTable(member); - existingTable.updateTable(renewedTable); + CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); + tableEntity.updateTable(tableCreateRequest.toTable(member)); - timeBoxRepository.deleteAllByTable(existingTable.getId()); - CustomizeTimeBoxEntities savedCustomizeTimeBoxes = saveTimeBoxes(tableCreateRequest, existingTable.toDomain()); - return new CustomizeTableResponse(existingTable.toDomain(), savedCustomizeTimeBoxes); + bellRepository.deleteAllByTable(tableEntity.getId()); + timeBoxRepository.deleteAllByTable(tableEntity.getId()); + List timeBoxes = tableCreateRequest.toTimeBoxList(); + saveTimeBoxes(tableEntity, timeBoxes); + return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); } @Transactional public CustomizeTableResponse updateUsedAt(long tableId, Member member) { CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - CustomizeTimeBoxEntities timeBoxes = timeBoxRepository.findTableTimeBoxes(tableEntity); - tableEntity.updateUsedAt(); + List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); + List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); + CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); + tableEntity.updateUsedAt(); + CustomizeTable table = tableEntity.toDomain(); + List timeBoxes = timeBoxEntities.toDomain(); + return new CustomizeTableResponse(table, timeBoxes); } @Transactional public void deleteTable(long tableId, Member member) { CustomizeTableEntity table = tableRepository.getByIdAndMember(tableId, member); + + bellRepository.deleteAllByTable(table.getId()); timeBoxRepository.deleteAllByTable(table.getId()); tableRepository.delete(table); } - private CustomizeTimeBoxEntities saveTimeBoxes( - CustomizeTableCreateRequest tableCreateRequest, - CustomizeTable table - ) { - CustomizeTimeBoxEntities customizeTimeBoxes = tableCreateRequest.toTimeBoxes(table); - List savedTimeBoxes = timeBoxRepository.saveAll( - customizeTimeBoxes.getTimeBoxes()); - return new CustomizeTimeBoxEntities(savedTimeBoxes); + private void saveTimeBoxes(CustomizeTableEntity tableEntity, List timeBoxes) { + IntStream.range(0, timeBoxes.size()) + .forEach(i -> saveTimeBox(tableEntity, timeBoxes.get(i), i + 1)); + } + + private void saveTimeBox(CustomizeTableEntity tableEntity, CustomizeTimeBox timeBox, int sequence) { + CustomizeTimeBoxEntity timeBoxEntity = timeBoxRepository.save( + new CustomizeTimeBoxEntity(tableEntity, timeBox, sequence)); + timeBox.getBells() + .forEach(bell -> bellRepository.save(new BellEntity(timeBoxEntity, bell))); } } diff --git a/src/main/java/com/debatetimer/service/customize/CustomizeServiceV2.java b/src/main/java/com/debatetimer/service/customize/CustomizeServiceV2.java deleted file mode 100644 index 392f8c89..00000000 --- a/src/main/java/com/debatetimer/service/customize/CustomizeServiceV2.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.debatetimer.service.customize; - -import com.debatetimer.domain.customize.CustomizeTable; -import com.debatetimer.domain.customize.CustomizeTimeBox; -import com.debatetimer.domain.member.Member; -import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; -import com.debatetimer.dto.customize.response.CustomizeTableResponse; -import com.debatetimer.entity.customize.BellEntity; -import com.debatetimer.entity.customize.CustomizeTableEntity; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntities; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; -import com.debatetimer.repository.customize.BellRepository; -import com.debatetimer.repository.customize.CustomizeTableRepository; -import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; -import java.util.List; -import java.util.stream.IntStream; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class CustomizeServiceV2 { - - private final CustomizeTableRepository tableRepository; - private final CustomizeTimeBoxRepository timeBoxRepository; - private final BellRepository bellRepository; - - @Transactional - public CustomizeTableResponse save(CustomizeTableCreateRequest tableCreateRequest, Member member) { - CustomizeTable table = tableCreateRequest.toTable(member); - List timeBoxes = tableCreateRequest.toTimeBoxList(); - - CustomizeTableEntity savedTableEntity = tableRepository.save(new CustomizeTableEntity(table)); - saveTimeBoxes(savedTableEntity, timeBoxes); - return new CustomizeTableResponse(savedTableEntity.toDomain(), timeBoxes); - } - - @Transactional(readOnly = true) - public CustomizeTableResponse findTable(long tableId, Member member) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); - List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); - CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); - - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxEntities.toDomain()); - } - - @Transactional - public CustomizeTableResponse updateTable( - CustomizeTableCreateRequest tableCreateRequest, - long tableId, - Member member - ) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - tableEntity.updateTable(tableCreateRequest.toTable(member)); - - bellRepository.deleteAllByTable(tableEntity.getId()); - timeBoxRepository.deleteAllByTable(tableEntity.getId()); - List timeBoxes = tableCreateRequest.toTimeBoxList(); - saveTimeBoxes(tableEntity, timeBoxes); - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); - } - - @Transactional - public CustomizeTableResponse updateUsedAt(long tableId, Member member) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); - List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); - CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); - - tableEntity.updateUsedAt(); - CustomizeTable table = tableEntity.toDomain(); - List timeBoxes = timeBoxEntities.toDomain(); - return new CustomizeTableResponse(table, timeBoxes); - } - - @Transactional - public void deleteTable(long tableId, Member member) { - CustomizeTableEntity table = tableRepository.getByIdAndMember(tableId, member); - - bellRepository.deleteAllByTable(table.getId()); - timeBoxRepository.deleteAllByTable(table.getId()); - tableRepository.delete(table); - } - - private void saveTimeBoxes(CustomizeTableEntity tableEntity, List timeBoxes) { - IntStream.range(0, timeBoxes.size()) - .forEach(i -> saveTimeBox(tableEntity, timeBoxes.get(i), i + 1)); - } - - private void saveTimeBox(CustomizeTableEntity tableEntity, CustomizeTimeBox timeBox, int sequence) { - CustomizeTimeBoxEntity timeBoxEntity = timeBoxRepository.save( - new CustomizeTimeBoxEntity(tableEntity, timeBox, sequence)); - timeBox.getBells() - .forEach(bell -> bellRepository.save(new BellEntity(timeBoxEntity, bell))); - } -} diff --git a/src/main/resources/db/migration/V12__add_bell_type_into_bell.sql b/src/main/resources/db/migration/V12__add_bell_type_into_bell.sql new file mode 100644 index 00000000..e2f1a133 --- /dev/null +++ b/src/main/resources/db/migration/V12__add_bell_type_into_bell.sql @@ -0,0 +1,2 @@ +ALTER TABLE bell + ADD COLUMN bell_type enum ('AFTER_START','BEFORE_END','AFTER_END') NOT NULL diff --git a/src/test/java/com/debatetimer/controller/customize/CustomizeDocumentTest.java b/src/test/java/com/debatetimer/controller/customize/CustomizeDocumentTest.java index e7545638..e2613aa0 100644 --- a/src/test/java/com/debatetimer/controller/customize/CustomizeDocumentTest.java +++ b/src/test/java/com/debatetimer/controller/customize/CustomizeDocumentTest.java @@ -18,6 +18,7 @@ import com.debatetimer.controller.RestDocumentationRequest; import com.debatetimer.controller.RestDocumentationResponse; import com.debatetimer.controller.Tag; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.customize.Stance; import com.debatetimer.dto.customize.request.BellRequest; @@ -71,8 +72,9 @@ class Save { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -95,8 +97,9 @@ class Save { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -109,9 +112,9 @@ class Save { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), null, null, "콜리"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxCreateRequest(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), null, null, "비토"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -124,9 +127,9 @@ class Save { "찬성", "반대", true, true), List.of( new CustomizeTimeBoxResponse(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1)), null, null, "콜리"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxResponse(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1), new BellResponse(120, 2)), null, null, "비토"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1), new BellResponse(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -168,9 +171,9 @@ class Save { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), null, null, "콜리"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxCreateRequest(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), null, null, "비토"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -230,8 +233,9 @@ class GetTable { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -246,9 +250,9 @@ class GetTable { "찬성", "반대", true, true), List.of( new CustomizeTimeBoxResponse(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1)), null, null, "콜리"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxResponse(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1), new BellResponse(120, 2)), null, null, "비토"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1), new BellResponse(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -323,8 +327,9 @@ class UpdateTable { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -347,8 +352,9 @@ class UpdateTable { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -362,9 +368,9 @@ class UpdateTable { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), null, null, "콜리"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxCreateRequest(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), null, null, "비토"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -377,9 +383,9 @@ class UpdateTable { "찬성", "반대", true, true), List.of( new CustomizeTimeBoxResponse(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1)), null, null, "콜리"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxResponse(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1), new BellResponse(120, 2)), null, null, "비토"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1), new BellResponse(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -424,9 +430,9 @@ class UpdateTable { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), null, null, "콜리"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxCreateRequest(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), null, null, "비토"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -488,8 +494,9 @@ class Debate { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -505,9 +512,9 @@ class Debate { "찬성", "반대", true, true), List.of( new CustomizeTimeBoxResponse(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1)), null, null, "콜리"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxResponse(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1), new BellResponse(120, 2)), null, null, "비토"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1), new BellResponse(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, diff --git a/src/test/java/com/debatetimer/domain/customize/BellTest.java b/src/test/java/com/debatetimer/domain/customize/BellTest.java index a99f40eb..25b99e70 100644 --- a/src/test/java/com/debatetimer/domain/customize/BellTest.java +++ b/src/test/java/com/debatetimer/domain/customize/BellTest.java @@ -17,21 +17,21 @@ class Validate { @Test void 벨_시간이_음수면_생성되지_않는다() { - assertThatThrownBy(() -> new Bell(-1, 1)) + assertThatThrownBy(() -> new Bell(BellType.AFTER_START, -1, 1)) .isInstanceOf(DTClientErrorException.class) .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); } @Test void 벨_시간은_0이상이어야_한다() { - assertThatCode(() -> new Bell(0, 1)) + assertThatCode(() -> new Bell(BellType.AFTER_START, 0, 1)) .doesNotThrowAnyException(); } @ValueSource(ints = {0, Bell.MAX_BELL_COUNT + 1}) @ParameterizedTest void 벨_횟수는_정해진_횟수_바깥일_경우_생성되지_않는다(int count) { - assertThatThrownBy(() -> new Bell(1, count)) + assertThatThrownBy(() -> new Bell(BellType.AFTER_START, 1, count)) .isInstanceOf(DTClientErrorException.class) .hasMessage(ClientErrorCode.INVALID_BELL_COUNT.getMessage()); } @@ -39,7 +39,7 @@ class Validate { @ValueSource(ints = {1, Bell.MAX_BELL_COUNT}) @ParameterizedTest void 벨_횟수는_정해진_횟수_이내여야_한다(int count) { - assertThatCode(() -> new Bell(1, count)) + assertThatCode(() -> new Bell(BellType.AFTER_START, 1, count)) .doesNotThrowAnyException(); } } diff --git a/src/test/java/com/debatetimer/entity/customize/BellEntityTest.java b/src/test/java/com/debatetimer/entity/customize/BellEntityTest.java index 73535499..c0483f9f 100644 --- a/src/test/java/com/debatetimer/entity/customize/BellEntityTest.java +++ b/src/test/java/com/debatetimer/entity/customize/BellEntityTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.exception.custom.DTClientErrorException; import com.debatetimer.exception.errorcode.ClientErrorCode; import org.junit.jupiter.api.Nested; @@ -16,7 +17,7 @@ class Validate { @Test void 벨_시간은_0이상이어야_한다() { - assertThatThrownBy(() -> new BellEntity(null, -1, 1)) + assertThatThrownBy(() -> new BellEntity(null, BellType.AFTER_END, -1, 1)) .isInstanceOf(DTClientErrorException.class) .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); } @@ -24,7 +25,7 @@ class Validate { @ValueSource(ints = {0, BellEntity.MAX_BELL_COUNT + 1}) @ParameterizedTest void 벨_횟수는_정해진_횟수_이내여야_한다(int count) { - assertThatThrownBy(() -> new BellEntity(null, 1, count)) + assertThatThrownBy(() -> new BellEntity(null, BellType.AFTER_END, 1, count)) .isInstanceOf(DTClientErrorException.class) .hasMessage(ClientErrorCode.INVALID_BELL_COUNT.getMessage()); } diff --git a/src/test/java/com/debatetimer/fixture/BellGenerator.java b/src/test/java/com/debatetimer/fixture/BellGenerator.java index 1c2392ce..335c6441 100644 --- a/src/test/java/com/debatetimer/fixture/BellGenerator.java +++ b/src/test/java/com/debatetimer/fixture/BellGenerator.java @@ -1,5 +1,6 @@ package com.debatetimer.fixture; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.entity.customize.BellEntity; import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; import com.debatetimer.repository.customize.BellRepository; @@ -14,8 +15,8 @@ public BellGenerator(BellRepository bellRepository) { this.bellRepository = bellRepository; } - public BellEntity generate(CustomizeTimeBoxEntity timeBox, int time, int count) { - BellEntity bell = new BellEntity(timeBox, time, count); + public BellEntity generate(CustomizeTimeBoxEntity timeBox, BellType type, int time, int count) { + BellEntity bell = new BellEntity(timeBox, type, time, count); return bellRepository.save(bell); } } diff --git a/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java b/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java index 6dbb6919..b8fcc4e4 100644 --- a/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.member.Member; import com.debatetimer.entity.customize.CustomizeTableEntity; @@ -30,9 +31,9 @@ class DeleteAllByTable { CustomizeBoxType.NORMAL, 1); CustomizeTimeBoxEntity otherTimeBox = customizeTimeBoxGenerator.generate(otherTable, CustomizeBoxType.NORMAL, 1); - bellGenerator.generate(deleteBellTimeBox, 45, 1); - bellGenerator.generate(deleteBellTimeBox, 60, 1); - bellGenerator.generate(otherTimeBox, 45, 1); + bellGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 45, 1); + bellGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 60, 1); + bellGenerator.generate(otherTimeBox, BellType.AFTER_START, 45, 1); bellRepository.deleteAllByTable(deleteBellTable.getId()); diff --git a/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java b/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java index 410c0042..baf45e4d 100644 --- a/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java +++ b/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java @@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.customize.Stance; import com.debatetimer.domain.member.Member; @@ -12,6 +13,7 @@ import com.debatetimer.dto.customize.request.CustomizeTableInfoCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTimeBoxCreateRequest; import com.debatetimer.dto.customize.response.CustomizeTableResponse; +import com.debatetimer.entity.customize.BellEntity; import com.debatetimer.entity.customize.CustomizeTableEntity; import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; import com.debatetimer.exception.custom.DTClientErrorException; @@ -40,19 +42,22 @@ class Save { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); CustomizeTableResponse savedTableResponse = customizeService.save(customizeTableCreateRequest, chan); CustomizeTableEntity foundTable = customizeTableRepository.getByIdAndMember(savedTableResponse.id(), chan); - List foundTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable(foundTable); + List foundTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( + foundTable); + List foundBells = bellRepository.findAllByCustomizeTimeBoxIn(foundTimeBoxes); assertAll( () -> assertThat(foundTable.getName()).isEqualTo(customizeTableCreateRequest.info().name()), - () -> assertThat(foundTimeBoxes).hasSize(customizeTableCreateRequest.table().size()) + () -> assertThat(foundTimeBoxes).hasSize(customizeTableCreateRequest.table().size()), + () -> assertThat(foundBells).hasSize(3) ); } } @@ -64,14 +69,19 @@ class FindTable { void 사용자_지정_토론_테이블을_조회한다() { Member chan = memberGenerator.generate("default@gmail.com"); CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); + CustomizeTimeBoxEntity customizeTimeBox = customizeTimeBoxGenerator.generate( + chanTable, CustomizeBoxType.NORMAL, 1); customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); + bellGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 1); + bellGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 2); CustomizeTableResponse foundResponse = customizeService.findTable(chanTable.getId(), chan); assertAll( () -> assertThat(foundResponse.id()).isEqualTo(chanTable.getId()), - () -> assertThat(foundResponse.table()).hasSize(2) + () -> assertThat(foundResponse.table()).hasSize(2), + () -> assertThat(foundResponse.table().get(0).bell()).hasSize(2), + () -> assertThat(foundResponse.table().get(1).bell()).isNull() ); } @@ -100,21 +110,24 @@ class UpdateTable { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); customizeService.updateTable(renewTableRequest, chanTable.getId(), chan); CustomizeTableEntity updatedTable = customizeTableRepository.getByIdAndMember(chanTable.getId(), chan); - List updatedTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable(updatedTable); + List updatedTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( + updatedTable); + List bells = bellRepository.findAllByCustomizeTimeBoxIn(updatedTimeBoxes); assertAll( () -> assertThat(updatedTable.getId()).isEqualTo(chanTable.getId()), () -> assertThat(updatedTable.getName()).isEqualTo(renewTableRequest.info().name()), - () -> assertThat(updatedTimeBoxes).hasSize(renewTableRequest.table().size()) + () -> assertThat(updatedTimeBoxes).hasSize(renewTableRequest.table().size()), + () -> assertThat(bells).hasSize(3) ); } @@ -129,9 +142,9 @@ class UpdateTable { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -149,9 +162,9 @@ class UpdateTable { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -207,10 +220,12 @@ class DeleteTable { Optional foundTable = customizeTableRepository.findById(chanTable.getId()); List timeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( chanTable); + List bells = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxes); assertAll( () -> assertThat(foundTable).isEmpty(), - () -> assertThat(timeBoxes).isEmpty() + () -> assertThat(timeBoxes).isEmpty(), + () -> assertThat(bells).isEmpty() ); } diff --git a/src/test/java/com/debatetimer/service/customize/CustomizeServiceV2Test.java b/src/test/java/com/debatetimer/service/customize/CustomizeServiceV2Test.java deleted file mode 100644 index 1e0b58b7..00000000 --- a/src/test/java/com/debatetimer/service/customize/CustomizeServiceV2Test.java +++ /dev/null @@ -1,243 +0,0 @@ -package com.debatetimer.service.customize; - -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.customize.CustomizeBoxType; -import com.debatetimer.domain.customize.Stance; -import com.debatetimer.domain.member.Member; -import com.debatetimer.dto.customize.request.BellRequest; -import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; -import com.debatetimer.dto.customize.request.CustomizeTableInfoCreateRequest; -import com.debatetimer.dto.customize.request.CustomizeTimeBoxCreateRequest; -import com.debatetimer.dto.customize.response.CustomizeTableResponse; -import com.debatetimer.entity.customize.BellEntity; -import com.debatetimer.entity.customize.CustomizeTableEntity; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; -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 CustomizeServiceV2Test extends BaseServiceTest { - - @Autowired - private CustomizeServiceV2 customizeService; - - @Nested - class Save { - - @Test - void 사용자_지정_토론_테이블을_생성한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableCreateRequest customizeTableCreateRequest = new CustomizeTableCreateRequest( - new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", - "반대", true, true), - List.of( - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") - ) - ); - - CustomizeTableResponse savedTableResponse = customizeService.save(customizeTableCreateRequest, chan); - CustomizeTableEntity foundTable = customizeTableRepository.getByIdAndMember(savedTableResponse.id(), chan); - List foundTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( - foundTable); - List foundBells = bellRepository.findAllByCustomizeTimeBoxIn(foundTimeBoxes); - - assertAll( - () -> assertThat(foundTable.getName()).isEqualTo(customizeTableCreateRequest.info().name()), - () -> assertThat(foundTimeBoxes).hasSize(customizeTableCreateRequest.table().size()), - () -> assertThat(foundBells).hasSize(3) - ); - } - } - - @Nested - class FindTable { - - @Test - void 사용자_지정_토론_테이블을_조회한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - CustomizeTimeBoxEntity customizeTimeBox = customizeTimeBoxGenerator.generate( - chanTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); - bellGenerator.generate(customizeTimeBox, 1, 1); - bellGenerator.generate(customizeTimeBox, 1, 2); - - CustomizeTableResponse foundResponse = customizeService.findTable(chanTable.getId(), chan); - - assertAll( - () -> assertThat(foundResponse.id()).isEqualTo(chanTable.getId()), - () -> assertThat(foundResponse.table()).hasSize(2), - () -> assertThat(foundResponse.table().get(0).bell()).hasSize(2), - () -> assertThat(foundResponse.table().get(1).bell()).isNull() - ); - } - - @Test - void 회원_소유가_아닌_테이블_조회_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - - assertThatThrownBy(() -> customizeService.findTable(chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.TABLE_NOT_FOUND.getMessage()); - } - } - - @Nested - class UpdateTable { - - @Test - void 사용자_지정_토론_테이블을_수정한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - CustomizeTableCreateRequest renewTableRequest = new CustomizeTableCreateRequest( - new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", - "반대", true, true), - List.of( - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") - ) - ); - - customizeService.updateTable(renewTableRequest, chanTable.getId(), chan); - - CustomizeTableEntity updatedTable = customizeTableRepository.getByIdAndMember(chanTable.getId(), chan); - List updatedTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( - updatedTable); - List bells = bellRepository.findAllByCustomizeTimeBoxIn(updatedTimeBoxes); - - assertAll( - () -> assertThat(updatedTable.getId()).isEqualTo(chanTable.getId()), - () -> assertThat(updatedTable.getName()).isEqualTo(renewTableRequest.info().name()), - () -> assertThat(updatedTimeBoxes).hasSize(renewTableRequest.table().size()), - () -> assertThat(bells).hasSize(3) - ); - } - - @Test - void 회원_소유가_아닌_테이블_수정_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - CustomizeTableCreateRequest renewTableRequest = new CustomizeTableCreateRequest( - new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", - "반대", true, true), - List.of( - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") - ) - ); - - assertThatThrownBy(() -> customizeService.updateTable(renewTableRequest, chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.TABLE_NOT_FOUND.getMessage()); - } - - @Test - void 테이블_정보_수정을_동시에_요청할_때_동시에_처리하지_않는다() throws InterruptedException { - Member member = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - CustomizeTableCreateRequest request = new CustomizeTableCreateRequest( - new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", - "반대", true, true), - List.of( - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") - ) - ); - - runAtSameTime(2, () -> customizeService.updateTable(request, table.getId(), member)); - - assertThat(customizeTimeBoxRepository.findAllByCustomizeTable(table)).hasSize(2); - } - } - - @Nested - class UpdateUsedAt { - - @Test - void 사용자_지정_토론_테이블의_사용_시각을_최신화한다() { - Member member = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - LocalDateTime beforeUsedAt = table.getUsedAt(); - - customizeService.updateUsedAt(table.getId(), member); - - CustomizeTableEntity updatedTable = customizeTableRepository.getByIdAndMember(table.getId(), member); - assertAll( - () -> assertThat(updatedTable.getId()).isEqualTo(table.getId()), - () -> assertThat(updatedTable.getUsedAt()).isAfter(beforeUsedAt) - ); - } - - @Test - void 회원_소유가_아닌_테이블_수정_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - - assertThatThrownBy(() -> customizeService.updateUsedAt(chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.TABLE_NOT_FOUND.getMessage()); - } - } - - @Nested - class DeleteTable { - - @Test - void 사용자_지정_토론_테이블을_삭제한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); - - customizeService.deleteTable(chanTable.getId(), chan); - - Optional foundTable = customizeTableRepository.findById(chanTable.getId()); - List timeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( - chanTable); - List bells = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxes); - - assertAll( - () -> assertThat(foundTable).isEmpty(), - () -> assertThat(timeBoxes).isEmpty(), - () -> assertThat(bells).isEmpty() - ); - } - - @Test - void 회원_소유가_아닌_테이블_삭제_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - - assertThatThrownBy(() -> customizeService.deleteTable(chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.TABLE_NOT_FOUND.getMessage()); - } - } -} From 275b54aaf6ee98559f00d174015815178be48a1b Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sat, 26 Jul 2025 14:25:10 +0900 Subject: [PATCH 02/15] =?UTF-8?q?refactor:=20TODO=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/CustomizeTableCreateRequest.java | 17 ++++------------- .../service/customize/CustomizeService.java | 4 ++-- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java b/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java index 8dc05809..b6ab52e1 100644 --- a/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java +++ b/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java @@ -2,31 +2,22 @@ import com.debatetimer.domain.customize.CustomizeTable; import com.debatetimer.domain.customize.CustomizeTimeBox; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntities; import com.debatetimer.domain.member.Member; import jakarta.validation.Valid; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; public record CustomizeTableCreateRequest( @Valid CustomizeTableInfoCreateRequest info, @Valid List table ) { - public CustomizeTimeBoxEntities toTimeBoxes(CustomizeTable customizeTable) { - return IntStream.range(0, table.size()) - .mapToObj(i -> table.get(i).toTimeBox(customizeTable, i + 1)) - .collect(Collectors.collectingAndThen(Collectors.toList(), CustomizeTimeBoxEntities::new)); + public List toTimeBoxes() { + return table.stream() + .map(CustomizeTimeBoxCreateRequest::toDomain) + .toList(); } public CustomizeTable toTable(Member member) { return info.toTable(member); } - - public List toTimeBoxList() { // TODO 메서드 네이밍 변경 toTimeBoxList() -> toTimeBoxes() - return table.stream() - .map(CustomizeTimeBoxCreateRequest::toDomain) - .toList(); - } } diff --git a/src/main/java/com/debatetimer/service/customize/CustomizeService.java b/src/main/java/com/debatetimer/service/customize/CustomizeService.java index 02c542ad..f0feb605 100644 --- a/src/main/java/com/debatetimer/service/customize/CustomizeService.java +++ b/src/main/java/com/debatetimer/service/customize/CustomizeService.java @@ -29,7 +29,7 @@ public class CustomizeService { @Transactional public CustomizeTableResponse save(CustomizeTableCreateRequest tableCreateRequest, Member member) { CustomizeTable table = tableCreateRequest.toTable(member); - List timeBoxes = tableCreateRequest.toTimeBoxList(); + List timeBoxes = tableCreateRequest.toTimeBoxes(); CustomizeTableEntity savedTableEntity = tableRepository.save(new CustomizeTableEntity(table)); saveTimeBoxes(savedTableEntity, timeBoxes); @@ -57,7 +57,7 @@ public CustomizeTableResponse updateTable( bellRepository.deleteAllByTable(tableEntity.getId()); timeBoxRepository.deleteAllByTable(tableEntity.getId()); - List timeBoxes = tableCreateRequest.toTimeBoxList(); + List timeBoxes = tableCreateRequest.toTimeBoxes(); saveTimeBoxes(tableEntity, timeBoxes); return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); } From 530b26b1281370050f67fad4f00de19b27ed133f Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sat, 26 Jul 2025 15:32:26 +0900 Subject: [PATCH 03/15] =?UTF-8?q?refactor:=20domain=20repository=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomizeTableDomainRepository.java | 89 +++++++++++++++++++ .../poll/CustomizeTableDomainRepository.java | 24 ----- .../service/customize/CustomizeService.java | 67 +++----------- .../debatetimer/service/poll/PollService.java | 2 +- 4 files changed, 104 insertions(+), 78 deletions(-) create mode 100644 src/main/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepository.java delete mode 100644 src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java diff --git a/src/main/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepository.java b/src/main/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepository.java new file mode 100644 index 00000000..de3705b8 --- /dev/null +++ b/src/main/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepository.java @@ -0,0 +1,89 @@ +package com.debatetimer.domainrepository.customize; + +import com.debatetimer.domain.customize.CustomizeTable; +import com.debatetimer.domain.customize.CustomizeTimeBox; +import com.debatetimer.domain.member.Member; +import com.debatetimer.entity.customize.BellEntity; +import com.debatetimer.entity.customize.CustomizeTableEntity; +import com.debatetimer.entity.customize.CustomizeTimeBoxEntities; +import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; +import com.debatetimer.repository.customize.BellRepository; +import com.debatetimer.repository.customize.CustomizeTableRepository; +import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; +import java.util.List; +import java.util.stream.IntStream; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +@Repository +@RequiredArgsConstructor +public class CustomizeTableDomainRepository { + + private final CustomizeTableRepository tableRepository; + private final CustomizeTimeBoxRepository timeBoxRepository; + private final BellRepository bellRepository; + + @Transactional + public CustomizeTable save(CustomizeTable table, List timeBoxes) { + CustomizeTableEntity savedTableEntity = tableRepository.save(new CustomizeTableEntity(table)); + saveTimeBoxes(savedTableEntity, timeBoxes); + + return savedTableEntity.toDomain(); + } + + private void saveTimeBoxes(CustomizeTableEntity tableEntity, List timeBoxes) { + IntStream.range(0, timeBoxes.size()) + .forEach(i -> saveTimeBox(tableEntity, timeBoxes.get(i), i + 1)); + } + + private void saveTimeBox(CustomizeTableEntity tableEntity, CustomizeTimeBox timeBox, int sequence) { + CustomizeTimeBoxEntity timeBoxEntity = timeBoxRepository.save( + new CustomizeTimeBoxEntity(tableEntity, timeBox, sequence)); + timeBox.getBells() + .forEach(bell -> bellRepository.save(new BellEntity(timeBoxEntity, bell))); + } + + @Transactional(readOnly = true) + public CustomizeTable getByIdAndMember(long tableId, Member member) { + return tableRepository.getByIdAndMember(tableId, member) + .toDomain(); + } + + @Transactional(readOnly = true) + public List getCustomizeTimeBoxes(long tableId, Member member) { + CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); + List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); + List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); + CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); + return timeBoxEntities.toDomain(); + } + + @Transactional + public CustomizeTable update(CustomizeTable table, long tableId, Member member, List timeBoxes) { + CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); + tableEntity.updateTable(table); + + bellRepository.deleteAllByTable(tableEntity.getId()); + timeBoxRepository.deleteAllByTable(tableEntity.getId()); + + saveTimeBoxes(tableEntity, timeBoxes); + return tableEntity.toDomain(); + } + + @Transactional + public CustomizeTable updateUsedAt(long tableId, Member member) { + CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); + tableEntity.updateUsedAt(); + return tableEntity.toDomain(); + } + + @Transactional + public void delete(long tableId, Member member) { + CustomizeTableEntity table = tableRepository.getByIdAndMember(tableId, member); + + bellRepository.deleteAllByTable(table.getId()); + timeBoxRepository.deleteAllByTable(table.getId()); + tableRepository.delete(table); + } +} diff --git a/src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java b/src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java deleted file mode 100644 index 850c53bd..00000000 --- a/src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.debatetimer.domainrepository.poll; - -import com.debatetimer.domain.customize.CustomizeTable; -import com.debatetimer.domain.member.Member; -import com.debatetimer.exception.custom.DTClientErrorException; -import com.debatetimer.exception.errorcode.ClientErrorCode; -import com.debatetimer.repository.customize.CustomizeTableRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -@Repository -@RequiredArgsConstructor -public class CustomizeTableDomainRepository { - - private final CustomizeTableRepository customizeTableRepository; - - @Transactional(readOnly = true) - public CustomizeTable getByIdAndMember(long tableId, Member member) { - return customizeTableRepository.findByIdAndMember(tableId, member) - .orElseThrow(() -> new DTClientErrorException(ClientErrorCode.TABLE_NOT_FOUND)) - .toDomain(); - } -} diff --git a/src/main/java/com/debatetimer/service/customize/CustomizeService.java b/src/main/java/com/debatetimer/service/customize/CustomizeService.java index f0feb605..f9df4a3b 100644 --- a/src/main/java/com/debatetimer/service/customize/CustomizeService.java +++ b/src/main/java/com/debatetimer/service/customize/CustomizeService.java @@ -3,17 +3,10 @@ import com.debatetimer.domain.customize.CustomizeTable; import com.debatetimer.domain.customize.CustomizeTimeBox; import com.debatetimer.domain.member.Member; +import com.debatetimer.domainrepository.customize.CustomizeTableDomainRepository; import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; import com.debatetimer.dto.customize.response.CustomizeTableResponse; -import com.debatetimer.entity.customize.BellEntity; -import com.debatetimer.entity.customize.CustomizeTableEntity; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntities; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; -import com.debatetimer.repository.customize.BellRepository; -import com.debatetimer.repository.customize.CustomizeTableRepository; -import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; import java.util.List; -import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -22,28 +15,21 @@ @RequiredArgsConstructor public class CustomizeService { - private final CustomizeTableRepository tableRepository; - private final CustomizeTimeBoxRepository timeBoxRepository; - private final BellRepository bellRepository; + private final CustomizeTableDomainRepository customizeTableDomainRepository; @Transactional public CustomizeTableResponse save(CustomizeTableCreateRequest tableCreateRequest, Member member) { CustomizeTable table = tableCreateRequest.toTable(member); List timeBoxes = tableCreateRequest.toTimeBoxes(); - - CustomizeTableEntity savedTableEntity = tableRepository.save(new CustomizeTableEntity(table)); - saveTimeBoxes(savedTableEntity, timeBoxes); - return new CustomizeTableResponse(savedTableEntity.toDomain(), timeBoxes); + CustomizeTable savedTable = customizeTableDomainRepository.save(table, timeBoxes); + return new CustomizeTableResponse(savedTable, timeBoxes); } @Transactional(readOnly = true) public CustomizeTableResponse findTable(long tableId, Member member) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); - List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); - CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); - - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxEntities.toDomain()); + CustomizeTable table = customizeTableDomainRepository.getByIdAndMember(tableId, member); + List timeBoxEntities = customizeTableDomainRepository.getCustomizeTimeBoxes(tableId, member); + return new CustomizeTableResponse(table, timeBoxEntities); } @Transactional @@ -52,47 +38,22 @@ public CustomizeTableResponse updateTable( long tableId, Member member ) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - tableEntity.updateTable(tableCreateRequest.toTable(member)); - - bellRepository.deleteAllByTable(tableEntity.getId()); - timeBoxRepository.deleteAllByTable(tableEntity.getId()); + CustomizeTable table = tableCreateRequest.toTable(member); List timeBoxes = tableCreateRequest.toTimeBoxes(); - saveTimeBoxes(tableEntity, timeBoxes); - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); + + CustomizeTable updatedTable = customizeTableDomainRepository.update(table, tableId, member, timeBoxes); + return new CustomizeTableResponse(updatedTable, timeBoxes); } @Transactional public CustomizeTableResponse updateUsedAt(long tableId, Member member) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); - List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); - CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); - - tableEntity.updateUsedAt(); - CustomizeTable table = tableEntity.toDomain(); - List timeBoxes = timeBoxEntities.toDomain(); + CustomizeTable table = customizeTableDomainRepository.updateUsedAt(tableId, member); + List timeBoxes = customizeTableDomainRepository.getCustomizeTimeBoxes(tableId, member); return new CustomizeTableResponse(table, timeBoxes); } @Transactional public void deleteTable(long tableId, Member member) { - CustomizeTableEntity table = tableRepository.getByIdAndMember(tableId, member); - - bellRepository.deleteAllByTable(table.getId()); - timeBoxRepository.deleteAllByTable(table.getId()); - tableRepository.delete(table); - } - - private void saveTimeBoxes(CustomizeTableEntity tableEntity, List timeBoxes) { - IntStream.range(0, timeBoxes.size()) - .forEach(i -> saveTimeBox(tableEntity, timeBoxes.get(i), i + 1)); - } - - private void saveTimeBox(CustomizeTableEntity tableEntity, CustomizeTimeBox timeBox, int sequence) { - CustomizeTimeBoxEntity timeBoxEntity = timeBoxRepository.save( - new CustomizeTimeBoxEntity(tableEntity, timeBox, sequence)); - timeBox.getBells() - .forEach(bell -> bellRepository.save(new BellEntity(timeBoxEntity, bell))); + customizeTableDomainRepository.delete(tableId, member); } } diff --git a/src/main/java/com/debatetimer/service/poll/PollService.java b/src/main/java/com/debatetimer/service/poll/PollService.java index a6409fdb..cfa021b9 100644 --- a/src/main/java/com/debatetimer/service/poll/PollService.java +++ b/src/main/java/com/debatetimer/service/poll/PollService.java @@ -4,7 +4,7 @@ import com.debatetimer.domain.member.Member; import com.debatetimer.domain.poll.Poll; import com.debatetimer.domain.poll.VoteInfo; -import com.debatetimer.domainrepository.poll.CustomizeTableDomainRepository; +import com.debatetimer.domainrepository.customize.CustomizeTableDomainRepository; import com.debatetimer.domainrepository.poll.PollDomainRepository; import com.debatetimer.domainrepository.poll.VoteDomainRepository; import com.debatetimer.dto.poll.response.PollCreateResponse; From b3ad675d31f8a2708d76366c76e4fa1d73ecc4f7 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sat, 26 Jul 2025 16:45:52 +0900 Subject: [PATCH 04/15] =?UTF-8?q?refactor:=20CustomizeTableDomainRepositor?= =?UTF-8?q?yTest=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BaseControllerTest.java | 18 +- .../customize/CustomizeControllerTest.java | 34 ++-- .../controller/poll/PollControllerTest.java | 16 +- .../BaseDomainRepositoryTest.java | 46 ++++- .../CustomizeTableDomainRepositoryTest.java | 159 ++++++++++++++++++ .../poll/PollDomainRepositoryTest.java | 10 +- .../poll/VoteDomainRepositoryTest.java | 10 +- .../fixture/domain/BellGenerator.java | 23 +++ .../domain/CustomizeTableGenerator.java | 36 ++++ .../domain/CustomizeTimeBoxGenerator.java | 32 ++++ .../BellEntityGenerator.java} | 6 +- .../CustomizeTableEntityGenerator.java} | 6 +- .../CustomizeTimeBoxEntityGenerator.java} | 6 +- .../fixture/{ => entity}/MemberGenerator.java | 2 +- .../PollEntityGenerator.java} | 6 +- .../VoteEntityGenerator.java} | 6 +- .../repository/BaseRepositoryTest.java | 20 +-- .../customize/BellRepositoryTest.java | 14 +- .../CustomizeTableEntityRepositoryTest.java | 10 +- .../CustomizeTimeBoxRepositoryTest.java | 32 ++-- .../debatetimer/service/BaseServiceTest.java | 22 +-- .../customize/CustomizeServiceTest.java | 42 ++--- .../service/member/MemberServiceTest.java | 6 +- .../service/poll/PollServiceTest.java | 16 +- 24 files changed, 433 insertions(+), 145 deletions(-) create mode 100644 src/test/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepositoryTest.java create mode 100644 src/test/java/com/debatetimer/fixture/domain/BellGenerator.java create mode 100644 src/test/java/com/debatetimer/fixture/domain/CustomizeTableGenerator.java create mode 100644 src/test/java/com/debatetimer/fixture/domain/CustomizeTimeBoxGenerator.java rename src/test/java/com/debatetimer/fixture/{BellGenerator.java => entity/BellEntityGenerator.java} (81%) rename src/test/java/com/debatetimer/fixture/{CustomizeTableGenerator.java => entity/CustomizeTableEntityGenerator.java} (84%) rename src/test/java/com/debatetimer/fixture/{CustomizeTimeBoxGenerator.java => entity/CustomizeTimeBoxEntityGenerator.java} (88%) rename src/test/java/com/debatetimer/fixture/{ => entity}/MemberGenerator.java (92%) rename src/test/java/com/debatetimer/fixture/{PollGenerator.java => entity/PollEntityGenerator.java} (85%) rename src/test/java/com/debatetimer/fixture/{VoteGenerator.java => entity/VoteEntityGenerator.java} (81%) diff --git a/src/test/java/com/debatetimer/controller/BaseControllerTest.java b/src/test/java/com/debatetimer/controller/BaseControllerTest.java index 83d35dda..73fcbedd 100644 --- a/src/test/java/com/debatetimer/controller/BaseControllerTest.java +++ b/src/test/java/com/debatetimer/controller/BaseControllerTest.java @@ -8,13 +8,13 @@ import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTableInfoCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTimeBoxCreateRequest; -import com.debatetimer.fixture.CustomizeTableGenerator; -import com.debatetimer.fixture.CustomizeTimeBoxGenerator; +import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; import com.debatetimer.fixture.HeaderGenerator; -import com.debatetimer.fixture.MemberGenerator; -import com.debatetimer.fixture.PollGenerator; +import com.debatetimer.fixture.entity.MemberGenerator; +import com.debatetimer.fixture.entity.PollEntityGenerator; import com.debatetimer.fixture.TokenGenerator; -import com.debatetimer.fixture.VoteGenerator; +import com.debatetimer.fixture.entity.VoteEntityGenerator; import com.debatetimer.repository.customize.CustomizeTableRepository; import com.navercorp.fixturemonkey.ArbitraryBuilder; import com.navercorp.fixturemonkey.FixtureMonkey; @@ -42,16 +42,16 @@ public abstract class BaseControllerTest { protected MemberGenerator memberGenerator; @Autowired - protected CustomizeTableGenerator customizeTableGenerator; + protected CustomizeTableEntityGenerator customizeTableEntityGenerator; @Autowired - protected CustomizeTimeBoxGenerator customizeTimeBoxGenerator; + protected CustomizeTimeBoxEntityGenerator customizeTimeBoxEntityGenerator; @Autowired - protected PollGenerator pollGenerator; + protected PollEntityGenerator pollEntityGenerator; @Autowired - protected VoteGenerator voteGenerator; + protected VoteEntityGenerator voteEntityGenerator; @Autowired protected HeaderGenerator headerGenerator; diff --git a/src/test/java/com/debatetimer/controller/customize/CustomizeControllerTest.java b/src/test/java/com/debatetimer/controller/customize/CustomizeControllerTest.java index e82c3c5e..df0c91e2 100644 --- a/src/test/java/com/debatetimer/controller/customize/CustomizeControllerTest.java +++ b/src/test/java/com/debatetimer/controller/customize/CustomizeControllerTest.java @@ -154,9 +154,9 @@ class GetTable { @Test void 사용자_지정_테이블을_조회한다() { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); - customizeTimeBoxGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); + customizeTimeBoxEntityGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableResponse response = given() @@ -180,7 +180,7 @@ class UpdateTable { @Test void 사용자_지정_토론_테이블을_업데이트한다() { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest renewTableRequest = getCustomizeTableCreateRequestBuilder() .set("table[1].speaker", null) @@ -201,7 +201,7 @@ class UpdateTable { @NullAndEmptyAndBlankSource void 사용자_지정_테이블을_업데이트할때_테이블_이름은_개행문자_외_다른_글자가_포함되야한다(String tableName) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("info.name", tableName) @@ -218,7 +218,7 @@ class UpdateTable { @ParameterizedTest void 사용자_지정_테이블을_업데이트할때_테이블_주제는_null이_올_수_없다(String agenda) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("info.agenda", agenda) @@ -235,7 +235,7 @@ class UpdateTable { @NullAndEmptyAndBlankSource void 사용자_지정_테이블을_업데이트할때_찬성팀_이름은_개행문자_외_다른_글자가_포함되야한다(String prosTeamName) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("info.prosTeamName", prosTeamName) @@ -252,7 +252,7 @@ class UpdateTable { @NullAndEmptyAndBlankSource void 사용자_지정_테이블을_업데이트할때_반대팀_이름은_개행문자_외_다른_글자가_포함되야한다(String consTeamName) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() @@ -270,7 +270,7 @@ class UpdateTable { @ParameterizedTest void 사용자_지정_테이블을_업데이트할때_타임박스_입장은_null이_올_수_없다(Stance stance) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("table[0].stance", stance) @@ -287,7 +287,7 @@ class UpdateTable { @NullAndEmptyAndBlankSource void 사용자_지정_테이블을_업데이트할때_타임박스_발언_유형은_개행문자_외_다른_글자가_포함되야한다(String speechType) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("table[0].speechType", speechType) @@ -304,7 +304,7 @@ class UpdateTable { @ParameterizedTest void 사용자_지정_테이블을_업데이트할때_타임박스_타입은_null이_올_수_없다(CustomizeBoxType boxType) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("table[0].boxType", boxType) @@ -339,9 +339,9 @@ class Debate { @Test void 사용자_지정_토론을_시작한다() { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); - customizeTimeBoxGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); + customizeTimeBoxEntityGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableResponse response = given() @@ -366,9 +366,9 @@ class DeleteTable { @Test void 사용자_지정_토론_테이블을_삭제한다() { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); - customizeTimeBoxGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); + customizeTimeBoxEntityGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); Headers headers = headerGenerator.generateAccessTokenHeader(bito); given() diff --git a/src/test/java/com/debatetimer/controller/poll/PollControllerTest.java b/src/test/java/com/debatetimer/controller/poll/PollControllerTest.java index 22487d85..ee3fad9b 100644 --- a/src/test/java/com/debatetimer/controller/poll/PollControllerTest.java +++ b/src/test/java/com/debatetimer/controller/poll/PollControllerTest.java @@ -24,7 +24,7 @@ class CreatePoll { @Test void 선거를_생성할_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); Headers headers = headerGenerator.generateAccessTokenHeader(member); given() @@ -42,11 +42,11 @@ class GetPollInfo { @Test void 선거정보를_읽을_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); - voteGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); + voteEntityGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); Headers headers = headerGenerator.generateAccessTokenHeader(member); PollInfoResponse response = given() @@ -75,8 +75,8 @@ class FinishPoll { @Test void 선거정보를_완료상태로_변경한다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); Headers headers = headerGenerator.generateAccessTokenHeader(member); PollInfoResponse response = given() diff --git a/src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java b/src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java index 37ac4fba..485a7f25 100644 --- a/src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java +++ b/src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java @@ -1,10 +1,18 @@ package com.debatetimer.domainrepository; import com.debatetimer.DataBaseCleaner; -import com.debatetimer.fixture.CustomizeTableGenerator; -import com.debatetimer.fixture.MemberGenerator; -import com.debatetimer.fixture.PollGenerator; -import com.debatetimer.fixture.VoteGenerator; +import com.debatetimer.fixture.domain.BellGenerator; +import com.debatetimer.fixture.domain.CustomizeTableGenerator; +import com.debatetimer.fixture.domain.CustomizeTimeBoxGenerator; +import com.debatetimer.fixture.entity.BellEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; +import com.debatetimer.fixture.entity.MemberGenerator; +import com.debatetimer.fixture.entity.PollEntityGenerator; +import com.debatetimer.fixture.entity.VoteEntityGenerator; +import com.debatetimer.repository.customize.BellRepository; +import com.debatetimer.repository.customize.CustomizeTableRepository; +import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; import com.debatetimer.repository.poll.PollRepository; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -14,18 +22,42 @@ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) public abstract class BaseDomainRepositoryTest { + @Autowired + protected CustomizeTableGenerator tableGenerator; + + @Autowired + protected CustomizeTimeBoxGenerator timeBoxGenerator; + + @Autowired + protected BellGenerator bellGenerator; + @Autowired protected MemberGenerator memberGenerator; @Autowired - protected CustomizeTableGenerator customizeTableGenerator; + protected CustomizeTableEntityGenerator tableEntityGenerator; + + @Autowired + protected CustomizeTimeBoxEntityGenerator timeBoxEntityGenerator; @Autowired - protected PollGenerator pollGenerator; + protected BellEntityGenerator bellEntityGenerator; @Autowired - protected VoteGenerator voteGenerator; + protected PollEntityGenerator pollEntityGenerator; + + @Autowired + protected VoteEntityGenerator voteEntityGenerator; @Autowired protected PollRepository pollRepository; + + @Autowired + protected CustomizeTableRepository tableRepository; + + @Autowired + protected CustomizeTimeBoxRepository timeBoxRepository; + + @Autowired + protected BellRepository bellRepository; } diff --git a/src/test/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepositoryTest.java b/src/test/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepositoryTest.java new file mode 100644 index 00000000..e9108935 --- /dev/null +++ b/src/test/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepositoryTest.java @@ -0,0 +1,159 @@ +package com.debatetimer.domainrepository.customize; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.BellType; +import com.debatetimer.domain.customize.CustomizeBoxType; +import com.debatetimer.domain.customize.CustomizeTable; +import com.debatetimer.domain.customize.CustomizeTimeBox; +import com.debatetimer.domain.member.Member; +import com.debatetimer.domainrepository.BaseDomainRepositoryTest; +import com.debatetimer.entity.customize.BellEntity; +import com.debatetimer.entity.customize.CustomizeTableEntity; +import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; +import java.time.LocalDateTime; +import java.util.Collections; +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 CustomizeTableDomainRepositoryTest extends BaseDomainRepositoryTest { + + @Autowired + private CustomizeTableDomainRepository customizeTableDomainRepository; + + @Nested + class Save { + + @Test + void 테이블을_저장한다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTable table = tableGenerator.generate(member); + List bells = bellGenerator.generate(3); + CustomizeTimeBox timeBox1 = timeBoxGenerator.generate(bells); + CustomizeTimeBox timeBox2 = timeBoxGenerator.generate(Collections.emptyList()); + + CustomizeTable savedTable = customizeTableDomainRepository.save(table, List.of(timeBox1, timeBox2)); + List timeBoxEntities = timeBoxRepository.findAllByCustomizeTable( + new CustomizeTableEntity(savedTable)); + List bellEntities = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntities); + + assertAll( + () -> assertThat(savedTable.getName()).isEqualTo(table.getName()), + () -> assertThat(timeBoxEntities).hasSize(2), + () -> assertThat(bellEntities).hasSize(3) + ); + } + } + + @Nested + class GetByIdAndMember { + + @Test + void 회원이_소유한_테이블을_가져온다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + + CustomizeTable foundTable = customizeTableDomainRepository.getByIdAndMember(table.getId(), member); + + assertThat(foundTable.getId()).isEqualTo(table.getId()); + } + } + + @Nested + class GetCustomizeTimeBoxes { + + @Test + void 테이블의_시간박스를_가져온다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity tableEntity = tableEntityGenerator.generate(member); + timeBoxEntityGenerator.generate(tableEntity, CustomizeBoxType.NORMAL, 1); + timeBoxEntityGenerator.generate(tableEntity, CustomizeBoxType.NORMAL, 2); + + List timeBoxes = customizeTableDomainRepository.getCustomizeTimeBoxes( + tableEntity.getId(), member); + + assertThat(timeBoxes).hasSize(2); + } + } + + @Nested + class Update { + + @Test + void 테이블을_수정한다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity tableEntity = tableEntityGenerator.generate(member); + CustomizeTimeBoxEntity timeBox1 = timeBoxEntityGenerator.generate(tableEntity, CustomizeBoxType.NORMAL, 1); + CustomizeTimeBoxEntity timeBox2 = timeBoxEntityGenerator.generate(tableEntity, CustomizeBoxType.NORMAL, 2); + bellEntityGenerator.generate(timeBox1, BellType.AFTER_START, 10, 1); + bellEntityGenerator.generate(timeBox1, BellType.AFTER_START, 20, 1); + bellEntityGenerator.generate(timeBox2, BellType.AFTER_START, 20, 1); + + CustomizeTable table = tableGenerator.generate(member, "수정된 테이블"); + List bells = bellGenerator.generate(3); + CustomizeTimeBox timeBox = timeBoxGenerator.generate(bells, "수정"); + + CustomizeTable updatedTable = customizeTableDomainRepository.update(table, tableEntity.getId(), member, + List.of(timeBox)); + CustomizeTableEntity foundTable = tableRepository.getByIdAndMember(tableEntity.getId(), member); + List timeBoxEntities = timeBoxRepository.findAllByCustomizeTable( + new CustomizeTableEntity(updatedTable)); + List bellEntities = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntities); + + assertAll( + () -> assertThat(foundTable.getName()).isEqualTo(updatedTable.getName()), + () -> assertThat(timeBoxEntities).hasSize(1), + () -> assertThat(bellEntities).hasSize(3) + ); + } + } + + @Nested + class UpdateUsedAt { + + @Test + void 테이블의_사용_시간을_업데이트한다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity tableEntity = tableEntityGenerator.generate(member); + LocalDateTime beforeUsedAt = tableEntity.getUsedAt(); + + CustomizeTable customizeTable = customizeTableDomainRepository.updateUsedAt(tableEntity.getId(), member); + + assertAll( + () -> assertThat(customizeTable.getId()).isEqualTo(tableEntity.getId()), + () -> assertThat(customizeTable.getUsedAt()).isAfter(beforeUsedAt) + ); + } + } + + @Nested + class Delete { + + @Test + void 테이블을_삭제한다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + CustomizeTimeBoxEntity timeBox1 = timeBoxEntityGenerator.generate(table, CustomizeBoxType.NORMAL, 1); + CustomizeTimeBoxEntity timeBox2 = timeBoxEntityGenerator.generate(table, CustomizeBoxType.NORMAL, 2); + bellEntityGenerator.generate(timeBox1, BellType.AFTER_START, 10, 1); + bellEntityGenerator.generate(timeBox1, BellType.AFTER_START, 20, 1); + bellEntityGenerator.generate(timeBox2, BellType.AFTER_START, 20, 1); + + customizeTableDomainRepository.delete(table.getId(), member); + Optional foundTable = tableRepository.findById(table.getId()); + List timeBoxEntities = timeBoxRepository.findAllByCustomizeTable(table); + List bellEntities = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntities); + + assertAll( + () -> assertThat(foundTable).isEmpty(), + () -> assertThat(timeBoxEntities).isEmpty(), + () -> assertThat(bellEntities).isEmpty() + ); + } + } +} diff --git a/src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java b/src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java index c97849e4..48a65773 100644 --- a/src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java +++ b/src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java @@ -25,7 +25,7 @@ class Create { @Test void 선거를_생성한다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = tableEntityGenerator.generate(member); Poll poll = new Poll(table.getId(), member.getId(), "찬성", "반대", "주제"); Poll createdPoll = pollDomainRepository.create(poll); @@ -41,8 +41,8 @@ class GetByIdAndMemberId { @Test void 회원이_개최한_선거를_가져온다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); Poll foundPoll = pollDomainRepository.getByIdAndMemberId(pollEntity.getId(), member.getId()); @@ -63,8 +63,8 @@ class FinishPoll { @Test void 선거를_완료_상태로_변경한다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); Poll updatedPoll = pollDomainRepository.finishPoll(pollEntity.getId(), member.getId()); diff --git a/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java b/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java index 068e782e..4892a56e 100644 --- a/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java +++ b/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java @@ -25,11 +25,11 @@ class GetVoteInfo { @Test void 팀별_투표_현황을_알_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); - voteGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); + voteEntityGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); VoteInfo voteInfo = voteDomainRepository.findVoteInfoByPollId(pollEntity.getId()); diff --git a/src/test/java/com/debatetimer/fixture/domain/BellGenerator.java b/src/test/java/com/debatetimer/fixture/domain/BellGenerator.java new file mode 100644 index 00000000..4db99724 --- /dev/null +++ b/src/test/java/com/debatetimer/fixture/domain/BellGenerator.java @@ -0,0 +1,23 @@ +package com.debatetimer.fixture.domain; + +import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.BellType; +import java.util.ArrayList; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class BellGenerator { + + public List generate(int size) { + List bells = new ArrayList<>(); + for (int i = 0; i < size; i++) { + bells.add(generate()); + } + return bells; + } + + private Bell generate() { + return new Bell(BellType.AFTER_START, 10, 1); + } +} diff --git a/src/test/java/com/debatetimer/fixture/domain/CustomizeTableGenerator.java b/src/test/java/com/debatetimer/fixture/domain/CustomizeTableGenerator.java new file mode 100644 index 00000000..3efb05cc --- /dev/null +++ b/src/test/java/com/debatetimer/fixture/domain/CustomizeTableGenerator.java @@ -0,0 +1,36 @@ +package com.debatetimer.fixture.domain; + +import com.debatetimer.domain.customize.CustomizeTable; +import com.debatetimer.domain.member.Member; +import java.time.LocalDateTime; +import org.springframework.stereotype.Component; + +@Component +public class CustomizeTableGenerator { + + public CustomizeTable generate(Member member) { + return new CustomizeTable( + member, + "토론 테이블", + "주제", + "찬성", + "반대", + false, + false, + LocalDateTime.now() + ); + } + + public CustomizeTable generate(Member member, String name) { + return new CustomizeTable( + member, + name, + "주제", + "찬성", + "반대", + false, + false, + LocalDateTime.now() + ); + } +} diff --git a/src/test/java/com/debatetimer/fixture/domain/CustomizeTimeBoxGenerator.java b/src/test/java/com/debatetimer/fixture/domain/CustomizeTimeBoxGenerator.java new file mode 100644 index 00000000..35bc429e --- /dev/null +++ b/src/test/java/com/debatetimer/fixture/domain/CustomizeTimeBoxGenerator.java @@ -0,0 +1,32 @@ +package com.debatetimer.fixture.domain; + +import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.CustomizeTimeBox; +import com.debatetimer.domain.customize.NormalTimeBox; +import com.debatetimer.domain.customize.Stance; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class CustomizeTimeBoxGenerator { + + public CustomizeTimeBox generate(List bells) { + return new NormalTimeBox( + Stance.PROS, + "입론", + "콜리", + 10, + bells + ); + } + + public CustomizeTimeBox generate(List bells, String speechType) { + return new NormalTimeBox( + Stance.PROS, + speechType, + "콜리", + 10, + bells + ); + } +} diff --git a/src/test/java/com/debatetimer/fixture/BellGenerator.java b/src/test/java/com/debatetimer/fixture/entity/BellEntityGenerator.java similarity index 81% rename from src/test/java/com/debatetimer/fixture/BellGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/BellEntityGenerator.java index 335c6441..53f5d421 100644 --- a/src/test/java/com/debatetimer/fixture/BellGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/BellEntityGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.customize.BellType; import com.debatetimer.entity.customize.BellEntity; @@ -7,11 +7,11 @@ import org.springframework.stereotype.Component; @Component -public class BellGenerator { +public class BellEntityGenerator { private final BellRepository bellRepository; - public BellGenerator(BellRepository bellRepository) { + public BellEntityGenerator(BellRepository bellRepository) { this.bellRepository = bellRepository; } diff --git a/src/test/java/com/debatetimer/fixture/CustomizeTableGenerator.java b/src/test/java/com/debatetimer/fixture/entity/CustomizeTableEntityGenerator.java similarity index 84% rename from src/test/java/com/debatetimer/fixture/CustomizeTableGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/CustomizeTableEntityGenerator.java index 80a7b8dc..93ec96aa 100644 --- a/src/test/java/com/debatetimer/fixture/CustomizeTableGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/CustomizeTableEntityGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.customize.CustomizeTable; import com.debatetimer.domain.member.Member; @@ -8,11 +8,11 @@ import org.springframework.stereotype.Component; @Component -public class CustomizeTableGenerator { +public class CustomizeTableEntityGenerator { private final CustomizeTableRepository customizeTableRepository; - public CustomizeTableGenerator(CustomizeTableRepository customizeTableRepository) { + public CustomizeTableEntityGenerator(CustomizeTableRepository customizeTableRepository) { this.customizeTableRepository = customizeTableRepository; } diff --git a/src/test/java/com/debatetimer/fixture/CustomizeTimeBoxGenerator.java b/src/test/java/com/debatetimer/fixture/entity/CustomizeTimeBoxEntityGenerator.java similarity index 88% rename from src/test/java/com/debatetimer/fixture/CustomizeTimeBoxGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/CustomizeTimeBoxEntityGenerator.java index e068269d..7b2ca578 100644 --- a/src/test/java/com/debatetimer/fixture/CustomizeTimeBoxGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/CustomizeTimeBoxEntityGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.customize.Stance; @@ -8,11 +8,11 @@ import org.springframework.stereotype.Component; @Component -public class CustomizeTimeBoxGenerator { +public class CustomizeTimeBoxEntityGenerator { private final CustomizeTimeBoxRepository customizeTimeBoxRepository; - public CustomizeTimeBoxGenerator(CustomizeTimeBoxRepository customizeTimeBoxRepository) { + public CustomizeTimeBoxEntityGenerator(CustomizeTimeBoxRepository customizeTimeBoxRepository) { this.customizeTimeBoxRepository = customizeTimeBoxRepository; } diff --git a/src/test/java/com/debatetimer/fixture/MemberGenerator.java b/src/test/java/com/debatetimer/fixture/entity/MemberGenerator.java similarity index 92% rename from src/test/java/com/debatetimer/fixture/MemberGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/MemberGenerator.java index d0aa97bb..69dc56a3 100644 --- a/src/test/java/com/debatetimer/fixture/MemberGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/MemberGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.member.Member; import com.debatetimer.repository.member.MemberRepository; diff --git a/src/test/java/com/debatetimer/fixture/PollGenerator.java b/src/test/java/com/debatetimer/fixture/entity/PollEntityGenerator.java similarity index 85% rename from src/test/java/com/debatetimer/fixture/PollGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/PollEntityGenerator.java index 24059cba..5f01a4b5 100644 --- a/src/test/java/com/debatetimer/fixture/PollGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/PollEntityGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.poll.Poll; import com.debatetimer.domain.poll.PollStatus; @@ -8,11 +8,11 @@ import org.springframework.stereotype.Component; @Component -public class PollGenerator { +public class PollEntityGenerator { private final PollRepository pollRepository; - public PollGenerator(final PollRepository pollRepository) { + public PollEntityGenerator(final PollRepository pollRepository) { this.pollRepository = pollRepository; } diff --git a/src/test/java/com/debatetimer/fixture/VoteGenerator.java b/src/test/java/com/debatetimer/fixture/entity/VoteEntityGenerator.java similarity index 81% rename from src/test/java/com/debatetimer/fixture/VoteGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/VoteEntityGenerator.java index 9efdd80c..86a6ca6b 100644 --- a/src/test/java/com/debatetimer/fixture/VoteGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/VoteEntityGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.poll.VoteTeam; import com.debatetimer.entity.poll.PollEntity; @@ -8,11 +8,11 @@ import org.springframework.stereotype.Component; @Component -public class VoteGenerator { +public class VoteEntityGenerator { private final VoteRepository voteRepository; - public VoteGenerator(VoteRepository voteRepository) { + public VoteEntityGenerator(VoteRepository voteRepository) { this.voteRepository = voteRepository; } diff --git a/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java b/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java index 87b5404b..ab973a1e 100644 --- a/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java @@ -1,10 +1,10 @@ package com.debatetimer.repository; import com.debatetimer.config.JpaAuditingConfig; -import com.debatetimer.fixture.BellGenerator; -import com.debatetimer.fixture.CustomizeTableGenerator; -import com.debatetimer.fixture.CustomizeTimeBoxGenerator; -import com.debatetimer.fixture.MemberGenerator; +import com.debatetimer.fixture.entity.BellEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; +import com.debatetimer.fixture.entity.MemberGenerator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; @@ -12,9 +12,9 @@ @Import({ JpaAuditingConfig.class, MemberGenerator.class, - CustomizeTableGenerator.class, - CustomizeTimeBoxGenerator.class, - BellGenerator.class, + CustomizeTableEntityGenerator.class, + CustomizeTimeBoxEntityGenerator.class, + BellEntityGenerator.class, }) @DataJpaTest public abstract class BaseRepositoryTest { @@ -23,11 +23,11 @@ public abstract class BaseRepositoryTest { protected MemberGenerator memberGenerator; @Autowired - protected CustomizeTableGenerator customizeTableGenerator; + protected CustomizeTableEntityGenerator customizeTableEntityGenerator; @Autowired - protected CustomizeTimeBoxGenerator customizeTimeBoxGenerator; + protected CustomizeTimeBoxEntityGenerator customizeTimeBoxEntityGenerator; @Autowired - protected BellGenerator bellGenerator; + protected BellEntityGenerator bellEntityGenerator; } diff --git a/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java b/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java index b8fcc4e4..7747fb03 100644 --- a/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java @@ -25,15 +25,15 @@ class DeleteAllByTable { @Test void 특정_테이블에_해당하는_벨을_삭제한다() { Member member = memberGenerator.generate("chan@gmail.com"); - CustomizeTableEntity deleteBellTable = customizeTableGenerator.generate(member); - CustomizeTableEntity otherTable = customizeTableGenerator.generate(member); - CustomizeTimeBoxEntity deleteBellTimeBox = customizeTimeBoxGenerator.generate(deleteBellTable, + CustomizeTableEntity deleteBellTable = customizeTableEntityGenerator.generate(member); + CustomizeTableEntity otherTable = customizeTableEntityGenerator.generate(member); + CustomizeTimeBoxEntity deleteBellTimeBox = customizeTimeBoxEntityGenerator.generate(deleteBellTable, CustomizeBoxType.NORMAL, 1); - CustomizeTimeBoxEntity otherTimeBox = customizeTimeBoxGenerator.generate(otherTable, + CustomizeTimeBoxEntity otherTimeBox = customizeTimeBoxEntityGenerator.generate(otherTable, CustomizeBoxType.NORMAL, 1); - bellGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 45, 1); - bellGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 60, 1); - bellGenerator.generate(otherTimeBox, BellType.AFTER_START, 45, 1); + bellEntityGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 45, 1); + bellEntityGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 60, 1); + bellEntityGenerator.generate(otherTimeBox, BellType.AFTER_START, 45, 1); bellRepository.deleteAllByTable(deleteBellTable.getId()); diff --git a/src/test/java/com/debatetimer/repository/customize/CustomizeTableEntityRepositoryTest.java b/src/test/java/com/debatetimer/repository/customize/CustomizeTableEntityRepositoryTest.java index ebc3e626..428ae069 100644 --- a/src/test/java/com/debatetimer/repository/customize/CustomizeTableEntityRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/customize/CustomizeTableEntityRepositoryTest.java @@ -25,9 +25,9 @@ class FindAllByMember { void 특정_회원의_테이블만_조회한다() { Member chan = memberGenerator.generate("default@gmail.com"); Member bito = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable1 = customizeTableGenerator.generate(chan); - CustomizeTableEntity chanTable2 = customizeTableGenerator.generate(chan); - customizeTableGenerator.generate(bito); + CustomizeTableEntity chanTable1 = customizeTableEntityGenerator.generate(chan); + CustomizeTableEntity chanTable2 = customizeTableEntityGenerator.generate(chan); + customizeTableEntityGenerator.generate(bito); List foundKeoChanTables = tableRepository.findAllByMember(chan); @@ -41,7 +41,7 @@ class GetByIdAndMember { @Test void 특정_회원의_테이블을_조회한다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(chan); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(chan); CustomizeTableEntity foundTable = tableRepository.getByIdAndMember(table.getId(), chan); @@ -51,7 +51,7 @@ class GetByIdAndMember { @Test void 존재하지_않는_테이블을_조회하면_예외를_던진다() { Member chan = memberGenerator.generate("default@gmail.com"); - customizeTableGenerator.generate(chan); + customizeTableEntityGenerator.generate(chan); long nonExistTableId = 99999999L; assertThatThrownBy(() -> tableRepository.getByIdAndMember(nonExistTableId, chan)) diff --git a/src/test/java/com/debatetimer/repository/customize/CustomizeTimeBoxRepositoryTest.java b/src/test/java/com/debatetimer/repository/customize/CustomizeTimeBoxRepositoryTest.java index eb94339f..5fcf6b39 100644 --- a/src/test/java/com/debatetimer/repository/customize/CustomizeTimeBoxRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/customize/CustomizeTimeBoxRepositoryTest.java @@ -25,12 +25,14 @@ class FindAllByCustomizeTableEntity { void 특정_테이블의_타임박스를_모두_조회한다() { Member chan = memberGenerator.generate("default@gmail.com"); Member bito = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); - CustomizeTimeBoxEntity chanBox1 = customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); - CustomizeTimeBoxEntity chanBox2 = customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); - customizeTimeBoxGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 2); - customizeTimeBoxGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); + CustomizeTimeBoxEntity chanBox1 = customizeTimeBoxEntityGenerator.generate(chanTable, + CustomizeBoxType.NORMAL, 1); + CustomizeTimeBoxEntity chanBox2 = customizeTimeBoxEntityGenerator.generate(chanTable, + CustomizeBoxType.NORMAL, 2); + customizeTimeBoxEntityGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 2); + customizeTimeBoxEntityGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 2); List foundBoxes = customizeTimeBoxRepository.findAllByCustomizeTable(chanTable); @@ -44,9 +46,9 @@ class DeleteAllByTable { @Test void 특정_테이블의_타임박스를_모두_삭제한다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); + customizeTimeBoxEntityGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); customizeTimeBoxRepository.deleteAllByTable(chanTable.getId()); @@ -57,11 +59,11 @@ class DeleteAllByTable { @Test void 특정_테이블의_타임_박스를_삭제해도_다른_테이블의_타임_박스는_삭제되지_않는다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity filledTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(filledTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(filledTable, CustomizeBoxType.NORMAL, 2); - CustomizeTableEntity deletedTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(deletedTable, CustomizeBoxType.NORMAL, 1); + CustomizeTableEntity filledTable = customizeTableEntityGenerator.generate(chan); + customizeTimeBoxEntityGenerator.generate(filledTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generate(filledTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity deletedTable = customizeTableEntityGenerator.generate(chan); + customizeTimeBoxEntityGenerator.generate(deletedTable, CustomizeBoxType.NORMAL, 1); customizeTimeBoxRepository.deleteAllByTable(deletedTable.getId()); @@ -72,7 +74,7 @@ class DeleteAllByTable { @Test void 테이블의_타임_박스가_없을_경우_타임_박스_삭제_시_예외가_발생하지_않는다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity emptyTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity emptyTable = customizeTableEntityGenerator.generate(chan); assertThatCode(() -> customizeTimeBoxRepository.deleteAllByTable(emptyTable.getId())) .doesNotThrowAnyException(); diff --git a/src/test/java/com/debatetimer/service/BaseServiceTest.java b/src/test/java/com/debatetimer/service/BaseServiceTest.java index a68e418d..3bd0a8c1 100644 --- a/src/test/java/com/debatetimer/service/BaseServiceTest.java +++ b/src/test/java/com/debatetimer/service/BaseServiceTest.java @@ -1,12 +1,12 @@ package com.debatetimer.service; import com.debatetimer.DataBaseCleaner; -import com.debatetimer.fixture.BellGenerator; -import com.debatetimer.fixture.CustomizeTableGenerator; -import com.debatetimer.fixture.CustomizeTimeBoxGenerator; -import com.debatetimer.fixture.MemberGenerator; -import com.debatetimer.fixture.PollGenerator; -import com.debatetimer.fixture.VoteGenerator; +import com.debatetimer.fixture.entity.BellEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; +import com.debatetimer.fixture.entity.MemberGenerator; +import com.debatetimer.fixture.entity.PollEntityGenerator; +import com.debatetimer.fixture.entity.VoteEntityGenerator; import com.debatetimer.repository.customize.BellRepository; import com.debatetimer.repository.customize.CustomizeTableRepository; import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; @@ -41,19 +41,19 @@ public abstract class BaseServiceTest { protected MemberGenerator memberGenerator; @Autowired - protected CustomizeTableGenerator customizeTableGenerator; + protected CustomizeTableEntityGenerator customizeTableEntityGenerator; @Autowired - protected CustomizeTimeBoxGenerator customizeTimeBoxGenerator; + protected CustomizeTimeBoxEntityGenerator customizeTimeBoxEntityGenerator; @Autowired - protected BellGenerator bellGenerator; + protected BellEntityGenerator bellEntityGenerator; @Autowired - protected PollGenerator pollGenerator; + protected PollEntityGenerator pollEntityGenerator; @Autowired - protected VoteGenerator voteGenerator; + protected VoteEntityGenerator voteEntityGenerator; protected void runAtSameTime(int count, Runnable task) throws InterruptedException { List threads = IntStream.range(0, count) diff --git a/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java b/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java index baf45e4d..664a50c5 100644 --- a/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java +++ b/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java @@ -44,7 +44,8 @@ class Save { new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), + new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -68,12 +69,12 @@ class FindTable { @Test void 사용자_지정_토론_테이블을_조회한다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - CustomizeTimeBoxEntity customizeTimeBox = customizeTimeBoxGenerator.generate( + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); + CustomizeTimeBoxEntity customizeTimeBox = customizeTimeBoxEntityGenerator.generate( chanTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); - bellGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 1); - bellGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 2); + customizeTimeBoxEntityGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); + bellEntityGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 1); + bellEntityGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 2); CustomizeTableResponse foundResponse = customizeService.findTable(chanTable.getId(), chan); @@ -89,7 +90,7 @@ class FindTable { void 회원_소유가_아닌_테이블_조회_시_예외를_발생시킨다() { Member chan = memberGenerator.generate("default@gmail.com"); Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); long chanTableId = chanTable.getId(); assertThatThrownBy(() -> customizeService.findTable(chanTableId, coli)) @@ -104,7 +105,7 @@ class UpdateTable { @Test void 사용자_지정_토론_테이블을_수정한다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); CustomizeTableCreateRequest renewTableRequest = new CustomizeTableCreateRequest( new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", "반대", true, true), @@ -112,7 +113,8 @@ class UpdateTable { new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), + new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -135,7 +137,7 @@ class UpdateTable { void 회원_소유가_아닌_테이블_수정_시_예외를_발생시킨다() { Member chan = memberGenerator.generate("default@gmail.com"); Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); long chanTableId = chanTable.getId(); CustomizeTableCreateRequest renewTableRequest = new CustomizeTableCreateRequest( new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", @@ -144,7 +146,8 @@ class UpdateTable { new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), + new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -156,7 +159,7 @@ class UpdateTable { @Test void 테이블_정보_수정을_동시에_요청할_때_동시에_처리하지_않는다() throws InterruptedException { Member member = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); CustomizeTableCreateRequest request = new CustomizeTableCreateRequest( new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", "반대", true, true), @@ -164,7 +167,8 @@ class UpdateTable { new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), + new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -180,7 +184,7 @@ class UpdateUsedAt { @Test void 사용자_지정_토론_테이블의_사용_시각을_최신화한다() { Member member = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); LocalDateTime beforeUsedAt = table.getUsedAt(); customizeService.updateUsedAt(table.getId(), member); @@ -196,7 +200,7 @@ class UpdateUsedAt { void 회원_소유가_아닌_테이블_수정_시_예외를_발생시킨다() { Member chan = memberGenerator.generate("default@gmail.com"); Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); long chanTableId = chanTable.getId(); assertThatThrownBy(() -> customizeService.updateUsedAt(chanTableId, coli)) @@ -211,9 +215,9 @@ class DeleteTable { @Test void 사용자_지정_토론_테이블을_삭제한다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); + customizeTimeBoxEntityGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); customizeService.deleteTable(chanTable.getId(), chan); @@ -233,7 +237,7 @@ class DeleteTable { void 회원_소유가_아닌_테이블_삭제_시_예외를_발생시킨다() { Member chan = memberGenerator.generate("default@gmail.com"); Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); long chanTableId = chanTable.getId(); assertThatThrownBy(() -> customizeService.deleteTable(chanTableId, coli)) diff --git a/src/test/java/com/debatetimer/service/member/MemberServiceTest.java b/src/test/java/com/debatetimer/service/member/MemberServiceTest.java index d78c50e7..185476e9 100644 --- a/src/test/java/com/debatetimer/service/member/MemberServiceTest.java +++ b/src/test/java/com/debatetimer/service/member/MemberServiceTest.java @@ -52,8 +52,8 @@ class GetTables { @Test void 회원의_전체_토론_시간표를_조회한다() { Member member = memberGenerator.generate("default@gmail.com"); - customizeTableGenerator.generate(member); - customizeTableGenerator.generate(member); + customizeTableEntityGenerator.generate(member); + customizeTableEntityGenerator.generate(member); TableResponses response = memberService.getTables(member.getId()); @@ -63,7 +63,7 @@ class GetTables { @Test void 회원의_전체_토론_시간표는_정해진_순서대로_반환한다() throws InterruptedException { Member member = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); Thread.sleep(1); TableResponses response = memberService.getTables(member.getId()); diff --git a/src/test/java/com/debatetimer/service/poll/PollServiceTest.java b/src/test/java/com/debatetimer/service/poll/PollServiceTest.java index fd5c96c2..4dd3e913 100644 --- a/src/test/java/com/debatetimer/service/poll/PollServiceTest.java +++ b/src/test/java/com/debatetimer/service/poll/PollServiceTest.java @@ -27,7 +27,7 @@ class CreatePoll { @Test void 선거를_생성한다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); PollCreateResponse createdPoll = pollService.create(table.getId(), member); @@ -42,11 +42,11 @@ class GetPollInfo { @Test void 선거_정보를_읽어온다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); - voteGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); + voteEntityGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); PollInfoResponse pollInfo = pollService.getPollInfo(table.getId(), member); @@ -68,8 +68,8 @@ class FinishPoll { @Test void 선거를_완료상태로_변경한다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + pollEntityGenerator.generate(table, PollStatus.PROGRESS); PollInfoResponse pollInfo = pollService.finishPoll(table.getId(), member); From 6b27490ae354f1f5fc21c0ea6478c8898854e297 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sun, 27 Jul 2025 23:08:06 +0900 Subject: [PATCH 05/15] =?UTF-8?q?feat:=20=EB=B2=A8=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=8B=9C=EA=B0=84=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../debatetimer/domain/customize/Bell.java | 6 ++-- .../domain/customize/BellType.java | 18 +++++++++-- .../controller/BaseControllerTest.java | 6 ++-- .../domain/customize/BellTest.java | 30 +++++++++++++++++-- 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/debatetimer/domain/customize/Bell.java b/src/main/java/com/debatetimer/domain/customize/Bell.java index 9488bef6..f5200976 100644 --- a/src/main/java/com/debatetimer/domain/customize/Bell.java +++ b/src/main/java/com/debatetimer/domain/customize/Bell.java @@ -14,15 +14,15 @@ public class Bell { private final int count; public Bell(BellType type, int time, int count) { - validateTime(time); + validateTime(type, time); validateCount(count); this.type = type; this.time = time; this.count = count; } - private void validateTime(int time) { - if (time < 0) { + private void validateTime(BellType type, int time) { + if (!type.isValidTime(time)) { throw new DTClientErrorException(ClientErrorCode.INVALID_BELL_TIME); } } diff --git a/src/main/java/com/debatetimer/domain/customize/BellType.java b/src/main/java/com/debatetimer/domain/customize/BellType.java index 56bc3134..121e4c51 100644 --- a/src/main/java/com/debatetimer/domain/customize/BellType.java +++ b/src/main/java/com/debatetimer/domain/customize/BellType.java @@ -1,9 +1,21 @@ package com.debatetimer.domain.customize; +import java.util.function.Predicate; + public enum BellType { - AFTER_START, - BEFORE_END, - AFTER_END, + AFTER_START(time -> time >= 0), + BEFORE_END(time -> time >= 0), + AFTER_END(time -> time <= 0), ; + + private final Predicate timeValidator; + + BellType(Predicate timeValidator) { + this.timeValidator = timeValidator; + } + + public boolean isValidTime(int time) { + return timeValidator.test(time); + } } diff --git a/src/test/java/com/debatetimer/controller/BaseControllerTest.java b/src/test/java/com/debatetimer/controller/BaseControllerTest.java index 73fcbedd..d987e07a 100644 --- a/src/test/java/com/debatetimer/controller/BaseControllerTest.java +++ b/src/test/java/com/debatetimer/controller/BaseControllerTest.java @@ -2,18 +2,19 @@ import com.debatetimer.DataBaseCleaner; import com.debatetimer.client.oauth.OAuthClient; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.customize.Stance; import com.debatetimer.dto.customize.request.BellRequest; import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTableInfoCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTimeBoxCreateRequest; +import com.debatetimer.fixture.HeaderGenerator; +import com.debatetimer.fixture.TokenGenerator; import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; -import com.debatetimer.fixture.HeaderGenerator; import com.debatetimer.fixture.entity.MemberGenerator; import com.debatetimer.fixture.entity.PollEntityGenerator; -import com.debatetimer.fixture.TokenGenerator; import com.debatetimer.fixture.entity.VoteEntityGenerator; import com.debatetimer.repository.customize.CustomizeTableRepository; import com.navercorp.fixturemonkey.ArbitraryBuilder; @@ -114,6 +115,7 @@ private ArbitraryBuilder getCustomizeTimeBoxCreat private ArbitraryBuilder getBellRequestBuilder() { return fixtureMonkey.giveMeBuilder(BellRequest.class) + .set("type", BellType.AFTER_START) .set("time", 30) .set("count", 1); } diff --git a/src/test/java/com/debatetimer/domain/customize/BellTest.java b/src/test/java/com/debatetimer/domain/customize/BellTest.java index 25b99e70..c2be8eb6 100644 --- a/src/test/java/com/debatetimer/domain/customize/BellTest.java +++ b/src/test/java/com/debatetimer/domain/customize/BellTest.java @@ -16,18 +16,44 @@ class BellTest { class Validate { @Test - void 벨_시간이_음수면_생성되지_않는다() { + void 벨_종류가_AFTER_START일때_시간이_음수면_생성되지_않는다() { assertThatThrownBy(() -> new Bell(BellType.AFTER_START, -1, 1)) .isInstanceOf(DTClientErrorException.class) .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); } @Test - void 벨_시간은_0이상이어야_한다() { + void 벨_종류가_AFTER_START일때_시간은_0이상이어야_한다() { assertThatCode(() -> new Bell(BellType.AFTER_START, 0, 1)) .doesNotThrowAnyException(); } + @Test + void 벨_종류가_BEFORE_END일때_시간이_음수면_생성되지_않는다() { + assertThatThrownBy(() -> new Bell(BellType.BEFORE_END, -1, 1)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); + } + + @Test + void 벨_종류가_BEFORE_END일때_시간은_0이상이어야_한다() { + assertThatCode(() -> new Bell(BellType.BEFORE_END, 0, 1)) + .doesNotThrowAnyException(); + } + + @Test + void 벨_종류가_AFTER_END일때_시간이_양수면_생성되지_않는다() { + assertThatThrownBy(() -> new Bell(BellType.AFTER_END, 1, 1)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); + } + + @Test + void 벨_종류가_BEFORE_END일때_시간은_0이하여야_한다() { + assertThatCode(() -> new Bell(BellType.AFTER_END, 0, 1)) + .doesNotThrowAnyException(); + } + @ValueSource(ints = {0, Bell.MAX_BELL_COUNT + 1}) @ParameterizedTest void 벨_횟수는_정해진_횟수_바깥일_경우_생성되지_않는다(int count) { From adcfaf5c23af699ea6f850bfbfa70d3fad0e5d95 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 28 Jul 2025 11:47:20 +0900 Subject: [PATCH 06/15] =?UTF-8?q?feat:=20Bell=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../debatetimer/domain/customize/Bell.java | 8 +--- .../domain/customize/BellType.java | 14 ++++--- .../service/customize/CustomizeService.java | 4 +- .../domain/customize/BellTest.java | 40 ------------------- .../domain/customize/BellTypeTest.java | 36 +++++++++++++++++ 5 files changed, 48 insertions(+), 54 deletions(-) create mode 100644 src/test/java/com/debatetimer/domain/customize/BellTypeTest.java diff --git a/src/main/java/com/debatetimer/domain/customize/Bell.java b/src/main/java/com/debatetimer/domain/customize/Bell.java index f5200976..4766bb31 100644 --- a/src/main/java/com/debatetimer/domain/customize/Bell.java +++ b/src/main/java/com/debatetimer/domain/customize/Bell.java @@ -14,19 +14,13 @@ public class Bell { private final int count; public Bell(BellType type, int time, int count) { - validateTime(type, time); + type.validateTime(time); validateCount(count); this.type = type; this.time = time; this.count = count; } - private void validateTime(BellType type, int time) { - if (!type.isValidTime(time)) { - throw new DTClientErrorException(ClientErrorCode.INVALID_BELL_TIME); - } - } - private void validateCount(int count) { if (count <= 0 || count > MAX_BELL_COUNT) { throw new DTClientErrorException(ClientErrorCode.INVALID_BELL_COUNT); diff --git a/src/main/java/com/debatetimer/domain/customize/BellType.java b/src/main/java/com/debatetimer/domain/customize/BellType.java index 121e4c51..e90dc35d 100644 --- a/src/main/java/com/debatetimer/domain/customize/BellType.java +++ b/src/main/java/com/debatetimer/domain/customize/BellType.java @@ -1,6 +1,8 @@ package com.debatetimer.domain.customize; -import java.util.function.Predicate; +import com.debatetimer.exception.custom.DTClientErrorException; +import com.debatetimer.exception.errorcode.ClientErrorCode; +import java.util.function.IntPredicate; public enum BellType { @@ -9,13 +11,15 @@ public enum BellType { AFTER_END(time -> time <= 0), ; - private final Predicate timeValidator; + private final IntPredicate timeValidator; - BellType(Predicate timeValidator) { + BellType(IntPredicate timeValidator) { this.timeValidator = timeValidator; } - public boolean isValidTime(int time) { - return timeValidator.test(time); + public void validateTime(int time) { + if (!timeValidator.test(time)) { + throw new DTClientErrorException(ClientErrorCode.INVALID_BELL_TIME); + } } } diff --git a/src/main/java/com/debatetimer/service/customize/CustomizeService.java b/src/main/java/com/debatetimer/service/customize/CustomizeService.java index f9df4a3b..1670036f 100644 --- a/src/main/java/com/debatetimer/service/customize/CustomizeService.java +++ b/src/main/java/com/debatetimer/service/customize/CustomizeService.java @@ -28,8 +28,8 @@ public CustomizeTableResponse save(CustomizeTableCreateRequest tableCreateReques @Transactional(readOnly = true) public CustomizeTableResponse findTable(long tableId, Member member) { CustomizeTable table = customizeTableDomainRepository.getByIdAndMember(tableId, member); - List timeBoxEntities = customizeTableDomainRepository.getCustomizeTimeBoxes(tableId, member); - return new CustomizeTableResponse(table, timeBoxEntities); + List timeBoxes = customizeTableDomainRepository.getCustomizeTimeBoxes(tableId, member); + return new CustomizeTableResponse(table, timeBoxes); } @Transactional diff --git a/src/test/java/com/debatetimer/domain/customize/BellTest.java b/src/test/java/com/debatetimer/domain/customize/BellTest.java index c2be8eb6..6ec93af3 100644 --- a/src/test/java/com/debatetimer/domain/customize/BellTest.java +++ b/src/test/java/com/debatetimer/domain/customize/BellTest.java @@ -6,7 +6,6 @@ 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; @@ -15,45 +14,6 @@ class BellTest { @Nested class Validate { - @Test - void 벨_종류가_AFTER_START일때_시간이_음수면_생성되지_않는다() { - assertThatThrownBy(() -> new Bell(BellType.AFTER_START, -1, 1)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); - } - - @Test - void 벨_종류가_AFTER_START일때_시간은_0이상이어야_한다() { - assertThatCode(() -> new Bell(BellType.AFTER_START, 0, 1)) - .doesNotThrowAnyException(); - } - - @Test - void 벨_종류가_BEFORE_END일때_시간이_음수면_생성되지_않는다() { - assertThatThrownBy(() -> new Bell(BellType.BEFORE_END, -1, 1)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); - } - - @Test - void 벨_종류가_BEFORE_END일때_시간은_0이상이어야_한다() { - assertThatCode(() -> new Bell(BellType.BEFORE_END, 0, 1)) - .doesNotThrowAnyException(); - } - - @Test - void 벨_종류가_AFTER_END일때_시간이_양수면_생성되지_않는다() { - assertThatThrownBy(() -> new Bell(BellType.AFTER_END, 1, 1)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); - } - - @Test - void 벨_종류가_BEFORE_END일때_시간은_0이하여야_한다() { - assertThatCode(() -> new Bell(BellType.AFTER_END, 0, 1)) - .doesNotThrowAnyException(); - } - @ValueSource(ints = {0, Bell.MAX_BELL_COUNT + 1}) @ParameterizedTest void 벨_횟수는_정해진_횟수_바깥일_경우_생성되지_않는다(int count) { diff --git a/src/test/java/com/debatetimer/domain/customize/BellTypeTest.java b/src/test/java/com/debatetimer/domain/customize/BellTypeTest.java new file mode 100644 index 00000000..8500d326 --- /dev/null +++ b/src/test/java/com/debatetimer/domain/customize/BellTypeTest.java @@ -0,0 +1,36 @@ +package com.debatetimer.domain.customize; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.debatetimer.exception.custom.DTClientErrorException; +import com.debatetimer.exception.errorcode.ClientErrorCode; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class BellTypeTest { + + @Nested + class ValidateTime { + + @Test + void 벨_타입이_AFTER_START일때_시간은_0이상이어야_한다() { + assertThatThrownBy(() -> BellType.AFTER_START.validateTime(-1)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); + } + + @Test + void 벨_타입이_BEFORE_END일때_시간은_0이상이어야_한다() { + assertThatThrownBy(() -> BellType.BEFORE_END.validateTime(-1)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); + } + + @Test + void 벨_타입이_AFTER_END일때_시간은_0이하여야_한다() { + assertThatThrownBy(() -> BellType.AFTER_END.validateTime(1)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); + } + } +} From 7a8c985956f10301fa288e759987284e75470a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B1=B4=EC=9A=B0?= Date: Thu, 31 Jul 2025 03:41:30 +0900 Subject: [PATCH 07/15] =?UTF-8?q?[FEAT]=20=ED=88=AC=ED=91=9C=EC=9E=90=20AP?= =?UTF-8?q?I=20=EA=B5=AC=ED=98=84=20(#205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/ErrorDecoderConfig.java | 33 ++++ .../controller/poll/VoteController.java | 37 ++++ .../com/debatetimer/domain/member/Member.java | 2 +- .../com/debatetimer/domain/poll/Poll.java | 4 + .../debatetimer/domain/poll/PollStatus.java | 4 + .../com/debatetimer/domain/poll/Vote.java | 4 + .../poll/PollDomainRepository.java | 17 +- .../poll/VoteDomainRepository.java | 28 +++ .../CustomizeTableDomainRepository.java | 2 +- .../dto/poll/request/VoteRequest.java | 13 ++ .../dto/poll/response/VoteCreateResponse.java | 16 ++ .../poll/response/VoterPollInfoResponse.java | 31 ++++ .../{customize => }/BaseTimeEntity.java | 2 +- .../customize/CustomizeTableEntity.java | 3 +- .../debatetimer/entity/poll/PollEntity.java | 2 +- .../debatetimer/entity/poll/VoteEntity.java | 15 +- .../exception/decoder/H2ErrorDecoder.java | 22 +++ .../exception/decoder/MySqlErrorDecoder.java | 27 +++ .../decoder/RepositoryErrorDecoder.java | 8 + .../exception/errorcode/ClientErrorCode.java | 2 + .../repository/poll/PollRepository.java | 12 ++ .../repository/poll/VoteRepository.java | 2 + .../debatetimer/service/poll/PollService.java | 2 +- .../debatetimer/service/poll/VoteService.java | 56 ++++++ ...add_participate_code_unique_constraint.sql | 5 + .../controller/BaseControllerTest.java | 10 + .../controller/BaseDocumentTest.java | 4 + .../controller/poll/VoteControllerTest.java | 173 ++++++++++++++++++ .../controller/poll/VoteDocumentTest.java | 156 ++++++++++++++++ .../poll/VoteDomainRepositoryTest.java | 62 +++++++ .../exception/decoder/H2ErrorDecoderTest.java | 51 ++++++ .../decoder/MySqlErrorDecoderTest.java | 54 ++++++ .../debatetimer/fixture/VoteGenerator.java | 6 +- .../service/poll/VoteServiceTest.java | 121 ++++++++++++ 34 files changed, 967 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/debatetimer/config/ErrorDecoderConfig.java create mode 100644 src/main/java/com/debatetimer/controller/poll/VoteController.java rename src/main/java/com/debatetimer/domainrepository/{poll => table}/CustomizeTableDomainRepository.java (95%) create mode 100644 src/main/java/com/debatetimer/dto/poll/request/VoteRequest.java create mode 100644 src/main/java/com/debatetimer/dto/poll/response/VoteCreateResponse.java create mode 100644 src/main/java/com/debatetimer/dto/poll/response/VoterPollInfoResponse.java rename src/main/java/com/debatetimer/entity/{customize => }/BaseTimeEntity.java (93%) create mode 100644 src/main/java/com/debatetimer/exception/decoder/H2ErrorDecoder.java create mode 100644 src/main/java/com/debatetimer/exception/decoder/MySqlErrorDecoder.java create mode 100644 src/main/java/com/debatetimer/exception/decoder/RepositoryErrorDecoder.java create mode 100644 src/main/java/com/debatetimer/service/poll/VoteService.java create mode 100644 src/main/resources/db/migration/V12__add_participate_code_unique_constraint.sql create mode 100644 src/test/java/com/debatetimer/controller/poll/VoteControllerTest.java create mode 100644 src/test/java/com/debatetimer/controller/poll/VoteDocumentTest.java create mode 100644 src/test/java/com/debatetimer/exception/decoder/H2ErrorDecoderTest.java create mode 100644 src/test/java/com/debatetimer/exception/decoder/MySqlErrorDecoderTest.java create mode 100644 src/test/java/com/debatetimer/service/poll/VoteServiceTest.java diff --git a/src/main/java/com/debatetimer/config/ErrorDecoderConfig.java b/src/main/java/com/debatetimer/config/ErrorDecoderConfig.java new file mode 100644 index 00000000..5fee2c04 --- /dev/null +++ b/src/main/java/com/debatetimer/config/ErrorDecoderConfig.java @@ -0,0 +1,33 @@ +package com.debatetimer.config; + +import com.debatetimer.exception.decoder.H2ErrorDecoder; +import com.debatetimer.exception.decoder.MySqlErrorDecoder; +import com.debatetimer.exception.decoder.RepositoryErrorDecoder; +import lombok.NoArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) +public class ErrorDecoderConfig { + + @Profile({"dev", "prod"}) + @Configuration + public static class MySqlErrorDecoderConfig { + + @Bean + public RepositoryErrorDecoder mySqlErrorDecoder() { + return new MySqlErrorDecoder(); + } + } + + @Profile({"test", "local"}) + @Configuration + public static class H2ErrorDecoderConfig { + + @Bean + public RepositoryErrorDecoder h2ErrorDecoder() { + return new H2ErrorDecoder(); + } + } +} diff --git a/src/main/java/com/debatetimer/controller/poll/VoteController.java b/src/main/java/com/debatetimer/controller/poll/VoteController.java new file mode 100644 index 00000000..64f53365 --- /dev/null +++ b/src/main/java/com/debatetimer/controller/poll/VoteController.java @@ -0,0 +1,37 @@ +package com.debatetimer.controller.poll; + +import com.debatetimer.dto.poll.request.VoteRequest; +import com.debatetimer.dto.poll.response.VoteCreateResponse; +import com.debatetimer.dto.poll.response.VoterPollInfoResponse; +import com.debatetimer.service.poll.VoteService; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +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 VoteController { + + private final VoteService voteService; + + @GetMapping("/api/polls/{pollId}/votes") + @ResponseStatus(HttpStatus.OK) + public VoterPollInfoResponse getVotersPollInfo(@PathVariable long pollId) { + return voteService.getVoterPollInfo(pollId); + } + + @PostMapping("/api/polls/{pollId}/votes") + @ResponseStatus(HttpStatus.CREATED) + public VoteCreateResponse votePoll( + @PathVariable long pollId, + @RequestBody @Valid VoteRequest voteRequest + ) { + return voteService.vote(pollId, voteRequest); + } +} diff --git a/src/main/java/com/debatetimer/domain/member/Member.java b/src/main/java/com/debatetimer/domain/member/Member.java index 9dec2246..923d17c5 100644 --- a/src/main/java/com/debatetimer/domain/member/Member.java +++ b/src/main/java/com/debatetimer/domain/member/Member.java @@ -1,6 +1,6 @@ package com.debatetimer.domain.member; -import com.debatetimer.entity.customize.BaseTimeEntity; +import com.debatetimer.entity.BaseTimeEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/src/main/java/com/debatetimer/domain/poll/Poll.java b/src/main/java/com/debatetimer/domain/poll/Poll.java index fd1c15a5..b3b23663 100644 --- a/src/main/java/com/debatetimer/domain/poll/Poll.java +++ b/src/main/java/com/debatetimer/domain/poll/Poll.java @@ -26,4 +26,8 @@ public Poll(Long id, long tableId, long memberId, PollStatus status, String prosTeamName, String consTeamName, String agenda) { this(id, tableId, memberId, status, new TeamName(prosTeamName), new TeamName(consTeamName), new Agenda(agenda)); } + + public boolean isProgress() { + return status.isProgress(); + } } diff --git a/src/main/java/com/debatetimer/domain/poll/PollStatus.java b/src/main/java/com/debatetimer/domain/poll/PollStatus.java index f2d0ebad..98379b68 100644 --- a/src/main/java/com/debatetimer/domain/poll/PollStatus.java +++ b/src/main/java/com/debatetimer/domain/poll/PollStatus.java @@ -5,4 +5,8 @@ public enum PollStatus { PROGRESS, DONE, ; + + public boolean isProgress() { + return this == PROGRESS; + } } diff --git a/src/main/java/com/debatetimer/domain/poll/Vote.java b/src/main/java/com/debatetimer/domain/poll/Vote.java index a69f946a..6d14cf5f 100644 --- a/src/main/java/com/debatetimer/domain/poll/Vote.java +++ b/src/main/java/com/debatetimer/domain/poll/Vote.java @@ -13,6 +13,10 @@ public class Vote { private final ParticipantName name; private final ParticipateCode code; + public Vote(long pollId, VoteTeam team, String name, String code) { + this(null, pollId, team, name, code); + } + public Vote(Long id, long pollId, VoteTeam team, String name, String code) { this(id, pollId, team, new ParticipantName(name), new ParticipateCode(code)); } diff --git a/src/main/java/com/debatetimer/domainrepository/poll/PollDomainRepository.java b/src/main/java/com/debatetimer/domainrepository/poll/PollDomainRepository.java index fa46adfb..e35ceca4 100644 --- a/src/main/java/com/debatetimer/domainrepository/poll/PollDomainRepository.java +++ b/src/main/java/com/debatetimer/domainrepository/poll/PollDomainRepository.java @@ -2,8 +2,6 @@ import com.debatetimer.domain.poll.Poll; import com.debatetimer.entity.poll.PollEntity; -import com.debatetimer.exception.custom.DTClientErrorException; -import com.debatetimer.exception.errorcode.ClientErrorCode; import com.debatetimer.repository.poll.PollRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -24,19 +22,20 @@ public Poll create(Poll poll) { @Transactional(readOnly = true) public Poll getByIdAndMemberId(long id, long memberId) { - return findPoll(id, memberId) + return pollRepository.getByIdAndMemberId(id, memberId) + .toDomain(); + } + + @Transactional(readOnly = true) + public Poll getById(long id) { + return pollRepository.getById(id) .toDomain(); } @Transactional public Poll finishPoll(long pollId, long memberId) { - PollEntity pollEntity = findPoll(pollId, memberId); + PollEntity pollEntity = pollRepository.getByIdAndMemberId(pollId, memberId); pollEntity.updateToDone(); return pollEntity.toDomain(); } - - private PollEntity findPoll(long pollId, long memberId) { - return pollRepository.findByIdAndMemberId(pollId, memberId) - .orElseThrow(() -> new DTClientErrorException(ClientErrorCode.POLL_NOT_FOUND)); - } } diff --git a/src/main/java/com/debatetimer/domainrepository/poll/VoteDomainRepository.java b/src/main/java/com/debatetimer/domainrepository/poll/VoteDomainRepository.java index 97f8dd1f..dc79f01f 100644 --- a/src/main/java/com/debatetimer/domainrepository/poll/VoteDomainRepository.java +++ b/src/main/java/com/debatetimer/domainrepository/poll/VoteDomainRepository.java @@ -1,20 +1,30 @@ package com.debatetimer.domainrepository.poll; +import com.debatetimer.domain.poll.ParticipateCode; +import com.debatetimer.domain.poll.Vote; import com.debatetimer.domain.poll.VoteInfo; import com.debatetimer.domain.poll.VoteTeam; +import com.debatetimer.entity.poll.PollEntity; import com.debatetimer.entity.poll.VoteEntity; +import com.debatetimer.exception.custom.DTClientErrorException; +import com.debatetimer.exception.decoder.RepositoryErrorDecoder; +import com.debatetimer.exception.errorcode.ClientErrorCode; +import com.debatetimer.repository.poll.PollRepository; import com.debatetimer.repository.poll.VoteRepository; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Repository; @Repository @RequiredArgsConstructor public class VoteDomainRepository { + private final PollRepository pollRepository; private final VoteRepository voteRepository; + private final RepositoryErrorDecoder errorDecoder; public VoteInfo findVoteInfoByPollId(long pollId) { List pollVotes = voteRepository.findAllByPollId(pollId); @@ -28,4 +38,22 @@ private VoteInfo countVotes(long pollId, List voteEntities) { long consCount = teamCount.getOrDefault(VoteTeam.CONS, 0L); return new VoteInfo(pollId, prosCount, consCount); } + + public boolean isExists(long pollId, ParticipateCode code) { + return voteRepository.existsByPollIdAndParticipateCode(pollId, code.getValue()); + } + + public Vote save(Vote vote) { + try { + PollEntity pollEntity = pollRepository.getById(vote.getPollId()); + VoteEntity voteEntity = new VoteEntity(vote, pollEntity); + return voteRepository.save(voteEntity) + .toDomain(); + } catch (DataIntegrityViolationException exception) { + if (errorDecoder.isUniqueConstraintViolation(exception)) { + throw new DTClientErrorException(ClientErrorCode.ALREADY_VOTED_PARTICIPANT); + } + throw exception; + } + } } diff --git a/src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java b/src/main/java/com/debatetimer/domainrepository/table/CustomizeTableDomainRepository.java similarity index 95% rename from src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java rename to src/main/java/com/debatetimer/domainrepository/table/CustomizeTableDomainRepository.java index 850c53bd..f48ffc33 100644 --- a/src/main/java/com/debatetimer/domainrepository/poll/CustomizeTableDomainRepository.java +++ b/src/main/java/com/debatetimer/domainrepository/table/CustomizeTableDomainRepository.java @@ -1,4 +1,4 @@ -package com.debatetimer.domainrepository.poll; +package com.debatetimer.domainrepository.table; import com.debatetimer.domain.customize.CustomizeTable; import com.debatetimer.domain.member.Member; diff --git a/src/main/java/com/debatetimer/dto/poll/request/VoteRequest.java b/src/main/java/com/debatetimer/dto/poll/request/VoteRequest.java new file mode 100644 index 00000000..ccf22242 --- /dev/null +++ b/src/main/java/com/debatetimer/dto/poll/request/VoteRequest.java @@ -0,0 +1,13 @@ +package com.debatetimer.dto.poll.request; + +import com.debatetimer.domain.poll.VoteTeam; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +public record VoteRequest( + @NotBlank String name, + @NotBlank String participateCode, + @NotNull VoteTeam team +) { + +} diff --git a/src/main/java/com/debatetimer/dto/poll/response/VoteCreateResponse.java b/src/main/java/com/debatetimer/dto/poll/response/VoteCreateResponse.java new file mode 100644 index 00000000..07bf2f2a --- /dev/null +++ b/src/main/java/com/debatetimer/dto/poll/response/VoteCreateResponse.java @@ -0,0 +1,16 @@ +package com.debatetimer.dto.poll.response; + +import com.debatetimer.domain.poll.Vote; +import com.debatetimer.domain.poll.VoteTeam; + +public record VoteCreateResponse( + long id, + String name, + String participateCode, + VoteTeam team +) { + + public VoteCreateResponse(Vote vote) { + this(vote.getId(), vote.getName().getValue(), vote.getCode().getValue(), vote.getTeam()); + } +} diff --git a/src/main/java/com/debatetimer/dto/poll/response/VoterPollInfoResponse.java b/src/main/java/com/debatetimer/dto/poll/response/VoterPollInfoResponse.java new file mode 100644 index 00000000..acf86030 --- /dev/null +++ b/src/main/java/com/debatetimer/dto/poll/response/VoterPollInfoResponse.java @@ -0,0 +1,31 @@ +package com.debatetimer.dto.poll.response; + +import com.debatetimer.domain.poll.ParticipateCode; +import com.debatetimer.domain.poll.Poll; +import com.debatetimer.domain.poll.PollStatus; +import com.debatetimer.domain.poll.VoteInfo; + +public record VoterPollInfoResponse( + long id, + PollStatus status, + String prosTeamName, + String consTeamName, + String participateCode, + long totalCount, + long prosCount, + long consCount +) { + + public VoterPollInfoResponse(Poll poll, VoteInfo voteInfo, ParticipateCode code) { + this( + poll.getId(), + poll.getStatus(), + poll.getProsTeamName().getValue(), + poll.getConsTeamName().getValue(), + code.getValue(), + voteInfo.getTotalCount(), + voteInfo.getProsCount(), + voteInfo.getConsCount() + ); + } +} diff --git a/src/main/java/com/debatetimer/entity/customize/BaseTimeEntity.java b/src/main/java/com/debatetimer/entity/BaseTimeEntity.java similarity index 93% rename from src/main/java/com/debatetimer/entity/customize/BaseTimeEntity.java rename to src/main/java/com/debatetimer/entity/BaseTimeEntity.java index 1bca8c75..e9405201 100644 --- a/src/main/java/com/debatetimer/entity/customize/BaseTimeEntity.java +++ b/src/main/java/com/debatetimer/entity/BaseTimeEntity.java @@ -1,4 +1,4 @@ -package com.debatetimer.entity.customize; +package com.debatetimer.entity; import jakarta.persistence.EntityListeners; import jakarta.persistence.MappedSuperclass; diff --git a/src/main/java/com/debatetimer/entity/customize/CustomizeTableEntity.java b/src/main/java/com/debatetimer/entity/customize/CustomizeTableEntity.java index 88cfd3bb..ff24334e 100644 --- a/src/main/java/com/debatetimer/entity/customize/CustomizeTableEntity.java +++ b/src/main/java/com/debatetimer/entity/customize/CustomizeTableEntity.java @@ -3,6 +3,7 @@ import com.debatetimer.domain.customize.CustomizeTable; import com.debatetimer.domain.member.Member; import com.debatetimer.dto.member.TableType; +import com.debatetimer.entity.BaseTimeEntity; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; @@ -22,7 +23,7 @@ @Getter @Table(name = "customize_table") @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class CustomizeTableEntity { +public class CustomizeTableEntity extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/debatetimer/entity/poll/PollEntity.java b/src/main/java/com/debatetimer/entity/poll/PollEntity.java index bb4e5433..04e8ac28 100644 --- a/src/main/java/com/debatetimer/entity/poll/PollEntity.java +++ b/src/main/java/com/debatetimer/entity/poll/PollEntity.java @@ -2,7 +2,7 @@ import com.debatetimer.domain.poll.Poll; import com.debatetimer.domain.poll.PollStatus; -import com.debatetimer.entity.customize.BaseTimeEntity; +import com.debatetimer.entity.BaseTimeEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; diff --git a/src/main/java/com/debatetimer/entity/poll/VoteEntity.java b/src/main/java/com/debatetimer/entity/poll/VoteEntity.java index 47dd0a2c..0b0f26c7 100644 --- a/src/main/java/com/debatetimer/entity/poll/VoteEntity.java +++ b/src/main/java/com/debatetimer/entity/poll/VoteEntity.java @@ -2,6 +2,7 @@ import com.debatetimer.domain.poll.Vote; import com.debatetimer.domain.poll.VoteTeam; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; @@ -12,6 +13,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.AccessLevel; @@ -21,7 +23,9 @@ @Entity @Getter -@Table(name = "vote") +@Table(name = "vote", uniqueConstraints = { + @UniqueConstraint(columnNames = {"poll_id", "participate_code"}) +}) @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor public class VoteEntity { @@ -43,9 +47,14 @@ public class VoteEntity { private String name; @NotBlank - private String participantCode; + @Column(name = "participate_code") + private String participateCode; + + public VoteEntity(Vote vote, PollEntity pollEntity) { + this(vote.getId(), pollEntity, vote.getTeam(), vote.getName().getValue(), vote.getCode().getValue()); + } public Vote toDomain() { - return new Vote(id, poll.getId(), team, name, participantCode); + return new Vote(id, poll.getId(), team, name, participateCode); } } diff --git a/src/main/java/com/debatetimer/exception/decoder/H2ErrorDecoder.java b/src/main/java/com/debatetimer/exception/decoder/H2ErrorDecoder.java new file mode 100644 index 00000000..42ea2660 --- /dev/null +++ b/src/main/java/com/debatetimer/exception/decoder/H2ErrorDecoder.java @@ -0,0 +1,22 @@ +package com.debatetimer.exception.decoder; + +import org.hibernate.exception.ConstraintViolationException; +import org.springframework.dao.DataIntegrityViolationException; + +public class H2ErrorDecoder implements RepositoryErrorDecoder { + + protected static final String UNIQUE_CONSTRAINT_VIOLATION_SQL_STATE = "23505"; + + @Override + public boolean isUniqueConstraintViolation(DataIntegrityViolationException e) { + Throwable cause = e.getCause(); + while (cause != null) { + if (cause instanceof ConstraintViolationException cve) { + String sqlState = cve.getSQLException().getSQLState(); + return UNIQUE_CONSTRAINT_VIOLATION_SQL_STATE.equals(sqlState); + } + cause = cause.getCause(); + } + return false; + } +} diff --git a/src/main/java/com/debatetimer/exception/decoder/MySqlErrorDecoder.java b/src/main/java/com/debatetimer/exception/decoder/MySqlErrorDecoder.java new file mode 100644 index 00000000..f7ddf38c --- /dev/null +++ b/src/main/java/com/debatetimer/exception/decoder/MySqlErrorDecoder.java @@ -0,0 +1,27 @@ +package com.debatetimer.exception.decoder; + +import java.sql.SQLException; +import org.hibernate.exception.ConstraintViolationException; +import org.springframework.dao.DataIntegrityViolationException; + +public class MySqlErrorDecoder implements RepositoryErrorDecoder { + + protected static final String MYSQL_UNIQUE_VIOLATION = "23000"; + protected static final int MYSQL_DUP_ERROR_CODE = 1062; + + @Override + public boolean isUniqueConstraintViolation(DataIntegrityViolationException e) { + Throwable cause = e.getCause(); + while (cause != null) { + if (cause instanceof ConstraintViolationException cve) { + SQLException sqlEx = cve.getSQLException(); + String sqlState = sqlEx.getSQLState(); + int errorCode = sqlEx.getErrorCode(); + return MYSQL_UNIQUE_VIOLATION.equals(sqlState) + && MYSQL_DUP_ERROR_CODE == errorCode; + } + cause = cause.getCause(); + } + return false; + } +} diff --git a/src/main/java/com/debatetimer/exception/decoder/RepositoryErrorDecoder.java b/src/main/java/com/debatetimer/exception/decoder/RepositoryErrorDecoder.java new file mode 100644 index 00000000..8d71e834 --- /dev/null +++ b/src/main/java/com/debatetimer/exception/decoder/RepositoryErrorDecoder.java @@ -0,0 +1,8 @@ +package com.debatetimer.exception.decoder; + +import org.springframework.dao.DataIntegrityViolationException; + +public interface RepositoryErrorDecoder { + + boolean isUniqueConstraintViolation(DataIntegrityViolationException exception); +} diff --git a/src/main/java/com/debatetimer/exception/errorcode/ClientErrorCode.java b/src/main/java/com/debatetimer/exception/errorcode/ClientErrorCode.java index f0672c70..695cbb0c 100644 --- a/src/main/java/com/debatetimer/exception/errorcode/ClientErrorCode.java +++ b/src/main/java/com/debatetimer/exception/errorcode/ClientErrorCode.java @@ -50,6 +50,8 @@ public enum ClientErrorCode implements ResponseErrorCode { INVALID_POLL_PARTICIPANT_NAME(HttpStatus.BAD_REQUEST, "잘못된 투표자 이름입니다"), INVALID_POLL_PARTICIPANT_CODE(HttpStatus.BAD_REQUEST, "잘못된 투표참여 코드입니다"), + ALREADY_DONE_POLL(HttpStatus.BAD_REQUEST, "이미 완료된 투표 입니다"), + ALREADY_VOTED_PARTICIPANT(HttpStatus.BAD_REQUEST, "이미 참여한 투표자 입니다"), TABLE_NOT_FOUND(HttpStatus.NOT_FOUND, "토론 테이블을 찾을 수 없습니다."), NOT_TABLE_OWNER(HttpStatus.UNAUTHORIZED, "테이블을 소유한 회원이 아닙니다."), diff --git a/src/main/java/com/debatetimer/repository/poll/PollRepository.java b/src/main/java/com/debatetimer/repository/poll/PollRepository.java index 121d1627..22c6db56 100644 --- a/src/main/java/com/debatetimer/repository/poll/PollRepository.java +++ b/src/main/java/com/debatetimer/repository/poll/PollRepository.java @@ -1,10 +1,22 @@ package com.debatetimer.repository.poll; import com.debatetimer.entity.poll.PollEntity; +import com.debatetimer.exception.custom.DTClientErrorException; +import com.debatetimer.exception.errorcode.ClientErrorCode; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface PollRepository extends JpaRepository { Optional findByIdAndMemberId(long id, long memberId); + + default PollEntity getById(long id) { + return findById(id) + .orElseThrow(() -> new DTClientErrorException(ClientErrorCode.POLL_NOT_FOUND)); + } + + default PollEntity getByIdAndMemberId(long id, long memberId) { + return findByIdAndMemberId(id, memberId) + .orElseThrow(() -> new DTClientErrorException(ClientErrorCode.POLL_NOT_FOUND)); + } } diff --git a/src/main/java/com/debatetimer/repository/poll/VoteRepository.java b/src/main/java/com/debatetimer/repository/poll/VoteRepository.java index a9709200..5f211efd 100644 --- a/src/main/java/com/debatetimer/repository/poll/VoteRepository.java +++ b/src/main/java/com/debatetimer/repository/poll/VoteRepository.java @@ -7,4 +7,6 @@ public interface VoteRepository extends JpaRepository { List findAllByPollId(long pollId); + + boolean existsByPollIdAndParticipateCode(long pollId, String participateCode); } diff --git a/src/main/java/com/debatetimer/service/poll/PollService.java b/src/main/java/com/debatetimer/service/poll/PollService.java index a6409fdb..7d21bffb 100644 --- a/src/main/java/com/debatetimer/service/poll/PollService.java +++ b/src/main/java/com/debatetimer/service/poll/PollService.java @@ -4,9 +4,9 @@ import com.debatetimer.domain.member.Member; import com.debatetimer.domain.poll.Poll; import com.debatetimer.domain.poll.VoteInfo; -import com.debatetimer.domainrepository.poll.CustomizeTableDomainRepository; import com.debatetimer.domainrepository.poll.PollDomainRepository; import com.debatetimer.domainrepository.poll.VoteDomainRepository; +import com.debatetimer.domainrepository.table.CustomizeTableDomainRepository; import com.debatetimer.dto.poll.response.PollCreateResponse; import com.debatetimer.dto.poll.response.PollInfoResponse; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/debatetimer/service/poll/VoteService.java b/src/main/java/com/debatetimer/service/poll/VoteService.java new file mode 100644 index 00000000..8c485907 --- /dev/null +++ b/src/main/java/com/debatetimer/service/poll/VoteService.java @@ -0,0 +1,56 @@ +package com.debatetimer.service.poll; + +import com.debatetimer.domain.poll.ParticipateCode; +import com.debatetimer.domain.poll.Poll; +import com.debatetimer.domain.poll.Vote; +import com.debatetimer.domain.poll.VoteInfo; +import com.debatetimer.domainrepository.poll.PollDomainRepository; +import com.debatetimer.domainrepository.poll.VoteDomainRepository; +import com.debatetimer.dto.poll.request.VoteRequest; +import com.debatetimer.dto.poll.response.VoteCreateResponse; +import com.debatetimer.dto.poll.response.VoterPollInfoResponse; +import com.debatetimer.exception.custom.DTClientErrorException; +import com.debatetimer.exception.errorcode.ClientErrorCode; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class VoteService { + + private final VoteDomainRepository voteDomainRepository; + private final PollDomainRepository pollDomainRepository; + + @Transactional + public VoteCreateResponse vote(long pollId, VoteRequest voteRequest) { + validateProgressPoll(pollId); + validateAlreadyVoted(pollId, voteRequest.participateCode()); + Vote vote = new Vote(pollId, voteRequest.team(), voteRequest.name(), voteRequest.participateCode()); + Vote savedVote = voteDomainRepository.save(vote); + return new VoteCreateResponse(savedVote); + } + + private void validateProgressPoll(long pollId) { + Poll poll = pollDomainRepository.getById(pollId); + if (!poll.isProgress()) { + throw new DTClientErrorException(ClientErrorCode.ALREADY_DONE_POLL); + } + } + + private void validateAlreadyVoted(long pollId, String participateCode) { + ParticipateCode code = new ParticipateCode(participateCode); + if (voteDomainRepository.isExists(pollId, code)) { + throw new DTClientErrorException(ClientErrorCode.ALREADY_VOTED_PARTICIPANT); + } + } + + @Transactional(readOnly = true) + public VoterPollInfoResponse getVoterPollInfo(long pollId) { + Poll poll = pollDomainRepository.getById(pollId); + VoteInfo voteInfo = voteDomainRepository.findVoteInfoByPollId(pollId); + ParticipateCode code = new ParticipateCode(UUID.randomUUID().toString()); + return new VoterPollInfoResponse(poll, voteInfo, code); + } +} diff --git a/src/main/resources/db/migration/V12__add_participate_code_unique_constraint.sql b/src/main/resources/db/migration/V12__add_participate_code_unique_constraint.sql new file mode 100644 index 00000000..315fd427 --- /dev/null +++ b/src/main/resources/db/migration/V12__add_participate_code_unique_constraint.sql @@ -0,0 +1,5 @@ +ALTER TABLE vote + CHANGE participant_code participate_code VARCHAR (255) NOT NULL; + +ALTER TABLE vote + ADD CONSTRAINT uq_vote_poll_participate UNIQUE (poll_id, participate_code); diff --git a/src/test/java/com/debatetimer/controller/BaseControllerTest.java b/src/test/java/com/debatetimer/controller/BaseControllerTest.java index 83d35dda..c63a61fb 100644 --- a/src/test/java/com/debatetimer/controller/BaseControllerTest.java +++ b/src/test/java/com/debatetimer/controller/BaseControllerTest.java @@ -4,10 +4,12 @@ import com.debatetimer.client.oauth.OAuthClient; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.customize.Stance; +import com.debatetimer.domain.poll.VoteTeam; import com.debatetimer.dto.customize.request.BellRequest; import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTableInfoCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTimeBoxCreateRequest; +import com.debatetimer.dto.poll.request.VoteRequest; import com.debatetimer.fixture.CustomizeTableGenerator; import com.debatetimer.fixture.CustomizeTimeBoxGenerator; import com.debatetimer.fixture.HeaderGenerator; @@ -24,6 +26,7 @@ import io.restassured.filter.log.RequestLoggingFilter; import io.restassured.filter.log.ResponseLoggingFilter; import io.restassured.specification.RequestSpecification; +import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -90,6 +93,13 @@ protected ArbitraryBuilder getCustomizeTableCreateR .set("table", getCustomizeTimeBoxCreateRequestBuilder().sampleList(2)); } + protected ArbitraryBuilder getVoteRequestBuilder() { + return fixtureMonkey.giveMeBuilder(VoteRequest.class) + .set("name", "콜리") + .set("team", VoteTeam.PROS) + .set("participateCode", UUID.randomUUID().toString()); + } + private ArbitraryBuilder getCustomizeTableInfoCreateRequestBuilder() { return fixtureMonkey.giveMeBuilder(CustomizeTableInfoCreateRequest.class) .set("name", "자유 테이블") diff --git a/src/test/java/com/debatetimer/controller/BaseDocumentTest.java b/src/test/java/com/debatetimer/controller/BaseDocumentTest.java index 40c80cc1..0a74a3cc 100644 --- a/src/test/java/com/debatetimer/controller/BaseDocumentTest.java +++ b/src/test/java/com/debatetimer/controller/BaseDocumentTest.java @@ -13,6 +13,7 @@ import com.debatetimer.service.customize.CustomizeService; import com.debatetimer.service.member.MemberService; import com.debatetimer.service.poll.PollService; +import com.debatetimer.service.poll.VoteService; import io.restassured.RestAssured; import io.restassured.builder.RequestSpecBuilder; import io.restassured.filter.log.RequestLoggingFilter; @@ -66,6 +67,9 @@ public abstract class BaseDocumentTest { @MockitoBean protected PollService pollService; + @MockitoBean + protected VoteService voteService; + @MockitoBean protected AuthManager authManager; diff --git a/src/test/java/com/debatetimer/controller/poll/VoteControllerTest.java b/src/test/java/com/debatetimer/controller/poll/VoteControllerTest.java new file mode 100644 index 00000000..06276c5b --- /dev/null +++ b/src/test/java/com/debatetimer/controller/poll/VoteControllerTest.java @@ -0,0 +1,173 @@ +package com.debatetimer.controller.poll; + +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.member.Member; +import com.debatetimer.domain.poll.PollStatus; +import com.debatetimer.domain.poll.VoteTeam; +import com.debatetimer.dto.poll.request.VoteRequest; +import com.debatetimer.dto.poll.response.VoteCreateResponse; +import com.debatetimer.dto.poll.response.VoterPollInfoResponse; +import com.debatetimer.entity.customize.CustomizeTableEntity; +import com.debatetimer.entity.poll.PollEntity; +import com.debatetimer.fixture.NullAndEmptyAndBlankSource; +import io.restassured.http.ContentType; +import java.util.UUID; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.springframework.http.HttpStatus; + +class VoteControllerTest extends BaseControllerTest { + + @Nested + class GetVotersPollInfo { + + @Test + void 투표자가_선거정보를_조회할_수_있다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); + voteGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); + + VoterPollInfoResponse response = given() + .contentType(ContentType.JSON) + .pathParam("pollId", pollEntity.getId()) + .when().get("/api/polls/{pollId}/votes") + .then().statusCode(HttpStatus.OK.value()) + .extract().as(VoterPollInfoResponse.class); + + assertAll( + () -> assertThat(response.id()).isEqualTo(pollEntity.getId()), + () -> assertThat(response.prosTeamName()).isEqualTo(pollEntity.getProsTeamName()), + () -> assertThat(response.consTeamName()).isEqualTo(pollEntity.getConsTeamName()), + () -> assertThat(response.status()).isEqualTo(pollEntity.getStatus()), + () -> assertThat(response.totalCount()).isEqualTo(3L), + () -> assertThat(response.participateCode()).isNotBlank(), + () -> assertThat(response.prosCount()).isEqualTo(2L), + () -> assertThat(response.consCount()).isEqualTo(1L) + ); + } + } + + @Nested + class VotePoll { + + @Test + void 진행_중인_선거에_최초로_투표_할_수_있다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + VoteRequest voteRequest = getVoteRequestBuilder().sample(); + + VoteCreateResponse response = given() + .contentType(ContentType.JSON) + .body(voteRequest) + .pathParam("pollId", pollEntity.getId()) + .when().post("/api/polls/{pollId}/votes") + .then().statusCode(HttpStatus.CREATED.value()) + .extract().as(VoteCreateResponse.class); + + assertAll( + () -> assertThat(response.name()).isEqualTo(voteRequest.name()), + () -> assertThat(response.participateCode()).isEqualTo(voteRequest.participateCode()), + () -> assertThat(response.team()).isEqualTo(voteRequest.team()) + ); + } + + @ParameterizedTest + @NullAndEmptyAndBlankSource + void 투표_시_이름은_널이거나_빈_문자열일_수_없다(String invalidName) { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + VoteRequest voteRequest = getVoteRequestBuilder() + .set("name", invalidName) + .sample(); + + given() + .contentType(ContentType.JSON) + .body(voteRequest) + .pathParam("pollId", pollEntity.getId()) + .when().post("/api/polls/{pollId}/votes") + .then().statusCode(HttpStatus.BAD_REQUEST.value()); + } + + @Test + void 투표_시_팀은_널일_수_없다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + VoteRequest voteRequest = getVoteRequestBuilder() + .set("team", null) + .sample(); + + given() + .contentType(ContentType.JSON) + .body(voteRequest) + .pathParam("pollId", pollEntity.getId()) + .when().post("/api/polls/{pollId}/votes") + .then().statusCode(HttpStatus.BAD_REQUEST.value()); + } + + @ParameterizedTest + @NullAndEmptyAndBlankSource + void 투표_시_참여코드는_널이거나_빈_문자열일_수_없다(String participateCode) { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + VoteRequest voteRequest = getVoteRequestBuilder() + .set("participateCode", participateCode) + .sample(); + + given() + .contentType(ContentType.JSON) + .body(voteRequest) + .pathParam("pollId", pollEntity.getId()) + .when().post("/api/polls/{pollId}/votes") + .then().statusCode(HttpStatus.BAD_REQUEST.value()); + } + + @Test + void 이미_참여한_선거에_투표_할_수_없다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + String participatecode = UUID.randomUUID().toString(); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리", participatecode); + VoteRequest voteRequest = getVoteRequestBuilder() + .set("participateCode", participatecode) + .sample(); + + given() + .contentType(ContentType.JSON) + .body(voteRequest) + .pathParam("pollId", pollEntity.getId()) + .when().post("/api/polls/{pollId}/votes") + .then().statusCode(HttpStatus.BAD_REQUEST.value()); + } + + @Test + void 끝난_선거에_투표_할_수_없다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity alreadyDonePoll = pollGenerator.generate(table, PollStatus.DONE); + VoteRequest voteRequest = getVoteRequestBuilder().sample(); + + given() + .contentType(ContentType.JSON) + .body(voteRequest) + .pathParam("pollId", alreadyDonePoll.getId()) + .when().post("/api/polls/{pollId}/votes") + .then().statusCode(HttpStatus.BAD_REQUEST.value()); + } + } +} diff --git a/src/test/java/com/debatetimer/controller/poll/VoteDocumentTest.java b/src/test/java/com/debatetimer/controller/poll/VoteDocumentTest.java new file mode 100644 index 00000000..998c6989 --- /dev/null +++ b/src/test/java/com/debatetimer/controller/poll/VoteDocumentTest.java @@ -0,0 +1,156 @@ +package com.debatetimer.controller.poll; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; +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.poll.PollStatus; +import com.debatetimer.domain.poll.VoteTeam; +import com.debatetimer.dto.poll.request.VoteRequest; +import com.debatetimer.dto.poll.response.VoteCreateResponse; +import com.debatetimer.dto.poll.response.VoterPollInfoResponse; +import com.debatetimer.exception.custom.DTClientErrorException; +import com.debatetimer.exception.errorcode.ClientErrorCode; +import io.restassured.http.ContentType; +import java.util.UUID; +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; + +public class VoteDocumentTest extends BaseDocumentTest { + + @Nested + class GetVotersPollInfo { + + private final RestDocumentationRequest requestDocument = request() + .tag(Tag.POLL_API) + .summary("투표자 - 선거 정보 조회") + .pathParameter( + parameterWithName("pollId").description("선거 ID") + ); + + private final RestDocumentationResponse responseDocument = response() + .responseBodyField( + fieldWithPath("id").type(NUMBER).description("선거 ID"), + fieldWithPath("status").type(STRING).description("선거 상태 - 진행중 : PROGRESS, 완료 : DONE"), + fieldWithPath("prosTeamName").type(STRING).description("찬성측 팀 이름"), + fieldWithPath("consTeamName").type(STRING).description("반대측 팀 이름"), + fieldWithPath("participateCode").type(STRING).description("참여 코드"), + fieldWithPath("totalCount").type(NUMBER).description("전체 투표 수"), + fieldWithPath("prosCount").type(NUMBER).description("찬성 투표 수"), + fieldWithPath("consCount").type(NUMBER).description("반대 투표 수") + ); + + @Test + void 투표자_선거_정보_조회() { + VoterPollInfoResponse response = new VoterPollInfoResponse( + 1L, + PollStatus.PROGRESS, + "찬성", + "반대", + UUID.randomUUID().toString(), + 3L, + 2L, + 1L + ); + doReturn(response).when(voteService).getVoterPollInfo(anyLong()); + + var document = document("vote/get", 200) + .request(requestDocument) + .response(responseDocument) + .build(); + + given(document) + .contentType(ContentType.JSON) + .pathParam("pollId", 1l) + .when().get("/api/polls/{pollId}/votes") + .then().statusCode(200); + } + } + + @Nested + class VotePoll { + + private final RestDocumentationRequest requestDocument = request() + .tag(Tag.POLL_API) + .summary("투표자 - 선거 투표") + .pathParameter( + parameterWithName("pollId").description("선거 ID") + ) + .requestBodyField( + fieldWithPath("name").type(STRING).description("투표자 이름"), + fieldWithPath("participateCode").type(STRING).description("투표 참여 코드"), + fieldWithPath("team").type(STRING).description("투표 팀") + ); + + private final RestDocumentationResponse responseDocument = response() + .responseBodyField( + fieldWithPath("id").type(NUMBER).description("투표 ID"), + fieldWithPath("name").type(STRING).description("투표자 이름"), + fieldWithPath("participateCode").type(STRING).description("투표 참여 코드"), + fieldWithPath("team").type(STRING).description("투표 팀") + ); + + @Test + void 투표자_선거_정보_조회() { + VoteRequest voteRequest = new VoteRequest("콜리", UUID.randomUUID().toString(), VoteTeam.PROS); + VoteCreateResponse response = new VoteCreateResponse( + 1L, + voteRequest.name(), + voteRequest.participateCode(), + voteRequest.team() + ); + doReturn(response).when(voteService).vote(anyLong(), any()); + + var document = document("vote/post", 201) + .request(requestDocument) + .response(responseDocument) + .build(); + + given(document) + .contentType(ContentType.JSON) + .body(voteRequest) + .pathParam("pollId", 1l) + .when().post("/api/polls/{pollId}/votes") + .then().statusCode(201); + } + + @EnumSource( + value = ClientErrorCode.class, + names = { + "ALREADY_DONE_POLL", + "ALREADY_VOTED_PARTICIPANT", + "INVALID_POLL_PARTICIPANT_CODE", + "INVALID_POLL_PARTICIPANT_NAME" + } + ) + @ParameterizedTest + void 투표자_투표_실패(ClientErrorCode clientErrorCode) { + VoteRequest voteRequest = new VoteRequest("콜리", UUID.randomUUID().toString(), VoteTeam.PROS); + doThrow(new DTClientErrorException(clientErrorCode)).when(voteService).vote(anyLong(), any()); + + var document = document("vote/post", clientErrorCode) + .request(requestDocument) + .response(ERROR_RESPONSE) + .build(); + + given(document) + .contentType(ContentType.JSON) + .body(voteRequest) + .pathParam("pollId", 1l) + .when().post("/api/polls/{pollId}/votes") + .then().statusCode(clientErrorCode.getStatus().value()); + + } + } +} diff --git a/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java b/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java index 068e782e..11ed5d33 100644 --- a/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java +++ b/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java @@ -1,15 +1,21 @@ package com.debatetimer.domainrepository.poll; 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.member.Member; +import com.debatetimer.domain.poll.ParticipateCode; import com.debatetimer.domain.poll.PollStatus; +import com.debatetimer.domain.poll.Vote; import com.debatetimer.domain.poll.VoteInfo; import com.debatetimer.domain.poll.VoteTeam; import com.debatetimer.domainrepository.BaseDomainRepositoryTest; import com.debatetimer.entity.customize.CustomizeTableEntity; import com.debatetimer.entity.poll.PollEntity; +import com.debatetimer.exception.custom.DTClientErrorException; +import com.debatetimer.exception.errorcode.ClientErrorCode; +import java.util.UUID; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -42,4 +48,60 @@ class GetVoteInfo { } } + @Nested + class isExists { + + @Test + void 이미_참여한_투표인지_알_수_있다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity alreadyParticipatedPoll = pollGenerator.generate(table, PollStatus.PROGRESS); + PollEntity notYetParticipatedPoll = pollGenerator.generate(table, PollStatus.PROGRESS); + ParticipateCode participateCode = new ParticipateCode(UUID.randomUUID().toString()); + voteGenerator.generate(alreadyParticipatedPoll, VoteTeam.PROS, "콜리", participateCode.getValue()); + + boolean participated = voteDomainRepository.isExists(alreadyParticipatedPoll.getId(), participateCode); + boolean notYetParticipated = voteDomainRepository.isExists(notYetParticipatedPoll.getId(), + participateCode); + + assertAll( + () -> assertThat(participated).isTrue(), + () -> assertThat(notYetParticipated).isFalse() + ); + } + } + + @Nested + class Save { + + @Test + void 투표를_저장할_수_있다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + Vote vote = new Vote(pollEntity.getId(), VoteTeam.PROS, "콜리", UUID.randomUUID().toString()); + + Vote savedVote = voteDomainRepository.save(vote); + + assertAll( + () -> assertThat(savedVote.getName().getValue()).isEqualTo(vote.getName().getValue()), + () -> assertThat(savedVote.getCode().getValue()).isEqualTo(vote.getCode().getValue()), + () -> assertThat(savedVote.getTeam()).isEqualTo(vote.getTeam()) + ); + } + + @Test + void 중복_투표할_수_없다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + String participateCode = UUID.randomUUID().toString(); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리", participateCode); + Vote vote = new Vote(pollEntity.getId(), VoteTeam.PROS, "콜리", participateCode); + + assertThatThrownBy(() -> voteDomainRepository.save(vote)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.ALREADY_VOTED_PARTICIPANT.getMessage()); + } + } } diff --git a/src/test/java/com/debatetimer/exception/decoder/H2ErrorDecoderTest.java b/src/test/java/com/debatetimer/exception/decoder/H2ErrorDecoderTest.java new file mode 100644 index 00000000..147ff327 --- /dev/null +++ b/src/test/java/com/debatetimer/exception/decoder/H2ErrorDecoderTest.java @@ -0,0 +1,51 @@ +package com.debatetimer.exception.decoder; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.sql.SQLException; +import org.hibernate.exception.ConstraintViolationException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.dao.DataIntegrityViolationException; + +class H2ErrorDecoderTest { + + private H2ErrorDecoder errorDecoder; + + + @BeforeEach + void setUp() { + errorDecoder = new H2ErrorDecoder(); + } + + @Nested + class isUniqueError { + + @Test + void 유니크_제약조건_에러를_판단할_수_있다() { + SQLException uniqueError = new SQLException("유니크 에러", H2ErrorDecoder.UNIQUE_CONSTRAINT_VIOLATION_SQL_STATE); + ConstraintViolationException uniqueViolation = new ConstraintViolationException("유니크 에러", uniqueError, + "vote_poll_id_participate_code"); + DataIntegrityViolationException uniqueException = new DataIntegrityViolationException("유니크 에러", + uniqueViolation); + + boolean isUniqueError = errorDecoder.isUniqueConstraintViolation(uniqueException); + + assertThat(isUniqueError).isTrue(); + } + + @Test + void 유니크_제약조건_에러가_아님을_판단한다() { + SQLException notUniqueError = new SQLException("다른 에러", "23000"); + ConstraintViolationException notUniqueViolation = new ConstraintViolationException("기타 에러", notUniqueError, + "some_constraint"); + DataIntegrityViolationException extraException = new DataIntegrityViolationException("에러", + notUniqueViolation); + + boolean isNotUniqueError = errorDecoder.isUniqueConstraintViolation(extraException); + + assertThat(isNotUniqueError).isFalse(); + } + } +} diff --git a/src/test/java/com/debatetimer/exception/decoder/MySqlErrorDecoderTest.java b/src/test/java/com/debatetimer/exception/decoder/MySqlErrorDecoderTest.java new file mode 100644 index 00000000..f49d5978 --- /dev/null +++ b/src/test/java/com/debatetimer/exception/decoder/MySqlErrorDecoderTest.java @@ -0,0 +1,54 @@ +package com.debatetimer.exception.decoder; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.sql.SQLException; +import org.hibernate.exception.ConstraintViolationException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.dao.DataIntegrityViolationException; + +class MySqlErrorDecoderTest { + + private MySqlErrorDecoder errorDecoder; + + + @BeforeEach + void setUp() { + errorDecoder = new MySqlErrorDecoder(); + } + + @Nested + class isUniqueError { + + @Test + void 유니크_제약조건_에러를_판단할_수_있다() { + SQLException uniqueError = new SQLException("유니크 에러", + MySqlErrorDecoder.MYSQL_UNIQUE_VIOLATION, + MySqlErrorDecoder.MYSQL_DUP_ERROR_CODE + ); + ConstraintViolationException uniqueViolation = new ConstraintViolationException("유니크 에러", uniqueError, + "vote_poll_id_participate_code"); + DataIntegrityViolationException uniqueException = new DataIntegrityViolationException("유니크 에러", + uniqueViolation); + + boolean isUniqueError = errorDecoder.isUniqueConstraintViolation(uniqueException); + + assertThat(isUniqueError).isTrue(); + } + + @Test + void 유니크_제약조건_에러가_아님을_판단한다() { + SQLException notUniqueError = new SQLException("다른 에러", "32050", 1234); + ConstraintViolationException notUniqueViolation = new ConstraintViolationException("기타 에러", notUniqueError, + "some_constraint"); + DataIntegrityViolationException extraException = new DataIntegrityViolationException("에러", + notUniqueViolation); + + boolean isNotUniqueError = errorDecoder.isUniqueConstraintViolation(extraException); + + assertThat(isNotUniqueError).isFalse(); + } + } +} diff --git a/src/test/java/com/debatetimer/fixture/VoteGenerator.java b/src/test/java/com/debatetimer/fixture/VoteGenerator.java index 9efdd80c..ed97b1f1 100644 --- a/src/test/java/com/debatetimer/fixture/VoteGenerator.java +++ b/src/test/java/com/debatetimer/fixture/VoteGenerator.java @@ -17,7 +17,11 @@ public VoteGenerator(VoteRepository voteRepository) { } public VoteEntity generate(PollEntity pollEntity, VoteTeam team, String name) { - VoteEntity vote = new VoteEntity(null, pollEntity, team, name, UUID.randomUUID().toString()); + return generate(pollEntity, team, name, UUID.randomUUID().toString()); + } + + public VoteEntity generate(PollEntity pollEntity, VoteTeam team, String name, String code) { + VoteEntity vote = new VoteEntity(null, pollEntity, team, name, code); return voteRepository.save(vote); } } diff --git a/src/test/java/com/debatetimer/service/poll/VoteServiceTest.java b/src/test/java/com/debatetimer/service/poll/VoteServiceTest.java new file mode 100644 index 00000000..52626c73 --- /dev/null +++ b/src/test/java/com/debatetimer/service/poll/VoteServiceTest.java @@ -0,0 +1,121 @@ +package com.debatetimer.service.poll; + +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.member.Member; +import com.debatetimer.domain.poll.PollStatus; +import com.debatetimer.domain.poll.VoteTeam; +import com.debatetimer.dto.poll.request.VoteRequest; +import com.debatetimer.dto.poll.response.VoteCreateResponse; +import com.debatetimer.dto.poll.response.VoterPollInfoResponse; +import com.debatetimer.entity.customize.CustomizeTableEntity; +import com.debatetimer.entity.poll.PollEntity; +import com.debatetimer.exception.custom.DTClientErrorException; +import com.debatetimer.exception.errorcode.ClientErrorCode; +import com.debatetimer.repository.poll.VoteRepository; +import com.debatetimer.service.BaseServiceTest; +import java.util.UUID; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class VoteServiceTest extends BaseServiceTest { + + @Autowired + private VoteService voteService; + + @Autowired + private VoteRepository voteRepository; + + @Nested + class Vote { + + @Test + void 진행_중인_선거에_최초로_투표_할_수_있다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + String participateCode = UUID.randomUUID().toString(); + VoteRequest voteRequest = new VoteRequest("콜리", participateCode, VoteTeam.PROS); + + VoteCreateResponse response = voteService.vote(pollEntity.getId(), voteRequest); + + assertAll( + () -> assertThat(response.name()).isEqualTo(voteRequest.name()), + () -> assertThat(response.participateCode()).isEqualTo(voteRequest.participateCode()), + () -> assertThat(response.team()).isEqualTo(voteRequest.team()) + ); + } + + @Test + void 이미_참여한_선거에_투표_할_수_없다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + String participateCode = UUID.randomUUID().toString(); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리", participateCode); + VoteRequest voteRequest = new VoteRequest("콜리", participateCode, VoteTeam.PROS); + + assertThatThrownBy(() -> voteService.vote(pollEntity.getId(), voteRequest)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.ALREADY_VOTED_PARTICIPANT.getMessage()); + } + + @Test + void 투표_동시성_이슈에_단일_표만_유효하게_취급한다() throws InterruptedException { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + String participateCode = UUID.randomUUID().toString(); + VoteRequest voteRequest = new VoteRequest("콜리", participateCode, VoteTeam.PROS); + + runAtSameTime(2, () -> voteService.vote(pollEntity.getId(), voteRequest)); + + long voteCount = voteRepository.count(); + assertThat(voteCount).isEqualTo(1); + } + + @Test + void 끝난_선거에_투표_할_수_없다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity alreadyDonePoll = pollGenerator.generate(table, PollStatus.DONE); + String participateCode = UUID.randomUUID().toString(); + VoteRequest voteRequest = new VoteRequest("콜리", participateCode, VoteTeam.PROS); + + assertThatThrownBy(() -> voteService.vote(alreadyDonePoll.getId(), voteRequest)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.ALREADY_DONE_POLL.getMessage()); + } + } + + @Nested + class GetVoterPollInfo { + + @Test + void 투표자가_선거정보를_조회할_수_있다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = customizeTableGenerator.generate(member); + PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + voteGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); + voteGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); + + VoterPollInfoResponse response = voteService.getVoterPollInfo(pollEntity.getId()); + + assertAll( + () -> assertThat(response.id()).isEqualTo(pollEntity.getId()), + () -> assertThat(response.prosTeamName()).isEqualTo(pollEntity.getProsTeamName()), + () -> assertThat(response.consTeamName()).isEqualTo(pollEntity.getConsTeamName()), + () -> assertThat(response.status()).isEqualTo(pollEntity.getStatus()), + () -> assertThat(response.totalCount()).isEqualTo(3L), + () -> assertThat(response.participateCode()).isNotBlank(), + () -> assertThat(response.prosCount()).isEqualTo(2L), + () -> assertThat(response.consCount()).isEqualTo(1L) + ); + } + } +} From c6bcebc8fcea04408c3b408492e491d12569a428 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sat, 26 Jul 2025 14:18:01 +0900 Subject: [PATCH 08/15] =?UTF-8?q?refactor:=20bell=5Ftype=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EC=84=9C=EB=B9=84=EC=8A=A4=20v2?= =?UTF-8?q?=EB=A1=9C=20=EA=B5=90=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../debatetimer/domain/customize/Bell.java | 4 +- .../domain/customize/BellType.java | 9 + .../dto/customize/request/BellRequest.java | 6 +- .../dto/customize/response/BellResponse.java | 4 +- .../entity/customize/BellEntity.java | 14 +- .../service/customize/CustomizeService.java | 62 +++-- .../service/customize/CustomizeServiceV2.java | 98 ------- .../V12__add_bell_type_into_bell.sql | 2 + .../customize/CustomizeDocumentTest.java | 63 +++-- .../domain/customize/BellTest.java | 8 +- .../entity/customize/BellEntityTest.java | 5 +- .../debatetimer/fixture/BellGenerator.java | 5 +- .../customize/BellRepositoryTest.java | 7 +- .../customize/CustomizeServiceTest.java | 45 ++-- .../customize/CustomizeServiceV2Test.java | 243 ------------------ 15 files changed, 153 insertions(+), 422 deletions(-) create mode 100644 src/main/java/com/debatetimer/domain/customize/BellType.java delete mode 100644 src/main/java/com/debatetimer/service/customize/CustomizeServiceV2.java create mode 100644 src/main/resources/db/migration/V12__add_bell_type_into_bell.sql delete mode 100644 src/test/java/com/debatetimer/service/customize/CustomizeServiceV2Test.java diff --git a/src/main/java/com/debatetimer/domain/customize/Bell.java b/src/main/java/com/debatetimer/domain/customize/Bell.java index 58fb4443..9488bef6 100644 --- a/src/main/java/com/debatetimer/domain/customize/Bell.java +++ b/src/main/java/com/debatetimer/domain/customize/Bell.java @@ -9,12 +9,14 @@ public class Bell { public static final int MAX_BELL_COUNT = 3; + private final BellType type; private final int time; private final int count; - public Bell(int time, int count) { + public Bell(BellType type, int time, int count) { validateTime(time); validateCount(count); + this.type = type; this.time = time; this.count = count; } diff --git a/src/main/java/com/debatetimer/domain/customize/BellType.java b/src/main/java/com/debatetimer/domain/customize/BellType.java new file mode 100644 index 00000000..56bc3134 --- /dev/null +++ b/src/main/java/com/debatetimer/domain/customize/BellType.java @@ -0,0 +1,9 @@ +package com.debatetimer.domain.customize; + +public enum BellType { + + AFTER_START, + BEFORE_END, + AFTER_END, + ; +} diff --git a/src/main/java/com/debatetimer/dto/customize/request/BellRequest.java b/src/main/java/com/debatetimer/dto/customize/request/BellRequest.java index fa5f2d88..5142fe8c 100644 --- a/src/main/java/com/debatetimer/dto/customize/request/BellRequest.java +++ b/src/main/java/com/debatetimer/dto/customize/request/BellRequest.java @@ -1,13 +1,17 @@ package com.debatetimer.dto.customize.request; import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.BellType; +import jakarta.validation.constraints.NotNull; public record BellRequest( + @NotNull + BellType type, int time, int count ) { public Bell toDomain() { - return new Bell(time, count); + return new Bell(type, time, count); } } diff --git a/src/main/java/com/debatetimer/dto/customize/response/BellResponse.java b/src/main/java/com/debatetimer/dto/customize/response/BellResponse.java index 0ec2b060..080782d5 100644 --- a/src/main/java/com/debatetimer/dto/customize/response/BellResponse.java +++ b/src/main/java/com/debatetimer/dto/customize/response/BellResponse.java @@ -1,13 +1,15 @@ package com.debatetimer.dto.customize.response; import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.BellType; public record BellResponse( + BellType type, int time, int count ) { public BellResponse(Bell bell) { - this(bell.getTime(), bell.getCount()); + this(bell.getType(), bell.getTime(), bell.getCount()); } } diff --git a/src/main/java/com/debatetimer/entity/customize/BellEntity.java b/src/main/java/com/debatetimer/entity/customize/BellEntity.java index 9c1f9982..81c33816 100644 --- a/src/main/java/com/debatetimer/entity/customize/BellEntity.java +++ b/src/main/java/com/debatetimer/entity/customize/BellEntity.java @@ -1,10 +1,13 @@ package com.debatetimer.entity.customize; import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.exception.custom.DTClientErrorException; import com.debatetimer.exception.errorcode.ClientErrorCode; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -34,21 +37,28 @@ public class BellEntity { @JoinColumn(name = "customize_time_box_id") private CustomizeTimeBoxEntity customizeTimeBox; + @Column(name = "bell_type") + @NotNull + @Enumerated(value = EnumType.STRING) + private BellType type; + @Column(name = "bell_time") private int time; private int count; - public BellEntity(CustomizeTimeBoxEntity customizeTimeBox, int time, int count) { + public BellEntity(CustomizeTimeBoxEntity customizeTimeBox, BellType type, int time, int count) { validateTime(time); validateCount(count); this.customizeTimeBox = customizeTimeBox; + this.type = type; this.time = time; this.count = count; } public BellEntity(CustomizeTimeBoxEntity customizeTimeBox, Bell bell) { this.customizeTimeBox = customizeTimeBox; + this.type = bell.getType(); this.time = bell.getTime(); this.count = bell.getCount(); } @@ -66,7 +76,7 @@ private void validateCount(int count) { } public Bell toDomain() { - return new Bell(time, count); + return new Bell(type, time, count); } public boolean isContained(CustomizeTimeBoxEntity timeBox) { diff --git a/src/main/java/com/debatetimer/service/customize/CustomizeService.java b/src/main/java/com/debatetimer/service/customize/CustomizeService.java index 13b3e44d..02c542ad 100644 --- a/src/main/java/com/debatetimer/service/customize/CustomizeService.java +++ b/src/main/java/com/debatetimer/service/customize/CustomizeService.java @@ -1,15 +1,19 @@ package com.debatetimer.service.customize; import com.debatetimer.domain.customize.CustomizeTable; +import com.debatetimer.domain.customize.CustomizeTimeBox; import com.debatetimer.domain.member.Member; import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; import com.debatetimer.dto.customize.response.CustomizeTableResponse; +import com.debatetimer.entity.customize.BellEntity; import com.debatetimer.entity.customize.CustomizeTableEntity; import com.debatetimer.entity.customize.CustomizeTimeBoxEntities; import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; +import com.debatetimer.repository.customize.BellRepository; import com.debatetimer.repository.customize.CustomizeTableRepository; import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; import java.util.List; +import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -20,21 +24,26 @@ public class CustomizeService { private final CustomizeTableRepository tableRepository; private final CustomizeTimeBoxRepository timeBoxRepository; + private final BellRepository bellRepository; @Transactional public CustomizeTableResponse save(CustomizeTableCreateRequest tableCreateRequest, Member member) { CustomizeTable table = tableCreateRequest.toTable(member); - CustomizeTableEntity savedTable = tableRepository.save(new CustomizeTableEntity(table)); + List timeBoxes = tableCreateRequest.toTimeBoxList(); - CustomizeTimeBoxEntities savedCustomizeTimeBoxes = saveTimeBoxes(tableCreateRequest, savedTable.toDomain()); - return new CustomizeTableResponse(savedTable.toDomain(), savedCustomizeTimeBoxes); + CustomizeTableEntity savedTableEntity = tableRepository.save(new CustomizeTableEntity(table)); + saveTimeBoxes(savedTableEntity, timeBoxes); + return new CustomizeTableResponse(savedTableEntity.toDomain(), timeBoxes); } @Transactional(readOnly = true) public CustomizeTableResponse findTable(long tableId, Member member) { CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - CustomizeTimeBoxEntities timeBoxes = timeBoxRepository.findTableTimeBoxes(tableEntity); - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); + List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); + List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); + CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); + + return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxEntities.toDomain()); } @Transactional @@ -43,38 +52,47 @@ public CustomizeTableResponse updateTable( long tableId, Member member ) { - CustomizeTableEntity existingTable = tableRepository.getByIdAndMember(tableId, member); - CustomizeTable renewedTable = tableCreateRequest.toTable(member); - existingTable.updateTable(renewedTable); + CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); + tableEntity.updateTable(tableCreateRequest.toTable(member)); - timeBoxRepository.deleteAllByTable(existingTable.getId()); - CustomizeTimeBoxEntities savedCustomizeTimeBoxes = saveTimeBoxes(tableCreateRequest, existingTable.toDomain()); - return new CustomizeTableResponse(existingTable.toDomain(), savedCustomizeTimeBoxes); + bellRepository.deleteAllByTable(tableEntity.getId()); + timeBoxRepository.deleteAllByTable(tableEntity.getId()); + List timeBoxes = tableCreateRequest.toTimeBoxList(); + saveTimeBoxes(tableEntity, timeBoxes); + return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); } @Transactional public CustomizeTableResponse updateUsedAt(long tableId, Member member) { CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - CustomizeTimeBoxEntities timeBoxes = timeBoxRepository.findTableTimeBoxes(tableEntity); - tableEntity.updateUsedAt(); + List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); + List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); + CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); + tableEntity.updateUsedAt(); + CustomizeTable table = tableEntity.toDomain(); + List timeBoxes = timeBoxEntities.toDomain(); + return new CustomizeTableResponse(table, timeBoxes); } @Transactional public void deleteTable(long tableId, Member member) { CustomizeTableEntity table = tableRepository.getByIdAndMember(tableId, member); + + bellRepository.deleteAllByTable(table.getId()); timeBoxRepository.deleteAllByTable(table.getId()); tableRepository.delete(table); } - private CustomizeTimeBoxEntities saveTimeBoxes( - CustomizeTableCreateRequest tableCreateRequest, - CustomizeTable table - ) { - CustomizeTimeBoxEntities customizeTimeBoxes = tableCreateRequest.toTimeBoxes(table); - List savedTimeBoxes = timeBoxRepository.saveAll( - customizeTimeBoxes.getTimeBoxes()); - return new CustomizeTimeBoxEntities(savedTimeBoxes); + private void saveTimeBoxes(CustomizeTableEntity tableEntity, List timeBoxes) { + IntStream.range(0, timeBoxes.size()) + .forEach(i -> saveTimeBox(tableEntity, timeBoxes.get(i), i + 1)); + } + + private void saveTimeBox(CustomizeTableEntity tableEntity, CustomizeTimeBox timeBox, int sequence) { + CustomizeTimeBoxEntity timeBoxEntity = timeBoxRepository.save( + new CustomizeTimeBoxEntity(tableEntity, timeBox, sequence)); + timeBox.getBells() + .forEach(bell -> bellRepository.save(new BellEntity(timeBoxEntity, bell))); } } diff --git a/src/main/java/com/debatetimer/service/customize/CustomizeServiceV2.java b/src/main/java/com/debatetimer/service/customize/CustomizeServiceV2.java deleted file mode 100644 index 392f8c89..00000000 --- a/src/main/java/com/debatetimer/service/customize/CustomizeServiceV2.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.debatetimer.service.customize; - -import com.debatetimer.domain.customize.CustomizeTable; -import com.debatetimer.domain.customize.CustomizeTimeBox; -import com.debatetimer.domain.member.Member; -import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; -import com.debatetimer.dto.customize.response.CustomizeTableResponse; -import com.debatetimer.entity.customize.BellEntity; -import com.debatetimer.entity.customize.CustomizeTableEntity; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntities; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; -import com.debatetimer.repository.customize.BellRepository; -import com.debatetimer.repository.customize.CustomizeTableRepository; -import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; -import java.util.List; -import java.util.stream.IntStream; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class CustomizeServiceV2 { - - private final CustomizeTableRepository tableRepository; - private final CustomizeTimeBoxRepository timeBoxRepository; - private final BellRepository bellRepository; - - @Transactional - public CustomizeTableResponse save(CustomizeTableCreateRequest tableCreateRequest, Member member) { - CustomizeTable table = tableCreateRequest.toTable(member); - List timeBoxes = tableCreateRequest.toTimeBoxList(); - - CustomizeTableEntity savedTableEntity = tableRepository.save(new CustomizeTableEntity(table)); - saveTimeBoxes(savedTableEntity, timeBoxes); - return new CustomizeTableResponse(savedTableEntity.toDomain(), timeBoxes); - } - - @Transactional(readOnly = true) - public CustomizeTableResponse findTable(long tableId, Member member) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); - List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); - CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); - - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxEntities.toDomain()); - } - - @Transactional - public CustomizeTableResponse updateTable( - CustomizeTableCreateRequest tableCreateRequest, - long tableId, - Member member - ) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - tableEntity.updateTable(tableCreateRequest.toTable(member)); - - bellRepository.deleteAllByTable(tableEntity.getId()); - timeBoxRepository.deleteAllByTable(tableEntity.getId()); - List timeBoxes = tableCreateRequest.toTimeBoxList(); - saveTimeBoxes(tableEntity, timeBoxes); - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); - } - - @Transactional - public CustomizeTableResponse updateUsedAt(long tableId, Member member) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); - List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); - CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); - - tableEntity.updateUsedAt(); - CustomizeTable table = tableEntity.toDomain(); - List timeBoxes = timeBoxEntities.toDomain(); - return new CustomizeTableResponse(table, timeBoxes); - } - - @Transactional - public void deleteTable(long tableId, Member member) { - CustomizeTableEntity table = tableRepository.getByIdAndMember(tableId, member); - - bellRepository.deleteAllByTable(table.getId()); - timeBoxRepository.deleteAllByTable(table.getId()); - tableRepository.delete(table); - } - - private void saveTimeBoxes(CustomizeTableEntity tableEntity, List timeBoxes) { - IntStream.range(0, timeBoxes.size()) - .forEach(i -> saveTimeBox(tableEntity, timeBoxes.get(i), i + 1)); - } - - private void saveTimeBox(CustomizeTableEntity tableEntity, CustomizeTimeBox timeBox, int sequence) { - CustomizeTimeBoxEntity timeBoxEntity = timeBoxRepository.save( - new CustomizeTimeBoxEntity(tableEntity, timeBox, sequence)); - timeBox.getBells() - .forEach(bell -> bellRepository.save(new BellEntity(timeBoxEntity, bell))); - } -} diff --git a/src/main/resources/db/migration/V12__add_bell_type_into_bell.sql b/src/main/resources/db/migration/V12__add_bell_type_into_bell.sql new file mode 100644 index 00000000..e2f1a133 --- /dev/null +++ b/src/main/resources/db/migration/V12__add_bell_type_into_bell.sql @@ -0,0 +1,2 @@ +ALTER TABLE bell + ADD COLUMN bell_type enum ('AFTER_START','BEFORE_END','AFTER_END') NOT NULL diff --git a/src/test/java/com/debatetimer/controller/customize/CustomizeDocumentTest.java b/src/test/java/com/debatetimer/controller/customize/CustomizeDocumentTest.java index e7545638..e2613aa0 100644 --- a/src/test/java/com/debatetimer/controller/customize/CustomizeDocumentTest.java +++ b/src/test/java/com/debatetimer/controller/customize/CustomizeDocumentTest.java @@ -18,6 +18,7 @@ import com.debatetimer.controller.RestDocumentationRequest; import com.debatetimer.controller.RestDocumentationResponse; import com.debatetimer.controller.Tag; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.customize.Stance; import com.debatetimer.dto.customize.request.BellRequest; @@ -71,8 +72,9 @@ class Save { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -95,8 +97,9 @@ class Save { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -109,9 +112,9 @@ class Save { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), null, null, "콜리"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxCreateRequest(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), null, null, "비토"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -124,9 +127,9 @@ class Save { "찬성", "반대", true, true), List.of( new CustomizeTimeBoxResponse(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1)), null, null, "콜리"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxResponse(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1), new BellResponse(120, 2)), null, null, "비토"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1), new BellResponse(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -168,9 +171,9 @@ class Save { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), null, null, "콜리"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxCreateRequest(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), null, null, "비토"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -230,8 +233,9 @@ class GetTable { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -246,9 +250,9 @@ class GetTable { "찬성", "반대", true, true), List.of( new CustomizeTimeBoxResponse(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1)), null, null, "콜리"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxResponse(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1), new BellResponse(120, 2)), null, null, "비토"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1), new BellResponse(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -323,8 +327,9 @@ class UpdateTable { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -347,8 +352,9 @@ class UpdateTable { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -362,9 +368,9 @@ class UpdateTable { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), null, null, "콜리"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxCreateRequest(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), null, null, "비토"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -377,9 +383,9 @@ class UpdateTable { "찬성", "반대", true, true), List.of( new CustomizeTimeBoxResponse(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1)), null, null, "콜리"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxResponse(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1), new BellResponse(120, 2)), null, null, "비토"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1), new BellResponse(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -424,9 +430,9 @@ class UpdateTable { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), null, null, "콜리"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxCreateRequest(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), null, null, "비토"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxCreateRequest(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, @@ -488,8 +494,9 @@ class Debate { fieldWithPath("table[].boxType").type(STRING).description("타임 박스 유형"), fieldWithPath("table[].time").type(NUMBER).description("발언 시간(초)").optional(), fieldWithPath("table[].bell").type(ARRAY).description("종소리 정보").optional(), - fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)").optional(), - fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수").optional(), + fieldWithPath("table[].bell[].type").type(STRING).description("종소리 종류"), + fieldWithPath("table[].bell[].time").type(NUMBER).description("종소리 울릴 시간(초)"), + fieldWithPath("table[].bell[].count").type(NUMBER).description("종소리 횟수"), fieldWithPath("table[].timePerTeam").type(NUMBER).description("팀당 발언 시간 (초)").optional(), fieldWithPath("table[].timePerSpeaking").type(NUMBER).description("1회 발언 시간 (초)").optional(), fieldWithPath("table[].speaker").type(STRING).description("발언자 이름").optional() @@ -505,9 +512,9 @@ class Debate { "찬성", "반대", true, true), List.of( new CustomizeTimeBoxResponse(Stance.PROS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1)), null, null, "콜리"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1)), null, null, "콜리"), new CustomizeTimeBoxResponse(Stance.CONS, "입론", CustomizeBoxType.NORMAL, - 120, List.of(new BellResponse(90, 1), new BellResponse(120, 2)), null, null, "비토"), + 120, List.of(new BellResponse(BellType.AFTER_START, 90, 1), new BellResponse(BellType.AFTER_START, 120, 2)), null, null, "비토"), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "난상 토론", CustomizeBoxType.TIME_BASED, null, null, 360, 120, null), new CustomizeTimeBoxResponse(Stance.NEUTRAL, "존중 토론", CustomizeBoxType.TIME_BASED, diff --git a/src/test/java/com/debatetimer/domain/customize/BellTest.java b/src/test/java/com/debatetimer/domain/customize/BellTest.java index a99f40eb..25b99e70 100644 --- a/src/test/java/com/debatetimer/domain/customize/BellTest.java +++ b/src/test/java/com/debatetimer/domain/customize/BellTest.java @@ -17,21 +17,21 @@ class Validate { @Test void 벨_시간이_음수면_생성되지_않는다() { - assertThatThrownBy(() -> new Bell(-1, 1)) + assertThatThrownBy(() -> new Bell(BellType.AFTER_START, -1, 1)) .isInstanceOf(DTClientErrorException.class) .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); } @Test void 벨_시간은_0이상이어야_한다() { - assertThatCode(() -> new Bell(0, 1)) + assertThatCode(() -> new Bell(BellType.AFTER_START, 0, 1)) .doesNotThrowAnyException(); } @ValueSource(ints = {0, Bell.MAX_BELL_COUNT + 1}) @ParameterizedTest void 벨_횟수는_정해진_횟수_바깥일_경우_생성되지_않는다(int count) { - assertThatThrownBy(() -> new Bell(1, count)) + assertThatThrownBy(() -> new Bell(BellType.AFTER_START, 1, count)) .isInstanceOf(DTClientErrorException.class) .hasMessage(ClientErrorCode.INVALID_BELL_COUNT.getMessage()); } @@ -39,7 +39,7 @@ class Validate { @ValueSource(ints = {1, Bell.MAX_BELL_COUNT}) @ParameterizedTest void 벨_횟수는_정해진_횟수_이내여야_한다(int count) { - assertThatCode(() -> new Bell(1, count)) + assertThatCode(() -> new Bell(BellType.AFTER_START, 1, count)) .doesNotThrowAnyException(); } } diff --git a/src/test/java/com/debatetimer/entity/customize/BellEntityTest.java b/src/test/java/com/debatetimer/entity/customize/BellEntityTest.java index 73535499..c0483f9f 100644 --- a/src/test/java/com/debatetimer/entity/customize/BellEntityTest.java +++ b/src/test/java/com/debatetimer/entity/customize/BellEntityTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.exception.custom.DTClientErrorException; import com.debatetimer.exception.errorcode.ClientErrorCode; import org.junit.jupiter.api.Nested; @@ -16,7 +17,7 @@ class Validate { @Test void 벨_시간은_0이상이어야_한다() { - assertThatThrownBy(() -> new BellEntity(null, -1, 1)) + assertThatThrownBy(() -> new BellEntity(null, BellType.AFTER_END, -1, 1)) .isInstanceOf(DTClientErrorException.class) .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); } @@ -24,7 +25,7 @@ class Validate { @ValueSource(ints = {0, BellEntity.MAX_BELL_COUNT + 1}) @ParameterizedTest void 벨_횟수는_정해진_횟수_이내여야_한다(int count) { - assertThatThrownBy(() -> new BellEntity(null, 1, count)) + assertThatThrownBy(() -> new BellEntity(null, BellType.AFTER_END, 1, count)) .isInstanceOf(DTClientErrorException.class) .hasMessage(ClientErrorCode.INVALID_BELL_COUNT.getMessage()); } diff --git a/src/test/java/com/debatetimer/fixture/BellGenerator.java b/src/test/java/com/debatetimer/fixture/BellGenerator.java index 1c2392ce..335c6441 100644 --- a/src/test/java/com/debatetimer/fixture/BellGenerator.java +++ b/src/test/java/com/debatetimer/fixture/BellGenerator.java @@ -1,5 +1,6 @@ package com.debatetimer.fixture; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.entity.customize.BellEntity; import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; import com.debatetimer.repository.customize.BellRepository; @@ -14,8 +15,8 @@ public BellGenerator(BellRepository bellRepository) { this.bellRepository = bellRepository; } - public BellEntity generate(CustomizeTimeBoxEntity timeBox, int time, int count) { - BellEntity bell = new BellEntity(timeBox, time, count); + public BellEntity generate(CustomizeTimeBoxEntity timeBox, BellType type, int time, int count) { + BellEntity bell = new BellEntity(timeBox, type, time, count); return bellRepository.save(bell); } } diff --git a/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java b/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java index 6dbb6919..b8fcc4e4 100644 --- a/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.member.Member; import com.debatetimer.entity.customize.CustomizeTableEntity; @@ -30,9 +31,9 @@ class DeleteAllByTable { CustomizeBoxType.NORMAL, 1); CustomizeTimeBoxEntity otherTimeBox = customizeTimeBoxGenerator.generate(otherTable, CustomizeBoxType.NORMAL, 1); - bellGenerator.generate(deleteBellTimeBox, 45, 1); - bellGenerator.generate(deleteBellTimeBox, 60, 1); - bellGenerator.generate(otherTimeBox, 45, 1); + bellGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 45, 1); + bellGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 60, 1); + bellGenerator.generate(otherTimeBox, BellType.AFTER_START, 45, 1); bellRepository.deleteAllByTable(deleteBellTable.getId()); diff --git a/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java b/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java index 410c0042..baf45e4d 100644 --- a/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java +++ b/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java @@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertAll; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.customize.Stance; import com.debatetimer.domain.member.Member; @@ -12,6 +13,7 @@ import com.debatetimer.dto.customize.request.CustomizeTableInfoCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTimeBoxCreateRequest; import com.debatetimer.dto.customize.response.CustomizeTableResponse; +import com.debatetimer.entity.customize.BellEntity; import com.debatetimer.entity.customize.CustomizeTableEntity; import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; import com.debatetimer.exception.custom.DTClientErrorException; @@ -40,19 +42,22 @@ class Save { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); CustomizeTableResponse savedTableResponse = customizeService.save(customizeTableCreateRequest, chan); CustomizeTableEntity foundTable = customizeTableRepository.getByIdAndMember(savedTableResponse.id(), chan); - List foundTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable(foundTable); + List foundTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( + foundTable); + List foundBells = bellRepository.findAllByCustomizeTimeBoxIn(foundTimeBoxes); assertAll( () -> assertThat(foundTable.getName()).isEqualTo(customizeTableCreateRequest.info().name()), - () -> assertThat(foundTimeBoxes).hasSize(customizeTableCreateRequest.table().size()) + () -> assertThat(foundTimeBoxes).hasSize(customizeTableCreateRequest.table().size()), + () -> assertThat(foundBells).hasSize(3) ); } } @@ -64,14 +69,19 @@ class FindTable { void 사용자_지정_토론_테이블을_조회한다() { Member chan = memberGenerator.generate("default@gmail.com"); CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); + CustomizeTimeBoxEntity customizeTimeBox = customizeTimeBoxGenerator.generate( + chanTable, CustomizeBoxType.NORMAL, 1); customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); + bellGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 1); + bellGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 2); CustomizeTableResponse foundResponse = customizeService.findTable(chanTable.getId(), chan); assertAll( () -> assertThat(foundResponse.id()).isEqualTo(chanTable.getId()), - () -> assertThat(foundResponse.table()).hasSize(2) + () -> assertThat(foundResponse.table()).hasSize(2), + () -> assertThat(foundResponse.table().get(0).bell()).hasSize(2), + () -> assertThat(foundResponse.table().get(1).bell()).isNull() ); } @@ -100,21 +110,24 @@ class UpdateTable { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); customizeService.updateTable(renewTableRequest, chanTable.getId(), chan); CustomizeTableEntity updatedTable = customizeTableRepository.getByIdAndMember(chanTable.getId(), chan); - List updatedTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable(updatedTable); + List updatedTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( + updatedTable); + List bells = bellRepository.findAllByCustomizeTimeBoxIn(updatedTimeBoxes); assertAll( () -> assertThat(updatedTable.getId()).isEqualTo(chanTable.getId()), () -> assertThat(updatedTable.getName()).isEqualTo(renewTableRequest.info().name()), - () -> assertThat(updatedTimeBoxes).hasSize(renewTableRequest.table().size()) + () -> assertThat(updatedTimeBoxes).hasSize(renewTableRequest.table().size()), + () -> assertThat(bells).hasSize(3) ); } @@ -129,9 +142,9 @@ class UpdateTable { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -149,9 +162,9 @@ class UpdateTable { "반대", true, true), List.of( new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -207,10 +220,12 @@ class DeleteTable { Optional foundTable = customizeTableRepository.findById(chanTable.getId()); List timeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( chanTable); + List bells = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxes); assertAll( () -> assertThat(foundTable).isEmpty(), - () -> assertThat(timeBoxes).isEmpty() + () -> assertThat(timeBoxes).isEmpty(), + () -> assertThat(bells).isEmpty() ); } diff --git a/src/test/java/com/debatetimer/service/customize/CustomizeServiceV2Test.java b/src/test/java/com/debatetimer/service/customize/CustomizeServiceV2Test.java deleted file mode 100644 index 1e0b58b7..00000000 --- a/src/test/java/com/debatetimer/service/customize/CustomizeServiceV2Test.java +++ /dev/null @@ -1,243 +0,0 @@ -package com.debatetimer.service.customize; - -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.customize.CustomizeBoxType; -import com.debatetimer.domain.customize.Stance; -import com.debatetimer.domain.member.Member; -import com.debatetimer.dto.customize.request.BellRequest; -import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; -import com.debatetimer.dto.customize.request.CustomizeTableInfoCreateRequest; -import com.debatetimer.dto.customize.request.CustomizeTimeBoxCreateRequest; -import com.debatetimer.dto.customize.response.CustomizeTableResponse; -import com.debatetimer.entity.customize.BellEntity; -import com.debatetimer.entity.customize.CustomizeTableEntity; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; -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 CustomizeServiceV2Test extends BaseServiceTest { - - @Autowired - private CustomizeServiceV2 customizeService; - - @Nested - class Save { - - @Test - void 사용자_지정_토론_테이블을_생성한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableCreateRequest customizeTableCreateRequest = new CustomizeTableCreateRequest( - new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", - "반대", true, true), - List.of( - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") - ) - ); - - CustomizeTableResponse savedTableResponse = customizeService.save(customizeTableCreateRequest, chan); - CustomizeTableEntity foundTable = customizeTableRepository.getByIdAndMember(savedTableResponse.id(), chan); - List foundTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( - foundTable); - List foundBells = bellRepository.findAllByCustomizeTimeBoxIn(foundTimeBoxes); - - assertAll( - () -> assertThat(foundTable.getName()).isEqualTo(customizeTableCreateRequest.info().name()), - () -> assertThat(foundTimeBoxes).hasSize(customizeTableCreateRequest.table().size()), - () -> assertThat(foundBells).hasSize(3) - ); - } - } - - @Nested - class FindTable { - - @Test - void 사용자_지정_토론_테이블을_조회한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - CustomizeTimeBoxEntity customizeTimeBox = customizeTimeBoxGenerator.generate( - chanTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); - bellGenerator.generate(customizeTimeBox, 1, 1); - bellGenerator.generate(customizeTimeBox, 1, 2); - - CustomizeTableResponse foundResponse = customizeService.findTable(chanTable.getId(), chan); - - assertAll( - () -> assertThat(foundResponse.id()).isEqualTo(chanTable.getId()), - () -> assertThat(foundResponse.table()).hasSize(2), - () -> assertThat(foundResponse.table().get(0).bell()).hasSize(2), - () -> assertThat(foundResponse.table().get(1).bell()).isNull() - ); - } - - @Test - void 회원_소유가_아닌_테이블_조회_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - - assertThatThrownBy(() -> customizeService.findTable(chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.TABLE_NOT_FOUND.getMessage()); - } - } - - @Nested - class UpdateTable { - - @Test - void 사용자_지정_토론_테이블을_수정한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - CustomizeTableCreateRequest renewTableRequest = new CustomizeTableCreateRequest( - new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", - "반대", true, true), - List.of( - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") - ) - ); - - customizeService.updateTable(renewTableRequest, chanTable.getId(), chan); - - CustomizeTableEntity updatedTable = customizeTableRepository.getByIdAndMember(chanTable.getId(), chan); - List updatedTimeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( - updatedTable); - List bells = bellRepository.findAllByCustomizeTimeBoxIn(updatedTimeBoxes); - - assertAll( - () -> assertThat(updatedTable.getId()).isEqualTo(chanTable.getId()), - () -> assertThat(updatedTable.getName()).isEqualTo(renewTableRequest.info().name()), - () -> assertThat(updatedTimeBoxes).hasSize(renewTableRequest.table().size()), - () -> assertThat(bells).hasSize(3) - ); - } - - @Test - void 회원_소유가_아닌_테이블_수정_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - CustomizeTableCreateRequest renewTableRequest = new CustomizeTableCreateRequest( - new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", - "반대", true, true), - List.of( - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") - ) - ); - - assertThatThrownBy(() -> customizeService.updateTable(renewTableRequest, chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.TABLE_NOT_FOUND.getMessage()); - } - - @Test - void 테이블_정보_수정을_동시에_요청할_때_동시에_처리하지_않는다() throws InterruptedException { - Member member = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - CustomizeTableCreateRequest request = new CustomizeTableCreateRequest( - new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", - "반대", true, true), - List.of( - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1)), 60, null, "발언자1"), - new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(90, 1), new BellRequest(120, 2)), 60, null, "발언자2") - ) - ); - - runAtSameTime(2, () -> customizeService.updateTable(request, table.getId(), member)); - - assertThat(customizeTimeBoxRepository.findAllByCustomizeTable(table)).hasSize(2); - } - } - - @Nested - class UpdateUsedAt { - - @Test - void 사용자_지정_토론_테이블의_사용_시각을_최신화한다() { - Member member = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - LocalDateTime beforeUsedAt = table.getUsedAt(); - - customizeService.updateUsedAt(table.getId(), member); - - CustomizeTableEntity updatedTable = customizeTableRepository.getByIdAndMember(table.getId(), member); - assertAll( - () -> assertThat(updatedTable.getId()).isEqualTo(table.getId()), - () -> assertThat(updatedTable.getUsedAt()).isAfter(beforeUsedAt) - ); - } - - @Test - void 회원_소유가_아닌_테이블_수정_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - - assertThatThrownBy(() -> customizeService.updateUsedAt(chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.TABLE_NOT_FOUND.getMessage()); - } - } - - @Nested - class DeleteTable { - - @Test - void 사용자_지정_토론_테이블을_삭제한다() { - Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); - - customizeService.deleteTable(chanTable.getId(), chan); - - Optional foundTable = customizeTableRepository.findById(chanTable.getId()); - List timeBoxes = customizeTimeBoxRepository.findAllByCustomizeTable( - chanTable); - List bells = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxes); - - assertAll( - () -> assertThat(foundTable).isEmpty(), - () -> assertThat(timeBoxes).isEmpty(), - () -> assertThat(bells).isEmpty() - ); - } - - @Test - void 회원_소유가_아닌_테이블_삭제_시_예외를_발생시킨다() { - Member chan = memberGenerator.generate("default@gmail.com"); - Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - long chanTableId = chanTable.getId(); - - assertThatThrownBy(() -> customizeService.deleteTable(chanTableId, coli)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.TABLE_NOT_FOUND.getMessage()); - } - } -} From 644987dbceaf2ab4b1ddc3037eae0824680b2148 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sat, 26 Jul 2025 14:25:10 +0900 Subject: [PATCH 09/15] =?UTF-8?q?refactor:=20TODO=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/CustomizeTableCreateRequest.java | 17 ++++------------- .../service/customize/CustomizeService.java | 4 ++-- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java b/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java index 8dc05809..b6ab52e1 100644 --- a/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java +++ b/src/main/java/com/debatetimer/dto/customize/request/CustomizeTableCreateRequest.java @@ -2,31 +2,22 @@ import com.debatetimer.domain.customize.CustomizeTable; import com.debatetimer.domain.customize.CustomizeTimeBox; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntities; import com.debatetimer.domain.member.Member; import jakarta.validation.Valid; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; public record CustomizeTableCreateRequest( @Valid CustomizeTableInfoCreateRequest info, @Valid List table ) { - public CustomizeTimeBoxEntities toTimeBoxes(CustomizeTable customizeTable) { - return IntStream.range(0, table.size()) - .mapToObj(i -> table.get(i).toTimeBox(customizeTable, i + 1)) - .collect(Collectors.collectingAndThen(Collectors.toList(), CustomizeTimeBoxEntities::new)); + public List toTimeBoxes() { + return table.stream() + .map(CustomizeTimeBoxCreateRequest::toDomain) + .toList(); } public CustomizeTable toTable(Member member) { return info.toTable(member); } - - public List toTimeBoxList() { // TODO 메서드 네이밍 변경 toTimeBoxList() -> toTimeBoxes() - return table.stream() - .map(CustomizeTimeBoxCreateRequest::toDomain) - .toList(); - } } diff --git a/src/main/java/com/debatetimer/service/customize/CustomizeService.java b/src/main/java/com/debatetimer/service/customize/CustomizeService.java index 02c542ad..f0feb605 100644 --- a/src/main/java/com/debatetimer/service/customize/CustomizeService.java +++ b/src/main/java/com/debatetimer/service/customize/CustomizeService.java @@ -29,7 +29,7 @@ public class CustomizeService { @Transactional public CustomizeTableResponse save(CustomizeTableCreateRequest tableCreateRequest, Member member) { CustomizeTable table = tableCreateRequest.toTable(member); - List timeBoxes = tableCreateRequest.toTimeBoxList(); + List timeBoxes = tableCreateRequest.toTimeBoxes(); CustomizeTableEntity savedTableEntity = tableRepository.save(new CustomizeTableEntity(table)); saveTimeBoxes(savedTableEntity, timeBoxes); @@ -57,7 +57,7 @@ public CustomizeTableResponse updateTable( bellRepository.deleteAllByTable(tableEntity.getId()); timeBoxRepository.deleteAllByTable(tableEntity.getId()); - List timeBoxes = tableCreateRequest.toTimeBoxList(); + List timeBoxes = tableCreateRequest.toTimeBoxes(); saveTimeBoxes(tableEntity, timeBoxes); return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); } From 5d46dabc65957a2acb2715a55bb33ea4eb09afad Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sat, 26 Jul 2025 15:32:26 +0900 Subject: [PATCH 10/15] =?UTF-8?q?refactor:=20domain=20repository=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomizeTableDomainRepository.java | 89 +++++++++++++++++++ .../service/customize/CustomizeService.java | 67 +++----------- .../debatetimer/service/poll/PollService.java | 2 +- 3 files changed, 104 insertions(+), 54 deletions(-) create mode 100644 src/main/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepository.java diff --git a/src/main/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepository.java b/src/main/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepository.java new file mode 100644 index 00000000..de3705b8 --- /dev/null +++ b/src/main/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepository.java @@ -0,0 +1,89 @@ +package com.debatetimer.domainrepository.customize; + +import com.debatetimer.domain.customize.CustomizeTable; +import com.debatetimer.domain.customize.CustomizeTimeBox; +import com.debatetimer.domain.member.Member; +import com.debatetimer.entity.customize.BellEntity; +import com.debatetimer.entity.customize.CustomizeTableEntity; +import com.debatetimer.entity.customize.CustomizeTimeBoxEntities; +import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; +import com.debatetimer.repository.customize.BellRepository; +import com.debatetimer.repository.customize.CustomizeTableRepository; +import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; +import java.util.List; +import java.util.stream.IntStream; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +@Repository +@RequiredArgsConstructor +public class CustomizeTableDomainRepository { + + private final CustomizeTableRepository tableRepository; + private final CustomizeTimeBoxRepository timeBoxRepository; + private final BellRepository bellRepository; + + @Transactional + public CustomizeTable save(CustomizeTable table, List timeBoxes) { + CustomizeTableEntity savedTableEntity = tableRepository.save(new CustomizeTableEntity(table)); + saveTimeBoxes(savedTableEntity, timeBoxes); + + return savedTableEntity.toDomain(); + } + + private void saveTimeBoxes(CustomizeTableEntity tableEntity, List timeBoxes) { + IntStream.range(0, timeBoxes.size()) + .forEach(i -> saveTimeBox(tableEntity, timeBoxes.get(i), i + 1)); + } + + private void saveTimeBox(CustomizeTableEntity tableEntity, CustomizeTimeBox timeBox, int sequence) { + CustomizeTimeBoxEntity timeBoxEntity = timeBoxRepository.save( + new CustomizeTimeBoxEntity(tableEntity, timeBox, sequence)); + timeBox.getBells() + .forEach(bell -> bellRepository.save(new BellEntity(timeBoxEntity, bell))); + } + + @Transactional(readOnly = true) + public CustomizeTable getByIdAndMember(long tableId, Member member) { + return tableRepository.getByIdAndMember(tableId, member) + .toDomain(); + } + + @Transactional(readOnly = true) + public List getCustomizeTimeBoxes(long tableId, Member member) { + CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); + List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); + List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); + CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); + return timeBoxEntities.toDomain(); + } + + @Transactional + public CustomizeTable update(CustomizeTable table, long tableId, Member member, List timeBoxes) { + CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); + tableEntity.updateTable(table); + + bellRepository.deleteAllByTable(tableEntity.getId()); + timeBoxRepository.deleteAllByTable(tableEntity.getId()); + + saveTimeBoxes(tableEntity, timeBoxes); + return tableEntity.toDomain(); + } + + @Transactional + public CustomizeTable updateUsedAt(long tableId, Member member) { + CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); + tableEntity.updateUsedAt(); + return tableEntity.toDomain(); + } + + @Transactional + public void delete(long tableId, Member member) { + CustomizeTableEntity table = tableRepository.getByIdAndMember(tableId, member); + + bellRepository.deleteAllByTable(table.getId()); + timeBoxRepository.deleteAllByTable(table.getId()); + tableRepository.delete(table); + } +} diff --git a/src/main/java/com/debatetimer/service/customize/CustomizeService.java b/src/main/java/com/debatetimer/service/customize/CustomizeService.java index f0feb605..f9df4a3b 100644 --- a/src/main/java/com/debatetimer/service/customize/CustomizeService.java +++ b/src/main/java/com/debatetimer/service/customize/CustomizeService.java @@ -3,17 +3,10 @@ import com.debatetimer.domain.customize.CustomizeTable; import com.debatetimer.domain.customize.CustomizeTimeBox; import com.debatetimer.domain.member.Member; +import com.debatetimer.domainrepository.customize.CustomizeTableDomainRepository; import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; import com.debatetimer.dto.customize.response.CustomizeTableResponse; -import com.debatetimer.entity.customize.BellEntity; -import com.debatetimer.entity.customize.CustomizeTableEntity; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntities; -import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; -import com.debatetimer.repository.customize.BellRepository; -import com.debatetimer.repository.customize.CustomizeTableRepository; -import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; import java.util.List; -import java.util.stream.IntStream; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -22,28 +15,21 @@ @RequiredArgsConstructor public class CustomizeService { - private final CustomizeTableRepository tableRepository; - private final CustomizeTimeBoxRepository timeBoxRepository; - private final BellRepository bellRepository; + private final CustomizeTableDomainRepository customizeTableDomainRepository; @Transactional public CustomizeTableResponse save(CustomizeTableCreateRequest tableCreateRequest, Member member) { CustomizeTable table = tableCreateRequest.toTable(member); List timeBoxes = tableCreateRequest.toTimeBoxes(); - - CustomizeTableEntity savedTableEntity = tableRepository.save(new CustomizeTableEntity(table)); - saveTimeBoxes(savedTableEntity, timeBoxes); - return new CustomizeTableResponse(savedTableEntity.toDomain(), timeBoxes); + CustomizeTable savedTable = customizeTableDomainRepository.save(table, timeBoxes); + return new CustomizeTableResponse(savedTable, timeBoxes); } @Transactional(readOnly = true) public CustomizeTableResponse findTable(long tableId, Member member) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); - List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); - CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); - - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxEntities.toDomain()); + CustomizeTable table = customizeTableDomainRepository.getByIdAndMember(tableId, member); + List timeBoxEntities = customizeTableDomainRepository.getCustomizeTimeBoxes(tableId, member); + return new CustomizeTableResponse(table, timeBoxEntities); } @Transactional @@ -52,47 +38,22 @@ public CustomizeTableResponse updateTable( long tableId, Member member ) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - tableEntity.updateTable(tableCreateRequest.toTable(member)); - - bellRepository.deleteAllByTable(tableEntity.getId()); - timeBoxRepository.deleteAllByTable(tableEntity.getId()); + CustomizeTable table = tableCreateRequest.toTable(member); List timeBoxes = tableCreateRequest.toTimeBoxes(); - saveTimeBoxes(tableEntity, timeBoxes); - return new CustomizeTableResponse(tableEntity.toDomain(), timeBoxes); + + CustomizeTable updatedTable = customizeTableDomainRepository.update(table, tableId, member, timeBoxes); + return new CustomizeTableResponse(updatedTable, timeBoxes); } @Transactional public CustomizeTableResponse updateUsedAt(long tableId, Member member) { - CustomizeTableEntity tableEntity = tableRepository.getByIdAndMember(tableId, member); - List timeBoxEntityList = timeBoxRepository.findAllByCustomizeTable(tableEntity); - List bellEntityList = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntityList); - CustomizeTimeBoxEntities timeBoxEntities = new CustomizeTimeBoxEntities(timeBoxEntityList, bellEntityList); - - tableEntity.updateUsedAt(); - CustomizeTable table = tableEntity.toDomain(); - List timeBoxes = timeBoxEntities.toDomain(); + CustomizeTable table = customizeTableDomainRepository.updateUsedAt(tableId, member); + List timeBoxes = customizeTableDomainRepository.getCustomizeTimeBoxes(tableId, member); return new CustomizeTableResponse(table, timeBoxes); } @Transactional public void deleteTable(long tableId, Member member) { - CustomizeTableEntity table = tableRepository.getByIdAndMember(tableId, member); - - bellRepository.deleteAllByTable(table.getId()); - timeBoxRepository.deleteAllByTable(table.getId()); - tableRepository.delete(table); - } - - private void saveTimeBoxes(CustomizeTableEntity tableEntity, List timeBoxes) { - IntStream.range(0, timeBoxes.size()) - .forEach(i -> saveTimeBox(tableEntity, timeBoxes.get(i), i + 1)); - } - - private void saveTimeBox(CustomizeTableEntity tableEntity, CustomizeTimeBox timeBox, int sequence) { - CustomizeTimeBoxEntity timeBoxEntity = timeBoxRepository.save( - new CustomizeTimeBoxEntity(tableEntity, timeBox, sequence)); - timeBox.getBells() - .forEach(bell -> bellRepository.save(new BellEntity(timeBoxEntity, bell))); + customizeTableDomainRepository.delete(tableId, member); } } diff --git a/src/main/java/com/debatetimer/service/poll/PollService.java b/src/main/java/com/debatetimer/service/poll/PollService.java index 7d21bffb..cfa021b9 100644 --- a/src/main/java/com/debatetimer/service/poll/PollService.java +++ b/src/main/java/com/debatetimer/service/poll/PollService.java @@ -4,9 +4,9 @@ import com.debatetimer.domain.member.Member; import com.debatetimer.domain.poll.Poll; import com.debatetimer.domain.poll.VoteInfo; +import com.debatetimer.domainrepository.customize.CustomizeTableDomainRepository; import com.debatetimer.domainrepository.poll.PollDomainRepository; import com.debatetimer.domainrepository.poll.VoteDomainRepository; -import com.debatetimer.domainrepository.table.CustomizeTableDomainRepository; import com.debatetimer.dto.poll.response.PollCreateResponse; import com.debatetimer.dto.poll.response.PollInfoResponse; import lombok.RequiredArgsConstructor; From 37508a5451a3e39c2041196e574331ca90e3b248 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sat, 26 Jul 2025 16:45:52 +0900 Subject: [PATCH 11/15] =?UTF-8?q?refactor:=20CustomizeTableDomainRepositor?= =?UTF-8?q?yTest=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BaseControllerTest.java | 16 +- .../customize/CustomizeControllerTest.java | 34 ++-- .../controller/poll/PollControllerTest.java | 16 +- .../BaseDomainRepositoryTest.java | 46 ++++- .../CustomizeTableDomainRepositoryTest.java | 159 ++++++++++++++++++ .../poll/PollDomainRepositoryTest.java | 10 +- .../poll/VoteDomainRepositoryTest.java | 10 +- .../fixture/domain/BellGenerator.java | 23 +++ .../domain/CustomizeTableGenerator.java | 36 ++++ .../domain/CustomizeTimeBoxGenerator.java | 32 ++++ .../BellEntityGenerator.java} | 6 +- .../CustomizeTableEntityGenerator.java} | 6 +- .../CustomizeTimeBoxEntityGenerator.java} | 6 +- .../fixture/{ => entity}/MemberGenerator.java | 2 +- .../PollEntityGenerator.java} | 6 +- .../VoteEntityGenerator.java} | 6 +- .../repository/BaseRepositoryTest.java | 20 +-- .../customize/BellRepositoryTest.java | 14 +- .../CustomizeTableEntityRepositoryTest.java | 10 +- .../CustomizeTimeBoxRepositoryTest.java | 32 ++-- .../debatetimer/service/BaseServiceTest.java | 22 +-- .../customize/CustomizeServiceTest.java | 42 ++--- .../service/member/MemberServiceTest.java | 6 +- .../service/poll/PollServiceTest.java | 16 +- 24 files changed, 433 insertions(+), 143 deletions(-) create mode 100644 src/test/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepositoryTest.java create mode 100644 src/test/java/com/debatetimer/fixture/domain/BellGenerator.java create mode 100644 src/test/java/com/debatetimer/fixture/domain/CustomizeTableGenerator.java create mode 100644 src/test/java/com/debatetimer/fixture/domain/CustomizeTimeBoxGenerator.java rename src/test/java/com/debatetimer/fixture/{BellGenerator.java => entity/BellEntityGenerator.java} (81%) rename src/test/java/com/debatetimer/fixture/{CustomizeTableGenerator.java => entity/CustomizeTableEntityGenerator.java} (84%) rename src/test/java/com/debatetimer/fixture/{CustomizeTimeBoxGenerator.java => entity/CustomizeTimeBoxEntityGenerator.java} (88%) rename src/test/java/com/debatetimer/fixture/{ => entity}/MemberGenerator.java (92%) rename src/test/java/com/debatetimer/fixture/{PollGenerator.java => entity/PollEntityGenerator.java} (85%) rename src/test/java/com/debatetimer/fixture/{VoteGenerator.java => entity/VoteEntityGenerator.java} (84%) diff --git a/src/test/java/com/debatetimer/controller/BaseControllerTest.java b/src/test/java/com/debatetimer/controller/BaseControllerTest.java index c63a61fb..a1c7505d 100644 --- a/src/test/java/com/debatetimer/controller/BaseControllerTest.java +++ b/src/test/java/com/debatetimer/controller/BaseControllerTest.java @@ -9,14 +9,16 @@ import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTableInfoCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTimeBoxCreateRequest; +import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; import com.debatetimer.dto.poll.request.VoteRequest; import com.debatetimer.fixture.CustomizeTableGenerator; import com.debatetimer.fixture.CustomizeTimeBoxGenerator; import com.debatetimer.fixture.HeaderGenerator; -import com.debatetimer.fixture.MemberGenerator; -import com.debatetimer.fixture.PollGenerator; +import com.debatetimer.fixture.entity.MemberGenerator; +import com.debatetimer.fixture.entity.PollEntityGenerator; import com.debatetimer.fixture.TokenGenerator; -import com.debatetimer.fixture.VoteGenerator; +import com.debatetimer.fixture.entity.VoteEntityGenerator; import com.debatetimer.repository.customize.CustomizeTableRepository; import com.navercorp.fixturemonkey.ArbitraryBuilder; import com.navercorp.fixturemonkey.FixtureMonkey; @@ -45,16 +47,16 @@ public abstract class BaseControllerTest { protected MemberGenerator memberGenerator; @Autowired - protected CustomizeTableGenerator customizeTableGenerator; + protected CustomizeTableEntityGenerator customizeTableEntityGenerator; @Autowired - protected CustomizeTimeBoxGenerator customizeTimeBoxGenerator; + protected CustomizeTimeBoxEntityGenerator customizeTimeBoxEntityGenerator; @Autowired - protected PollGenerator pollGenerator; + protected PollEntityGenerator pollEntityGenerator; @Autowired - protected VoteGenerator voteGenerator; + protected VoteEntityGenerator voteEntityGenerator; @Autowired protected HeaderGenerator headerGenerator; diff --git a/src/test/java/com/debatetimer/controller/customize/CustomizeControllerTest.java b/src/test/java/com/debatetimer/controller/customize/CustomizeControllerTest.java index e82c3c5e..df0c91e2 100644 --- a/src/test/java/com/debatetimer/controller/customize/CustomizeControllerTest.java +++ b/src/test/java/com/debatetimer/controller/customize/CustomizeControllerTest.java @@ -154,9 +154,9 @@ class GetTable { @Test void 사용자_지정_테이블을_조회한다() { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); - customizeTimeBoxGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); + customizeTimeBoxEntityGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableResponse response = given() @@ -180,7 +180,7 @@ class UpdateTable { @Test void 사용자_지정_토론_테이블을_업데이트한다() { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest renewTableRequest = getCustomizeTableCreateRequestBuilder() .set("table[1].speaker", null) @@ -201,7 +201,7 @@ class UpdateTable { @NullAndEmptyAndBlankSource void 사용자_지정_테이블을_업데이트할때_테이블_이름은_개행문자_외_다른_글자가_포함되야한다(String tableName) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("info.name", tableName) @@ -218,7 +218,7 @@ class UpdateTable { @ParameterizedTest void 사용자_지정_테이블을_업데이트할때_테이블_주제는_null이_올_수_없다(String agenda) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("info.agenda", agenda) @@ -235,7 +235,7 @@ class UpdateTable { @NullAndEmptyAndBlankSource void 사용자_지정_테이블을_업데이트할때_찬성팀_이름은_개행문자_외_다른_글자가_포함되야한다(String prosTeamName) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("info.prosTeamName", prosTeamName) @@ -252,7 +252,7 @@ class UpdateTable { @NullAndEmptyAndBlankSource void 사용자_지정_테이블을_업데이트할때_반대팀_이름은_개행문자_외_다른_글자가_포함되야한다(String consTeamName) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() @@ -270,7 +270,7 @@ class UpdateTable { @ParameterizedTest void 사용자_지정_테이블을_업데이트할때_타임박스_입장은_null이_올_수_없다(Stance stance) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("table[0].stance", stance) @@ -287,7 +287,7 @@ class UpdateTable { @NullAndEmptyAndBlankSource void 사용자_지정_테이블을_업데이트할때_타임박스_발언_유형은_개행문자_외_다른_글자가_포함되야한다(String speechType) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("table[0].speechType", speechType) @@ -304,7 +304,7 @@ class UpdateTable { @ParameterizedTest void 사용자_지정_테이블을_업데이트할때_타임박스_타입은_null이_올_수_없다(CustomizeBoxType boxType) { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableCreateRequest request = getCustomizeTableCreateRequestBuilder() .set("table[0].boxType", boxType) @@ -339,9 +339,9 @@ class Debate { @Test void 사용자_지정_토론을_시작한다() { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); - customizeTimeBoxGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); + customizeTimeBoxEntityGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); Headers headers = headerGenerator.generateAccessTokenHeader(bito); CustomizeTableResponse response = given() @@ -366,9 +366,9 @@ class DeleteTable { @Test void 사용자_지정_토론_테이블을_삭제한다() { Member bito = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); - customizeTimeBoxGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); + customizeTimeBoxEntityGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generateNotExistSpeaker(bitoTable, CustomizeBoxType.NORMAL, 2); Headers headers = headerGenerator.generateAccessTokenHeader(bito); given() diff --git a/src/test/java/com/debatetimer/controller/poll/PollControllerTest.java b/src/test/java/com/debatetimer/controller/poll/PollControllerTest.java index 22487d85..ee3fad9b 100644 --- a/src/test/java/com/debatetimer/controller/poll/PollControllerTest.java +++ b/src/test/java/com/debatetimer/controller/poll/PollControllerTest.java @@ -24,7 +24,7 @@ class CreatePoll { @Test void 선거를_생성할_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); Headers headers = headerGenerator.generateAccessTokenHeader(member); given() @@ -42,11 +42,11 @@ class GetPollInfo { @Test void 선거정보를_읽을_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); - voteGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); + voteEntityGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); Headers headers = headerGenerator.generateAccessTokenHeader(member); PollInfoResponse response = given() @@ -75,8 +75,8 @@ class FinishPoll { @Test void 선거정보를_완료상태로_변경한다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); Headers headers = headerGenerator.generateAccessTokenHeader(member); PollInfoResponse response = given() diff --git a/src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java b/src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java index 37ac4fba..485a7f25 100644 --- a/src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java +++ b/src/test/java/com/debatetimer/domainrepository/BaseDomainRepositoryTest.java @@ -1,10 +1,18 @@ package com.debatetimer.domainrepository; import com.debatetimer.DataBaseCleaner; -import com.debatetimer.fixture.CustomizeTableGenerator; -import com.debatetimer.fixture.MemberGenerator; -import com.debatetimer.fixture.PollGenerator; -import com.debatetimer.fixture.VoteGenerator; +import com.debatetimer.fixture.domain.BellGenerator; +import com.debatetimer.fixture.domain.CustomizeTableGenerator; +import com.debatetimer.fixture.domain.CustomizeTimeBoxGenerator; +import com.debatetimer.fixture.entity.BellEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; +import com.debatetimer.fixture.entity.MemberGenerator; +import com.debatetimer.fixture.entity.PollEntityGenerator; +import com.debatetimer.fixture.entity.VoteEntityGenerator; +import com.debatetimer.repository.customize.BellRepository; +import com.debatetimer.repository.customize.CustomizeTableRepository; +import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; import com.debatetimer.repository.poll.PollRepository; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -14,18 +22,42 @@ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) public abstract class BaseDomainRepositoryTest { + @Autowired + protected CustomizeTableGenerator tableGenerator; + + @Autowired + protected CustomizeTimeBoxGenerator timeBoxGenerator; + + @Autowired + protected BellGenerator bellGenerator; + @Autowired protected MemberGenerator memberGenerator; @Autowired - protected CustomizeTableGenerator customizeTableGenerator; + protected CustomizeTableEntityGenerator tableEntityGenerator; + + @Autowired + protected CustomizeTimeBoxEntityGenerator timeBoxEntityGenerator; @Autowired - protected PollGenerator pollGenerator; + protected BellEntityGenerator bellEntityGenerator; @Autowired - protected VoteGenerator voteGenerator; + protected PollEntityGenerator pollEntityGenerator; + + @Autowired + protected VoteEntityGenerator voteEntityGenerator; @Autowired protected PollRepository pollRepository; + + @Autowired + protected CustomizeTableRepository tableRepository; + + @Autowired + protected CustomizeTimeBoxRepository timeBoxRepository; + + @Autowired + protected BellRepository bellRepository; } diff --git a/src/test/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepositoryTest.java b/src/test/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepositoryTest.java new file mode 100644 index 00000000..e9108935 --- /dev/null +++ b/src/test/java/com/debatetimer/domainrepository/customize/CustomizeTableDomainRepositoryTest.java @@ -0,0 +1,159 @@ +package com.debatetimer.domainrepository.customize; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.BellType; +import com.debatetimer.domain.customize.CustomizeBoxType; +import com.debatetimer.domain.customize.CustomizeTable; +import com.debatetimer.domain.customize.CustomizeTimeBox; +import com.debatetimer.domain.member.Member; +import com.debatetimer.domainrepository.BaseDomainRepositoryTest; +import com.debatetimer.entity.customize.BellEntity; +import com.debatetimer.entity.customize.CustomizeTableEntity; +import com.debatetimer.entity.customize.CustomizeTimeBoxEntity; +import java.time.LocalDateTime; +import java.util.Collections; +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 CustomizeTableDomainRepositoryTest extends BaseDomainRepositoryTest { + + @Autowired + private CustomizeTableDomainRepository customizeTableDomainRepository; + + @Nested + class Save { + + @Test + void 테이블을_저장한다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTable table = tableGenerator.generate(member); + List bells = bellGenerator.generate(3); + CustomizeTimeBox timeBox1 = timeBoxGenerator.generate(bells); + CustomizeTimeBox timeBox2 = timeBoxGenerator.generate(Collections.emptyList()); + + CustomizeTable savedTable = customizeTableDomainRepository.save(table, List.of(timeBox1, timeBox2)); + List timeBoxEntities = timeBoxRepository.findAllByCustomizeTable( + new CustomizeTableEntity(savedTable)); + List bellEntities = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntities); + + assertAll( + () -> assertThat(savedTable.getName()).isEqualTo(table.getName()), + () -> assertThat(timeBoxEntities).hasSize(2), + () -> assertThat(bellEntities).hasSize(3) + ); + } + } + + @Nested + class GetByIdAndMember { + + @Test + void 회원이_소유한_테이블을_가져온다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + + CustomizeTable foundTable = customizeTableDomainRepository.getByIdAndMember(table.getId(), member); + + assertThat(foundTable.getId()).isEqualTo(table.getId()); + } + } + + @Nested + class GetCustomizeTimeBoxes { + + @Test + void 테이블의_시간박스를_가져온다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity tableEntity = tableEntityGenerator.generate(member); + timeBoxEntityGenerator.generate(tableEntity, CustomizeBoxType.NORMAL, 1); + timeBoxEntityGenerator.generate(tableEntity, CustomizeBoxType.NORMAL, 2); + + List timeBoxes = customizeTableDomainRepository.getCustomizeTimeBoxes( + tableEntity.getId(), member); + + assertThat(timeBoxes).hasSize(2); + } + } + + @Nested + class Update { + + @Test + void 테이블을_수정한다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity tableEntity = tableEntityGenerator.generate(member); + CustomizeTimeBoxEntity timeBox1 = timeBoxEntityGenerator.generate(tableEntity, CustomizeBoxType.NORMAL, 1); + CustomizeTimeBoxEntity timeBox2 = timeBoxEntityGenerator.generate(tableEntity, CustomizeBoxType.NORMAL, 2); + bellEntityGenerator.generate(timeBox1, BellType.AFTER_START, 10, 1); + bellEntityGenerator.generate(timeBox1, BellType.AFTER_START, 20, 1); + bellEntityGenerator.generate(timeBox2, BellType.AFTER_START, 20, 1); + + CustomizeTable table = tableGenerator.generate(member, "수정된 테이블"); + List bells = bellGenerator.generate(3); + CustomizeTimeBox timeBox = timeBoxGenerator.generate(bells, "수정"); + + CustomizeTable updatedTable = customizeTableDomainRepository.update(table, tableEntity.getId(), member, + List.of(timeBox)); + CustomizeTableEntity foundTable = tableRepository.getByIdAndMember(tableEntity.getId(), member); + List timeBoxEntities = timeBoxRepository.findAllByCustomizeTable( + new CustomizeTableEntity(updatedTable)); + List bellEntities = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntities); + + assertAll( + () -> assertThat(foundTable.getName()).isEqualTo(updatedTable.getName()), + () -> assertThat(timeBoxEntities).hasSize(1), + () -> assertThat(bellEntities).hasSize(3) + ); + } + } + + @Nested + class UpdateUsedAt { + + @Test + void 테이블의_사용_시간을_업데이트한다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity tableEntity = tableEntityGenerator.generate(member); + LocalDateTime beforeUsedAt = tableEntity.getUsedAt(); + + CustomizeTable customizeTable = customizeTableDomainRepository.updateUsedAt(tableEntity.getId(), member); + + assertAll( + () -> assertThat(customizeTable.getId()).isEqualTo(tableEntity.getId()), + () -> assertThat(customizeTable.getUsedAt()).isAfter(beforeUsedAt) + ); + } + } + + @Nested + class Delete { + + @Test + void 테이블을_삭제한다() { + Member member = memberGenerator.generate("email@email.com"); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + CustomizeTimeBoxEntity timeBox1 = timeBoxEntityGenerator.generate(table, CustomizeBoxType.NORMAL, 1); + CustomizeTimeBoxEntity timeBox2 = timeBoxEntityGenerator.generate(table, CustomizeBoxType.NORMAL, 2); + bellEntityGenerator.generate(timeBox1, BellType.AFTER_START, 10, 1); + bellEntityGenerator.generate(timeBox1, BellType.AFTER_START, 20, 1); + bellEntityGenerator.generate(timeBox2, BellType.AFTER_START, 20, 1); + + customizeTableDomainRepository.delete(table.getId(), member); + Optional foundTable = tableRepository.findById(table.getId()); + List timeBoxEntities = timeBoxRepository.findAllByCustomizeTable(table); + List bellEntities = bellRepository.findAllByCustomizeTimeBoxIn(timeBoxEntities); + + assertAll( + () -> assertThat(foundTable).isEmpty(), + () -> assertThat(timeBoxEntities).isEmpty(), + () -> assertThat(bellEntities).isEmpty() + ); + } + } +} diff --git a/src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java b/src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java index c97849e4..48a65773 100644 --- a/src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java +++ b/src/test/java/com/debatetimer/domainrepository/poll/PollDomainRepositoryTest.java @@ -25,7 +25,7 @@ class Create { @Test void 선거를_생성한다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = tableEntityGenerator.generate(member); Poll poll = new Poll(table.getId(), member.getId(), "찬성", "반대", "주제"); Poll createdPoll = pollDomainRepository.create(poll); @@ -41,8 +41,8 @@ class GetByIdAndMemberId { @Test void 회원이_개최한_선거를_가져온다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); Poll foundPoll = pollDomainRepository.getByIdAndMemberId(pollEntity.getId(), member.getId()); @@ -63,8 +63,8 @@ class FinishPoll { @Test void 선거를_완료_상태로_변경한다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); Poll updatedPoll = pollDomainRepository.finishPoll(pollEntity.getId(), member.getId()); diff --git a/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java b/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java index 11ed5d33..3c05199f 100644 --- a/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java +++ b/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java @@ -31,11 +31,11 @@ class GetVoteInfo { @Test void 팀별_투표_현황을_알_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); - voteGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); + voteEntityGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); VoteInfo voteInfo = voteDomainRepository.findVoteInfoByPollId(pollEntity.getId()); diff --git a/src/test/java/com/debatetimer/fixture/domain/BellGenerator.java b/src/test/java/com/debatetimer/fixture/domain/BellGenerator.java new file mode 100644 index 00000000..4db99724 --- /dev/null +++ b/src/test/java/com/debatetimer/fixture/domain/BellGenerator.java @@ -0,0 +1,23 @@ +package com.debatetimer.fixture.domain; + +import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.BellType; +import java.util.ArrayList; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class BellGenerator { + + public List generate(int size) { + List bells = new ArrayList<>(); + for (int i = 0; i < size; i++) { + bells.add(generate()); + } + return bells; + } + + private Bell generate() { + return new Bell(BellType.AFTER_START, 10, 1); + } +} diff --git a/src/test/java/com/debatetimer/fixture/domain/CustomizeTableGenerator.java b/src/test/java/com/debatetimer/fixture/domain/CustomizeTableGenerator.java new file mode 100644 index 00000000..3efb05cc --- /dev/null +++ b/src/test/java/com/debatetimer/fixture/domain/CustomizeTableGenerator.java @@ -0,0 +1,36 @@ +package com.debatetimer.fixture.domain; + +import com.debatetimer.domain.customize.CustomizeTable; +import com.debatetimer.domain.member.Member; +import java.time.LocalDateTime; +import org.springframework.stereotype.Component; + +@Component +public class CustomizeTableGenerator { + + public CustomizeTable generate(Member member) { + return new CustomizeTable( + member, + "토론 테이블", + "주제", + "찬성", + "반대", + false, + false, + LocalDateTime.now() + ); + } + + public CustomizeTable generate(Member member, String name) { + return new CustomizeTable( + member, + name, + "주제", + "찬성", + "반대", + false, + false, + LocalDateTime.now() + ); + } +} diff --git a/src/test/java/com/debatetimer/fixture/domain/CustomizeTimeBoxGenerator.java b/src/test/java/com/debatetimer/fixture/domain/CustomizeTimeBoxGenerator.java new file mode 100644 index 00000000..35bc429e --- /dev/null +++ b/src/test/java/com/debatetimer/fixture/domain/CustomizeTimeBoxGenerator.java @@ -0,0 +1,32 @@ +package com.debatetimer.fixture.domain; + +import com.debatetimer.domain.customize.Bell; +import com.debatetimer.domain.customize.CustomizeTimeBox; +import com.debatetimer.domain.customize.NormalTimeBox; +import com.debatetimer.domain.customize.Stance; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class CustomizeTimeBoxGenerator { + + public CustomizeTimeBox generate(List bells) { + return new NormalTimeBox( + Stance.PROS, + "입론", + "콜리", + 10, + bells + ); + } + + public CustomizeTimeBox generate(List bells, String speechType) { + return new NormalTimeBox( + Stance.PROS, + speechType, + "콜리", + 10, + bells + ); + } +} diff --git a/src/test/java/com/debatetimer/fixture/BellGenerator.java b/src/test/java/com/debatetimer/fixture/entity/BellEntityGenerator.java similarity index 81% rename from src/test/java/com/debatetimer/fixture/BellGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/BellEntityGenerator.java index 335c6441..53f5d421 100644 --- a/src/test/java/com/debatetimer/fixture/BellGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/BellEntityGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.customize.BellType; import com.debatetimer.entity.customize.BellEntity; @@ -7,11 +7,11 @@ import org.springframework.stereotype.Component; @Component -public class BellGenerator { +public class BellEntityGenerator { private final BellRepository bellRepository; - public BellGenerator(BellRepository bellRepository) { + public BellEntityGenerator(BellRepository bellRepository) { this.bellRepository = bellRepository; } diff --git a/src/test/java/com/debatetimer/fixture/CustomizeTableGenerator.java b/src/test/java/com/debatetimer/fixture/entity/CustomizeTableEntityGenerator.java similarity index 84% rename from src/test/java/com/debatetimer/fixture/CustomizeTableGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/CustomizeTableEntityGenerator.java index 80a7b8dc..93ec96aa 100644 --- a/src/test/java/com/debatetimer/fixture/CustomizeTableGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/CustomizeTableEntityGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.customize.CustomizeTable; import com.debatetimer.domain.member.Member; @@ -8,11 +8,11 @@ import org.springframework.stereotype.Component; @Component -public class CustomizeTableGenerator { +public class CustomizeTableEntityGenerator { private final CustomizeTableRepository customizeTableRepository; - public CustomizeTableGenerator(CustomizeTableRepository customizeTableRepository) { + public CustomizeTableEntityGenerator(CustomizeTableRepository customizeTableRepository) { this.customizeTableRepository = customizeTableRepository; } diff --git a/src/test/java/com/debatetimer/fixture/CustomizeTimeBoxGenerator.java b/src/test/java/com/debatetimer/fixture/entity/CustomizeTimeBoxEntityGenerator.java similarity index 88% rename from src/test/java/com/debatetimer/fixture/CustomizeTimeBoxGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/CustomizeTimeBoxEntityGenerator.java index e068269d..7b2ca578 100644 --- a/src/test/java/com/debatetimer/fixture/CustomizeTimeBoxGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/CustomizeTimeBoxEntityGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.customize.Stance; @@ -8,11 +8,11 @@ import org.springframework.stereotype.Component; @Component -public class CustomizeTimeBoxGenerator { +public class CustomizeTimeBoxEntityGenerator { private final CustomizeTimeBoxRepository customizeTimeBoxRepository; - public CustomizeTimeBoxGenerator(CustomizeTimeBoxRepository customizeTimeBoxRepository) { + public CustomizeTimeBoxEntityGenerator(CustomizeTimeBoxRepository customizeTimeBoxRepository) { this.customizeTimeBoxRepository = customizeTimeBoxRepository; } diff --git a/src/test/java/com/debatetimer/fixture/MemberGenerator.java b/src/test/java/com/debatetimer/fixture/entity/MemberGenerator.java similarity index 92% rename from src/test/java/com/debatetimer/fixture/MemberGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/MemberGenerator.java index d0aa97bb..69dc56a3 100644 --- a/src/test/java/com/debatetimer/fixture/MemberGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/MemberGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.member.Member; import com.debatetimer.repository.member.MemberRepository; diff --git a/src/test/java/com/debatetimer/fixture/PollGenerator.java b/src/test/java/com/debatetimer/fixture/entity/PollEntityGenerator.java similarity index 85% rename from src/test/java/com/debatetimer/fixture/PollGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/PollEntityGenerator.java index 24059cba..5f01a4b5 100644 --- a/src/test/java/com/debatetimer/fixture/PollGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/PollEntityGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.poll.Poll; import com.debatetimer.domain.poll.PollStatus; @@ -8,11 +8,11 @@ import org.springframework.stereotype.Component; @Component -public class PollGenerator { +public class PollEntityGenerator { private final PollRepository pollRepository; - public PollGenerator(final PollRepository pollRepository) { + public PollEntityGenerator(final PollRepository pollRepository) { this.pollRepository = pollRepository; } diff --git a/src/test/java/com/debatetimer/fixture/VoteGenerator.java b/src/test/java/com/debatetimer/fixture/entity/VoteEntityGenerator.java similarity index 84% rename from src/test/java/com/debatetimer/fixture/VoteGenerator.java rename to src/test/java/com/debatetimer/fixture/entity/VoteEntityGenerator.java index ed97b1f1..b083ce45 100644 --- a/src/test/java/com/debatetimer/fixture/VoteGenerator.java +++ b/src/test/java/com/debatetimer/fixture/entity/VoteEntityGenerator.java @@ -1,4 +1,4 @@ -package com.debatetimer.fixture; +package com.debatetimer.fixture.entity; import com.debatetimer.domain.poll.VoteTeam; import com.debatetimer.entity.poll.PollEntity; @@ -8,11 +8,11 @@ import org.springframework.stereotype.Component; @Component -public class VoteGenerator { +public class VoteEntityGenerator { private final VoteRepository voteRepository; - public VoteGenerator(VoteRepository voteRepository) { + public VoteEntityGenerator(VoteRepository voteRepository) { this.voteRepository = voteRepository; } diff --git a/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java b/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java index 87b5404b..ab973a1e 100644 --- a/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/BaseRepositoryTest.java @@ -1,10 +1,10 @@ package com.debatetimer.repository; import com.debatetimer.config.JpaAuditingConfig; -import com.debatetimer.fixture.BellGenerator; -import com.debatetimer.fixture.CustomizeTableGenerator; -import com.debatetimer.fixture.CustomizeTimeBoxGenerator; -import com.debatetimer.fixture.MemberGenerator; +import com.debatetimer.fixture.entity.BellEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; +import com.debatetimer.fixture.entity.MemberGenerator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.context.annotation.Import; @@ -12,9 +12,9 @@ @Import({ JpaAuditingConfig.class, MemberGenerator.class, - CustomizeTableGenerator.class, - CustomizeTimeBoxGenerator.class, - BellGenerator.class, + CustomizeTableEntityGenerator.class, + CustomizeTimeBoxEntityGenerator.class, + BellEntityGenerator.class, }) @DataJpaTest public abstract class BaseRepositoryTest { @@ -23,11 +23,11 @@ public abstract class BaseRepositoryTest { protected MemberGenerator memberGenerator; @Autowired - protected CustomizeTableGenerator customizeTableGenerator; + protected CustomizeTableEntityGenerator customizeTableEntityGenerator; @Autowired - protected CustomizeTimeBoxGenerator customizeTimeBoxGenerator; + protected CustomizeTimeBoxEntityGenerator customizeTimeBoxEntityGenerator; @Autowired - protected BellGenerator bellGenerator; + protected BellEntityGenerator bellEntityGenerator; } diff --git a/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java b/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java index b8fcc4e4..7747fb03 100644 --- a/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/customize/BellRepositoryTest.java @@ -25,15 +25,15 @@ class DeleteAllByTable { @Test void 특정_테이블에_해당하는_벨을_삭제한다() { Member member = memberGenerator.generate("chan@gmail.com"); - CustomizeTableEntity deleteBellTable = customizeTableGenerator.generate(member); - CustomizeTableEntity otherTable = customizeTableGenerator.generate(member); - CustomizeTimeBoxEntity deleteBellTimeBox = customizeTimeBoxGenerator.generate(deleteBellTable, + CustomizeTableEntity deleteBellTable = customizeTableEntityGenerator.generate(member); + CustomizeTableEntity otherTable = customizeTableEntityGenerator.generate(member); + CustomizeTimeBoxEntity deleteBellTimeBox = customizeTimeBoxEntityGenerator.generate(deleteBellTable, CustomizeBoxType.NORMAL, 1); - CustomizeTimeBoxEntity otherTimeBox = customizeTimeBoxGenerator.generate(otherTable, + CustomizeTimeBoxEntity otherTimeBox = customizeTimeBoxEntityGenerator.generate(otherTable, CustomizeBoxType.NORMAL, 1); - bellGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 45, 1); - bellGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 60, 1); - bellGenerator.generate(otherTimeBox, BellType.AFTER_START, 45, 1); + bellEntityGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 45, 1); + bellEntityGenerator.generate(deleteBellTimeBox, BellType.AFTER_START, 60, 1); + bellEntityGenerator.generate(otherTimeBox, BellType.AFTER_START, 45, 1); bellRepository.deleteAllByTable(deleteBellTable.getId()); diff --git a/src/test/java/com/debatetimer/repository/customize/CustomizeTableEntityRepositoryTest.java b/src/test/java/com/debatetimer/repository/customize/CustomizeTableEntityRepositoryTest.java index ebc3e626..428ae069 100644 --- a/src/test/java/com/debatetimer/repository/customize/CustomizeTableEntityRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/customize/CustomizeTableEntityRepositoryTest.java @@ -25,9 +25,9 @@ class FindAllByMember { void 특정_회원의_테이블만_조회한다() { Member chan = memberGenerator.generate("default@gmail.com"); Member bito = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable1 = customizeTableGenerator.generate(chan); - CustomizeTableEntity chanTable2 = customizeTableGenerator.generate(chan); - customizeTableGenerator.generate(bito); + CustomizeTableEntity chanTable1 = customizeTableEntityGenerator.generate(chan); + CustomizeTableEntity chanTable2 = customizeTableEntityGenerator.generate(chan); + customizeTableEntityGenerator.generate(bito); List foundKeoChanTables = tableRepository.findAllByMember(chan); @@ -41,7 +41,7 @@ class GetByIdAndMember { @Test void 특정_회원의_테이블을_조회한다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(chan); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(chan); CustomizeTableEntity foundTable = tableRepository.getByIdAndMember(table.getId(), chan); @@ -51,7 +51,7 @@ class GetByIdAndMember { @Test void 존재하지_않는_테이블을_조회하면_예외를_던진다() { Member chan = memberGenerator.generate("default@gmail.com"); - customizeTableGenerator.generate(chan); + customizeTableEntityGenerator.generate(chan); long nonExistTableId = 99999999L; assertThatThrownBy(() -> tableRepository.getByIdAndMember(nonExistTableId, chan)) diff --git a/src/test/java/com/debatetimer/repository/customize/CustomizeTimeBoxRepositoryTest.java b/src/test/java/com/debatetimer/repository/customize/CustomizeTimeBoxRepositoryTest.java index eb94339f..5fcf6b39 100644 --- a/src/test/java/com/debatetimer/repository/customize/CustomizeTimeBoxRepositoryTest.java +++ b/src/test/java/com/debatetimer/repository/customize/CustomizeTimeBoxRepositoryTest.java @@ -25,12 +25,14 @@ class FindAllByCustomizeTableEntity { void 특정_테이블의_타임박스를_모두_조회한다() { Member chan = memberGenerator.generate("default@gmail.com"); Member bito = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - CustomizeTableEntity bitoTable = customizeTableGenerator.generate(bito); - CustomizeTimeBoxEntity chanBox1 = customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); - CustomizeTimeBoxEntity chanBox2 = customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); - customizeTimeBoxGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 2); - customizeTimeBoxGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); + CustomizeTableEntity bitoTable = customizeTableEntityGenerator.generate(bito); + CustomizeTimeBoxEntity chanBox1 = customizeTimeBoxEntityGenerator.generate(chanTable, + CustomizeBoxType.NORMAL, 1); + CustomizeTimeBoxEntity chanBox2 = customizeTimeBoxEntityGenerator.generate(chanTable, + CustomizeBoxType.NORMAL, 2); + customizeTimeBoxEntityGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 2); + customizeTimeBoxEntityGenerator.generate(bitoTable, CustomizeBoxType.NORMAL, 2); List foundBoxes = customizeTimeBoxRepository.findAllByCustomizeTable(chanTable); @@ -44,9 +46,9 @@ class DeleteAllByTable { @Test void 특정_테이블의_타임박스를_모두_삭제한다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); + customizeTimeBoxEntityGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); customizeTimeBoxRepository.deleteAllByTable(chanTable.getId()); @@ -57,11 +59,11 @@ class DeleteAllByTable { @Test void 특정_테이블의_타임_박스를_삭제해도_다른_테이블의_타임_박스는_삭제되지_않는다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity filledTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(filledTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(filledTable, CustomizeBoxType.NORMAL, 2); - CustomizeTableEntity deletedTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(deletedTable, CustomizeBoxType.NORMAL, 1); + CustomizeTableEntity filledTable = customizeTableEntityGenerator.generate(chan); + customizeTimeBoxEntityGenerator.generate(filledTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generate(filledTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity deletedTable = customizeTableEntityGenerator.generate(chan); + customizeTimeBoxEntityGenerator.generate(deletedTable, CustomizeBoxType.NORMAL, 1); customizeTimeBoxRepository.deleteAllByTable(deletedTable.getId()); @@ -72,7 +74,7 @@ class DeleteAllByTable { @Test void 테이블의_타임_박스가_없을_경우_타임_박스_삭제_시_예외가_발생하지_않는다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity emptyTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity emptyTable = customizeTableEntityGenerator.generate(chan); assertThatCode(() -> customizeTimeBoxRepository.deleteAllByTable(emptyTable.getId())) .doesNotThrowAnyException(); diff --git a/src/test/java/com/debatetimer/service/BaseServiceTest.java b/src/test/java/com/debatetimer/service/BaseServiceTest.java index a68e418d..3bd0a8c1 100644 --- a/src/test/java/com/debatetimer/service/BaseServiceTest.java +++ b/src/test/java/com/debatetimer/service/BaseServiceTest.java @@ -1,12 +1,12 @@ package com.debatetimer.service; import com.debatetimer.DataBaseCleaner; -import com.debatetimer.fixture.BellGenerator; -import com.debatetimer.fixture.CustomizeTableGenerator; -import com.debatetimer.fixture.CustomizeTimeBoxGenerator; -import com.debatetimer.fixture.MemberGenerator; -import com.debatetimer.fixture.PollGenerator; -import com.debatetimer.fixture.VoteGenerator; +import com.debatetimer.fixture.entity.BellEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; +import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; +import com.debatetimer.fixture.entity.MemberGenerator; +import com.debatetimer.fixture.entity.PollEntityGenerator; +import com.debatetimer.fixture.entity.VoteEntityGenerator; import com.debatetimer.repository.customize.BellRepository; import com.debatetimer.repository.customize.CustomizeTableRepository; import com.debatetimer.repository.customize.CustomizeTimeBoxRepository; @@ -41,19 +41,19 @@ public abstract class BaseServiceTest { protected MemberGenerator memberGenerator; @Autowired - protected CustomizeTableGenerator customizeTableGenerator; + protected CustomizeTableEntityGenerator customizeTableEntityGenerator; @Autowired - protected CustomizeTimeBoxGenerator customizeTimeBoxGenerator; + protected CustomizeTimeBoxEntityGenerator customizeTimeBoxEntityGenerator; @Autowired - protected BellGenerator bellGenerator; + protected BellEntityGenerator bellEntityGenerator; @Autowired - protected PollGenerator pollGenerator; + protected PollEntityGenerator pollEntityGenerator; @Autowired - protected VoteGenerator voteGenerator; + protected VoteEntityGenerator voteEntityGenerator; protected void runAtSameTime(int count, Runnable task) throws InterruptedException { List threads = IntStream.range(0, count) diff --git a/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java b/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java index baf45e4d..664a50c5 100644 --- a/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java +++ b/src/test/java/com/debatetimer/service/customize/CustomizeServiceTest.java @@ -44,7 +44,8 @@ class Save { new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), + new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -68,12 +69,12 @@ class FindTable { @Test void 사용자_지정_토론_테이블을_조회한다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - CustomizeTimeBoxEntity customizeTimeBox = customizeTimeBoxGenerator.generate( + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); + CustomizeTimeBoxEntity customizeTimeBox = customizeTimeBoxEntityGenerator.generate( chanTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); - bellGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 1); - bellGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 2); + customizeTimeBoxEntityGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); + bellEntityGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 1); + bellEntityGenerator.generate(customizeTimeBox, BellType.AFTER_START, 1, 2); CustomizeTableResponse foundResponse = customizeService.findTable(chanTable.getId(), chan); @@ -89,7 +90,7 @@ class FindTable { void 회원_소유가_아닌_테이블_조회_시_예외를_발생시킨다() { Member chan = memberGenerator.generate("default@gmail.com"); Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); long chanTableId = chanTable.getId(); assertThatThrownBy(() -> customizeService.findTable(chanTableId, coli)) @@ -104,7 +105,7 @@ class UpdateTable { @Test void 사용자_지정_토론_테이블을_수정한다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); CustomizeTableCreateRequest renewTableRequest = new CustomizeTableCreateRequest( new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", "반대", true, true), @@ -112,7 +113,8 @@ class UpdateTable { new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), + new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -135,7 +137,7 @@ class UpdateTable { void 회원_소유가_아닌_테이블_수정_시_예외를_발생시킨다() { Member chan = memberGenerator.generate("default@gmail.com"); Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); long chanTableId = chanTable.getId(); CustomizeTableCreateRequest renewTableRequest = new CustomizeTableCreateRequest( new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", @@ -144,7 +146,8 @@ class UpdateTable { new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), + new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -156,7 +159,7 @@ class UpdateTable { @Test void 테이블_정보_수정을_동시에_요청할_때_동시에_처리하지_않는다() throws InterruptedException { Member member = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); CustomizeTableCreateRequest request = new CustomizeTableCreateRequest( new CustomizeTableInfoCreateRequest("자유 테이블", "주제", "찬성", "반대", true, true), @@ -164,7 +167,8 @@ class UpdateTable { new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론1", CustomizeBoxType.NORMAL, 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1)), 60, null, "발언자1"), new CustomizeTimeBoxCreateRequest(Stance.PROS, "입론2", CustomizeBoxType.NORMAL, - 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") + 120, List.of(new BellRequest(BellType.AFTER_START, 90, 1), + new BellRequest(BellType.AFTER_START, 120, 2)), 60, null, "발언자2") ) ); @@ -180,7 +184,7 @@ class UpdateUsedAt { @Test void 사용자_지정_토론_테이블의_사용_시각을_최신화한다() { Member member = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); LocalDateTime beforeUsedAt = table.getUsedAt(); customizeService.updateUsedAt(table.getId(), member); @@ -196,7 +200,7 @@ class UpdateUsedAt { void 회원_소유가_아닌_테이블_수정_시_예외를_발생시킨다() { Member chan = memberGenerator.generate("default@gmail.com"); Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); long chanTableId = chanTable.getId(); assertThatThrownBy(() -> customizeService.updateUsedAt(chanTableId, coli)) @@ -211,9 +215,9 @@ class DeleteTable { @Test void 사용자_지정_토론_테이블을_삭제한다() { Member chan = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); - customizeTimeBoxGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); + customizeTimeBoxEntityGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 1); + customizeTimeBoxEntityGenerator.generate(chanTable, CustomizeBoxType.NORMAL, 2); customizeService.deleteTable(chanTable.getId(), chan); @@ -233,7 +237,7 @@ class DeleteTable { void 회원_소유가_아닌_테이블_삭제_시_예외를_발생시킨다() { Member chan = memberGenerator.generate("default@gmail.com"); Member coli = memberGenerator.generate("default2@gmail.com"); - CustomizeTableEntity chanTable = customizeTableGenerator.generate(chan); + CustomizeTableEntity chanTable = customizeTableEntityGenerator.generate(chan); long chanTableId = chanTable.getId(); assertThatThrownBy(() -> customizeService.deleteTable(chanTableId, coli)) diff --git a/src/test/java/com/debatetimer/service/member/MemberServiceTest.java b/src/test/java/com/debatetimer/service/member/MemberServiceTest.java index d78c50e7..185476e9 100644 --- a/src/test/java/com/debatetimer/service/member/MemberServiceTest.java +++ b/src/test/java/com/debatetimer/service/member/MemberServiceTest.java @@ -52,8 +52,8 @@ class GetTables { @Test void 회원의_전체_토론_시간표를_조회한다() { Member member = memberGenerator.generate("default@gmail.com"); - customizeTableGenerator.generate(member); - customizeTableGenerator.generate(member); + customizeTableEntityGenerator.generate(member); + customizeTableEntityGenerator.generate(member); TableResponses response = memberService.getTables(member.getId()); @@ -63,7 +63,7 @@ class GetTables { @Test void 회원의_전체_토론_시간표는_정해진_순서대로_반환한다() throws InterruptedException { Member member = memberGenerator.generate("default@gmail.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); Thread.sleep(1); TableResponses response = memberService.getTables(member.getId()); diff --git a/src/test/java/com/debatetimer/service/poll/PollServiceTest.java b/src/test/java/com/debatetimer/service/poll/PollServiceTest.java index fd5c96c2..4dd3e913 100644 --- a/src/test/java/com/debatetimer/service/poll/PollServiceTest.java +++ b/src/test/java/com/debatetimer/service/poll/PollServiceTest.java @@ -27,7 +27,7 @@ class CreatePoll { @Test void 선거를_생성한다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); PollCreateResponse createdPoll = pollService.create(table.getId(), member); @@ -42,11 +42,11 @@ class GetPollInfo { @Test void 선거_정보를_읽어온다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); - voteGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); + voteEntityGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); PollInfoResponse pollInfo = pollService.getPollInfo(table.getId(), member); @@ -68,8 +68,8 @@ class FinishPoll { @Test void 선거를_완료상태로_변경한다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + pollEntityGenerator.generate(table, PollStatus.PROGRESS); PollInfoResponse pollInfo = pollService.finishPoll(table.getId(), member); From 14040c29242b610436cfcbf80e67d244c37617f2 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Sun, 27 Jul 2025 23:08:06 +0900 Subject: [PATCH 12/15] =?UTF-8?q?feat:=20=EB=B2=A8=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=8B=9C=EA=B0=84=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../debatetimer/domain/customize/Bell.java | 6 ++-- .../domain/customize/BellType.java | 18 +++++++++-- .../controller/BaseControllerTest.java | 5 +++- .../domain/customize/BellTest.java | 30 +++++++++++++++++-- 4 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/debatetimer/domain/customize/Bell.java b/src/main/java/com/debatetimer/domain/customize/Bell.java index 9488bef6..f5200976 100644 --- a/src/main/java/com/debatetimer/domain/customize/Bell.java +++ b/src/main/java/com/debatetimer/domain/customize/Bell.java @@ -14,15 +14,15 @@ public class Bell { private final int count; public Bell(BellType type, int time, int count) { - validateTime(time); + validateTime(type, time); validateCount(count); this.type = type; this.time = time; this.count = count; } - private void validateTime(int time) { - if (time < 0) { + private void validateTime(BellType type, int time) { + if (!type.isValidTime(time)) { throw new DTClientErrorException(ClientErrorCode.INVALID_BELL_TIME); } } diff --git a/src/main/java/com/debatetimer/domain/customize/BellType.java b/src/main/java/com/debatetimer/domain/customize/BellType.java index 56bc3134..121e4c51 100644 --- a/src/main/java/com/debatetimer/domain/customize/BellType.java +++ b/src/main/java/com/debatetimer/domain/customize/BellType.java @@ -1,9 +1,21 @@ package com.debatetimer.domain.customize; +import java.util.function.Predicate; + public enum BellType { - AFTER_START, - BEFORE_END, - AFTER_END, + AFTER_START(time -> time >= 0), + BEFORE_END(time -> time >= 0), + AFTER_END(time -> time <= 0), ; + + private final Predicate timeValidator; + + BellType(Predicate timeValidator) { + this.timeValidator = timeValidator; + } + + public boolean isValidTime(int time) { + return timeValidator.test(time); + } } diff --git a/src/test/java/com/debatetimer/controller/BaseControllerTest.java b/src/test/java/com/debatetimer/controller/BaseControllerTest.java index a1c7505d..d73b42b7 100644 --- a/src/test/java/com/debatetimer/controller/BaseControllerTest.java +++ b/src/test/java/com/debatetimer/controller/BaseControllerTest.java @@ -2,6 +2,7 @@ import com.debatetimer.DataBaseCleaner; import com.debatetimer.client.oauth.OAuthClient; +import com.debatetimer.domain.customize.BellType; import com.debatetimer.domain.customize.CustomizeBoxType; import com.debatetimer.domain.customize.Stance; import com.debatetimer.domain.poll.VoteTeam; @@ -9,6 +10,8 @@ import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTableInfoCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTimeBoxCreateRequest; +import com.debatetimer.fixture.HeaderGenerator; +import com.debatetimer.fixture.TokenGenerator; import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; import com.debatetimer.dto.poll.request.VoteRequest; @@ -17,7 +20,6 @@ import com.debatetimer.fixture.HeaderGenerator; import com.debatetimer.fixture.entity.MemberGenerator; import com.debatetimer.fixture.entity.PollEntityGenerator; -import com.debatetimer.fixture.TokenGenerator; import com.debatetimer.fixture.entity.VoteEntityGenerator; import com.debatetimer.repository.customize.CustomizeTableRepository; import com.navercorp.fixturemonkey.ArbitraryBuilder; @@ -126,6 +128,7 @@ private ArbitraryBuilder getCustomizeTimeBoxCreat private ArbitraryBuilder getBellRequestBuilder() { return fixtureMonkey.giveMeBuilder(BellRequest.class) + .set("type", BellType.AFTER_START) .set("time", 30) .set("count", 1); } diff --git a/src/test/java/com/debatetimer/domain/customize/BellTest.java b/src/test/java/com/debatetimer/domain/customize/BellTest.java index 25b99e70..c2be8eb6 100644 --- a/src/test/java/com/debatetimer/domain/customize/BellTest.java +++ b/src/test/java/com/debatetimer/domain/customize/BellTest.java @@ -16,18 +16,44 @@ class BellTest { class Validate { @Test - void 벨_시간이_음수면_생성되지_않는다() { + void 벨_종류가_AFTER_START일때_시간이_음수면_생성되지_않는다() { assertThatThrownBy(() -> new Bell(BellType.AFTER_START, -1, 1)) .isInstanceOf(DTClientErrorException.class) .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); } @Test - void 벨_시간은_0이상이어야_한다() { + void 벨_종류가_AFTER_START일때_시간은_0이상이어야_한다() { assertThatCode(() -> new Bell(BellType.AFTER_START, 0, 1)) .doesNotThrowAnyException(); } + @Test + void 벨_종류가_BEFORE_END일때_시간이_음수면_생성되지_않는다() { + assertThatThrownBy(() -> new Bell(BellType.BEFORE_END, -1, 1)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); + } + + @Test + void 벨_종류가_BEFORE_END일때_시간은_0이상이어야_한다() { + assertThatCode(() -> new Bell(BellType.BEFORE_END, 0, 1)) + .doesNotThrowAnyException(); + } + + @Test + void 벨_종류가_AFTER_END일때_시간이_양수면_생성되지_않는다() { + assertThatThrownBy(() -> new Bell(BellType.AFTER_END, 1, 1)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); + } + + @Test + void 벨_종류가_BEFORE_END일때_시간은_0이하여야_한다() { + assertThatCode(() -> new Bell(BellType.AFTER_END, 0, 1)) + .doesNotThrowAnyException(); + } + @ValueSource(ints = {0, Bell.MAX_BELL_COUNT + 1}) @ParameterizedTest void 벨_횟수는_정해진_횟수_바깥일_경우_생성되지_않는다(int count) { From e96fecf283873384c1924143da5bea95e4111c8d Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Mon, 28 Jul 2025 11:47:20 +0900 Subject: [PATCH 13/15] =?UTF-8?q?feat:=20Bell=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../debatetimer/domain/customize/Bell.java | 8 +--- .../domain/customize/BellType.java | 14 ++++--- .../service/customize/CustomizeService.java | 4 +- .../domain/customize/BellTest.java | 40 ------------------- .../domain/customize/BellTypeTest.java | 36 +++++++++++++++++ 5 files changed, 48 insertions(+), 54 deletions(-) create mode 100644 src/test/java/com/debatetimer/domain/customize/BellTypeTest.java diff --git a/src/main/java/com/debatetimer/domain/customize/Bell.java b/src/main/java/com/debatetimer/domain/customize/Bell.java index f5200976..4766bb31 100644 --- a/src/main/java/com/debatetimer/domain/customize/Bell.java +++ b/src/main/java/com/debatetimer/domain/customize/Bell.java @@ -14,19 +14,13 @@ public class Bell { private final int count; public Bell(BellType type, int time, int count) { - validateTime(type, time); + type.validateTime(time); validateCount(count); this.type = type; this.time = time; this.count = count; } - private void validateTime(BellType type, int time) { - if (!type.isValidTime(time)) { - throw new DTClientErrorException(ClientErrorCode.INVALID_BELL_TIME); - } - } - private void validateCount(int count) { if (count <= 0 || count > MAX_BELL_COUNT) { throw new DTClientErrorException(ClientErrorCode.INVALID_BELL_COUNT); diff --git a/src/main/java/com/debatetimer/domain/customize/BellType.java b/src/main/java/com/debatetimer/domain/customize/BellType.java index 121e4c51..e90dc35d 100644 --- a/src/main/java/com/debatetimer/domain/customize/BellType.java +++ b/src/main/java/com/debatetimer/domain/customize/BellType.java @@ -1,6 +1,8 @@ package com.debatetimer.domain.customize; -import java.util.function.Predicate; +import com.debatetimer.exception.custom.DTClientErrorException; +import com.debatetimer.exception.errorcode.ClientErrorCode; +import java.util.function.IntPredicate; public enum BellType { @@ -9,13 +11,15 @@ public enum BellType { AFTER_END(time -> time <= 0), ; - private final Predicate timeValidator; + private final IntPredicate timeValidator; - BellType(Predicate timeValidator) { + BellType(IntPredicate timeValidator) { this.timeValidator = timeValidator; } - public boolean isValidTime(int time) { - return timeValidator.test(time); + public void validateTime(int time) { + if (!timeValidator.test(time)) { + throw new DTClientErrorException(ClientErrorCode.INVALID_BELL_TIME); + } } } diff --git a/src/main/java/com/debatetimer/service/customize/CustomizeService.java b/src/main/java/com/debatetimer/service/customize/CustomizeService.java index f9df4a3b..1670036f 100644 --- a/src/main/java/com/debatetimer/service/customize/CustomizeService.java +++ b/src/main/java/com/debatetimer/service/customize/CustomizeService.java @@ -28,8 +28,8 @@ public CustomizeTableResponse save(CustomizeTableCreateRequest tableCreateReques @Transactional(readOnly = true) public CustomizeTableResponse findTable(long tableId, Member member) { CustomizeTable table = customizeTableDomainRepository.getByIdAndMember(tableId, member); - List timeBoxEntities = customizeTableDomainRepository.getCustomizeTimeBoxes(tableId, member); - return new CustomizeTableResponse(table, timeBoxEntities); + List timeBoxes = customizeTableDomainRepository.getCustomizeTimeBoxes(tableId, member); + return new CustomizeTableResponse(table, timeBoxes); } @Transactional diff --git a/src/test/java/com/debatetimer/domain/customize/BellTest.java b/src/test/java/com/debatetimer/domain/customize/BellTest.java index c2be8eb6..6ec93af3 100644 --- a/src/test/java/com/debatetimer/domain/customize/BellTest.java +++ b/src/test/java/com/debatetimer/domain/customize/BellTest.java @@ -6,7 +6,6 @@ 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; @@ -15,45 +14,6 @@ class BellTest { @Nested class Validate { - @Test - void 벨_종류가_AFTER_START일때_시간이_음수면_생성되지_않는다() { - assertThatThrownBy(() -> new Bell(BellType.AFTER_START, -1, 1)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); - } - - @Test - void 벨_종류가_AFTER_START일때_시간은_0이상이어야_한다() { - assertThatCode(() -> new Bell(BellType.AFTER_START, 0, 1)) - .doesNotThrowAnyException(); - } - - @Test - void 벨_종류가_BEFORE_END일때_시간이_음수면_생성되지_않는다() { - assertThatThrownBy(() -> new Bell(BellType.BEFORE_END, -1, 1)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); - } - - @Test - void 벨_종류가_BEFORE_END일때_시간은_0이상이어야_한다() { - assertThatCode(() -> new Bell(BellType.BEFORE_END, 0, 1)) - .doesNotThrowAnyException(); - } - - @Test - void 벨_종류가_AFTER_END일때_시간이_양수면_생성되지_않는다() { - assertThatThrownBy(() -> new Bell(BellType.AFTER_END, 1, 1)) - .isInstanceOf(DTClientErrorException.class) - .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); - } - - @Test - void 벨_종류가_BEFORE_END일때_시간은_0이하여야_한다() { - assertThatCode(() -> new Bell(BellType.AFTER_END, 0, 1)) - .doesNotThrowAnyException(); - } - @ValueSource(ints = {0, Bell.MAX_BELL_COUNT + 1}) @ParameterizedTest void 벨_횟수는_정해진_횟수_바깥일_경우_생성되지_않는다(int count) { diff --git a/src/test/java/com/debatetimer/domain/customize/BellTypeTest.java b/src/test/java/com/debatetimer/domain/customize/BellTypeTest.java new file mode 100644 index 00000000..8500d326 --- /dev/null +++ b/src/test/java/com/debatetimer/domain/customize/BellTypeTest.java @@ -0,0 +1,36 @@ +package com.debatetimer.domain.customize; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import com.debatetimer.exception.custom.DTClientErrorException; +import com.debatetimer.exception.errorcode.ClientErrorCode; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +class BellTypeTest { + + @Nested + class ValidateTime { + + @Test + void 벨_타입이_AFTER_START일때_시간은_0이상이어야_한다() { + assertThatThrownBy(() -> BellType.AFTER_START.validateTime(-1)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); + } + + @Test + void 벨_타입이_BEFORE_END일때_시간은_0이상이어야_한다() { + assertThatThrownBy(() -> BellType.BEFORE_END.validateTime(-1)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); + } + + @Test + void 벨_타입이_AFTER_END일때_시간은_0이하여야_한다() { + assertThatThrownBy(() -> BellType.AFTER_END.validateTime(1)) + .isInstanceOf(DTClientErrorException.class) + .hasMessage(ClientErrorCode.INVALID_BELL_TIME.getMessage()); + } + } +} From 582aa5bcd567a5e5925f9427921b417811f4a9d8 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 31 Jul 2025 04:29:37 +0900 Subject: [PATCH 14/15] =?UTF-8?q?fix:=20=EB=B3=91=ED=95=A9=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=98=A4=EB=A5=98=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../table/CustomizeTableDomainRepository.java | 24 ---------- ...l.sql => V13__add_bell_type_into_bell.sql} | 0 .../controller/BaseControllerTest.java | 5 +-- .../controller/poll/VoteControllerTest.java | 44 +++++++++---------- .../poll/VoteDomainRepositoryTest.java | 18 ++++---- .../service/poll/VoteServiceTest.java | 30 ++++++------- 6 files changed, 47 insertions(+), 74 deletions(-) delete mode 100644 src/main/java/com/debatetimer/domainrepository/table/CustomizeTableDomainRepository.java rename src/main/resources/db/migration/{V12__add_bell_type_into_bell.sql => V13__add_bell_type_into_bell.sql} (100%) diff --git a/src/main/java/com/debatetimer/domainrepository/table/CustomizeTableDomainRepository.java b/src/main/java/com/debatetimer/domainrepository/table/CustomizeTableDomainRepository.java deleted file mode 100644 index f48ffc33..00000000 --- a/src/main/java/com/debatetimer/domainrepository/table/CustomizeTableDomainRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.debatetimer.domainrepository.table; - -import com.debatetimer.domain.customize.CustomizeTable; -import com.debatetimer.domain.member.Member; -import com.debatetimer.exception.custom.DTClientErrorException; -import com.debatetimer.exception.errorcode.ClientErrorCode; -import com.debatetimer.repository.customize.CustomizeTableRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -@Repository -@RequiredArgsConstructor -public class CustomizeTableDomainRepository { - - private final CustomizeTableRepository customizeTableRepository; - - @Transactional(readOnly = true) - public CustomizeTable getByIdAndMember(long tableId, Member member) { - return customizeTableRepository.findByIdAndMember(tableId, member) - .orElseThrow(() -> new DTClientErrorException(ClientErrorCode.TABLE_NOT_FOUND)) - .toDomain(); - } -} diff --git a/src/main/resources/db/migration/V12__add_bell_type_into_bell.sql b/src/main/resources/db/migration/V13__add_bell_type_into_bell.sql similarity index 100% rename from src/main/resources/db/migration/V12__add_bell_type_into_bell.sql rename to src/main/resources/db/migration/V13__add_bell_type_into_bell.sql diff --git a/src/test/java/com/debatetimer/controller/BaseControllerTest.java b/src/test/java/com/debatetimer/controller/BaseControllerTest.java index d73b42b7..504c5dcd 100644 --- a/src/test/java/com/debatetimer/controller/BaseControllerTest.java +++ b/src/test/java/com/debatetimer/controller/BaseControllerTest.java @@ -10,14 +10,11 @@ import com.debatetimer.dto.customize.request.CustomizeTableCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTableInfoCreateRequest; import com.debatetimer.dto.customize.request.CustomizeTimeBoxCreateRequest; +import com.debatetimer.dto.poll.request.VoteRequest; import com.debatetimer.fixture.HeaderGenerator; import com.debatetimer.fixture.TokenGenerator; import com.debatetimer.fixture.entity.CustomizeTableEntityGenerator; import com.debatetimer.fixture.entity.CustomizeTimeBoxEntityGenerator; -import com.debatetimer.dto.poll.request.VoteRequest; -import com.debatetimer.fixture.CustomizeTableGenerator; -import com.debatetimer.fixture.CustomizeTimeBoxGenerator; -import com.debatetimer.fixture.HeaderGenerator; import com.debatetimer.fixture.entity.MemberGenerator; import com.debatetimer.fixture.entity.PollEntityGenerator; import com.debatetimer.fixture.entity.VoteEntityGenerator; diff --git a/src/test/java/com/debatetimer/controller/poll/VoteControllerTest.java b/src/test/java/com/debatetimer/controller/poll/VoteControllerTest.java index 06276c5b..19fe3fdd 100644 --- a/src/test/java/com/debatetimer/controller/poll/VoteControllerTest.java +++ b/src/test/java/com/debatetimer/controller/poll/VoteControllerTest.java @@ -28,11 +28,11 @@ class GetVotersPollInfo { @Test void 투표자가_선거정보를_조회할_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); - voteGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); + voteEntityGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); VoterPollInfoResponse response = given() .contentType(ContentType.JSON) @@ -60,9 +60,9 @@ class VotePoll { @Test void 진행_중인_선거에_최초로_투표_할_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); VoteRequest voteRequest = getVoteRequestBuilder().sample(); VoteCreateResponse response = given() @@ -84,9 +84,9 @@ class VotePoll { @NullAndEmptyAndBlankSource void 투표_시_이름은_널이거나_빈_문자열일_수_없다(String invalidName) { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); VoteRequest voteRequest = getVoteRequestBuilder() .set("name", invalidName) .sample(); @@ -102,9 +102,9 @@ class VotePoll { @Test void 투표_시_팀은_널일_수_없다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); VoteRequest voteRequest = getVoteRequestBuilder() .set("team", null) .sample(); @@ -121,9 +121,9 @@ class VotePoll { @NullAndEmptyAndBlankSource void 투표_시_참여코드는_널이거나_빈_문자열일_수_없다(String participateCode) { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); VoteRequest voteRequest = getVoteRequestBuilder() .set("participateCode", participateCode) .sample(); @@ -139,10 +139,10 @@ class VotePoll { @Test void 이미_참여한_선거에_투표_할_수_없다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); String participatecode = UUID.randomUUID().toString(); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리", participatecode); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리", participatecode); VoteRequest voteRequest = getVoteRequestBuilder() .set("participateCode", participatecode) .sample(); @@ -158,8 +158,8 @@ class VotePoll { @Test void 끝난_선거에_투표_할_수_없다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity alreadyDonePoll = pollGenerator.generate(table, PollStatus.DONE); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity alreadyDonePoll = pollEntityGenerator.generate(table, PollStatus.DONE); VoteRequest voteRequest = getVoteRequestBuilder().sample(); given() diff --git a/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java b/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java index 3c05199f..1aea13bb 100644 --- a/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java +++ b/src/test/java/com/debatetimer/domainrepository/poll/VoteDomainRepositoryTest.java @@ -54,11 +54,11 @@ class isExists { @Test void 이미_참여한_투표인지_알_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity alreadyParticipatedPoll = pollGenerator.generate(table, PollStatus.PROGRESS); - PollEntity notYetParticipatedPoll = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + PollEntity alreadyParticipatedPoll = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + PollEntity notYetParticipatedPoll = pollEntityGenerator.generate(table, PollStatus.PROGRESS); ParticipateCode participateCode = new ParticipateCode(UUID.randomUUID().toString()); - voteGenerator.generate(alreadyParticipatedPoll, VoteTeam.PROS, "콜리", participateCode.getValue()); + voteEntityGenerator.generate(alreadyParticipatedPoll, VoteTeam.PROS, "콜리", participateCode.getValue()); boolean participated = voteDomainRepository.isExists(alreadyParticipatedPoll.getId(), participateCode); boolean notYetParticipated = voteDomainRepository.isExists(notYetParticipatedPoll.getId(), @@ -77,8 +77,8 @@ class Save { @Test void 투표를_저장할_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); Vote vote = new Vote(pollEntity.getId(), VoteTeam.PROS, "콜리", UUID.randomUUID().toString()); Vote savedVote = voteDomainRepository.save(vote); @@ -93,10 +93,10 @@ class Save { @Test void 중복_투표할_수_없다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = tableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); String participateCode = UUID.randomUUID().toString(); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리", participateCode); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리", participateCode); Vote vote = new Vote(pollEntity.getId(), VoteTeam.PROS, "콜리", participateCode); assertThatThrownBy(() -> voteDomainRepository.save(vote)) diff --git a/src/test/java/com/debatetimer/service/poll/VoteServiceTest.java b/src/test/java/com/debatetimer/service/poll/VoteServiceTest.java index 52626c73..e2f26ecb 100644 --- a/src/test/java/com/debatetimer/service/poll/VoteServiceTest.java +++ b/src/test/java/com/debatetimer/service/poll/VoteServiceTest.java @@ -35,9 +35,9 @@ class Vote { @Test void 진행_중인_선거에_최초로_투표_할_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); String participateCode = UUID.randomUUID().toString(); VoteRequest voteRequest = new VoteRequest("콜리", participateCode, VoteTeam.PROS); @@ -53,10 +53,10 @@ class Vote { @Test void 이미_참여한_선거에_투표_할_수_없다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); String participateCode = UUID.randomUUID().toString(); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리", participateCode); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리", participateCode); VoteRequest voteRequest = new VoteRequest("콜리", participateCode, VoteTeam.PROS); assertThatThrownBy(() -> voteService.vote(pollEntity.getId(), voteRequest)) @@ -67,8 +67,8 @@ class Vote { @Test void 투표_동시성_이슈에_단일_표만_유효하게_취급한다() throws InterruptedException { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); String participateCode = UUID.randomUUID().toString(); VoteRequest voteRequest = new VoteRequest("콜리", participateCode, VoteTeam.PROS); @@ -81,8 +81,8 @@ class Vote { @Test void 끝난_선거에_투표_할_수_없다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity alreadyDonePoll = pollGenerator.generate(table, PollStatus.DONE); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity alreadyDonePoll = pollEntityGenerator.generate(table, PollStatus.DONE); String participateCode = UUID.randomUUID().toString(); VoteRequest voteRequest = new VoteRequest("콜리", participateCode, VoteTeam.PROS); @@ -98,11 +98,11 @@ class GetVoterPollInfo { @Test void 투표자가_선거정보를_조회할_수_있다() { Member member = memberGenerator.generate("email@email.com"); - CustomizeTableEntity table = customizeTableGenerator.generate(member); - PollEntity pollEntity = pollGenerator.generate(table, PollStatus.PROGRESS); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); - voteGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); - voteGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); + CustomizeTableEntity table = customizeTableEntityGenerator.generate(member); + PollEntity pollEntity = pollEntityGenerator.generate(table, PollStatus.PROGRESS); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "콜리"); + voteEntityGenerator.generate(pollEntity, VoteTeam.PROS, "비토"); + voteEntityGenerator.generate(pollEntity, VoteTeam.CONS, "커찬"); VoterPollInfoResponse response = voteService.getVoterPollInfo(pollEntity.getId()); From 981cd09e86518364d5af9d04beeaccde43467c42 Mon Sep 17 00:00:00 2001 From: unifolio0 Date: Thu, 31 Jul 2025 04:34:37 +0900 Subject: [PATCH 15/15] =?UTF-8?q?fix:=20rebase=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=B4=20=EC=A4=91=EB=B3=B5=EB=90=9C=20sql=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/db/migration/V12__add_bell_type_into_bell.sql | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 src/main/resources/db/migration/V12__add_bell_type_into_bell.sql diff --git a/src/main/resources/db/migration/V12__add_bell_type_into_bell.sql b/src/main/resources/db/migration/V12__add_bell_type_into_bell.sql deleted file mode 100644 index e2f1a133..00000000 --- a/src/main/resources/db/migration/V12__add_bell_type_into_bell.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE bell - ADD COLUMN bell_type enum ('AFTER_START','BEFORE_END','AFTER_END') NOT NULL