From 7e0836307d3cf885c2d362ccf1446e7b215db69c Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 01:00:14 +0900 Subject: [PATCH 01/11] =?UTF-8?q?Feat:=20=EC=A3=BC=EC=B0=A8=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20API=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20?= =?UTF-8?q?=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/VisitationController.java | 13 +++++++++ .../visitation/dto/VisitationRequest.java | 8 ++++++ .../service/VisitationFacadeService.java | 4 +++ .../controller/VisitationControllerTest.java | 27 +++++++++++++++++++ .../mock/MockRegisterParkingDto.java | 17 ++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 src/test/java/com/livable/server/visitation/mock/MockRegisterParkingDto.java diff --git a/src/main/java/com/livable/server/visitation/controller/VisitationController.java b/src/main/java/com/livable/server/visitation/controller/VisitationController.java index 33f61f8d..c413446e 100644 --- a/src/main/java/com/livable/server/visitation/controller/VisitationController.java +++ b/src/main/java/com/livable/server/visitation/controller/VisitationController.java @@ -9,6 +9,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import javax.validation.Valid; + @RequiredArgsConstructor @RestController @RequestMapping("/api/visitation") @@ -32,4 +34,15 @@ public ResponseEntity> validateQrCode(@RequestBody V return ApiResponse.success(HttpStatus.OK); } + + @PostMapping("/parking") + public ResponseEntity> registerParking( + @RequestBody @Valid VisitationRequest.RegisterParkingDto registerParkingDto + ) { + Long visitorId = 1L; + visitationFacadeService.registerParking(visitorId, registerParkingDto.getCarNumber()); + + return ApiResponse.success(HttpStatus.CREATED); + } + } diff --git a/src/main/java/com/livable/server/visitation/dto/VisitationRequest.java b/src/main/java/com/livable/server/visitation/dto/VisitationRequest.java index aa6c5c01..81c94ce5 100644 --- a/src/main/java/com/livable/server/visitation/dto/VisitationRequest.java +++ b/src/main/java/com/livable/server/visitation/dto/VisitationRequest.java @@ -4,6 +4,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import javax.validation.constraints.Pattern; + @NoArgsConstructor(access = AccessLevel.PRIVATE) public class VisitationRequest { @@ -11,4 +13,10 @@ public class VisitationRequest { public static class ValidateQrDto { private String qr; } + + @Getter + public static class RegisterParkingDto { + @Pattern(regexp = "^\\d{2,3}[가-힣]{1}\\d{4}$") + private String carNumber; + } } diff --git a/src/main/java/com/livable/server/visitation/service/VisitationFacadeService.java b/src/main/java/com/livable/server/visitation/service/VisitationFacadeService.java index c45e142b..cc0de8b8 100644 --- a/src/main/java/com/livable/server/visitation/service/VisitationFacadeService.java +++ b/src/main/java/com/livable/server/visitation/service/VisitationFacadeService.java @@ -25,4 +25,8 @@ public String createQrCode(Long visitorId) { public void validateQrCode(String qr) { visitationService.validateQrCode(qr); } + + public void registerParking(Long visitorId, String carNumber) { + + } } diff --git a/src/test/java/com/livable/server/visitation/controller/VisitationControllerTest.java b/src/test/java/com/livable/server/visitation/controller/VisitationControllerTest.java index 932044ce..237a48ce 100644 --- a/src/test/java/com/livable/server/visitation/controller/VisitationControllerTest.java +++ b/src/test/java/com/livable/server/visitation/controller/VisitationControllerTest.java @@ -5,6 +5,7 @@ import com.livable.server.core.exception.GlobalRuntimeException; import com.livable.server.visitation.domain.VisitationErrorCode; import com.livable.server.visitation.dto.VisitationRequest; +import com.livable.server.visitation.mock.MockRegisterParkingDto; import com.livable.server.visitation.mock.ValidateQrCodeSuccessMockRequest; import com.livable.server.visitation.service.VisitationFacadeService; import org.junit.jupiter.api.DisplayName; @@ -103,4 +104,30 @@ void validateQrCodeFail() throws Exception { then(visitationFacadeService).should(times(1)).validateQrCode(anyString()); } + + @DisplayName("[POST][/api/visitation/parking] - 차량 등록 성공") + @Test + void registerParking() throws Exception { + // given + String carNumber = "12가1234"; + MockRegisterParkingDto mockRegisterParkingDto = new MockRegisterParkingDto(carNumber); + Long visitorId = 1L; + + + willDoNothing().given(visitationFacadeService).registerParking(visitorId, mockRegisterParkingDto.getCarNumber()); + + // when + ResultActions resultActions = mockMvc.perform( + post("/api/visitation/parking") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(mockRegisterParkingDto)) + ); + + // then + resultActions.andExpect(status().isCreated()); + + then(visitationFacadeService) + .should(times(1)) + .registerParking(visitorId, mockRegisterParkingDto.getCarNumber()); + } } \ No newline at end of file diff --git a/src/test/java/com/livable/server/visitation/mock/MockRegisterParkingDto.java b/src/test/java/com/livable/server/visitation/mock/MockRegisterParkingDto.java new file mode 100644 index 00000000..fb70b815 --- /dev/null +++ b/src/test/java/com/livable/server/visitation/mock/MockRegisterParkingDto.java @@ -0,0 +1,17 @@ +package com.livable.server.visitation.mock; + +import com.livable.server.visitation.dto.VisitationRequest; + +public class MockRegisterParkingDto extends VisitationRequest.RegisterParkingDto { + + private final String carNumber; + + public MockRegisterParkingDto(String carNumber) { + this.carNumber = carNumber; + } + + @Override + public String getCarNumber() { + return carNumber; + } +} From 24ca67e516113b3674897dc5bd3259a6ea6deb7e Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 15:21:22 +0900 Subject: [PATCH 02/11] =?UTF-8?q?Test:=20=EC=A3=BC=EC=B0=A8=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EC=A0=95=EA=B7=9C=EC=8B=9D=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../visitation/dto/VisitationRequestTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/test/java/com/livable/server/visitation/dto/VisitationRequestTest.java diff --git a/src/test/java/com/livable/server/visitation/dto/VisitationRequestTest.java b/src/test/java/com/livable/server/visitation/dto/VisitationRequestTest.java new file mode 100644 index 00000000..fb8fd399 --- /dev/null +++ b/src/test/java/com/livable/server/visitation/dto/VisitationRequestTest.java @@ -0,0 +1,51 @@ +package com.livable.server.visitation.dto; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +import java.util.Set; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class VisitationRequestTest { + + private static ValidatorFactory factory; + private static Validator validator; + + private static ObjectMapper objectMapper = new ObjectMapper(); + + @BeforeAll + public static void init() { + factory = Validation.buildDefaultValidatorFactory(); + validator = factory.getValidator(); + } + + @DisplayName("VisitationRequest.RegisterParkingDto carNumber 정규식 성공 테스트") + @CsvSource({"12가1234", "12흫3456", "123핡0000"}) + @ParameterizedTest(name = "[{index}] 차량번호: {0}") + void carNumberPatternSuccessTest(String carNumber) throws JsonProcessingException { + String requestDto = "{\n" + + " \"carNumber\": \"" + carNumber + "\"\n" + + " }"; + + VisitationRequest.RegisterParkingDto registerParkingDto = + objectMapper.readValue(requestDto, VisitationRequest.RegisterParkingDto.class); + + Set> validate = validator.validate(registerParkingDto); + + assertThat(validate.size()).isEqualTo(0); + } +} \ No newline at end of file From 2ea012216e7df9d446bcee7d96e2e53d3acc90ba Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 15:21:48 +0900 Subject: [PATCH 03/11] =?UTF-8?q?Feat:=20ParkingLogRepository=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/ParkingLogRepository.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/com/livable/server/visitation/repository/ParkingLogRepository.java diff --git a/src/main/java/com/livable/server/visitation/repository/ParkingLogRepository.java b/src/main/java/com/livable/server/visitation/repository/ParkingLogRepository.java new file mode 100644 index 00000000..019495dd --- /dev/null +++ b/src/main/java/com/livable/server/visitation/repository/ParkingLogRepository.java @@ -0,0 +1,15 @@ +package com.livable.server.visitation.repository; + +import com.livable.server.entity.ParkingLog; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.Optional; + +public interface ParkingLogRepository extends JpaRepository { + + @Query("select p from ParkingLog p" + + " where p.visitor.id = :visitorId") + Optional findParkingLogByVisitorId(@Param("visitorId") Long visitorId); +} From 67f74209e9b076859621551eda7b96c887e40876 Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 15:22:06 +0900 Subject: [PATCH 04/11] =?UTF-8?q?Test:=20ParkingLogRepository=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EA=B5=AC=ED=98=84=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 작성한 JPQL 쿼리 테스트 --- .../repository/ParkingLogRepositoryTest.java | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/test/java/com/livable/server/visitation/repository/ParkingLogRepositoryTest.java diff --git a/src/test/java/com/livable/server/visitation/repository/ParkingLogRepositoryTest.java b/src/test/java/com/livable/server/visitation/repository/ParkingLogRepositoryTest.java new file mode 100644 index 00000000..3be1a726 --- /dev/null +++ b/src/test/java/com/livable/server/visitation/repository/ParkingLogRepositoryTest.java @@ -0,0 +1,118 @@ +package com.livable.server.visitation.repository; + +import com.livable.server.core.config.QueryDslConfig; +import com.livable.server.entity.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; + +import javax.persistence.EntityManager; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Optional; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +@DataJpaTest +@Import(QueryDslConfig.class) +class ParkingLogRepositoryTest { + + public static final LocalDate START_DATE = LocalDate.now(); + public static final LocalTime START_TIME = LocalTime.of(1, 10); + public static final LocalTime END_TIME = LocalTime.of(1, 20); + public static final LocalDate END_DATE = LocalDate.now(); + + @Autowired + ParkingLogRepository parkingLogRepository; + + @Autowired + VisitorRepository visitorRepository; + + @Autowired + EntityManager entityManager; + + @BeforeEach + void dataInit() { + Building building = Building.builder() + .name("63빌딩") + .scale("지하 3층, 지상 63층") + .representativeImageUrl("./thumbnailImage.jpg") + .endTime(LocalTime.of(10, 30)) + .startTime(LocalTime.of(18, 30)) + .parkingCostInformation("10분당 1000원") + .longitude("10.10.10.10") + .latitude("123.123.123") + .hasCafeteria(false) + .address("서울시 강남구 서초대로 61길 7, 392") + .subwayStation("석촌역") + .build(); + + entityManager.persist(building); + + Company company = Company.builder() + .name("패스트캠퍼스") + .building(building) + .build(); + + entityManager.persist(company); + + Member member = Member.builder() + .company(company) + .contact("01012345678") + .name("김훈섭") + .email("test@naver.com") + .employeeNumber("9q0mavfdmmpoaskp") + .profileImageUrl("./profileImageUrl") + .password("1234") + .role(Role.USER) + .build(); + + entityManager.persist(member); + + Invitation invitation = Invitation.builder() + .member(member) + .endDate(END_DATE) + .startDate(START_DATE) + .startTime(START_TIME) + .endTime(END_TIME) + .description("알아서 와") + .purpose("INTERVIEW") + .officeName("패스트캠퍼스 사무실") + .build(); + + entityManager.persist(invitation); + + Visitor visitor = Visitor.builder() + .invitation(invitation) + .name("최태윤") + .contact("01034567811") + .build(); + + entityManager.persist(visitor); + + ParkingLog parkingLog = ParkingLog.builder() + .visitor(visitor) + .carNumber("12가1234") + .build(); + + entityManager.persist(parkingLog); + } + + @DisplayName("ParkingLogRepository.findParkingLogByVisitorId 쿼리 확인용 테스트") + @Test + void test() { + ParkingLog parkingLog = parkingLogRepository.findParkingLogByVisitorId(1L).get(); + Visitor visitor = visitorRepository.findById(1L).get(); + + assertAll( + () -> assertThat(parkingLog.getId()).isEqualTo(1L), + () -> assertThat(parkingLog.getVisitor()).isEqualTo(visitor), + () -> assertThat(parkingLog.getCarNumber()).isEqualTo("12가1234") + ); + } +} \ No newline at end of file From 25b9ab7930009b4f08f90e823993c1c364edd3bd Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 15:26:30 +0900 Subject: [PATCH 05/11] =?UTF-8?q?Modify:=20ParkingLog=EC=97=90=20Visitor?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20=EB=A7=A4=ED=95=91=20=EC=96=B4?= =?UTF-8?q?=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=88=98=EC=A0=95=20(#2?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @ManyToOne -> @OneToOne --- src/main/java/com/livable/server/entity/ParkingLog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/livable/server/entity/ParkingLog.java b/src/main/java/com/livable/server/entity/ParkingLog.java index 044ea298..4bf5b9a7 100644 --- a/src/main/java/com/livable/server/entity/ParkingLog.java +++ b/src/main/java/com/livable/server/entity/ParkingLog.java @@ -17,7 +17,7 @@ public class ParkingLog extends BaseTimeEntity { private Long id; @JoinColumn(nullable = false, unique = true) - @ManyToOne(fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.LAZY) private Visitor visitor; @Column(nullable = false) From 7d3accbeb95343eca4a199b9d038e5151a769c42 Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 15:26:58 +0900 Subject: [PATCH 06/11] =?UTF-8?q?Feat:=20=EC=A3=BC=EC=B0=A8=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/VisitationErrorCode.java | 3 +- .../visitation/service/ParkingLogService.java | 29 +++++++++++++++++++ .../service/VisitationFacadeService.java | 16 ++++++++++ .../visitation/service/VisitorService.java | 6 ++++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/livable/server/visitation/service/ParkingLogService.java diff --git a/src/main/java/com/livable/server/visitation/domain/VisitationErrorCode.java b/src/main/java/com/livable/server/visitation/domain/VisitationErrorCode.java index 43388cfb..a66bf63e 100644 --- a/src/main/java/com/livable/server/visitation/domain/VisitationErrorCode.java +++ b/src/main/java/com/livable/server/visitation/domain/VisitationErrorCode.java @@ -15,7 +15,8 @@ public enum VisitationErrorCode implements ErrorCode { IO(HttpStatus.INTERNAL_SERVER_ERROR, "I/O를 진행하는 과정에서 알 수 없는 에러가 발생했습니다."), INVALID_QR_PERIOD(HttpStatus.BAD_REQUEST, "QR을 생성할 수 없는 시간입니다."), INVALID_PERIOD(HttpStatus.BAD_REQUEST, "시작 및 종료시간이 올바르지 않습니다."), - NOT_FOUND(HttpStatus.BAD_REQUEST, "존재하지 않는 정보입니다."); + NOT_FOUND(HttpStatus.BAD_REQUEST, "존재하지 않는 정보입니다."), + ALREADY_REGISTER_PARKING(HttpStatus.BAD_REQUEST, "이미 주차 등록을 완료하였습니다."); private final HttpStatus httpStatus; diff --git a/src/main/java/com/livable/server/visitation/service/ParkingLogService.java b/src/main/java/com/livable/server/visitation/service/ParkingLogService.java new file mode 100644 index 00000000..9382a9df --- /dev/null +++ b/src/main/java/com/livable/server/visitation/service/ParkingLogService.java @@ -0,0 +1,29 @@ +package com.livable.server.visitation.service; + +import com.livable.server.entity.ParkingLog; +import com.livable.server.entity.Visitor; +import com.livable.server.visitation.repository.ParkingLogRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@RequiredArgsConstructor +@Service +public class ParkingLogService { + + private final ParkingLogRepository parkingLogRepository; + + public Optional findParkingLogByVisitorId(Long visitorId) { + return parkingLogRepository.findParkingLogByVisitorId(visitorId); + } + + public void registerParkingLog(Visitor visitor, String carNumber) { + ParkingLog parkingLog = ParkingLog.builder() + .carNumber(carNumber) + .visitor(visitor) + .build(); + + parkingLogRepository.save(parkingLog); + } +} diff --git a/src/main/java/com/livable/server/visitation/service/VisitationFacadeService.java b/src/main/java/com/livable/server/visitation/service/VisitationFacadeService.java index cc0de8b8..e513f832 100644 --- a/src/main/java/com/livable/server/visitation/service/VisitationFacadeService.java +++ b/src/main/java/com/livable/server/visitation/service/VisitationFacadeService.java @@ -1,11 +1,17 @@ package com.livable.server.visitation.service; +import com.livable.server.core.exception.GlobalRuntimeException; +import com.livable.server.entity.ParkingLog; +import com.livable.server.entity.Visitor; import com.livable.server.invitation.service.InvitationService; +import com.livable.server.visitation.domain.VisitationErrorCode; import com.livable.server.visitation.dto.VisitationResponse; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + @RequiredArgsConstructor @Service @Transactional(readOnly = true) @@ -14,6 +20,7 @@ public class VisitationFacadeService { private final VisitationService visitationService; private final InvitationService invitationService; private final VisitorService visitorService; + private final ParkingLogService parkingLogService; public String createQrCode(Long visitorId) { Long invitationId = visitorService.findInvitationId(visitorId); @@ -26,7 +33,16 @@ public void validateQrCode(String qr) { visitationService.validateQrCode(qr); } + @Transactional public void registerParking(Long visitorId, String carNumber) { + validateDuplicationRegister(visitorId); + Visitor visitor = visitorService.findById(visitorId); + parkingLogService.registerParkingLog(visitor, carNumber); + } + private void validateDuplicationRegister(Long visitorId) { + if (parkingLogService.findParkingLogByVisitorId(visitorId).isPresent()) { + throw new GlobalRuntimeException(VisitationErrorCode.ALREADY_REGISTER_PARKING); + } } } diff --git a/src/main/java/com/livable/server/visitation/service/VisitorService.java b/src/main/java/com/livable/server/visitation/service/VisitorService.java index 0084daa5..da55c4c3 100644 --- a/src/main/java/com/livable/server/visitation/service/VisitorService.java +++ b/src/main/java/com/livable/server/visitation/service/VisitorService.java @@ -1,6 +1,7 @@ package com.livable.server.visitation.service; import com.livable.server.core.exception.GlobalRuntimeException; +import com.livable.server.entity.Visitor; import com.livable.server.visitation.domain.VisitationErrorCode; import com.livable.server.visitation.repository.VisitorRepository; import lombok.RequiredArgsConstructor; @@ -18,4 +19,9 @@ public Long findInvitationId(Long visitorId) { .getInvitation() .getId(); } + + public Visitor findById(Long visitorId) { + return visitorRepository.findById(visitorId) + .orElseThrow(() -> new GlobalRuntimeException(VisitationErrorCode.NOT_FOUND)); + } } From f6b66b7fb71b1fb2be9170abd3825f1cadb5dbd3 Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 15:38:31 +0900 Subject: [PATCH 07/11] =?UTF-8?q?Test:=20VisitationFacadeService.registerP?= =?UTF-8?q?arking=20=EC=84=B1=EA=B3=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/VisitationFacadeServiceTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/test/java/com/livable/server/visitation/service/VisitationFacadeServiceTest.java b/src/test/java/com/livable/server/visitation/service/VisitationFacadeServiceTest.java index 2cb55a4a..56626cd6 100644 --- a/src/test/java/com/livable/server/visitation/service/VisitationFacadeServiceTest.java +++ b/src/test/java/com/livable/server/visitation/service/VisitationFacadeServiceTest.java @@ -1,5 +1,6 @@ package com.livable.server.visitation.service; +import com.livable.server.entity.Visitor; import com.livable.server.invitation.service.InvitationService; import com.livable.server.visitation.dto.VisitationResponse; import org.junit.jupiter.api.DisplayName; @@ -12,6 +13,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.util.Optional; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; import static org.junit.jupiter.api.Assertions.*; @@ -30,11 +32,16 @@ class VisitationFacadeServiceTest { @Mock VisitationService visitationService; + @Mock InvitationService invitationService; + @Mock VisitorService visitorService; + @Mock + ParkingLogService parkingLogService; + @DisplayName("VisitationFacadeService.createQrCode 성공 테스트") @Test void createQrCodeSuccessTest() { @@ -73,4 +80,24 @@ void validateQrCodeSuccessTest() { // Then then(visitationService).should(times(1)).validateQrCode(anyString()); } + + @DisplayName("VisitationFacadeService.registerParking 성공 테스트") + @Test + void registerParkingSuccessTest() { + // Given + Visitor visitor = Visitor.builder() + .id(1L) + .build(); + given(visitorService.findById(anyLong())).willReturn(visitor); + given(parkingLogService.findParkingLogByVisitorId(any())).willReturn(Optional.empty()); + willDoNothing().given(parkingLogService).registerParkingLog(any(), anyString()); + + // When + visitationFacadeService.registerParking(visitor.getId(), "12가1234"); + + // Then + then(visitorService).should(times(1)).findById(anyLong()); + then(parkingLogService).should(times(1)).findParkingLogByVisitorId(any()); + then(parkingLogService).should(times(1)).registerParkingLog(any(), anyString()); + } } \ No newline at end of file From 35ba3be9b9a51dfeca8617d07b9cdfbd6e455592 Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 15:42:37 +0900 Subject: [PATCH 08/11] =?UTF-8?q?Test:=20VisitationFacadeService.registerP?= =?UTF-8?q?arking=20=EC=8B=A4=ED=8C=A8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/VisitationFacadeServiceTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/test/java/com/livable/server/visitation/service/VisitationFacadeServiceTest.java b/src/test/java/com/livable/server/visitation/service/VisitationFacadeServiceTest.java index 56626cd6..a102032c 100644 --- a/src/test/java/com/livable/server/visitation/service/VisitationFacadeServiceTest.java +++ b/src/test/java/com/livable/server/visitation/service/VisitationFacadeServiceTest.java @@ -1,7 +1,11 @@ package com.livable.server.visitation.service; +import com.livable.server.core.exception.GlobalRuntimeException; +import com.livable.server.entity.ParkingLog; import com.livable.server.entity.Visitor; +import com.livable.server.invitation.domain.InvitationErrorCode; import com.livable.server.invitation.service.InvitationService; +import com.livable.server.visitation.domain.VisitationErrorCode; import com.livable.server.visitation.dto.VisitationResponse; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -100,4 +104,23 @@ void registerParkingSuccessTest() { then(parkingLogService).should(times(1)).findParkingLogByVisitorId(any()); then(parkingLogService).should(times(1)).registerParkingLog(any(), anyString()); } + + @DisplayName("VisitationFacadeService.registerParking 실패 테스트") + @Test + void registerParkingFailTest() { + // Given + ParkingLog parkingLog = ParkingLog.builder() + .build(); + given(parkingLogService.findParkingLogByVisitorId(any())).willReturn(Optional.of(parkingLog)); + + // When + GlobalRuntimeException globalRuntimeException = assertThrows( + GlobalRuntimeException.class, + () -> visitationFacadeService.registerParking(any(), "12가1234") + ); + + // Then + then(parkingLogService).should(times(1)).findParkingLogByVisitorId(any()); + assertThat(globalRuntimeException.getErrorCode()).isEqualTo(VisitationErrorCode.ALREADY_REGISTER_PARKING); + } } \ No newline at end of file From 94062d6f6fb1e04a557a659a2b6cd9b21a72ab6f Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 16:07:55 +0900 Subject: [PATCH 09/11] =?UTF-8?q?Test:=20ParkingLogService.findParkingLogB?= =?UTF-8?q?yVisitorId=20=EC=84=B1=EA=B3=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ParkingLogServiceTest.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/test/java/com/livable/server/visitation/service/ParkingLogServiceTest.java diff --git a/src/test/java/com/livable/server/visitation/service/ParkingLogServiceTest.java b/src/test/java/com/livable/server/visitation/service/ParkingLogServiceTest.java new file mode 100644 index 00000000..ae5b0504 --- /dev/null +++ b/src/test/java/com/livable/server/visitation/service/ParkingLogServiceTest.java @@ -0,0 +1,48 @@ +package com.livable.server.visitation.service; + +import com.livable.server.entity.ParkingLog; +import com.livable.server.visitation.repository.ParkingLogRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Optional; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.times; + +@ExtendWith(MockitoExtension.class) +class ParkingLogServiceTest { + + @InjectMocks + ParkingLogService parkingLogService; + + @Mock + ParkingLogRepository parkingLogRepository; + + @DisplayName("ParkingLogService.findParkingLogByVisitorId 성공 테스트") + @Test + void findParkingLogByVisitorIdSuccessTest() { + + // Given + ParkingLog parkingLog = ParkingLog.builder() + .build(); + + Optional expectedOptionalParkingLog = Optional.of(parkingLog); + + given(parkingLogRepository.findParkingLogByVisitorId(anyLong())).willReturn(Optional.of(parkingLog)); + + // When + Optional optionalParkingLog = parkingLogService.findParkingLogByVisitorId(1L); + + // Then + assertThat(optionalParkingLog).isEqualTo(expectedOptionalParkingLog); + then(parkingLogRepository).should(times(1)).findParkingLogByVisitorId(anyLong()); + } +} \ No newline at end of file From 12ce82f2a9a075fa44ebbf27f5f9e310a3945892 Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 16:11:59 +0900 Subject: [PATCH 10/11] =?UTF-8?q?Test:=20ParkingLogService.registerParking?= =?UTF-8?q?Log=20=EC=84=B1=EA=B3=B5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ParkingLogServiceTest.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/livable/server/visitation/service/ParkingLogServiceTest.java b/src/test/java/com/livable/server/visitation/service/ParkingLogServiceTest.java index ae5b0504..9d573cf0 100644 --- a/src/test/java/com/livable/server/visitation/service/ParkingLogServiceTest.java +++ b/src/test/java/com/livable/server/visitation/service/ParkingLogServiceTest.java @@ -1,6 +1,7 @@ package com.livable.server.visitation.service; import com.livable.server.entity.ParkingLog; +import com.livable.server.entity.Visitor; import com.livable.server.visitation.repository.ParkingLogRepository; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -13,8 +14,7 @@ import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.then; +import static org.mockito.BDDMockito.*; import static org.mockito.Mockito.times; @ExtendWith(MockitoExtension.class) @@ -45,4 +45,25 @@ void findParkingLogByVisitorIdSuccessTest() { assertThat(optionalParkingLog).isEqualTo(expectedOptionalParkingLog); then(parkingLogRepository).should(times(1)).findParkingLogByVisitorId(anyLong()); } + + @DisplayName("ParkingLogService.registerParkingLog 성공 테스트") + @Test + void registerParkingLogSuccessTest() { + ParkingLog parkingLog = ParkingLog.builder() + .build(); + + Visitor visitor = Visitor.builder() + .build(); + + String carNumber = "testCarNumber"; + + // Given + given(parkingLogRepository.save(any())).willReturn(parkingLog); + + // When + parkingLogService.registerParkingLog(visitor, carNumber); + + // Then + then(parkingLogRepository).should(times(1)).save(any()); + } } \ No newline at end of file From 364fc6d29fcd7df2e2fcc137f3f6adfd0b39f582 Mon Sep 17 00:00:00 2001 From: cxxxtxxyxx Date: Tue, 19 Sep 2023 16:23:21 +0900 Subject: [PATCH 11/11] =?UTF-8?q?Feat:=20Validation=20Error=20Message=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../invitation/domain/InvitationValidationGuideMessage.java | 6 ++++++ .../livable/server/visitation/dto/VisitationRequest.java | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/livable/server/invitation/domain/InvitationValidationGuideMessage.java diff --git a/src/main/java/com/livable/server/invitation/domain/InvitationValidationGuideMessage.java b/src/main/java/com/livable/server/invitation/domain/InvitationValidationGuideMessage.java new file mode 100644 index 00000000..6f8df1ec --- /dev/null +++ b/src/main/java/com/livable/server/invitation/domain/InvitationValidationGuideMessage.java @@ -0,0 +1,6 @@ +package com.livable.server.invitation.domain; + +public interface InvitationValidationGuideMessage { + + String INVALID_CAR_NUMBER = "차량 번호를 올바르게 입력해 주세요."; +} diff --git a/src/main/java/com/livable/server/visitation/dto/VisitationRequest.java b/src/main/java/com/livable/server/visitation/dto/VisitationRequest.java index 81c94ce5..6ea73d65 100644 --- a/src/main/java/com/livable/server/visitation/dto/VisitationRequest.java +++ b/src/main/java/com/livable/server/visitation/dto/VisitationRequest.java @@ -1,5 +1,6 @@ package com.livable.server.visitation.dto; +import com.livable.server.invitation.domain.InvitationValidationGuideMessage; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @@ -16,7 +17,7 @@ public static class ValidateQrDto { @Getter public static class RegisterParkingDto { - @Pattern(regexp = "^\\d{2,3}[가-힣]{1}\\d{4}$") + @Pattern(regexp = "^\\d{2,3}[가-힣]{1}\\d{4}$", message = InvitationValidationGuideMessage.INVALID_CAR_NUMBER) private String carNumber; } }