From ea098891e4fb450d3c64eb3c965febc827551bfe Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Wed, 29 May 2024 16:56:42 +0900 Subject: [PATCH 01/79] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=97=90=20tok?= =?UTF-8?q?en=20=EA=B0=92=EB=8F=84=20=EC=B6=9C=EB=A0=A5=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../playkuroundserver/global/security/LoggingFilter.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java b/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java index a849e9d..514553b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java @@ -5,6 +5,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; @@ -17,7 +18,12 @@ private static void logRequest(HttpServletRequest request) { return; } String queryString = request.getQueryString(); - log.info("Request : {} uri=[{}] content-type=[{}]", request.getMethod(), queryString == null ? request.getRequestURI() : request.getRequestURI() + queryString, request.getContentType()); + String bearerToken = request.getHeader(HttpHeaders.AUTHORIZATION); + log.info("Request : {} uri=[{}] content-type=[{}] token=[{}]", + request.getMethod(), + queryString == null ? request.getRequestURI() : request.getRequestURI() + queryString, + request.getContentType(), + bearerToken); } @Override From f9e053556dbf1039b8355911d93ae0374c996f8c Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Thu, 30 May 2024 12:02:14 +0900 Subject: [PATCH 02/79] feat: logback config file --- src/main/resources/logback-spring.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index f6b1aa0..9f98186 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -42,15 +42,12 @@ - - ${LOG_PATH}/${LOG_FILE_NAME}_${BY_DATE}.log - ${FILE_LOG_PATTERN} - ${LOG_PATH}/archive/${LOG_FILE_NAME}.%d{yyyy-MM-dd}.log + ${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}.log ${LOG_MAX_HISTORY} ${LOG_TOTAL_SIZE_CAP} @@ -89,6 +86,10 @@ + + + \ No newline at end of file From 839d456d1a8a28267d7fa603653f2f6ddf5fdc5e Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Thu, 30 May 2024 12:10:09 +0900 Subject: [PATCH 03/79] =?UTF-8?q?feat:=20health=20check=20=EC=A3=BC?= =?UTF-8?q?=EC=86=8C=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=A1=9C=EA=B9=85?= =?UTF-8?q?=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/systemcheck/api/SystemCheckApi.java | 6 +++--- .../playkuroundserver/global/config/WebSecurityConfig.java | 2 +- .../playkuroundserver/global/security/LoggingFilter.java | 3 ++- .../domain/systemcheck/api/SystemCheckApiTest.java | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java index 55f2f9e..3fa81c8 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java @@ -11,21 +11,21 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping("/api/admin/system-available") +@RequestMapping("api") @RequiredArgsConstructor @Tag(name = "System Check") public class SystemCheckApi { private final SystemCheckService systemCheckService; - @PostMapping + @PostMapping("/admin/system-available") @Operation(summary = "시스템 사용가능 여부 변경하기", description = "시스템 점검 유무를 변경합니다.") public ApiResponse changeSystemAvailable(@RequestParam("available") boolean appVersion) { systemCheckService.changeSystemAvailable(appVersion); return ApiUtils.success(null); } - @GetMapping + @GetMapping("/system-available") @Operation(summary = "시스템 사용가능 여부 체크", description = "현재 서버의 상태를 점검합니다.") public ApiResponse healthCheck() { HealthCheckDto healthCheckDto = systemCheckService.healthCheck(); diff --git a/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java b/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java index 162f98f..cd67535 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java @@ -49,7 +49,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/swagger-ui/**"), AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/swagger-ui.html"), AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api-docs/**"), - AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api/admin/system-available"), + AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api/system-available"), AntPathRequestMatcher.antMatcher("/actu/**") ).permitAll() .requestMatchers( diff --git a/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java b/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java index 514553b..9722ec4 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java @@ -14,7 +14,8 @@ public class LoggingFilter extends OncePerRequestFilter { private static void logRequest(HttpServletRequest request) { - if (request.getRequestURI() != null && request.getRequestURI().contains("/prometheus")) { + if (request.getRequestURI() != null && + (request.getRequestURI().contains("/prometheus") || request.getRequestURI().equals("/api/system-available"))) { return; } String queryString = request.getQueryString(); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApiTest.java index 02b9535..7acc5cf 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApiTest.java @@ -108,7 +108,7 @@ void success_1() throws Exception { appVersionRepository.save(new AppVersion(OperationSystem.IOS, "1.0.2")); // expect - MvcResult mvcResult = mockMvc.perform(get("/api/admin/system-available")) + MvcResult mvcResult = mockMvc.perform(get("/api/system-available")) .andExpect(status().isOk()) .andDo(print()) .andReturn(); @@ -135,7 +135,7 @@ void success_2() throws Exception { appVersionRepository.save(new AppVersion(OperationSystem.ANDROID, "1.0.1")); // expect - MvcResult mvcResult = mockMvc.perform(get("/api/admin/system-available")) + MvcResult mvcResult = mockMvc.perform(get("/api/system-available")) .andExpect(status().isOk()) .andDo(print()) .andReturn(); From 5b91216d1024ecdc987c5ea1e35e9d3f02caaa3b Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 28 Jun 2024 18:59:44 +0900 Subject: [PATCH 04/79] refactor: learning test refactor --- .../PlaykuroundServerApplicationTests.java | 13 ---- .../beanValidation/ValidationTest.java | 65 ------------------- .../domain/badge/api/BadgeApiTest.java | 8 +++ .../beanValidation/ConstructAnnotation.java} | 6 +- .../beanValidation/FieldAnnotation.java} | 6 +- .../LombokNotNullInConstructor.java} | 12 ++-- .../beanValidation/ValidationTest.java | 65 +++++++++++++++++++ .../{ => learning/java}/JavaTest.java | 2 +- .../{ => learning/redis}/RedisTest.java | 4 +- .../code => learning/reflection}/Domain.java | 16 ++--- .../reflection/ReflectionTest.java | 64 ++++++++---------- .../PersistenceController.java | 4 +- .../PersistenceService.java | 6 +- .../SecurityPersistenceTest.java} | 31 +++++---- 14 files changed, 148 insertions(+), 154 deletions(-) delete mode 100644 src/test/java/com/playkuround/playkuroundserver/PlaykuroundServerApplicationTests.java delete mode 100644 src/test/java/com/playkuround/playkuroundserver/beanValidation/ValidationTest.java rename src/test/java/com/playkuround/playkuroundserver/{beanValidation/code/UserConstruct.java => learning/beanValidation/ConstructAnnotation.java} (77%) rename src/test/java/com/playkuround/playkuroundserver/{beanValidation/code/UserField.java => learning/beanValidation/FieldAnnotation.java} (81%) rename src/test/java/com/playkuround/playkuroundserver/{beanValidation/code/UserConstruct2.java => learning/beanValidation/LombokNotNullInConstructor.java} (59%) create mode 100644 src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/ValidationTest.java rename src/test/java/com/playkuround/playkuroundserver/{ => learning/java}/JavaTest.java (92%) rename src/test/java/com/playkuround/playkuroundserver/{ => learning/redis}/RedisTest.java (98%) rename src/test/java/com/playkuround/playkuroundserver/{reflection/code => learning/reflection}/Domain.java (56%) rename src/test/java/com/playkuround/playkuroundserver/{ => learning}/reflection/ReflectionTest.java (50%) rename src/test/java/com/playkuround/playkuroundserver/{securityPersistence/code => learning/securityPersistence}/PersistenceController.java (88%) rename src/test/java/com/playkuround/playkuroundserver/{securityPersistence/code => learning/securityPersistence}/PersistenceService.java (84%) rename src/test/java/com/playkuround/playkuroundserver/{securityPersistence/PersistenceTest.java => learning/securityPersistence/SecurityPersistenceTest.java} (76%) diff --git a/src/test/java/com/playkuround/playkuroundserver/PlaykuroundServerApplicationTests.java b/src/test/java/com/playkuround/playkuroundserver/PlaykuroundServerApplicationTests.java deleted file mode 100644 index 1a97496..0000000 --- a/src/test/java/com/playkuround/playkuroundserver/PlaykuroundServerApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.playkuround.playkuroundserver; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest(properties = "spring.profiles.active=test") -class PlaykuroundServerApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/src/test/java/com/playkuround/playkuroundserver/beanValidation/ValidationTest.java b/src/test/java/com/playkuround/playkuroundserver/beanValidation/ValidationTest.java deleted file mode 100644 index 85da162..0000000 --- a/src/test/java/com/playkuround/playkuroundserver/beanValidation/ValidationTest.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.playkuround.playkuroundserver.beanValidation; - -import com.playkuround.playkuroundserver.beanValidation.code.UserConstruct; -import com.playkuround.playkuroundserver.beanValidation.code.UserConstruct2; -import com.playkuround.playkuroundserver.beanValidation.code.UserField; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.validation.ConstraintViolationException; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -@Disabled -@SpringBootTest(properties = "spring.profiles.active=test") -public class ValidationTest { - - @Autowired - private EntityManagerFactory emf; - - @Test - @DisplayName("필드에 직접 어노테이션을 붙이면, 검증은 persist 과정에서 수행된다.") - void testField() { - EntityManager em = emf.createEntityManager(); - em.getTransaction().begin(); - - UserField userField = new UserField("", -1); - - assertThatThrownBy(() -> { - em.persist(userField); - }).isInstanceOf(ConstraintViolationException.class); - } - - @Test - @DisplayName("validate 메서드를 별도로 호출하지 않는한, 생성자 인수의 애노테이션은 작동하지 않는다.") - void testConstruct() { - EntityManager em = emf.createEntityManager(); - em.getTransaction().begin(); - - UserConstruct userField = new UserConstruct("", -1); - - em.persist(userField); - em.getTransaction().commit(); - } - - @Test - @DisplayName("생성자 인수에 @NonNull(lombok)을 붙이면, 검증은 생성자 호출 시점에 수행된다.") - void testConstructNonnull() { - - assertThatThrownBy(() -> { - new UserConstruct2(null, -1); - }).isInstanceOf(NullPointerException.class); - - - assertThatThrownBy(() -> { - UserConstruct2.builder() - .name(null) - .age(-1) - .build(); - }).isInstanceOf(NullPointerException.class); - } -} diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java index 940ea13..92b584b 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java @@ -11,8 +11,11 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; import org.springframework.test.web.servlet.MockMvc; import java.util.List; @@ -27,6 +30,11 @@ @AutoConfigureMockMvc @SpringBootTest(properties = "spring.profiles.active=test") +@ComponentScan(basePackages = {"com.playkuround.playkuroundserver.domain"}, + excludeFilters = { + @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.playkuround.playkuroundserver.learning.*") + }) +@EntityScan(basePackages = {"com.playkuround.playkuroundserver.domain"}) class BadgeApiTest { @Autowired diff --git a/src/test/java/com/playkuround/playkuroundserver/beanValidation/code/UserConstruct.java b/src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/ConstructAnnotation.java similarity index 77% rename from src/test/java/com/playkuround/playkuroundserver/beanValidation/code/UserConstruct.java rename to src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/ConstructAnnotation.java index dbca2d3..8075338 100644 --- a/src/test/java/com/playkuround/playkuroundserver/beanValidation/code/UserConstruct.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/ConstructAnnotation.java @@ -1,4 +1,4 @@ -package com.playkuround.playkuroundserver.beanValidation.code; +package com.playkuround.playkuroundserver.learning.beanValidation; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -13,7 +13,7 @@ @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class UserConstruct { +class ConstructAnnotation { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -21,7 +21,7 @@ public class UserConstruct { private String name; private int age; - public UserConstruct(@NotBlank String name, @Min(0) int age) { + public ConstructAnnotation(@NotBlank String name, @Min(0) int age) { this.name = name; this.age = age; } diff --git a/src/test/java/com/playkuround/playkuroundserver/beanValidation/code/UserField.java b/src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/FieldAnnotation.java similarity index 81% rename from src/test/java/com/playkuround/playkuroundserver/beanValidation/code/UserField.java rename to src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/FieldAnnotation.java index 6f607c7..f6e6eef 100644 --- a/src/test/java/com/playkuround/playkuroundserver/beanValidation/code/UserField.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/FieldAnnotation.java @@ -1,4 +1,4 @@ -package com.playkuround.playkuroundserver.beanValidation.code; +package com.playkuround.playkuroundserver.learning.beanValidation; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -13,7 +13,7 @@ @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class UserField { +class FieldAnnotation { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -25,7 +25,7 @@ public class UserField { @Min(0) private int age; - public UserField(String name, int age) { + public FieldAnnotation(String name, int age) { this.name = name; this.age = age; } diff --git a/src/test/java/com/playkuround/playkuroundserver/beanValidation/code/UserConstruct2.java b/src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/LombokNotNullInConstructor.java similarity index 59% rename from src/test/java/com/playkuround/playkuroundserver/beanValidation/code/UserConstruct2.java rename to src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/LombokNotNullInConstructor.java index 81e882a..a6e5acf 100644 --- a/src/test/java/com/playkuround/playkuroundserver/beanValidation/code/UserConstruct2.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/LombokNotNullInConstructor.java @@ -1,15 +1,18 @@ -package com.playkuround.playkuroundserver.beanValidation.code; +package com.playkuround.playkuroundserver.learning.beanValidation; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import lombok.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class UserConstruct2 { +class LombokNotNullInConstructor { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -17,8 +20,7 @@ public class UserConstruct2 { private String name; private int age; - @Builder - public UserConstruct2(@NonNull String name, int age) { + public LombokNotNullInConstructor(@NonNull String name, int age) { this.name = name; this.age = age; } diff --git a/src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/ValidationTest.java b/src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/ValidationTest.java new file mode 100644 index 0000000..8ef7934 --- /dev/null +++ b/src/test/java/com/playkuround/playkuroundserver/learning/beanValidation/ValidationTest.java @@ -0,0 +1,65 @@ +package com.playkuround.playkuroundserver.learning.beanValidation; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.validation.ConstraintViolationException; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.List; + +import static org.assertj.core.api.Assertions.*; + +@Disabled +@DisplayName("Bean Validation 및 lombok NonNull 테스트") +@SpringBootTest(properties = "spring.profiles.active=test") +public class ValidationTest { + + @Autowired + private EntityManagerFactory emf; + + @Test + @DisplayName("필드에 직접 애노테이션을 붙이면, 검증은 persist 과정에서 수행된다.") + void fieldAnnotation() { + // given + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + + // expected + FieldAnnotation fieldAnnotation = new FieldAnnotation("", -1); + assertThatThrownBy(() -> em.persist(fieldAnnotation)) + .isInstanceOf(ConstraintViolationException.class); + } + + @Test + @DisplayName("생성자 파라미터의 bean validation 애노테이션은 작동하지 않는다.") + void constructAnnotation() { + // given + EntityManager em = emf.createEntityManager(); + em.getTransaction().begin(); + + // when + ConstructAnnotation constructAnnotation = new ConstructAnnotation("", -1); + em.persist(constructAnnotation); + em.getTransaction().commit(); + + // when + List resultList = + em.createQuery("select c from ConstructAnnotation c", ConstructAnnotation.class) + .getResultList(); + assertThat(resultList).hasSize(1) + .extracting("name", "age") + .containsExactly(tuple("", -1)); + } + + @Test + @DisplayName("생성자 파라미터에 @NonNull(lombok)을 붙이면, 검증은 생성자 호출 시점에 수행된다.") + void lombokNotNullInConstructor() { + assertThatThrownBy(() -> { + new LombokNotNullInConstructor(null, -1); + }).isInstanceOf(NullPointerException.class); + } +} diff --git a/src/test/java/com/playkuround/playkuroundserver/JavaTest.java b/src/test/java/com/playkuround/playkuroundserver/learning/java/JavaTest.java similarity index 92% rename from src/test/java/com/playkuround/playkuroundserver/JavaTest.java rename to src/test/java/com/playkuround/playkuroundserver/learning/java/JavaTest.java index 0c035f8..ac295ad 100644 --- a/src/test/java/com/playkuround/playkuroundserver/JavaTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/java/JavaTest.java @@ -1,4 +1,4 @@ -package com.playkuround.playkuroundserver; +package com.playkuround.playkuroundserver.learning.java; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; diff --git a/src/test/java/com/playkuround/playkuroundserver/RedisTest.java b/src/test/java/com/playkuround/playkuroundserver/learning/redis/RedisTest.java similarity index 98% rename from src/test/java/com/playkuround/playkuroundserver/RedisTest.java rename to src/test/java/com/playkuround/playkuroundserver/learning/redis/RedisTest.java index 56219c6..7e1a967 100644 --- a/src/test/java/com/playkuround/playkuroundserver/RedisTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/redis/RedisTest.java @@ -1,7 +1,8 @@ -package com.playkuround.playkuroundserver; +package com.playkuround.playkuroundserver.learning.redis; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -17,6 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat; @Disabled +@DisplayName("Redis ZSet 테스트") @SpringBootTest(properties = "spring.profiles.active=test") public class RedisTest { diff --git a/src/test/java/com/playkuround/playkuroundserver/reflection/code/Domain.java b/src/test/java/com/playkuround/playkuroundserver/learning/reflection/Domain.java similarity index 56% rename from src/test/java/com/playkuround/playkuroundserver/reflection/code/Domain.java rename to src/test/java/com/playkuround/playkuroundserver/learning/reflection/Domain.java index 686d154..c696707 100644 --- a/src/test/java/com/playkuround/playkuroundserver/reflection/code/Domain.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/reflection/Domain.java @@ -1,9 +1,12 @@ -package com.playkuround.playkuroundserver.reflection.code; +package com.playkuround.playkuroundserver.learning.reflection; -public class Domain { +import lombok.Getter; + +@Getter +class Domain { - private String name; private int age; + private String name; private Domain() { } @@ -17,11 +20,4 @@ public Domain(String name, int age) { this.age = age; } - public String getName() { - return name; - } - - public int getAge() { - return age; - } } diff --git a/src/test/java/com/playkuround/playkuroundserver/reflection/ReflectionTest.java b/src/test/java/com/playkuround/playkuroundserver/learning/reflection/ReflectionTest.java similarity index 50% rename from src/test/java/com/playkuround/playkuroundserver/reflection/ReflectionTest.java rename to src/test/java/com/playkuround/playkuroundserver/learning/reflection/ReflectionTest.java index 1c68839..d7b93e7 100644 --- a/src/test/java/com/playkuround/playkuroundserver/reflection/ReflectionTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/reflection/ReflectionTest.java @@ -1,6 +1,5 @@ -package com.playkuround.playkuroundserver.reflection; +package com.playkuround.playkuroundserver.learning.reflection; -import com.playkuround.playkuroundserver.reflection.code.Domain; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -16,78 +15,69 @@ public class ReflectionTest { @Test @DisplayName("리플렉션을 이용하면 private 생성자를 호출할 수 있다.") - void test_1() throws Exception { + void privateConstructor1() throws Exception { Constructor declaredConstructor = Domain.class.getDeclaredConstructor(); declaredConstructor.setAccessible(true); Domain domain = declaredConstructor.newInstance(); - assertThat(domain.getName()).isNull(); assertThat(domain.getAge()).isZero(); + assertThat(domain.getName()).isNull(); } @Test @DisplayName("인자 타입을 이용해 생성자를 선택할 수 있다.") - void test_2() throws Exception { + void privateConstructor2() throws Exception { Constructor declaredConstructor = Domain.class.getDeclaredConstructor(String.class); declaredConstructor.setAccessible(true); - Domain domain = declaredConstructor.newInstance("name"); - assertThat(domain.getName()).isEqualTo("name"); + String name = "name"; + Domain domain = declaredConstructor.newInstance(name); + assertThat(domain.getAge()).isZero(); + assertThat(domain.getName()).isEqualTo(name); } @Test @DisplayName("setAccessible을 true로 바꾸지 않으면 IllegalAccessException이 발생한다.") - void test_3() throws Exception { + void privateConstructor3() throws Exception { Constructor declaredConstructor = Domain.class.getDeclaredConstructor(String.class); - assertThatThrownBy(() -> { - declaredConstructor.newInstance("name"); - }).isInstanceOf(IllegalAccessException.class); + assertThatThrownBy(() -> declaredConstructor.newInstance("name")) + .isInstanceOf(IllegalAccessException.class); } @Test @DisplayName("필드 정보 바꾸기") - void test_4() throws Exception { - Class domainClass = Domain.class; - Constructor declaredConstructor = domainClass.getDeclaredConstructor(); - declaredConstructor.setAccessible(true); - Domain landmark = declaredConstructor.newInstance(); - - assertThat(landmark.getName()).isNull(); + void changeField() throws Exception { + Domain domain = new Domain(null, 0); + assertThat(domain.getName()).isNull(); - Field targetField = domainClass.getDeclaredField("name"); + Field targetField = Domain.class.getDeclaredField("name"); targetField.setAccessible(true); - targetField.set(landmark, "test"); - assertThat(landmark.getName()).isEqualTo("test"); + String name = "test"; + targetField.set(domain, name); + + assertThat(domain.getName()).isEqualTo(name); } @Test @DisplayName("private 필드를 바꿀 땐 setAccessible을 true로 바꾸지 않으면 IllegalAccessException이 발생한다.") - void test_5() throws Exception { - Class domainClass = Domain.class; - Constructor declaredConstructor = domainClass.getDeclaredConstructor(); - declaredConstructor.setAccessible(true); - Domain landmark = declaredConstructor.newInstance(); - Field targetField = domainClass.getDeclaredField("name"); + void changeField2() throws Exception { + Domain domain = new Domain(null, 0); + Field targetField = Domain.class.getDeclaredField("name"); + assertThatThrownBy(() -> { - targetField.set(landmark, "test"); + targetField.set(domain, "test"); }).isInstanceOf(IllegalAccessException.class); } @Test @DisplayName("선언되지 않는 필드 이름이면 NoSuchFieldException이 발생한다.") - void test_6() throws Exception { - Class domainClass = Domain.class; - Constructor declaredConstructor = domainClass.getDeclaredConstructor(); - declaredConstructor.setAccessible(true); - Domain landmark = declaredConstructor.newInstance(); - - assertThat(landmark.getName()).isNull(); - + void changeField3() { assertThatThrownBy(() -> { - domainClass.getDeclaredField("notDeclaredField"); + Domain.class.getDeclaredField("notDeclaredField"); }).isInstanceOf(NoSuchFieldException.class); } + } diff --git a/src/test/java/com/playkuround/playkuroundserver/securityPersistence/code/PersistenceController.java b/src/test/java/com/playkuround/playkuroundserver/learning/securityPersistence/PersistenceController.java similarity index 88% rename from src/test/java/com/playkuround/playkuroundserver/securityPersistence/code/PersistenceController.java rename to src/test/java/com/playkuround/playkuroundserver/learning/securityPersistence/PersistenceController.java index adfe447..6ecfb43 100644 --- a/src/test/java/com/playkuround/playkuroundserver/securityPersistence/code/PersistenceController.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/securityPersistence/PersistenceController.java @@ -1,12 +1,14 @@ -package com.playkuround.playkuroundserver.securityPersistence.code; +package com.playkuround.playkuroundserver.learning.securityPersistence; import com.playkuround.playkuroundserver.global.security.UserDetailsImpl; import lombok.RequiredArgsConstructor; +import org.springframework.boot.test.context.TestComponent; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +@TestComponent @RestController @RequestMapping("api/persistence-test") @RequiredArgsConstructor diff --git a/src/test/java/com/playkuround/playkuroundserver/securityPersistence/code/PersistenceService.java b/src/test/java/com/playkuround/playkuroundserver/learning/securityPersistence/PersistenceService.java similarity index 84% rename from src/test/java/com/playkuround/playkuroundserver/securityPersistence/code/PersistenceService.java rename to src/test/java/com/playkuround/playkuroundserver/learning/securityPersistence/PersistenceService.java index d53ca9c..8d6823d 100644 --- a/src/test/java/com/playkuround/playkuroundserver/securityPersistence/code/PersistenceService.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/securityPersistence/PersistenceService.java @@ -1,12 +1,12 @@ -package com.playkuround.playkuroundserver.securityPersistence.code; +package com.playkuround.playkuroundserver.learning.securityPersistence; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; +import org.springframework.boot.test.context.TestComponent; import org.springframework.transaction.annotation.Transactional; -@Service +@TestComponent @Transactional @RequiredArgsConstructor public class PersistenceService { diff --git a/src/test/java/com/playkuround/playkuroundserver/securityPersistence/PersistenceTest.java b/src/test/java/com/playkuround/playkuroundserver/learning/securityPersistence/SecurityPersistenceTest.java similarity index 76% rename from src/test/java/com/playkuround/playkuroundserver/securityPersistence/PersistenceTest.java rename to src/test/java/com/playkuround/playkuroundserver/learning/securityPersistence/SecurityPersistenceTest.java index 3256409..e4150f8 100644 --- a/src/test/java/com/playkuround/playkuroundserver/securityPersistence/PersistenceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/securityPersistence/SecurityPersistenceTest.java @@ -1,4 +1,4 @@ -package com.playkuround.playkuroundserver.securityPersistence; +package com.playkuround.playkuroundserver.learning.securityPersistence; import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.auth.token.application.TokenManager; @@ -6,10 +6,14 @@ import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.securityConfig.WithMockCustomUser; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Disabled; +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.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; import org.springframework.http.HttpHeaders; import org.springframework.test.web.servlet.MockMvc; @@ -20,7 +24,9 @@ @Disabled @AutoConfigureMockMvc @SpringBootTest(properties = "spring.profiles.active=test") -public class PersistenceTest { +@Import({PersistenceController.class, PersistenceService.class}) +@DisplayName("Spring security의 @AuthenticationPrincipal 테스트") +public class SecurityPersistenceTest { @Autowired private MockMvc mockMvc; @@ -32,20 +38,19 @@ public class PersistenceTest { private TokenManager tokenManager; @AfterEach - @BeforeEach - void clean() { - userRepository.deleteAll(); + void tearDown() { + userRepository.deleteAllInBatch(); } @Test - @DisplayName("직접 save 함수를 호출해 update 쿼리를 실행한다.") - void successUpdate() throws Exception { + @DisplayName("Spring Data JPA의 save 함수를 호출해 update 쿼리를 실행한다.") + void springSecurityContextPersistent1() throws Exception { // given User user = TestUtil.createUser(); userRepository.save(user); + TokenDto tokenDto = tokenManager.createTokenDto(user.getEmail()); String accessToken = tokenDto.getAccessToken(); - System.out.println(accessToken); // expected mockMvc.perform(get("/api/persistence-test/success") @@ -58,11 +63,12 @@ void successUpdate() throws Exception { @Test @WithMockCustomUser - @DisplayName("spring security에서 조회한 user 객체는 영속성 컨텍스트에 존재하지 않는다.") - void failUpdate() throws Exception { + @DisplayName("spring security에서 조회한 user 객체는 영속 상태가 아니기 때문에 dirty check가 되지 않는다.") + void springSecurityContextPersistent2() throws Exception { // given User user = TestUtil.createUser(); userRepository.save(user); + TokenDto tokenDto = tokenManager.createTokenDto(user.getEmail()); String accessToken = tokenDto.getAccessToken(); @@ -77,11 +83,12 @@ void failUpdate() throws Exception { @Test @WithMockCustomUser - @DisplayName("save() 호출 이후 rollback을 수행한다.") + @DisplayName("Transaction 내에서 save() 호출 이후 에러가 발생하면 rollback을 수행한다.") void rollback() throws Exception { // given User user = TestUtil.createUser(); userRepository.save(user); + TokenDto tokenDto = tokenManager.createTokenDto(user.getEmail()); String accessToken = tokenDto.getAccessToken(); From 1e211f476d0658c7fa9c9ac307edba4c3ad9a48a Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 28 Jun 2024 19:09:32 +0900 Subject: [PATCH 05/79] =?UTF-8?q?test:=20controller=20integration=20test?= =?UTF-8?q?=20=ED=99=98=EA=B2=BD=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IntegrationControllerTest.java | 19 +++++++++++++++++++ .../adventure/api/AdventureApiTest.java | 14 ++++++-------- .../appversion/api/AppVersionApiTest.java | 10 ++++------ .../attendance/api/AttendanceApiTest.java | 15 +++++++-------- .../auth/email/api/AuthEmailSendApiTest.java | 10 ++++------ .../email/api/AuthEmailVerifyApiTest.java | 14 ++++++-------- .../domain/badge/api/BadgeApiTest.java | 18 ++++-------------- .../domain/fakedoor/api/FakeDoorApiTest.java | 10 ++++------ .../domain/landmark/api/LandmarkApiTest.java | 8 +++----- .../score/api/LandmarkScoreRankApiTest.java | 10 ++++------ .../score/api/ScoreTotalRankApiTest.java | 13 +++++++------ .../systemcheck/api/SystemCheckApiTest.java | 12 +++++------- .../domain/user/api/AdminApiTest.java | 10 ++++------ .../user/api/UserManagementApiTest.java | 10 ++++------ .../domain/user/api/UserProfileApiTest.java | 12 +++++------- 15 files changed, 86 insertions(+), 99 deletions(-) create mode 100644 src/test/java/com/playkuround/playkuroundserver/IntegrationControllerTest.java diff --git a/src/test/java/com/playkuround/playkuroundserver/IntegrationControllerTest.java b/src/test/java/com/playkuround/playkuroundserver/IntegrationControllerTest.java new file mode 100644 index 0000000..2718343 --- /dev/null +++ b/src/test/java/com/playkuround/playkuroundserver/IntegrationControllerTest.java @@ -0,0 +1,19 @@ +package com.playkuround.playkuroundserver; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@AutoConfigureMockMvc +@SpringBootTest(properties = "spring.profiles.active=test") +@EntityScan(basePackages = {"com.playkuround.playkuroundserver.domain"}) +public @interface IntegrationControllerTest { +} + diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java index 6656a38..2c52a18 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.domain.adventure.api; import com.fasterxml.jackson.databind.ObjectMapper; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.domain.adventure.api.request.AdventureSaveRequest; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; import com.playkuround.playkuroundserver.domain.adventure.domain.Adventure; @@ -17,8 +18,6 @@ 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.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.MediaType; import org.springframework.test.context.jdbc.Sql; @@ -32,8 +31,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest @Sql(scripts = {"/data-mysql.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) class AdventureApiTest { @@ -62,10 +60,10 @@ class AdventureApiTest { @AfterEach void clean() { - badgeRepository.deleteAll(); - adventureRepository.deleteAll(); - landmarkRepository.deleteAll(); - userRepository.deleteAll(); + badgeRepository.deleteAllInBatch(); + adventureRepository.deleteAllInBatch(); + landmarkRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); redisTemplate.delete(redisSetKey); } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java index a6e13c8..4d4e02f 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.domain.appversion.api; import com.fasterxml.jackson.databind.ObjectMapper; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.domain.appversion.api.request.UpdateAppVersionRequest; import com.playkuround.playkuroundserver.domain.appversion.dao.AppVersionRepository; import com.playkuround.playkuroundserver.domain.appversion.domain.AppVersion; @@ -14,8 +15,6 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; @@ -27,8 +26,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class AppVersionApiTest { @Autowired @@ -45,8 +43,8 @@ class AppVersionApiTest { @AfterEach void afterEach() { - appVersionRepository.deleteAll(); - userRepository.deleteAll(); + appVersionRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); } @Nested diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java index c9bbeea..54901d8 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.JsonPath; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.domain.attendance.api.request.AttendanceRegisterRequest; import com.playkuround.playkuroundserver.domain.attendance.application.AttendanceRegisterService; import com.playkuround.playkuroundserver.domain.attendance.dao.AttendanceRepository; @@ -20,8 +21,6 @@ import org.junit.jupiter.api.Test; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.data.auditing.AuditingHandler; @@ -46,8 +45,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class AttendanceApiTest { @Autowired @@ -65,15 +63,16 @@ class AttendanceApiTest { @Autowired private AttendanceRepository attendanceRepository; - private final String redisSetKey = "ranking"; @Autowired private RedisTemplate redisTemplate; + private final String redisSetKey = "ranking"; + @AfterEach void clean() { - attendanceRepository.deleteAll(); - badgeRepository.deleteAll(); - userRepository.deleteAll(); + attendanceRepository.deleteAllInBatch(); + badgeRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); redisTemplate.delete(redisSetKey); } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailSendApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailSendApiTest.java index a5902c8..90ca7c7 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailSendApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailSendApiTest.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.JsonPath; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.domain.auth.email.api.request.AuthEmailSendRequest; import com.playkuround.playkuroundserver.domain.auth.email.dao.AuthEmailRepository; import com.playkuround.playkuroundserver.domain.auth.email.domain.AuthEmail; @@ -15,8 +16,6 @@ import org.junit.jupiter.params.provider.NullAndEmptySource; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; @@ -35,8 +34,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class AuthEmailSendApiTest { @Autowired @@ -56,8 +54,8 @@ class AuthEmailSendApiTest { @AfterEach void clean() { - authEmailRepository.deleteAll(); - userRepository.deleteAll(); + authEmailRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); } @Test diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailVerifyApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailVerifyApiTest.java index 0caeb8e..fea7ac7 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailVerifyApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailVerifyApiTest.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.domain.auth.email.api; import com.jayway.jsonpath.JsonPath; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.domain.auth.email.dao.AuthEmailRepository; import com.playkuround.playkuroundserver.domain.auth.email.domain.AuthEmail; import com.playkuround.playkuroundserver.domain.auth.token.dao.AuthVerifyTokenRepository; @@ -16,8 +17,6 @@ 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.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -30,8 +29,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class AuthEmailVerifyApiTest { @Autowired @@ -51,10 +49,10 @@ class AuthEmailVerifyApiTest { @AfterEach void clean() { - authEmailRepository.deleteAll(); - refreshTokenRepository.deleteAll(); - authVerifyTokenRepository.deleteAll(); - userRepository.deleteAll(); + authEmailRepository.deleteAllInBatch(); + refreshTokenRepository.deleteAllInBatch(); + authVerifyTokenRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); } @Test diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java index 92b584b..2624bb8 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java @@ -1,5 +1,6 @@ package com.playkuround.playkuroundserver.domain.badge.api; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; @@ -11,11 +12,6 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.FilterType; import org.springframework.test.web.servlet.MockMvc; import java.util.List; @@ -28,13 +24,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") -@ComponentScan(basePackages = {"com.playkuround.playkuroundserver.domain"}, - excludeFilters = { - @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.playkuround.playkuroundserver.learning.*") - }) -@EntityScan(basePackages = {"com.playkuround.playkuroundserver.domain"}) +@IntegrationControllerTest class BadgeApiTest { @Autowired @@ -48,8 +38,8 @@ class BadgeApiTest { @AfterEach void clean() { - badgeRepository.deleteAll(); - userRepository.deleteAll(); + badgeRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); } @Nested diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/fakedoor/api/FakeDoorApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/fakedoor/api/FakeDoorApiTest.java index 5f7d48f..f24290b 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/fakedoor/api/FakeDoorApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/fakedoor/api/FakeDoorApiTest.java @@ -1,5 +1,6 @@ package com.playkuround.playkuroundserver.domain.fakedoor.api; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.domain.fakedoor.dao.FakeDoorRepository; import com.playkuround.playkuroundserver.domain.fakedoor.domain.FakeDoor; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; @@ -8,8 +9,6 @@ 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.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import java.util.List; @@ -18,8 +17,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class FakeDoorApiTest { @Autowired @@ -33,8 +31,8 @@ class FakeDoorApiTest { @AfterEach void clean() { - fakeDoorRepository.deleteAll(); - userRepository.deleteAll(); + fakeDoorRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); } @Test diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java index 55c8bec..6a164d2 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java @@ -1,5 +1,6 @@ package com.playkuround.playkuroundserver.domain.landmark.api; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; @@ -11,8 +12,6 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; @@ -21,8 +20,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class LandmarkApiTest { @Autowired @@ -36,7 +34,7 @@ class LandmarkApiTest { @AfterEach void clear() { - userRepository.deleteAll(); + userRepository.deleteAllInBatch(); } @Nested diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java index e663696..bffb5b3 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java @@ -1,5 +1,6 @@ package com.playkuround.playkuroundserver.domain.score.api; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; import com.playkuround.playkuroundserver.domain.adventure.domain.Adventure; @@ -15,8 +16,6 @@ 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.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -28,8 +27,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class LandmarkScoreRankApiTest { @Autowired @@ -46,8 +44,8 @@ class LandmarkScoreRankApiTest { @AfterEach void clean() { - adventureRepository.deleteAll(); - userRepository.deleteAll(); + adventureRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); } @Test diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java index c1367cf..6575cbd 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java @@ -1,5 +1,6 @@ package com.playkuround.playkuroundserver.domain.score.api; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; @@ -10,8 +11,6 @@ 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.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.test.web.servlet.MockMvc; @@ -25,22 +24,24 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class ScoreTotalRankApiTest { - private final String redisSetKey = "ranking"; @Autowired private MockMvc mockMvc; + @Autowired private UserRepository userRepository; + @Autowired private RedisTemplate redisTemplate; + private final String redisSetKey = "ranking"; + @AfterEach void clean() { + userRepository.deleteAllInBatch(); redisTemplate.delete("ranking"); - userRepository.deleteAll(); } @Test diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApiTest.java index 7acc5cf..56704d6 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApiTest.java @@ -1,5 +1,6 @@ package com.playkuround.playkuroundserver.domain.systemcheck.api; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.appversion.dao.AppVersionRepository; import com.playkuround.playkuroundserver.domain.appversion.domain.AppVersion; @@ -17,8 +18,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -30,8 +29,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class SystemCheckApiTest { @Autowired @@ -48,9 +46,9 @@ class SystemCheckApiTest { @AfterEach void clean() { - appVersionRepository.deleteAll(); - systemCheckRepository.deleteAll(); - userRepository.deleteAll(); + appVersionRepository.deleteAllInBatch(); + systemCheckRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); } @Nested diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java index b90ab28..5b65e96 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.domain.user.api; import com.fasterxml.jackson.databind.ObjectMapper; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; @@ -14,8 +15,6 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; @@ -29,8 +28,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class AdminApiTest { @Autowired @@ -47,8 +45,8 @@ class AdminApiTest { @AfterEach void clean() { - badgeRepository.deleteAll(); - userRepository.deleteAll(); + badgeRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); } @Nested diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApiTest.java index 6f210fc..b61fdad 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApiTest.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.domain.user.api; import com.fasterxml.jackson.databind.ObjectMapper; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.auth.token.application.TokenManager; import com.playkuround.playkuroundserver.domain.auth.token.application.TokenService; @@ -20,8 +21,6 @@ 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.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; @@ -35,8 +34,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class UserManagementApiTest { @Autowired @@ -63,8 +61,8 @@ class UserManagementApiTest { @AfterEach void afterEach() { - userRepository.deleteAll(); - refreshTokenRepository.deleteAll(); + userRepository.deleteAllInBatch(); + refreshTokenRepository.deleteAllInBatch(); } @Test diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java index 06fafe8..7714c13 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java @@ -1,5 +1,6 @@ package com.playkuround.playkuroundserver.domain.user.api; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.appversion.dao.AppVersionRepository; import com.playkuround.playkuroundserver.domain.appversion.domain.AppVersion; @@ -15,8 +16,6 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -24,8 +23,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class UserProfileApiTest { @Autowired @@ -42,9 +40,9 @@ class UserProfileApiTest { @AfterEach void afterEach() { - userRepository.deleteAll(); - appVersionRepository.deleteAll(); - systemCheckRepository.deleteAll(); + userRepository.deleteAllInBatch(); + appVersionRepository.deleteAllInBatch(); + systemCheckRepository.deleteAllInBatch(); } @Test From efc05eaabeaeb3c0cb1fb9d82eb08bc011017e94 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sat, 29 Jun 2024 22:50:01 +0900 Subject: [PATCH 06/79] test refactor: AdventureApiTest --- .../adventure/api/AdventureApiTest.java | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java index 2c52a18..ed43b12 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java @@ -24,8 +24,10 @@ import org.springframework.test.web.servlet.MockMvc; import java.util.List; +import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -69,7 +71,7 @@ void clean() { @Test @WithMockCustomUser - @DisplayName("탐험 저장 성공") + @DisplayName("탐험을 하게 되면 total score 증가, adventure 저장, 랜드마크별 최고기록과 유저별 게임 최고기록이 업데이트 된다.") void saveAdventure_1() throws Exception { // given Landmark landmark = landmarkRepository.findById(3L).get(); @@ -81,8 +83,7 @@ void saveAdventure_1() throws Exception { // expected mockMvc.perform(post("/api/adventures") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isCreated()) .andExpect(jsonPath("$.isSuccess").value(true)) .andExpect(jsonPath("$.response.newBadges.size()").value(1)) @@ -92,23 +93,22 @@ void saveAdventure_1() throws Exception { // Total Score 저장 및 최고 점수 갱신 List users = userRepository.findAll(); - assertThat(users).hasSize(1); - User user = users.get(0); - assertThat(user.getHighestScore().getHighestCardScore()).isEqualTo(100L); + assertThat(users).hasSize(1) + .extracting("highestScore.highestCardScore") + .containsOnly(100L); // adventure 저장 List adventures = adventureRepository.findAll(); - assertThat(adventures).hasSize(1); - Adventure adventure = adventures.get(0); - assertThat(adventure.getScore()).isEqualTo(100L); - assertThat(adventure.getScoreType()).isEqualTo(ScoreType.BOOK); - assertThat(adventure.getUser().getId()).isEqualTo(user.getId()); - assertThat(adventure.getLandmark().getId()).isEqualTo(landmark.getId()); + assertThat(adventures).hasSize(1) + .extracting("score", "scoreType", "user.id", "landmark.id") + .containsOnly(tuple(100L, ScoreType.BOOK, users.get(0).getId(), landmark.getId())); // 랜드마크 최고 점수 갱신 - Landmark updatedLandmark = landmarkRepository.findById(landmark.getId()).get(); - assertThat(updatedLandmark.getHighestScore()).isEqualTo(100L); - assertThat(updatedLandmark.getFirstUser().getId()).isEqualTo(user.getId()); + Optional optionalLandmark = landmarkRepository.findById(landmark.getId()); + assertThat(optionalLandmark).isPresent() + .get() + .extracting("highestScore", "firstUser.id") + .contains(100L, users.get(0).getId()); } @Test @@ -125,13 +125,15 @@ void saveAdventure_2() throws Exception { // expected mockMvc.perform(post("/api/adventures") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.isSuccess").value(false)) .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.NOT_FOUND.getCode())) .andExpect(jsonPath("$.errorResponse.status").value(ErrorCode.INVALID_VALUE.getStatus().value())) .andDo(print()); + + List adventures = adventureRepository.findAll(); + assertThat(adventures).isEmpty(); } @Test @@ -148,14 +150,16 @@ void saveAdventure_3() throws Exception { // expected mockMvc.perform(post("/api/adventures") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.isSuccess").value(false)) .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.INVALID_LOCATION_LANDMARK.getCode())) .andExpect(jsonPath("$.errorResponse.message").value(ErrorCode.INVALID_LOCATION_LANDMARK.getMessage())) .andExpect(jsonPath("$.errorResponse.status").value(ErrorCode.INVALID_LOCATION_LANDMARK.getStatus().value())) .andDo(print()); + + List adventures = adventureRepository.findAll(); + assertThat(adventures).isEmpty(); } @Test @@ -172,10 +176,12 @@ void saveAdventure_4() throws Exception { // expected mockMvc.perform(post("/api/adventures") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.isSuccess").value(false)) .andDo(print()); + + List adventures = adventureRepository.findAll(); + assertThat(adventures).isEmpty(); } } \ No newline at end of file From 8eee28026d626a6b254a6ec2b22cbdc548421797 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sat, 29 Jun 2024 22:50:11 +0900 Subject: [PATCH 07/79] test refactor: AppVersionApiTest --- .../appversion/api/AppVersionApiTest.java | 69 ++++++++++--------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java index 4d4e02f..6c9f1a8 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java @@ -6,7 +6,6 @@ import com.playkuround.playkuroundserver.domain.appversion.dao.AppVersionRepository; import com.playkuround.playkuroundserver.domain.appversion.domain.AppVersion; import com.playkuround.playkuroundserver.domain.appversion.domain.OperationSystem; -import com.playkuround.playkuroundserver.domain.appversion.dto.OSAndVersion; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Role; import com.playkuround.playkuroundserver.securityConfig.WithMockCustomUser; @@ -21,6 +20,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -55,34 +55,32 @@ class updateAppVersion { @WithMockCustomUser(role = Role.ROLE_ADMIN) @DisplayName("새로운 앱 버전 추가") void success_1() throws Exception { - // when + // given List osAndVersions = List.of( new UpdateAppVersionRequest.OsAndVersion("android", "2.0.3"), new UpdateAppVersionRequest.OsAndVersion("android", "2.0.4"), new UpdateAppVersionRequest.OsAndVersion("ios", "2.0.0"), new UpdateAppVersionRequest.OsAndVersion("ios", "2.0.1") ); - UpdateAppVersionRequest updateAppVersionRequest = new UpdateAppVersionRequest(osAndVersions); String request = objectMapper.writeValueAsString(updateAppVersionRequest); + // expected mockMvc.perform(post("/api/admin/app-version") .contentType(MediaType.APPLICATION_JSON) .content(request)) .andExpect(status().isOk()) .andDo(print()); - // then List appVersions = appVersionRepository.findAll(); - List osAndVersionList = appVersions.stream() - .map(appversion -> new OSAndVersion(appversion.getOs(), appversion.getVersion())) - .toList(); - assertThat(osAndVersionList).containsExactlyInAnyOrder( - new OSAndVersion(OperationSystem.ANDROID, "2.0.3"), - new OSAndVersion(OperationSystem.ANDROID, "2.0.4"), - new OSAndVersion(OperationSystem.IOS, "2.0.0"), - new OSAndVersion(OperationSystem.IOS, "2.0.1") - ); + assertThat(appVersions).hasSize(4) + .extracting("os", "version") + .containsExactlyInAnyOrder( + tuple(OperationSystem.ANDROID, "2.0.3"), + tuple(OperationSystem.ANDROID, "2.0.4"), + tuple(OperationSystem.IOS, "2.0.0"), + tuple(OperationSystem.IOS, "2.0.1") + ); } @Test @@ -90,67 +88,74 @@ void success_1() throws Exception { @DisplayName("기존에 지원하던 앱 버전을 완전히 덮어쓴다.") void success_2() throws Exception { // given - appVersionRepository.save(new AppVersion(OperationSystem.ANDROID, "2.0.3")); - appVersionRepository.save(new AppVersion(OperationSystem.IOS, "1.4.3")); + appVersionRepository.saveAll( + List.of( + new AppVersion(OperationSystem.ANDROID, "2.0.3"), + new AppVersion(OperationSystem.IOS, "1.4.3") + ) + ); - // when List osAndVersions = List.of( new UpdateAppVersionRequest.OsAndVersion("android", "2.0.3"), new UpdateAppVersionRequest.OsAndVersion("android", "2.0.4"), new UpdateAppVersionRequest.OsAndVersion("ios", "2.0.0"), new UpdateAppVersionRequest.OsAndVersion("ios", "2.0.1") ); - UpdateAppVersionRequest updateAppVersionRequest = new UpdateAppVersionRequest(osAndVersions); String request = objectMapper.writeValueAsString(updateAppVersionRequest); + // expected mockMvc.perform(post("/api/admin/app-version") .contentType(MediaType.APPLICATION_JSON) .content(request)) .andExpect(status().isOk()) .andDo(print()); - // then List appVersions = appVersionRepository.findAll(); - List osAndVersionList = appVersions.stream() - .map(appversion -> new OSAndVersion(appversion.getOs(), appversion.getVersion())) - .toList(); - assertThat(osAndVersionList).containsExactlyInAnyOrder( - new OSAndVersion(OperationSystem.ANDROID, "2.0.3"), - new OSAndVersion(OperationSystem.ANDROID, "2.0.4"), - new OSAndVersion(OperationSystem.IOS, "2.0.0"), - new OSAndVersion(OperationSystem.IOS, "2.0.1") - ); + assertThat(appVersions).hasSize(4) + .extracting("os", "version") + .containsExactlyInAnyOrder( + tuple(OperationSystem.ANDROID, "2.0.3"), + tuple(OperationSystem.ANDROID, "2.0.4"), + tuple(OperationSystem.IOS, "2.0.0"), + tuple(OperationSystem.IOS, "2.0.1") + ); } @Test @WithMockCustomUser(role = Role.ROLE_ADMIN) @DisplayName("존재하지 않는 OS이면 에러가 발생한다.") void fail_1() throws Exception { - List osAndVersions = List.of( - new UpdateAppVersionRequest.OsAndVersion("NOTFOUND", "2.0.3"), - new UpdateAppVersionRequest.OsAndVersion("ios", "2.0.1") - ); - + // given + List osAndVersions = + List.of(new UpdateAppVersionRequest.OsAndVersion("NOTFOUND", "2.0.3")); UpdateAppVersionRequest updateAppVersionRequest = new UpdateAppVersionRequest(osAndVersions); String request = objectMapper.writeValueAsString(updateAppVersionRequest); + // expected mockMvc.perform(post("/api/admin/app-version") .contentType(MediaType.APPLICATION_JSON) .content(request)) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.isSuccess").value(false)) .andDo(print()); + + List appVersions = appVersionRepository.findAll(); + assertThat(appVersions).isEmpty(); } @Test @WithMockCustomUser(role = Role.ROLE_USER) @DisplayName("ROLE_ADMIN이 아니면 권한 에러가 발생한다.") void fail_2() throws Exception { + // expected mockMvc.perform(post("/api/admin/app-version") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isForbidden()) .andDo(print()); + + List appVersions = appVersionRepository.findAll(); + assertThat(appVersions).isEmpty(); } } From c12285d08b20061f0939ab73a5468dac7045e0b4 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sun, 30 Jun 2024 23:46:32 +0900 Subject: [PATCH 08/79] =?UTF-8?q?feat:=20DateTimeService=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/common/DateTimeService.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/common/DateTimeService.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/common/DateTimeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/common/DateTimeService.java new file mode 100644 index 0000000..27feee3 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/common/DateTimeService.java @@ -0,0 +1,14 @@ +package com.playkuround.playkuroundserver.domain.common; + +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +@Component +public class DateTimeService { + + public LocalDateTime now() { + return LocalDateTime.now(); + } + +} From 94e841e9483d0befb6c4a04c2f856039f30185e9 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sun, 30 Jun 2024 23:47:14 +0900 Subject: [PATCH 09/79] =?UTF-8?q?feat:=20Attendance=EC=97=90=20=EC=B6=9C?= =?UTF-8?q?=EC=84=9D=EC=9D=BC=EC=8B=9C=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/attendance/domain/Attendance.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/domain/Attendance.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/domain/Attendance.java index 59190a4..536ce64 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/domain/Attendance.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/domain/Attendance.java @@ -10,6 +10,8 @@ import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; +import java.time.LocalDateTime; + @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -30,13 +32,16 @@ public class Attendance extends BaseTimeEntity { @OnDelete(action = OnDeleteAction.CASCADE) private User user; - private Attendance(User user, double latitude, double longitude) { + private LocalDateTime attendanceDateTime; + + private Attendance(User user, double latitude, double longitude, LocalDateTime attendanceDateTime) { this.user = user; this.latitude = latitude; this.longitude = longitude; + this.attendanceDateTime = attendanceDateTime; } - public static Attendance of(User user, Location location) { - return new Attendance(user, location.latitude(), location.longitude()); + public static Attendance of(User user, Location location, LocalDateTime attendanceDateTime) { + return new Attendance(user, location.latitude(), location.longitude(), attendanceDateTime); } } From e5951227f39f464cfcad9331683e65b600ccb5ab Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sun, 30 Jun 2024 23:47:46 +0900 Subject: [PATCH 10/79] =?UTF-8?q?feat:=20Attendance=EC=9D=98=20createdAt?= =?UTF-8?q?=20=EB=8C=80=EC=8B=A0=20=EC=B6=9C=EC=84=9D=EC=9D=BC=EC=8B=9C=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../attendance/application/AttendanceRegisterService.java | 6 ++++-- .../attendance/application/AttendanceSearchService.java | 5 ++--- .../domain/attendance/dao/AttendanceRepository.java | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java index e1e2cba..4222ce3 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java @@ -6,6 +6,7 @@ import com.playkuround.playkuroundserver.domain.attendance.exception.InvalidAttendanceLocationException; import com.playkuround.playkuroundserver.domain.badge.application.BadgeService; import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.score.application.TotalScoreService; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -25,6 +26,7 @@ public class AttendanceRegisterService { private final UserRepository userRepository; private final TotalScoreService totalScoreService; private final AttendanceRepository attendanceRepository; + private final DateTimeService dateTimeService; private final long attendanceScore = 10; @Transactional @@ -52,13 +54,13 @@ private void validateLocation(Location location) { } private void validateDuplicateAttendance(User user) { - if (attendanceRepository.existsByUserAndCreatedAtAfter(user, LocalDate.now().atStartOfDay())) { + if (attendanceRepository.existsByUserAndAttendanceDateTimeAfter(user, LocalDate.now().atStartOfDay())) { throw new DuplicateAttendanceException(); } } private void saveAttendance(User user, Location location) { - Attendance attendance = Attendance.of(user, location); + Attendance attendance = Attendance.of(user, location, dateTimeService.now()); attendanceRepository.save(attendance); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java index c3e5f22..b5ff638 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java @@ -2,7 +2,6 @@ import com.playkuround.playkuroundserver.domain.attendance.dao.AttendanceRepository; import com.playkuround.playkuroundserver.domain.attendance.domain.Attendance; -import com.playkuround.playkuroundserver.domain.common.BaseTimeEntity; import com.playkuround.playkuroundserver.domain.user.domain.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -21,9 +20,9 @@ public class AttendanceSearchService { @Transactional(readOnly = true) public List findAttendance(User user, int agoDays) { LocalDateTime monthAgo = LocalDate.now().minusMonths(agoDays).atStartOfDay(); - List attendances = attendanceRepository.findByUserAndCreatedAtAfter(user, monthAgo); + List attendances = attendanceRepository.findByUserAndAttendanceDateTimeAfter(user, monthAgo); return attendances.stream() - .map(BaseTimeEntity::getCreatedAt) + .map(Attendance::getAttendanceDateTime) .sorted() .toList(); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java index 76cc035..b41b11a 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java @@ -9,7 +9,7 @@ public interface AttendanceRepository extends JpaRepository { - List findByUserAndCreatedAtAfter(User user, LocalDateTime localDateTime); + List findByUserAndAttendanceDateTimeAfter(User user, LocalDateTime localDateTime); - boolean existsByUserAndCreatedAtAfter(User user, LocalDateTime localDateTime); + boolean existsByUserAndAttendanceDateTimeAfter(User user, LocalDateTime localDateTime); } From fe9d114177f77667d0ff4a0b649aad63f7d5bfb5 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sun, 30 Jun 2024 23:48:02 +0900 Subject: [PATCH 11/79] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=86=B5=EA=B3=BC=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../attendance/api/AttendanceApiTest.java | 56 ++++++++----------- .../AttendanceRegisterServiceTest.java | 11 +++- .../AttendanceSearchServiceTest.java | 11 ++-- 3 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java index 54901d8..47206c2 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java @@ -10,6 +10,7 @@ import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.global.error.ErrorCode; @@ -19,12 +20,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.data.auditing.AuditingHandler; -import org.springframework.data.auditing.DateTimeProvider; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.http.MediaType; @@ -35,10 +31,9 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; -import java.util.Optional; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; @@ -63,6 +58,9 @@ class AttendanceApiTest { @Autowired private AttendanceRepository attendanceRepository; + @Autowired + private DateTimeService dateTimeService; + @Autowired private RedisTemplate redisTemplate; @@ -91,8 +89,7 @@ void success_1() throws Exception { // expected mockMvc.perform(post("/api/attendances") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess").value(true)) .andExpect(jsonPath("$.response.newBadges.size()").value(1)) @@ -104,13 +101,14 @@ void success_1() throws Exception { assertThat(user.getAttendanceDays()).isEqualTo(1); List badges = badgeRepository.findAll(); - assertThat(badges.size()).isEqualTo(1); - assertThat(badges.get(0).getUser().getId()).isEqualTo(user.getId()); - assertThat(badges.get(0).getBadgeType()).isEqualTo(BadgeType.ATTENDANCE_1); + assertThat(badges).hasSize(1) + .extracting("user.id", "badgeType") + .containsExactly(tuple(user.getId(), BadgeType.ATTENDANCE_1)); List attendances = attendanceRepository.findAll(); - assertThat(attendances.size()).isEqualTo(1); - assertThat(attendances.get(0).getUser().getId()).isEqualTo(user.getId()); + assertThat(attendances).hasSize(1) + .extracting("user.id") + .containsExactly(user.getId()); ZSetOperations zSetOperations = redisTemplate.opsForZSet(); Double myTotalScore = zSetOperations.score(redisSetKey, user.getEmail()); @@ -124,7 +122,7 @@ void fail_1() throws Exception { // TODO : 12시 넘어가는 시점에는 테스트가 실패함 // given User user = userRepository.findAll().get(0); - attendanceRepository.save(Attendance.of(user, new Location(37.539927, 127.073006))); + attendanceRepository.save(Attendance.of(user, new Location(37.539927, 127.073006), dateTimeService.now())); AttendanceRegisterRequest attendanceRegisterRequest = new AttendanceRegisterRequest(37.539927, 127.073006); String request = objectMapper.writeValueAsString(attendanceRegisterRequest); @@ -132,14 +130,16 @@ void fail_1() throws Exception { // expected mockMvc.perform(post("/api/attendances") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.isSuccess").value(false)) .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.DUPLICATE_ATTENDANCE.getCode())) .andExpect(jsonPath("$.errorResponse.message").value(ErrorCode.DUPLICATE_ATTENDANCE.getMessage())) .andExpect(jsonPath("$.errorResponse.status").value(ErrorCode.DUPLICATE_ATTENDANCE.getStatus().value())) .andDo(print()); + + List attendances = attendanceRepository.findAll(); + assertThat(attendances).hasSize(1); } @Test @@ -153,14 +153,16 @@ void fail_2() throws Exception { // expected mockMvc.perform(post("/api/attendances") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.isSuccess").value(false)) .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.INVALID_LOCATION_KU.getCode())) .andExpect(jsonPath("$.errorResponse.message").value(ErrorCode.INVALID_LOCATION_KU.getMessage())) .andExpect(jsonPath("$.errorResponse.status").value(ErrorCode.INVALID_LOCATION_KU.getStatus().value())) .andDo(print()); + + List attendances = attendanceRepository.findAll(); + assertThat(attendances).isEmpty(); } } @@ -169,12 +171,6 @@ void fail_2() throws Exception { @DisplayName("출석 조회하기") class searchAttendance { - @MockBean - private DateTimeProvider dateTimeProvider; - - @SpyBean - private AuditingHandler auditingHandler; - @Autowired private AttendanceRegisterService attendanceRegisterService; @@ -184,8 +180,6 @@ class searchAttendance { void attendanceSearch() throws Exception { // TODO : need refactoring // given - MockitoAnnotations.openMocks(this); - auditingHandler.setDateTimeProvider(dateTimeProvider); User user = userRepository.findAll().get(0); Location location = new Location(37.539927, 127.073006); @@ -197,8 +191,7 @@ void attendanceSearch() throws Exception { String formatDate = thatLocalDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); dateList.add(formatDate); - when(dateTimeProvider.getNow()).thenReturn(Optional.of(thatLocalDateTime)); - attendanceRegisterService.registerAttendance(user, location); + attendanceRepository.save(Attendance.of(user, location, thatLocalDateTime)); } // expected @@ -209,8 +202,7 @@ void attendanceSearch() throws Exception { .andReturn(); String json = mvcResult.getResponse().getContentAsString(); List target = JsonPath.parse(json).read("$.response.attendances"); - - assertThat(dateList).isEqualTo(target); + assertThat(target).isEqualTo(dateList); } } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java index 571fd3c..b2b6e22 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java @@ -8,6 +8,7 @@ import com.playkuround.playkuroundserver.domain.badge.application.BadgeService; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.score.application.TotalScoreService; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -45,13 +46,19 @@ class AttendanceRegisterServiceTest { @Mock private TotalScoreService totalScoreService; + @Mock + private DateTimeService dateTimeService; + @Test @DisplayName("출석 시 뱃지와 출석정보가 저장되고 유저의 출석횟수가 증가한다") void registerAttendance_1() { // given - when(attendanceRepository.existsByUserAndCreatedAtAfter(any(User.class), any(LocalDateTime.class))) + when(attendanceRepository.existsByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) .thenReturn(false); + when(dateTimeService.now()) + .thenReturn(LocalDateTime.of(2024, 6, 30, 0, 0)); + NewlyRegisteredBadge newlyRegisteredBadge = new NewlyRegisteredBadge(); newlyRegisteredBadge.addBadge(BadgeType.ATTENDANCE_1); newlyRegisteredBadge.addBadge(BadgeType.ATTENDANCE_ARBOR_DAY); @@ -90,7 +97,7 @@ void registerAttendance_2() { @DisplayName("출석은 하루에 한번만 가능하다") void registerAttendance_3() { // given - when(attendanceRepository.existsByUserAndCreatedAtAfter(any(User.class), any(LocalDateTime.class))) + when(attendanceRepository.existsByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) .thenReturn(true); // expect diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java index 74098b8..935877a 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java @@ -11,7 +11,6 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.test.util.ReflectionTestUtils; import java.time.LocalDateTime; import java.util.ArrayList; @@ -49,13 +48,13 @@ void findAttendanceForMonth_1() { .distinct() .sorted() .forEach(x -> { - Attendance attendance = Attendance.of(user, location); - ReflectionTestUtils.setField(attendance, "createdAt", now.plusDays(x)); + Attendance attendance = Attendance.of(user, location, now.plusDays(x)); + //ReflectionTestUtils.setField(attendance, "createdAt", now.plusDays(x)); attendances.add(attendance); - expected.add(attendance.getCreatedAt()); + expected.add(attendance.getAttendanceDateTime()); }); - when(attendanceRepository.findByUserAndCreatedAtAfter(any(User.class), any(LocalDateTime.class))) + when(attendanceRepository.findByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) .thenReturn(attendances); // when @@ -69,7 +68,7 @@ void findAttendanceForMonth_1() { @DisplayName("출석정보가 없으면 빈리스트가 반환된다") void findAttendanceForMonth_2() { // given - when(attendanceRepository.findByUserAndCreatedAtAfter(any(User.class), any(LocalDateTime.class))) + when(attendanceRepository.findByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) .thenReturn(new ArrayList<>()); // when From 40ebafd945a2d972f920c7ec28b56f141c522522 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 1 Jul 2024 00:23:35 +0900 Subject: [PATCH 12/79] =?UTF-8?q?feat:=20DateTimeUtils=EC=9D=98=20?= =?UTF-8?q?=EB=AA=A8=EB=93=A0=20=EB=A9=94=EC=84=9C=EB=93=9C=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EB=82=A0=EC=A7=9C=EB=A5=BC=20=EC=9D=B8=EC=9E=90?= =?UTF-8?q?=EB=A1=9C=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=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 --- .../global/util/DateTimeUtils.java | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/global/util/DateTimeUtils.java b/src/main/java/com/playkuround/playkuroundserver/global/util/DateTimeUtils.java index 4c30652..32f42c3 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/util/DateTimeUtils.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/util/DateTimeUtils.java @@ -8,34 +8,28 @@ @NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) public class DateTimeUtils { - public static LocalDateTime getMonthStartDateTime() { - LocalDate today = LocalDate.now(); - return today.withDayOfMonth(1).atStartOfDay(); + public static LocalDateTime getMonthStartDateTime(LocalDate localDate) { + return localDate.withDayOfMonth(1).atStartOfDay(); } - public static boolean isTodayFoundationDay() { - LocalDate today = LocalDate.now(); - return today.getMonth().getValue() == 5 && today.getDayOfMonth() == 15; + public static boolean isFoundationDay(LocalDate localDate) { + return localDate.getMonth().getValue() == 5 && localDate.getDayOfMonth() == 15; } - public static boolean isTodayArborDay() { - LocalDate today = LocalDate.now(); - return today.getMonth().getValue() == 4 && today.getDayOfMonth() == 5; + public static boolean isArborDay(LocalDate localDate) { + return localDate.getMonth().getValue() == 4 && localDate.getDayOfMonth() == 5; } - public static boolean isTodayChildrenDay() { - LocalDate today = LocalDate.now(); - return today.getMonth().getValue() == 5 && today.getDayOfMonth() == 5; + public static boolean isChildrenDay(LocalDate localDate) { + return localDate.getMonth().getValue() == 5 && localDate.getDayOfMonth() == 5; } - public static boolean isTodayWhiteDay() { - LocalDate today = LocalDate.now(); - return today.getMonth().getValue() == 3 && today.getDayOfMonth() == 14; + public static boolean isWhiteDay(LocalDate localDate) { + return localDate.getMonth().getValue() == 3 && localDate.getDayOfMonth() == 14; } - public static boolean isTodayDuckDay() { - LocalDate today = LocalDate.now(); - return today.getMonth().getValue() == 5 && today.getDayOfMonth() == 2; + public static boolean isDuckDay(LocalDate localDate) { + return localDate.getMonth().getValue() == 5 && localDate.getDayOfMonth() == 2; } } From 6a8f84a074c5e1bcbe33799bd66fe536a25b734c Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 1 Jul 2024 00:23:54 +0900 Subject: [PATCH 13/79] =?UTF-8?q?feat:=20DateTimeUtils=20API=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/adventure/application/AdventureService.java | 4 +++- .../domain/badge/application/BadgeService.java | 4 +++- .../badge/application/specialday_badge/ArborDayBadge.java | 5 +++-- .../badge/application/specialday_badge/ChildrenDayBadge.java | 5 +++-- .../badge/application/specialday_badge/DuckDayBadge.java | 5 +++-- .../application/specialday_badge/FoundationDayBadge.java | 5 +++-- .../badge/application/specialday_badge/SpecialDayBadge.java | 3 ++- .../badge/application/specialday_badge/WhiteDayBadge.java | 5 +++-- .../domain/score/application/LandmarkRankService.java | 4 +++- 9 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java index 79294e2..2803df0 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java @@ -6,6 +6,7 @@ import com.playkuround.playkuroundserver.domain.adventure.exception.InvalidLandmarkLocationException; import com.playkuround.playkuroundserver.domain.badge.application.BadgeService; import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.exception.LandmarkNotFoundException; @@ -31,6 +32,7 @@ public class AdventureService { private final TotalScoreService totalScoreService; private final LandmarkRepository landmarkRepository; private final AdventureRepository adventureRepository; + private final DateTimeService dateTimeService; @Transactional public NewlyRegisteredBadge saveAdventure(AdventureSaveDto adventureSaveDto) { @@ -66,7 +68,7 @@ private void saveAdventure(User user, Landmark landmark, ScoreType scoreType, lo } private void updateLandmarkHighestScore(User user, Landmark landmark) { - LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(); + LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.now().toLocalDate()); long sumScore = adventureRepository.getSumScoreByUserAndLandmark(user, landmark, monthStartDateTime); landmark.updateFirstUser(user, sumScore); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java index 9623bee..74dee1e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java @@ -8,6 +8,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; @@ -27,6 +28,7 @@ public class BadgeService { private final UserRepository userRepository; private final BadgeRepository badgeRepository; + private final DateTimeService dateTimeService; private final CollegeSpecialBadgeFactory collegeSpecialBadgeFactory; @Transactional(readOnly = true) @@ -51,7 +53,7 @@ public NewlyRegisteredBadge updateNewlyAttendanceBadges(User user) { // 기념일 기준 뱃지 SpecialDayBadgeList.getSpecialDayBadges().stream() - .filter(specialDayBadge -> specialDayBadge.supports(userBadgeSet)) + .filter(specialDayBadge -> specialDayBadge.supports(userBadgeSet, dateTimeService.now().toLocalDate())) .forEach(specialDayBadge -> { BadgeType badgeType = specialDayBadge.getBadgeType(); badgeRepository.save(Badge.createBadge(user, badgeType)); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ArborDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ArborDayBadge.java index 193227a..8da1613 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ArborDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ArborDayBadge.java @@ -3,6 +3,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; +import java.time.LocalDate; import java.util.Set; public class ArborDayBadge implements SpecialDayBadge { @@ -11,9 +12,9 @@ public class ArborDayBadge implements SpecialDayBadge { } @Override - public boolean supports(Set userBadgeSet) { + public boolean supports(Set userBadgeSet, LocalDate localDate) { BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isTodayArborDay() && !userBadgeSet.contains(badgeType); + return DateTimeUtils.isArborDay(localDate) && !userBadgeSet.contains(badgeType); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChildrenDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChildrenDayBadge.java index 1662d94..4add59e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChildrenDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChildrenDayBadge.java @@ -3,6 +3,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; +import java.time.LocalDate; import java.util.Set; public class ChildrenDayBadge implements SpecialDayBadge { @@ -11,9 +12,9 @@ public class ChildrenDayBadge implements SpecialDayBadge { } @Override - public boolean supports(Set userBadgeSet) { + public boolean supports(Set userBadgeSet, LocalDate localDate) { BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isTodayChildrenDay() && !userBadgeSet.contains(badgeType); + return DateTimeUtils.isChildrenDay(localDate) && !userBadgeSet.contains(badgeType); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DuckDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DuckDayBadge.java index 42a6795..6dc2b3b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DuckDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DuckDayBadge.java @@ -3,6 +3,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; +import java.time.LocalDate; import java.util.Set; public class DuckDayBadge implements SpecialDayBadge { @@ -11,9 +12,9 @@ public class DuckDayBadge implements SpecialDayBadge { } @Override - public boolean supports(Set userBadgeSet) { + public boolean supports(Set userBadgeSet, LocalDate localDate) { BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isTodayDuckDay() && !userBadgeSet.contains(badgeType); + return DateTimeUtils.isDuckDay(localDate) && !userBadgeSet.contains(badgeType); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/FoundationDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/FoundationDayBadge.java index f58d480..024217d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/FoundationDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/FoundationDayBadge.java @@ -3,6 +3,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; +import java.time.LocalDate; import java.util.Set; public class FoundationDayBadge implements SpecialDayBadge { @@ -11,9 +12,9 @@ public class FoundationDayBadge implements SpecialDayBadge { } @Override - public boolean supports(Set userBadgeSet) { + public boolean supports(Set userBadgeSet, LocalDate localDate) { BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isTodayFoundationDay() && !userBadgeSet.contains(badgeType); + return DateTimeUtils.isFoundationDay(localDate) && !userBadgeSet.contains(badgeType); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadge.java index cbdaf05..9e2e144 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadge.java @@ -2,11 +2,12 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import java.time.LocalDate; import java.util.Set; public interface SpecialDayBadge { - boolean supports(Set userBadgeSet); + boolean supports(Set userBadgeSet, LocalDate localDate); BadgeType getBadgeType(); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/WhiteDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/WhiteDayBadge.java index 19890eb..ab03f6a 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/WhiteDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/WhiteDayBadge.java @@ -3,6 +3,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; +import java.time.LocalDate; import java.util.Set; public class WhiteDayBadge implements SpecialDayBadge { @@ -11,9 +12,9 @@ public class WhiteDayBadge implements SpecialDayBadge { } @Override - public boolean supports(Set userBadgeSet) { + public boolean supports(Set userBadgeSet, LocalDate localDate) { BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isTodayWhiteDay() && !userBadgeSet.contains(badgeType); + return DateTimeUtils.isWhiteDay(localDate) && !userBadgeSet.contains(badgeType); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java index 5b3031f..2421a79 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.domain.score.application; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; @@ -18,11 +19,12 @@ public class LandmarkRankService { private final AdventureRepository adventureRepository; + private final DateTimeService dateTimeService; @Transactional(readOnly = true) public ScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId) { ScoreRankingResponse response = ScoreRankingResponse.createEmptyResponse(); - LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(); + LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.now().toLocalDate()); List nicknameAndScores = adventureRepository.findRankTop100DescByLandmarkId(landmarkId, monthStartDateTime); nicknameAndScores.forEach(nicknameAndScore -> From 89610ac9e4396f6875cee26f111b481838c53c4e Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 1 Jul 2024 00:24:11 +0900 Subject: [PATCH 14/79] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=86=B5=EA=B3=BC=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 --- .../auth/email/api/AuthEmailSendApiTest.java | 7 +--- .../badge/application/BadgeServiceTest.java | 38 +++++++++++-------- .../application/LandmarkRankServiceTest.java | 12 ++++++ 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailSendApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailSendApiTest.java index 90ca7c7..247e125 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailSendApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailSendApiTest.java @@ -27,8 +27,6 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -62,8 +60,6 @@ void clean() { @DisplayName("이메일 인증 전송 성공") void sendAuthEmailSuccess() throws Exception { // given - doNothing().when(emailService).sendMail(any()); - String email = "test@konkuk.ac.kr"; AuthEmailSendRequest attendanceRegisterRequest = new AuthEmailSendRequest(email); String request = objectMapper.writeValueAsString(attendanceRegisterRequest); @@ -71,8 +67,7 @@ void sendAuthEmailSuccess() throws Exception { // expected MvcResult mvcResult = mockMvc.perform(post("/api/auth/emails") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess").value(true)) .andExpect(jsonPath("$.response.expireAt").exists()) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java index 09bf3ce..c697c75 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java @@ -6,6 +6,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; @@ -29,6 +30,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -54,6 +56,9 @@ class BadgeServiceTest { @Mock private CollegeSpecialBadgeFactory collegeSpecialBadgeFactory; + @Mock + private DateTimeService dateTimeService; + @Nested @DisplayName("뱃지 조회하기") class findBadge { @@ -131,14 +136,15 @@ void success_1(int attendanceDay, List expected) { user.increaseAttendanceDay(); } when(badgeRepository.findByUser(user)).thenReturn(new ArrayList<>()); + when(dateTimeService.now()).thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); List result; try (MockedStatic mockedStatic = Mockito.mockStatic(DateTimeUtils.class)) { - mockedStatic.when(DateTimeUtils::isTodayDuckDay).thenReturn(false); - mockedStatic.when(DateTimeUtils::isTodayArborDay).thenReturn(false); - mockedStatic.when(DateTimeUtils::isTodayWhiteDay).thenReturn(false); - mockedStatic.when(DateTimeUtils::isTodayChildrenDay).thenReturn(false); - mockedStatic.when(DateTimeUtils::isTodayFoundationDay).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isDuckDay(any())).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isArborDay(any())).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isWhiteDay(any())).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isChildrenDay(any())).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isFoundationDay(any())).thenReturn(false); // when NewlyRegisteredBadge newlyRegisteredBadge = badgeService.updateNewlyAttendanceBadges(user); @@ -158,14 +164,15 @@ void success_2() { // given User user = TestUtil.createUser(); when(badgeRepository.findByUser(user)).thenReturn(new ArrayList<>()); + when(dateTimeService.now()).thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); List result; try (MockedStatic mockedStatic = Mockito.mockStatic(DateTimeUtils.class)) { - mockedStatic.when(DateTimeUtils::isTodayDuckDay).thenReturn(false); - mockedStatic.when(DateTimeUtils::isTodayArborDay).thenReturn(false); - mockedStatic.when(DateTimeUtils::isTodayWhiteDay).thenReturn(false); - mockedStatic.when(DateTimeUtils::isTodayChildrenDay).thenReturn(true); - mockedStatic.when(DateTimeUtils::isTodayFoundationDay).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isDuckDay(any())).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isArborDay(any())).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isWhiteDay(any())).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isChildrenDay(any())).thenReturn(true); + mockedStatic.when(() -> DateTimeUtils.isFoundationDay(any())).thenReturn(false); // when NewlyRegisteredBadge newlyRegisteredBadge = badgeService.updateNewlyAttendanceBadges(user); @@ -191,14 +198,15 @@ void success_3() { new Badge(user, BadgeType.ATTENDANCE_10), new Badge(user, BadgeType.ATTENDANCE_CHILDREN_DAY) )); + when(dateTimeService.now()).thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); List result; try (MockedStatic mockedStatic = Mockito.mockStatic(DateTimeUtils.class)) { - mockedStatic.when(DateTimeUtils::isTodayDuckDay).thenReturn(false); - mockedStatic.when(DateTimeUtils::isTodayWhiteDay).thenReturn(false); - mockedStatic.when(DateTimeUtils::isTodayArborDay).thenReturn(false); - mockedStatic.when(DateTimeUtils::isTodayChildrenDay).thenReturn(true); - mockedStatic.when(DateTimeUtils::isTodayFoundationDay).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isDuckDay(any())).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isArborDay(any())).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isWhiteDay(any())).thenReturn(false); + mockedStatic.when(() -> DateTimeUtils.isChildrenDay(any())).thenReturn(true); + mockedStatic.when(() -> DateTimeUtils.isFoundationDay(any())).thenReturn(false); // when NewlyRegisteredBadge newlyRegisteredBadge = badgeService.updateNewlyAttendanceBadges(user); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java index 58450b4..bc6396f 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java @@ -2,6 +2,7 @@ import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; @@ -31,6 +32,9 @@ class LandmarkRankServiceTest { @Mock private AdventureRepository adventureRepository; + @Mock + private DateTimeService dateTimeService; + @Test @DisplayName("랭킹 유저가 한명도 없을 때") void getRankTop100ByLandmark1() { @@ -39,6 +43,8 @@ void getRankTop100ByLandmark1() { .thenReturn(List.of()); when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) .thenReturn(Optional.empty()); + when(dateTimeService.now()) + .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); // when User user = TestUtil.createUser(); @@ -61,6 +67,8 @@ void getRankTop100ByLandmark2() { .thenReturn(nicknameAndScores); when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) .thenReturn(Optional.empty()); + when(dateTimeService.now()) + .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); // when User user = TestUtil.createUser(); @@ -89,6 +97,8 @@ void getRankTop100ByLandmark3() { .thenReturn(nicknameAndScores); when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) .thenReturn(Optional.of(new RankAndScore(14, 37))); + when(dateTimeService.now()) + .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); // when User user = TestUtil.createUser(); @@ -116,6 +126,8 @@ void getRankTop100ByLandmark4() { .thenReturn(nicknameAndScores); when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) .thenReturn(Optional.of(new RankAndScore(40, 62))); + when(dateTimeService.now()) + .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); // when User user = TestUtil.createUser(); From 0b281ed6c51dc9817568db33d3bfb91df54d042c Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 1 Jul 2024 17:41:52 +0900 Subject: [PATCH 15/79] =?UTF-8?q?feat:=20LocalDateTime.now()=20=EB=B0=8F?= =?UTF-8?q?=20LocalDate.now()=20=EC=82=AC=EC=9A=A9=20=EC=8B=9C,=20DateTime?= =?UTF-8?q?Service=EC=97=90=EC=84=9C=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/adventure/application/AdventureService.java | 2 +- .../application/AttendanceRegisterService.java | 6 ++---- .../application/AttendanceSearchService.java | 8 ++++++-- .../auth/email/application/AuthEmailVerifyService.java | 6 +++--- .../domain/auth/token/application/TokenManager.java | 10 +++++++--- .../domain/badge/application/BadgeService.java | 2 +- .../domain/common/DateTimeService.java | 7 ++++++- .../domain/score/application/LandmarkRankService.java | 2 +- 8 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java index 2803df0..655a4c9 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java @@ -68,7 +68,7 @@ private void saveAdventure(User user, Landmark landmark, ScoreType scoreType, lo } private void updateLandmarkHighestScore(User user, Landmark landmark) { - LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.now().toLocalDate()); + LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.getLocalDateNow()); long sumScore = adventureRepository.getSumScoreByUserAndLandmark(user, landmark, monthStartDateTime); landmark.updateFirstUser(user, sumScore); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java index 4222ce3..b6d8298 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java @@ -16,8 +16,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDate; - @Service @RequiredArgsConstructor public class AttendanceRegisterService { @@ -54,13 +52,13 @@ private void validateLocation(Location location) { } private void validateDuplicateAttendance(User user) { - if (attendanceRepository.existsByUserAndAttendanceDateTimeAfter(user, LocalDate.now().atStartOfDay())) { + if (attendanceRepository.existsByUserAndAttendanceDateTimeAfter(user, dateTimeService.getLocalDateNow().atStartOfDay())) { throw new DuplicateAttendanceException(); } } private void saveAttendance(User user, Location location) { - Attendance attendance = Attendance.of(user, location, dateTimeService.now()); + Attendance attendance = Attendance.of(user, location, dateTimeService.getLocalDateTimeNow()); attendanceRepository.save(attendance); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java index b5ff638..e48c5aa 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java @@ -2,12 +2,12 @@ import com.playkuround.playkuroundserver.domain.attendance.dao.AttendanceRepository; import com.playkuround.playkuroundserver.domain.attendance.domain.Attendance; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.user.domain.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -16,10 +16,14 @@ public class AttendanceSearchService { private final AttendanceRepository attendanceRepository; + private final DateTimeService dateTimeService; @Transactional(readOnly = true) public List findAttendance(User user, int agoDays) { - LocalDateTime monthAgo = LocalDate.now().minusMonths(agoDays).atStartOfDay(); + LocalDateTime monthAgo = dateTimeService.getLocalDateNow() + .minusMonths(agoDays) + .atStartOfDay(); + List attendances = attendanceRepository.findByUserAndAttendanceDateTimeAfter(user, monthAgo); return attendances.stream() .map(Attendance::getAttendanceDateTime) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyService.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyService.java index 97f5e18..e9be648 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyService.java @@ -11,14 +11,13 @@ import com.playkuround.playkuroundserver.domain.auth.token.application.TokenService; import com.playkuround.playkuroundserver.domain.auth.token.domain.AuthVerifyToken; import com.playkuround.playkuroundserver.domain.auth.token.dto.TokenDto; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.user.application.UserLoginService; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; - @Service @RequiredArgsConstructor public class AuthEmailVerifyService { @@ -27,6 +26,7 @@ public class AuthEmailVerifyService { private final UserRepository userRepository; private final UserLoginService userLoginService; private final AuthEmailRepository authEmailRepository; + private final DateTimeService dateTimeService; @Transactional public AuthVerifyEmailResult verifyAuthEmail(String code, String email) { @@ -51,7 +51,7 @@ private void validateEmailAndCode(AuthEmail authEmail, String code) { if (!authEmail.isValidate()) { throw new AuthEmailNotFoundException(); } - if (authEmail.getExpiredAt().isBefore(LocalDateTime.now())) { + if (authEmail.getExpiredAt().isBefore(dateTimeService.getLocalDateTimeNow())) { throw new AuthCodeExpiredException(); } if (!authEmail.getCode().equals(code)) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenManager.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenManager.java index be25021..81fe6b0 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenManager.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenManager.java @@ -6,6 +6,7 @@ import com.playkuround.playkuroundserver.domain.auth.token.domain.TokenType; import com.playkuround.playkuroundserver.domain.auth.token.dto.TokenDto; import com.playkuround.playkuroundserver.domain.auth.token.exception.InvalidTokenException; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Header; import io.jsonwebtoken.Jwts; @@ -36,13 +37,15 @@ public class TokenManager { private final Long refreshTokenValidityInMilliseconds; private final Long authVerifyTokenValidityInSeconds; private final UserDetailsService userDetailsService; + private final DateTimeService dateTimeService; public TokenManager(@Value("${token.secret}") String secretKey, @Value("${token.issuer}") String issuer, @Value("${token.access-token-expiration-seconds}") Long accessTokenExpirationSeconds, @Value("${token.refresh-token-expiration-seconds}") Long refreshTokenExpirationSeconds, @Value("${token.authverify-token-expiration-seconds}") Long authVerifyTokenExpirationSeconds, - UserDetailsService userDetailsService) { + UserDetailsService userDetailsService, + DateTimeService dateTimeService) { this.accessTokenValidityInMilliseconds = accessTokenExpirationSeconds * 1000; this.refreshTokenValidityInMilliseconds = refreshTokenExpirationSeconds * 1000; this.authVerifyTokenValidityInSeconds = authVerifyTokenExpirationSeconds; @@ -51,6 +54,7 @@ public TokenManager(@Value("${token.secret}") String secretKey, this.key = Keys.hmacShaKeyFor(keyBytes); this.tokenTypeHeaderKey = "tokentype"; this.userDetailsService = userDetailsService; + this.dateTimeService = dateTimeService; } public TokenDto createTokenDto(String username) { @@ -149,12 +153,12 @@ public String getTokenType(String token) { public AuthVerifyToken createAuthVerifyTokenEntity() { String key = UUID.randomUUID().toString(); - LocalDateTime now = LocalDateTime.now(); + LocalDateTime now = dateTimeService.getLocalDateTimeNow(); return new AuthVerifyToken(key, now.plusSeconds(authVerifyTokenValidityInSeconds)); } public RefreshToken createRefreshTokenEntity(String username, String refreshToken) { - LocalDateTime now = LocalDateTime.now(); + LocalDateTime now = dateTimeService.getLocalDateTimeNow(); return RefreshToken.builder() .userEmail(username) .refreshToken(refreshToken) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java index 74dee1e..f6d4001 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java @@ -53,7 +53,7 @@ public NewlyRegisteredBadge updateNewlyAttendanceBadges(User user) { // 기념일 기준 뱃지 SpecialDayBadgeList.getSpecialDayBadges().stream() - .filter(specialDayBadge -> specialDayBadge.supports(userBadgeSet, dateTimeService.now().toLocalDate())) + .filter(specialDayBadge -> specialDayBadge.supports(userBadgeSet, dateTimeService.getLocalDateNow())) .forEach(specialDayBadge -> { BadgeType badgeType = specialDayBadge.getBadgeType(); badgeRepository.save(Badge.createBadge(user, badgeType)); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/common/DateTimeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/common/DateTimeService.java index 27feee3..494b89c 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/common/DateTimeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/common/DateTimeService.java @@ -2,13 +2,18 @@ import org.springframework.stereotype.Component; +import java.time.LocalDate; import java.time.LocalDateTime; @Component public class DateTimeService { - public LocalDateTime now() { + public LocalDateTime getLocalDateTimeNow() { return LocalDateTime.now(); } + public LocalDate getLocalDateNow() { + return LocalDate.now(); + } + } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java index 2421a79..0da421d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java @@ -24,7 +24,7 @@ public class LandmarkRankService { @Transactional(readOnly = true) public ScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId) { ScoreRankingResponse response = ScoreRankingResponse.createEmptyResponse(); - LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.now().toLocalDate()); + LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.getLocalDateNow()); List nicknameAndScores = adventureRepository.findRankTop100DescByLandmarkId(landmarkId, monthStartDateTime); nicknameAndScores.forEach(nicknameAndScore -> From ceafa748a1bed4434a0f50b3810b488207562a5f Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 1 Jul 2024 17:42:07 +0900 Subject: [PATCH 16/79] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=86=B5=EA=B3=BC=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 --- .../attendance/api/AttendanceApiTest.java | 22 ++++++++++----- .../AttendanceRegisterServiceTest.java | 19 ++++++++----- .../AttendanceSearchServiceTest.java | 14 ++++++++-- .../AuthEmailVerifyServiceTest.java | 23 +++++++++++++--- .../badge/application/BadgeServiceTest.java | 27 ++++++++++++------- .../application/LandmarkRankServiceTest.java | 17 ++++++------ 6 files changed, 85 insertions(+), 37 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java index 47206c2..bcea94e 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java @@ -21,12 +21,14 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -34,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; +import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; @@ -58,7 +61,7 @@ class AttendanceApiTest { @Autowired private AttendanceRepository attendanceRepository; - @Autowired + @SpyBean private DateTimeService dateTimeService; @Autowired @@ -119,10 +122,15 @@ void success_1() throws Exception { @WithMockCustomUser @DisplayName("출석은 하루에 한번만 가능하다.") void fail_1() throws Exception { - // TODO : 12시 넘어가는 시점에는 테스트가 실패함 // given - User user = userRepository.findAll().get(0); - attendanceRepository.save(Attendance.of(user, new Location(37.539927, 127.073006), dateTimeService.now())); + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 7, 1)); + + Attendance attendance = Attendance.of( + userRepository.findAll().get(0), + new Location(37.539927, 127.073006), + LocalDateTime.of(2024, 7, 1, 1, 0)); + attendanceRepository.save(attendance); AttendanceRegisterRequest attendanceRegisterRequest = new AttendanceRegisterRequest(37.539927, 127.073006); String request = objectMapper.writeValueAsString(attendanceRegisterRequest); @@ -180,11 +188,10 @@ class searchAttendance { void attendanceSearch() throws Exception { // TODO : need refactoring // given - User user = userRepository.findAll().get(0); Location location = new Location(37.539927, 127.073006); - LocalDateTime todayLocalDate = LocalDateTime.now(); + LocalDateTime todayLocalDate = LocalDateTime.of(2024, 7, 1, 0, 0); List dateList = new ArrayList<>(); for (int i = 29; i > 0; i -= 2) { LocalDateTime thatLocalDateTime = todayLocalDate.minusDays(i); @@ -194,6 +201,9 @@ void attendanceSearch() throws Exception { attendanceRepository.save(Attendance.of(user, location, thatLocalDateTime)); } + when(dateTimeService.getLocalDateNow()) + .thenReturn(todayLocalDate.toLocalDate()); + // expected MvcResult mvcResult = mockMvc.perform(get("/api/attendances")) .andExpect(status().isOk()) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java index b2b6e22..f81d11a 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java @@ -21,6 +21,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.time.LocalDate; import java.time.LocalDateTime; import static org.assertj.core.api.Assertions.assertThat; @@ -55,9 +56,8 @@ void registerAttendance_1() { // given when(attendanceRepository.existsByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) .thenReturn(false); - - when(dateTimeService.now()) - .thenReturn(LocalDateTime.of(2024, 6, 30, 0, 0)); + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 6, 30)); NewlyRegisteredBadge newlyRegisteredBadge = new NewlyRegisteredBadge(); newlyRegisteredBadge.addBadge(BadgeType.ATTENDANCE_1); @@ -65,9 +65,10 @@ void registerAttendance_1() { when(badgeService.updateNewlyAttendanceBadges(any(User.class))) .thenReturn(newlyRegisteredBadge); - // when User user = TestUtil.createUser(); Location location = new Location(37.539927, 127.073006); + + // when NewlyRegisteredBadge result = attendanceRegisterService.registerAttendance(user, location); // then @@ -86,9 +87,11 @@ void registerAttendance_1() { @Test @DisplayName("출석 범위에 벗어나면 에러가 발생한다") void registerAttendance_2() { - // expect + // given User user = TestUtil.createUser(); Location location = new Location(0.0, 0.0); + + // expect assertThatThrownBy(() -> attendanceRegisterService.registerAttendance(user, location)) .isInstanceOf(InvalidAttendanceLocationException.class); } @@ -99,10 +102,12 @@ void registerAttendance_3() { // given when(attendanceRepository.existsByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) .thenReturn(true); - - // expect + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 6, 30)); User user = TestUtil.createUser(); Location location = new Location(37.539927, 127.073006); + + // expect assertThatThrownBy(() -> attendanceRegisterService.registerAttendance(user, location)) .isInstanceOf(DuplicateAttendanceException.class); } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java index 935877a..79cf361 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java @@ -3,6 +3,7 @@ import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.attendance.dao.AttendanceRepository; import com.playkuround.playkuroundserver.domain.attendance.domain.Attendance; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.global.util.Location; import org.junit.jupiter.api.DisplayName; @@ -12,6 +13,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -31,12 +33,18 @@ class AttendanceSearchServiceTest { @Mock private AttendanceRepository attendanceRepository; + @Mock + private DateTimeService dateTimeService; + @Test @DisplayName("한달동안의 출석정보가 정렬되어 반환된다") void findAttendanceForMonth_1() { // given + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 7, 1)); + Random random = new Random(); - LocalDateTime now = LocalDateTime.now(); + LocalDateTime now = LocalDateTime.of(2024, 7, 1, 0, 0); User user = TestUtil.createUser(); Location location = new Location(37.539927, 127.073006); @@ -49,7 +57,6 @@ void findAttendanceForMonth_1() { .sorted() .forEach(x -> { Attendance attendance = Attendance.of(user, location, now.plusDays(x)); - //ReflectionTestUtils.setField(attendance, "createdAt", now.plusDays(x)); attendances.add(attendance); expected.add(attendance.getAttendanceDateTime()); @@ -57,6 +64,7 @@ void findAttendanceForMonth_1() { when(attendanceRepository.findByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) .thenReturn(attendances); + // when List result = attendanceSearchService.findAttendance(user, 30); @@ -68,6 +76,8 @@ void findAttendanceForMonth_1() { @DisplayName("출석정보가 없으면 빈리스트가 반환된다") void findAttendanceForMonth_2() { // given + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 7, 1)); when(attendanceRepository.findByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) .thenReturn(new ArrayList<>()); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java index ce17d1c..e815f3a 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java @@ -12,6 +12,7 @@ import com.playkuround.playkuroundserver.domain.auth.token.application.TokenService; import com.playkuround.playkuroundserver.domain.auth.token.domain.AuthVerifyToken; import com.playkuround.playkuroundserver.domain.auth.token.dto.TokenDto; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.user.application.UserLoginService; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -48,6 +49,9 @@ class AuthEmailVerifyServiceTest { @Mock private AuthEmailRepository authEmailRepository; + @Mock + private DateTimeService dateTimeService; + @Test @DisplayName("이메일 인증 정상 처리 : 기존회원") void authEmailSuccessExists() { @@ -55,11 +59,15 @@ void authEmailSuccessExists() { User user = TestUtil.createUser(); String target = user.getEmail(); String code = "123456"; - LocalDateTime expiredAt = LocalDateTime.now().plusMinutes(5); + LocalDateTime expiredAt = LocalDateTime.of(2024, 7, 1, 0, 0); AuthEmail authEmail = AuthEmail.createAuthEmail(target, code, expiredAt); when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(target)) .thenReturn(Optional.of(authEmail)); - when(userRepository.existsByEmail(target)).thenReturn(true); + when(userRepository.existsByEmail(target)) + .thenReturn(true); + when(dateTimeService.getLocalDateTimeNow()) + .thenReturn(expiredAt.minusMinutes(2)); + TokenDto tokenDto = new TokenDto("Bearer", "accessToken", "refreshToken", null, null); when(userLoginService.login(target)).thenReturn(tokenDto); @@ -83,11 +91,14 @@ void authEmailSuccessNewUser() { String target = user.getEmail(); String code = "123456"; String authVerify = "authVerifyToken"; - LocalDateTime expiredAt = LocalDateTime.now().plusMinutes(5); + LocalDateTime expiredAt = LocalDateTime.of(2024, 7, 1, 0, 0); AuthEmail authEmail = AuthEmail.createAuthEmail(target, code, expiredAt); when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(target)) .thenReturn(Optional.of(authEmail)); - when(userRepository.existsByEmail(target)).thenReturn(false); + when(userRepository.existsByEmail(target)) + .thenReturn(false); + when(dateTimeService.getLocalDateTimeNow()) + .thenReturn(expiredAt.minusMinutes(2)); AuthVerifyToken authVerifyToken = new AuthVerifyToken(authVerify, null); when(tokenService.registerAuthVerifyToken()).thenReturn(authVerifyToken); @@ -134,6 +145,8 @@ void authEmailExpired() { AuthEmail authEmail = AuthEmail.createAuthEmail("target", "code", LocalDateTime.now().minusDays(1)); when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(any(String.class))) .thenReturn(Optional.of(authEmail)); + when(dateTimeService.getLocalDateTimeNow()) + .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); // expected assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail("code", "target")) @@ -148,6 +161,8 @@ void authEmailCodeNotEquals() { AuthEmail authEmail = AuthEmail.createAuthEmail("target", code, LocalDateTime.now().plusMinutes(1)); when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(any(String.class))) .thenReturn(Optional.of(authEmail)); + when(dateTimeService.getLocalDateTimeNow()) + .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); // expected assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail(code + "NotEqual", "target")) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java index c697c75..a211056 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java @@ -30,7 +30,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.time.LocalDateTime; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -135,8 +135,10 @@ void success_1(int attendanceDay, List expected) { for (int i = 0; i < attendanceDay; i++) { user.increaseAttendanceDay(); } - when(badgeRepository.findByUser(user)).thenReturn(new ArrayList<>()); - when(dateTimeService.now()).thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); + when(badgeRepository.findByUser(user)) + .thenReturn(new ArrayList<>()); + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 7, 1)); List result; try (MockedStatic mockedStatic = Mockito.mockStatic(DateTimeUtils.class)) { @@ -163,8 +165,10 @@ void success_1(int attendanceDay, List expected) { void success_2() { // given User user = TestUtil.createUser(); - when(badgeRepository.findByUser(user)).thenReturn(new ArrayList<>()); - when(dateTimeService.now()).thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); + when(badgeRepository.findByUser(user)) + .thenReturn(new ArrayList<>()); + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 7, 1)); List result; try (MockedStatic mockedStatic = Mockito.mockStatic(DateTimeUtils.class)) { @@ -198,7 +202,8 @@ void success_3() { new Badge(user, BadgeType.ATTENDANCE_10), new Badge(user, BadgeType.ATTENDANCE_CHILDREN_DAY) )); - when(dateTimeService.now()).thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 7, 1)); List result; try (MockedStatic mockedStatic = Mockito.mockStatic(DateTimeUtils.class)) { @@ -281,12 +286,13 @@ void success_1(LandmarkType landmarkType, List badgeTypeList) throws Exc when(collegeSpecialBadgeFactory.getBadgeType(any(User.class), any(Set.class), any(Landmark.class))) .thenReturn(Optional.empty()); - // when Landmark landmark = createLandmark(landmarkType); + + // when NewlyRegisteredBadge newlyRegisteredBadge = badgeService.updateNewlyAdventureBadges(user, landmark); - List result = newlyRegisteredBadge.getNewlyBadges(); // then + List result = newlyRegisteredBadge.getNewlyBadges(); List target = result.stream() .map(NewlyRegisteredBadge.BadgeInfo::name) .toList(); @@ -303,12 +309,13 @@ void success_2() throws Exception { when(collegeSpecialBadgeFactory.getBadgeType(any(User.class), any(Set.class), any(Landmark.class))) .thenReturn(Optional.of(BadgeType.COLLEGE_OF_ENGINEERING_A)); - // when Landmark landmark = createLandmark(LandmarkType.공학관A); + + // when NewlyRegisteredBadge newlyRegisteredBadge = badgeService.updateNewlyAdventureBadges(user, landmark); - List result = newlyRegisteredBadge.getNewlyBadges(); // then + List result = newlyRegisteredBadge.getNewlyBadges(); List target = result.stream() .map(NewlyRegisteredBadge.BadgeInfo::name) .toList(); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java index bc6396f..6681886 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java @@ -14,6 +14,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -43,8 +44,8 @@ void getRankTop100ByLandmark1() { .thenReturn(List.of()); when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) .thenReturn(Optional.empty()); - when(dateTimeService.now()) - .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 7, 1)); // when User user = TestUtil.createUser(); @@ -67,8 +68,8 @@ void getRankTop100ByLandmark2() { .thenReturn(nicknameAndScores); when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) .thenReturn(Optional.empty()); - when(dateTimeService.now()) - .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 7, 1)); // when User user = TestUtil.createUser(); @@ -97,8 +98,8 @@ void getRankTop100ByLandmark3() { .thenReturn(nicknameAndScores); when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) .thenReturn(Optional.of(new RankAndScore(14, 37))); - when(dateTimeService.now()) - .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 7, 1)); // when User user = TestUtil.createUser(); @@ -126,8 +127,8 @@ void getRankTop100ByLandmark4() { .thenReturn(nicknameAndScores); when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) .thenReturn(Optional.of(new RankAndScore(40, 62))); - when(dateTimeService.now()) - .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); + when(dateTimeService.getLocalDateNow()) + .thenReturn(LocalDate.of(2024, 7, 1)); // when User user = TestUtil.createUser(); From 7b5409311139c652a681fab4b7ad068dce80cb43 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 2 Jul 2024 16:33:13 +0900 Subject: [PATCH 17/79] =?UTF-8?q?refactor:=20=EC=9D=B8=EC=8B=9D=20?= =?UTF-8?q?=EA=B1=B0=EB=A6=AC=20=EB=B0=98=EA=B2=BD=20=ED=8C=90=EB=8B=A8?= =?UTF-8?q?=EC=9D=84=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/AdventureService.java | 10 +++--- .../adventure/dao/AdventureRepository.java | 32 +++++++++---------- .../domain/landmark/domain/Landmark.java | 9 ++++++ 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java index 655a4c9..0afb147 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java @@ -16,7 +16,6 @@ import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import com.playkuround.playkuroundserver.global.util.Location; -import com.playkuround.playkuroundserver.global.util.LocationDistanceUtils; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -49,16 +48,15 @@ public NewlyRegisteredBadge saveAdventure(AdventureSaveDto adventureSaveDto) { } private void validateLocation(Landmark landmark, Location location) { - Location locationOfLandmark = new Location(landmark.getLatitude(), landmark.getLongitude()); - double distance = LocationDistanceUtils.distance(locationOfLandmark, location); - if (distance > landmark.getRecognitionRadius()) { + if (!landmark.isInRecognitionRadius(location)) { throw new InvalidLandmarkLocationException(); } } private void updateUserScore(User user, ScoreType scoreType, long score) { totalScoreService.incrementTotalScore(user, score); - user.getHighestScore().updateGameHighestScore(scoreType, score); + user.getHighestScore() + .updateGameHighestScore(scoreType, score); userRepository.save(user); } @@ -69,7 +67,7 @@ private void saveAdventure(User user, Landmark landmark, ScoreType scoreType, lo private void updateLandmarkHighestScore(User user, Landmark landmark) { LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.getLocalDateNow()); - long sumScore = adventureRepository.getSumScoreByUserAndLandmark(user, landmark, monthStartDateTime); + long sumScore = adventureRepository.getSumScoreByUserAndLandmarkAfter(user, landmark, monthStartDateTime); landmark.updateFirstUser(user, sumScore); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java index a7e6463..10c2ce2 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java @@ -15,22 +15,20 @@ public interface AdventureRepository extends JpaRepository { - @Query(value = - "SELECT new com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore(a.user.nickname, cast(SUM(a.score) as integer)) " + - "FROM Adventure a " + - "where a.landmark.id=:landmark AND a.createdAt >= :from " + - "GROUP BY a.user.id " + - "ORDER BY SUM(a.score) DESC, a.user.nickname DESC " + - "LIMIT 100") + @Query("SELECT new com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore(a.user.nickname, cast(SUM(a.score) as integer)) " + + "FROM Adventure a " + + "where a.landmark.id=:landmark AND a.createdAt >= :from " + + "GROUP BY a.user.id " + + "ORDER BY SUM(a.score) DESC, a.user.nickname DESC " + + "LIMIT 100") List findRankTop100DescByLandmarkId(@Param(value = "landmark") Long landmarkId, @Param(value = "from") LocalDateTime from); - @Query(value = - "SELECT new com.playkuround.playkuroundserver.domain.score.dto.RankAndScore(cast(user_rank as integer), cast(score as integer)) FROM " + - "(SELECT a.user.id as user_id, (RANK() over (order by SUM(a.score) desc)) as user_rank, SUM(a.score) as score " + - "FROM Adventure a " + - "where a.landmark.id=:landmark AND a.createdAt >= :from " + - "GROUP BY a.user.id) " + - "where user_id=:#{#user.id}") + @Query("SELECT new com.playkuround.playkuroundserver.domain.score.dto.RankAndScore(cast(user_rank as integer), cast(score as integer)) FROM " + + "(SELECT a.user.id as user_id, (RANK() over (order by SUM(a.score) desc)) as user_rank, SUM(a.score) as score " + + "FROM Adventure a " + + "where a.landmark.id=:landmark AND a.createdAt >= :from " + + "GROUP BY a.user.id) " + + "where user_id=:#{#user.id}") Optional findMyRankByLandmarkId(@Param(value = "user") User user, @Param(value = "landmark") Long landmarkId, @Param(value = "from") LocalDateTime from); @@ -38,9 +36,9 @@ Optional findMyRankByLandmarkId(@Param(value = "user") User user, @Query("SELECT SUM(a.score) " + "FROM Adventure a " + "WHERE a.user.id=:#{#user.id} AND a.landmark.id=:#{#landmark.id} AND a.createdAt >= :from") - long getSumScoreByUserAndLandmark(@Param(value = "user") User user, - @Param(value = "landmark") Landmark landmark, - @Param(value = "from") LocalDateTime from); + long getSumScoreByUserAndLandmarkAfter(@Param(value = "user") User user, + @Param(value = "landmark") Landmark landmark, + @Param(value = "from") LocalDateTime from); long countByUserAndLandmark(User user, Landmark requestSaveLandmark); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java index 27a30bf..c898c4d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java @@ -1,6 +1,8 @@ package com.playkuround.playkuroundserver.domain.landmark.domain; import com.playkuround.playkuroundserver.domain.user.domain.User; +import com.playkuround.playkuroundserver.global.util.Location; +import com.playkuround.playkuroundserver.global.util.LocationDistanceUtils; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; @@ -46,4 +48,11 @@ public void deleteRank() { this.firstUser = null; this.highestScore = 0; } + + public boolean isInRecognitionRadius(Location location) { + Location locationOfLandmark = new Location(latitude, longitude); + double distance = LocationDistanceUtils.distance(locationOfLandmark, location); + + return distance <= recognitionRadius; + } } From 0d3c52b726fb9fb85de579cb0c0d15708231e5b1 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 2 Jul 2024 16:33:46 +0900 Subject: [PATCH 18/79] test: AdventureService integration test --- .../IntegrationServiceTest.java | 17 ++ .../application/AdventureServiceTest.java | 157 ++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 src/test/java/com/playkuround/playkuroundserver/IntegrationServiceTest.java create mode 100644 src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java diff --git a/src/test/java/com/playkuround/playkuroundserver/IntegrationServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/IntegrationServiceTest.java new file mode 100644 index 0000000..4c8f07d --- /dev/null +++ b/src/test/java/com/playkuround/playkuroundserver/IntegrationServiceTest.java @@ -0,0 +1,17 @@ +package com.playkuround.playkuroundserver; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.context.SpringBootTest; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@SpringBootTest(properties = "spring.profiles.active=test") +@EntityScan(basePackages = {"com.playkuround.playkuroundserver.domain"}) +public @interface IntegrationServiceTest { +} + diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java new file mode 100644 index 0000000..2d59584 --- /dev/null +++ b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java @@ -0,0 +1,157 @@ +package com.playkuround.playkuroundserver.domain.adventure.application; + +import com.playkuround.playkuroundserver.IntegrationServiceTest; +import com.playkuround.playkuroundserver.TestUtil; +import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; +import com.playkuround.playkuroundserver.domain.adventure.domain.Adventure; +import com.playkuround.playkuroundserver.domain.adventure.dto.AdventureSaveDto; +import com.playkuround.playkuroundserver.domain.adventure.exception.InvalidLandmarkLocationException; +import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; +import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; +import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; +import com.playkuround.playkuroundserver.domain.landmark.exception.LandmarkNotFoundException; +import com.playkuround.playkuroundserver.domain.score.domain.ScoreType; +import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; +import com.playkuround.playkuroundserver.domain.user.domain.Major; +import com.playkuround.playkuroundserver.domain.user.domain.User; +import com.playkuround.playkuroundserver.global.util.Location; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.test.context.jdbc.Sql; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.*; + +@IntegrationServiceTest +@Sql(scripts = {"/data-mysql.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) +class AdventureServiceTest { + + private final String redisSetKey = "ranking"; + @Autowired + private BadgeRepository badgeRepository; + @Autowired + private UserRepository userRepository; + @Autowired + private AdventureRepository adventureRepository; + @Autowired + private RedisTemplate redisTemplate; + @Autowired + private LandmarkRepository landmarkRepository; + @Autowired + private AdventureService adventureService; + + @AfterEach + void clean() { + badgeRepository.deleteAllInBatch(); + adventureRepository.deleteAllInBatch(); + landmarkRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); + redisTemplate.delete(redisSetKey); + } + + @Test + @DisplayName("탐험을 하게 되면 total score 증가, adventure 저장, 랜드마크별 최고기록과 유저별 게임 최고기록이 업데이트 된다.") + void saveAdventure_1() { + // given + User user = TestUtil.createUser(); + + Landmark landmark = landmarkRepository.findById(3L).get(); + Location location = new Location(landmark.getLatitude(), landmark.getLongitude()); + AdventureSaveDto adventureSaveDto = new AdventureSaveDto(user, landmark.getId(), location, 100, ScoreType.BOOK); + + // when + NewlyRegisteredBadge newlyRegisteredBadge = adventureService.saveAdventure(adventureSaveDto); + + // then + // Total Score 저장 및 최고 점수 갱신 + List users = userRepository.findAll(); + assertThat(users).hasSize(1) + .extracting("highestScore.highestCardScore") + .containsExactly(adventureSaveDto.score()); + + // adventure 저장 + List adventures = adventureRepository.findAll(); + assertThat(adventures).hasSize(1) + .extracting("score", "scoreType", "user.id", "landmark.id") + .containsOnly(tuple(adventureSaveDto.score(), adventureSaveDto.scoreType(), users.get(0).getId(), landmark.getId())); + + // 랜드마크 최고 점수 갱신 + Optional optionalLandmark = landmarkRepository.findById(landmark.getId()); + assertThat(optionalLandmark).isPresent() + .get() + .extracting("highestScore", "firstUser.id") + .contains(adventureSaveDto.score(), users.get(0).getId()); + } + + @Test + @DisplayName("랜드마크가 존재하지 않으면 에러가 발생한다.") + void saveAdventure_2() { + // given + User user = TestUtil.createUser(); + + Landmark landmark = landmarkRepository.findById(3L).get(); + Location location = new Location(landmark.getLatitude(), landmark.getLongitude()); + AdventureSaveDto adventureSaveDto = new AdventureSaveDto(user, -1L, location, 100, ScoreType.BOOK); + + // expected + assertThatThrownBy(() -> adventureService.saveAdventure(adventureSaveDto)) + .isInstanceOf(LandmarkNotFoundException.class) + .hasMessage("-1의 랜드마크 조회에 실패하였습니다."); + + List adventures = adventureRepository.findAll(); + assertThat(adventures).isEmpty(); + } + + @Test + @DisplayName("인식 거리 밖에 있으면 에러가 발생한다.") + void saveAdventure_3() { + // given + User user = TestUtil.createUser(); + + Landmark landmark = landmarkRepository.findById(3L).get(); + Location location = new Location(0, 0); + AdventureSaveDto adventureSaveDto = new AdventureSaveDto(user, landmark.getId(), location, 100, ScoreType.BOOK); + + // when + assertThatThrownBy(() -> adventureService.saveAdventure(adventureSaveDto)) + .isInstanceOf(InvalidLandmarkLocationException.class) + .hasMessage("현재 위치와 랜드마크 위치가 너무 멉니다."); + + List adventures = adventureRepository.findAll(); + assertThat(adventures).isEmpty(); + } + + @Test + @DisplayName("랜드마크 최고 기록자가 아니라면, 랜드마크 랭킹 1위는 업데이트 되지 않는다.") + void saveAdventure_4() { + // given + User user = TestUtil.createUser(); + User otherUser = TestUtil.createUser("other@test.com", "other", Major.건축학부); + userRepository.saveAll(List.of(user, otherUser)); + + long highestScore = 1000; + Landmark landmark = landmarkRepository.findById(3L).get(); + landmark.updateFirstUser(otherUser, highestScore); + landmarkRepository.save(landmark); // update + + Location location = new Location(landmark.getLatitude(), landmark.getLongitude()); + AdventureSaveDto adventureSaveDto = new AdventureSaveDto(user, landmark.getId(), location, 100, ScoreType.BOOK); + + // when + NewlyRegisteredBadge newlyRegisteredBadge = adventureService.saveAdventure(adventureSaveDto); + + // then + Optional optionalLandmark = landmarkRepository.findById(landmark.getId()); + assertThat(optionalLandmark).isPresent() + .get() + .extracting("highestScore", "firstUser.id") + .contains(highestScore, otherUser.getId()); + } + +} \ No newline at end of file From 7c5745afb1a16945241e837d95eb7b216f62984e Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 2 Jul 2024 16:34:04 +0900 Subject: [PATCH 19/79] =?UTF-8?q?test:=20AuthEmailVerifyServiceTest=20?= =?UTF-8?q?=ED=86=B5=EA=B3=BC=EB=90=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/email/application/AuthEmailVerifyServiceTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java index e815f3a..e92dc21 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java @@ -142,11 +142,12 @@ void authEmailInvalidate() { @DisplayName("authEmail이 만료되면 AuthCodeExpiredException 발생") void authEmailExpired() { // given - AuthEmail authEmail = AuthEmail.createAuthEmail("target", "code", LocalDateTime.now().minusDays(1)); + LocalDateTime now = LocalDateTime.of(2024, 7, 1, 0, 0); + AuthEmail authEmail = AuthEmail.createAuthEmail("target", "code", now.minusDays(1)); when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(any(String.class))) .thenReturn(Optional.of(authEmail)); when(dateTimeService.getLocalDateTimeNow()) - .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); + .thenReturn(now); // expected assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail("code", "target")) From 897871c8948caa83ca2174512edd1192e7807b70 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sat, 17 Aug 2024 09:47:31 +0900 Subject: [PATCH 20/79] =?UTF-8?q?feat:=20=EC=83=88=EB=A1=9C=EC=9A=B4=20?= =?UTF-8?q?=EB=B1=83=EC=A7=80=20=EC=B6=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../specialday_badge/ChristmasDayBadge.java | 24 ++++++++++++ .../specialday_badge/ChuseokDayBadge.java | 24 ++++++++++++ .../specialday_badge/DokdoDayBadge.java | 24 ++++++++++++ .../specialday_badge/KimchiDayBadge.java | 24 ++++++++++++ .../specialday_badge/KoreanDayBadge.java | 24 ++++++++++++ .../specialday_badge/SpecialDayBadgeList.java | 9 ++++- .../domain/badge/domain/BadgeType.java | 6 +++ .../global/util/DateTimeUtils.java | 20 ++++++++++ .../WithMockCustomUserNotSave.java | 22 +++++++++++ ...stomUserNotSaveSecurityContextFactory.java | 38 +++++++++++++++++++ 10 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChristmasDayBadge.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChuseokDayBadge.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DokdoDayBadge.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KimchiDayBadge.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KoreanDayBadge.java create mode 100644 src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserNotSave.java create mode 100644 src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserNotSaveSecurityContextFactory.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChristmasDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChristmasDayBadge.java new file mode 100644 index 0000000..0962137 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChristmasDayBadge.java @@ -0,0 +1,24 @@ +package com.playkuround.playkuroundserver.domain.badge.application.specialday_badge; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.global.util.DateTimeUtils; + +import java.time.LocalDate; +import java.util.Set; + +public class ChristmasDayBadge implements SpecialDayBadge { + + ChristmasDayBadge() { + } + + @Override + public boolean supports(Set userBadgeSet, LocalDate localDate) { + BadgeType badgeType = getBadgeType(); + return DateTimeUtils.isChristmasDay(localDate) && !userBadgeSet.contains(badgeType); + } + + @Override + public BadgeType getBadgeType() { + return BadgeType.ATTENDANCE_CHRISTMAS_DAY; + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChuseokDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChuseokDayBadge.java new file mode 100644 index 0000000..f51bc2b --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChuseokDayBadge.java @@ -0,0 +1,24 @@ +package com.playkuround.playkuroundserver.domain.badge.application.specialday_badge; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.global.util.DateTimeUtils; + +import java.time.LocalDate; +import java.util.Set; + +public class ChuseokDayBadge implements SpecialDayBadge { + + ChuseokDayBadge() { + } + + @Override + public boolean supports(Set userBadgeSet, LocalDate localDate) { + BadgeType badgeType = getBadgeType(); + return DateTimeUtils.isChuseokDay(localDate) && !userBadgeSet.contains(badgeType); + } + + @Override + public BadgeType getBadgeType() { + return BadgeType.ATTENDANCE_CHUSEOK_DAY; + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DokdoDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DokdoDayBadge.java new file mode 100644 index 0000000..9fafdcc --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DokdoDayBadge.java @@ -0,0 +1,24 @@ +package com.playkuround.playkuroundserver.domain.badge.application.specialday_badge; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.global.util.DateTimeUtils; + +import java.time.LocalDate; +import java.util.Set; + +public class DokdoDayBadge implements SpecialDayBadge { + + DokdoDayBadge() { + } + + @Override + public boolean supports(Set userBadgeSet, LocalDate localDate) { + BadgeType badgeType = getBadgeType(); + return DateTimeUtils.isDokdoDay(localDate) && !userBadgeSet.contains(badgeType); + } + + @Override + public BadgeType getBadgeType() { + return BadgeType.ATTENDANCE_DOKDO_DAY; + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KimchiDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KimchiDayBadge.java new file mode 100644 index 0000000..6e84a7c --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KimchiDayBadge.java @@ -0,0 +1,24 @@ +package com.playkuround.playkuroundserver.domain.badge.application.specialday_badge; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.global.util.DateTimeUtils; + +import java.time.LocalDate; +import java.util.Set; + +public class KimchiDayBadge implements SpecialDayBadge { + + KimchiDayBadge() { + } + + @Override + public boolean supports(Set userBadgeSet, LocalDate localDate) { + BadgeType badgeType = getBadgeType(); + return DateTimeUtils.isKimchiDay(localDate) && !userBadgeSet.contains(badgeType); + } + + @Override + public BadgeType getBadgeType() { + return BadgeType.ATTENDANCE_KIMCHI_DAY; + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KoreanDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KoreanDayBadge.java new file mode 100644 index 0000000..254ac02 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KoreanDayBadge.java @@ -0,0 +1,24 @@ +package com.playkuround.playkuroundserver.domain.badge.application.specialday_badge; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.global.util.DateTimeUtils; + +import java.time.LocalDate; +import java.util.Set; + +public class KoreanDayBadge implements SpecialDayBadge { + + KoreanDayBadge() { + } + + @Override + public boolean supports(Set userBadgeSet, LocalDate localDate) { + BadgeType badgeType = getBadgeType(); + return DateTimeUtils.isKoreanDay(localDate) && !userBadgeSet.contains(badgeType); + } + + @Override + public BadgeType getBadgeType() { + return BadgeType.ATTENDANCE_KOREAN_DAY; + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadgeList.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadgeList.java index 8a3a864..bd3e6d7 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadgeList.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadgeList.java @@ -7,12 +7,17 @@ public class SpecialDayBadgeList { @Getter - private final static List specialDayBadges = List.of( + private static final List specialDayBadges = List.of( new FoundationDayBadge(), new ArborDayBadge(), new ChildrenDayBadge(), new DuckDayBadge(), - new WhiteDayBadge() + new WhiteDayBadge(), + new ChuseokDayBadge(), + new KoreanDayBadge(), + new DokdoDayBadge(), + new KimchiDayBadge(), + new ChristmasDayBadge() ); private SpecialDayBadgeList() { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java index fa0f7e2..ad6d2a0 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java @@ -21,6 +21,12 @@ public enum BadgeType { ATTENDANCE_CHILDREN_DAY("05월 05일 어린이날에 출석"), ATTENDANCE_WHITE_DAY("03월 14일 화이트데이에 출석"), ATTENDANCE_DUCK_DAY("05월 02일 오리데이에 출석"), + // 가을학기 추가 뱃지 + ATTENDANCE_CHUSEOK_DAY("09월 17일 추석날에 출석"), + ATTENDANCE_KOREAN_DAY("10월 09일 한글날에 출석"), + ATTENDANCE_DOKDO_DAY("10월 25일 독도의 날에 출석"), + ATTENDANCE_KIMCHI_DAY("11월 22일 김치의 날에 출석"), + ATTENDANCE_CHRISTMAS_DAY("12월 25일 성탄절에 출석"), // 대학별 COLLEGE_OF_LIBERAL_ARTS("문과대학 1회 이상 탐험"), diff --git a/src/main/java/com/playkuround/playkuroundserver/global/util/DateTimeUtils.java b/src/main/java/com/playkuround/playkuroundserver/global/util/DateTimeUtils.java index 32f42c3..cb7b572 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/util/DateTimeUtils.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/util/DateTimeUtils.java @@ -32,4 +32,24 @@ public static boolean isDuckDay(LocalDate localDate) { return localDate.getMonth().getValue() == 5 && localDate.getDayOfMonth() == 2; } + public static boolean isChuseokDay(LocalDate localDate) { + return localDate.getMonth().getValue() == 9 && localDate.getDayOfMonth() == 17; + } + + public static boolean isKoreanDay(LocalDate localDate) { + return localDate.getMonth().getValue() == 10 && localDate.getDayOfMonth() == 9; + } + + public static boolean isDokdoDay(LocalDate localDate) { + return localDate.getMonth().getValue() == 10 && localDate.getDayOfMonth() == 25; + } + + public static boolean isKimchiDay(LocalDate localDate) { + return localDate.getMonth().getValue() == 11 && localDate.getDayOfMonth() == 22; + } + + public static boolean isChristmasDay(LocalDate localDate) { + return localDate.getMonth().getValue() == 12 && localDate.getDayOfMonth() == 25; + } + } diff --git a/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserNotSave.java b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserNotSave.java new file mode 100644 index 0000000..a0e711d --- /dev/null +++ b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserNotSave.java @@ -0,0 +1,22 @@ +package com.playkuround.playkuroundserver.securityConfig; + + +import com.playkuround.playkuroundserver.domain.user.domain.Major; +import com.playkuround.playkuroundserver.domain.user.domain.Role; +import org.springframework.security.test.context.support.WithSecurityContext; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +@WithSecurityContext(factory = WithMockCustomUserNotSaveSecurityContextFactory.class) +public @interface WithMockCustomUserNotSave { + + String email() default "tester@konkuk.ac.kr"; + + String nickname() default "tester"; + + Major major() default Major.컴퓨터공학부; + + Role role() default Role.ROLE_USER; +} diff --git a/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserNotSaveSecurityContextFactory.java b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserNotSaveSecurityContextFactory.java new file mode 100644 index 0000000..b441856 --- /dev/null +++ b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserNotSaveSecurityContextFactory.java @@ -0,0 +1,38 @@ +package com.playkuround.playkuroundserver.securityConfig; + +import com.playkuround.playkuroundserver.domain.user.domain.User; +import com.playkuround.playkuroundserver.global.security.UserDetailsImpl; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.test.context.support.WithSecurityContextFactory; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +@Component +public class WithMockCustomUserNotSaveSecurityContextFactory + implements WithSecurityContextFactory { + + public SecurityContext createSecurityContext(WithMockCustomUserNotSave annotation) { + User user = User.create(annotation.email(), annotation.nickname(), annotation.major(), annotation.role()); + String roleName = user.getRole().toString(); + List role = Arrays.stream(roleName.split(",")).toList(); + UserDetailsImpl userDetails = new UserDetailsImpl(user, "", role); + + Collection authorities = role.stream() + .map(SimpleGrantedAuthority::new) + .toList(); + + Authentication authentication = UsernamePasswordAuthenticationToken.authenticated(userDetails, "", authorities); + + SecurityContext context = SecurityContextHolder.getContext(); + context.setAuthentication(authentication); + return context; + } +} From 25950a3c252f81af0f268abd2c54306ccb4b1a38 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sat, 17 Aug 2024 20:12:47 +0900 Subject: [PATCH 21/79] =?UTF-8?q?feat:=20=EC=A2=85=ED=95=A9=20=EC=A0=90?= =?UTF-8?q?=EC=88=98=20=ED=83=91=20100=20api=EC=97=90=EC=84=9C=20=EB=8C=80?= =?UTF-8?q?=ED=91=9C=20=EB=B1=83=EC=A7=80=EB=8F=84=20=ED=8F=AC=ED=95=A8?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/score/api/ScoreApi.java | 7 ++- .../response/ScoreRankingResponse.java | 2 +- .../response/TotalScoreRankingResponse.java | 58 +++++++++++++++++++ .../application/LandmarkRankService.java | 2 +- .../score/application/ScoreRankService.java | 13 +++-- .../score/application/TotalScoreService.java | 24 ++++---- .../domain/score/dto/NickNameAndBadge.java | 6 ++ .../domain/user/dao/UserRepository.java | 6 +- .../domain/user/domain/User.java | 21 ++++--- .../domain/user/dto/EmailAndNickname.java | 4 -- .../user/dto/EmailAndNicknameAndBadge.java | 6 ++ .../score/api/LandmarkScoreRankApiTest.java | 6 +- .../score/api/ScoreTotalRankApiTest.java | 6 +- .../application/LandmarkRankServiceTest.java | 10 ++-- .../application/TotalScoreServiceTest.java | 53 ++++++++--------- 15 files changed, 152 insertions(+), 72 deletions(-) rename src/main/java/com/playkuround/playkuroundserver/domain/score/{dto => api}/response/ScoreRankingResponse.java (94%) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NickNameAndBadge.java delete mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/user/dto/EmailAndNickname.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/user/dto/EmailAndNicknameAndBadge.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java index ddc89e7..318950d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java @@ -1,8 +1,9 @@ package com.playkuround.playkuroundserver.domain.score.api; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.application.LandmarkRankService; import com.playkuround.playkuroundserver.domain.score.application.TotalScoreService; -import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; import com.playkuround.playkuroundserver.global.security.UserDetailsImpl; import com.playkuround.playkuroundserver.global.util.ApiUtils; @@ -27,8 +28,8 @@ public class ScoreApi { @GetMapping("/rank") @Operation(summary = "종합 점수 탑100 얻기", description = "토탈 점수 탑100과 내 점수, 등수를 반환합니다. 내 점수가 0점이면 등수는 0등으로 반환됩니다.") - public ApiResponse getScoreTop100(@AuthenticationPrincipal UserDetailsImpl userDetails) { - ScoreRankingResponse response = totalScoreService.getRankTop100(userDetails.getUser()); + public ApiResponse getScoreTop100(@AuthenticationPrincipal UserDetailsImpl userDetails) { + TotalScoreRankingResponse response = totalScoreService.getRankTop100(userDetails.getUser()); return ApiUtils.success(response); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/response/ScoreRankingResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java similarity index 94% rename from src/main/java/com/playkuround/playkuroundserver/domain/score/dto/response/ScoreRankingResponse.java rename to src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java index 501f0d5..8d027a1 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/response/ScoreRankingResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java @@ -1,4 +1,4 @@ -package com.playkuround.playkuroundserver.domain.score.dto.response; +package com.playkuround.playkuroundserver.domain.score.api.response; import lombok.AccessLevel; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java new file mode 100644 index 0000000..c0f53eb --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java @@ -0,0 +1,58 @@ +package com.playkuround.playkuroundserver.domain.score.api.response; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class TotalScoreRankingResponse { + + private final List rank = new ArrayList<>(); + private MyRank myRank; + + public static TotalScoreRankingResponse createEmptyResponse() { + return new TotalScoreRankingResponse(); + } + + public void addRank(String nickname, int score, BadgeType badgeType) { + if (badgeType != null) { + this.rank.add(new RankList(nickname, badgeType.name(), score)); + } + else { + this.rank.add(new RankList(nickname, null, score)); + } + } + + public void setMyRank(int ranking, int score, BadgeType badgeType) { + if (badgeType != null) { + this.myRank = new MyRank(ranking, score, badgeType.name()); + } + else { + this.myRank = new MyRank(ranking, score, null); + } + } + + @Getter + @AllArgsConstructor(access = AccessLevel.PRIVATE) + @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class RankList { + private String nickname; + private String badgeType; + private int score; + } + + @Getter + @AllArgsConstructor(access = AccessLevel.PRIVATE) + @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class MyRank { + private int ranking; + private int score; + private String badgeType; + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java index 0da421d..b7426ab 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java @@ -2,9 +2,9 @@ import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; import com.playkuround.playkuroundserver.domain.common.DateTimeService; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; -import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java index 7b2201d..cf71807 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.domain.score.application; -import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.dto.NickNameAndBadge; import org.springframework.data.redis.core.ZSetOperations; import java.util.List; @@ -24,14 +25,14 @@ public List getRankUserEmails() { .toList(); } - public ScoreRankingResponse createScoreRankingResponse(Map emailBindingNickname) { - ScoreRankingResponse response = ScoreRankingResponse.createEmptyResponse(); + public TotalScoreRankingResponse createScoreRankingResponse(Map emailBindingData) { + TotalScoreRankingResponse response = TotalScoreRankingResponse.createEmptyResponse(); rankDataList.forEach(rankData -> { - String nickname = emailBindingNickname.get(rankData.email); - if (nickname == null) { + NickNameAndBadge nickNameAndBadge = emailBindingData.get(rankData.email); + if (nickNameAndBadge.nickname() == null) { throw new IllegalArgumentException("rank nickname is null"); } - response.addRank(nickname, rankData.score); + response.addRank(nickNameAndBadge.nickname(), rankData.score, nickNameAndBadge.badgeType()); }); return response; } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java index 795fc5d..ace7fd5 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java @@ -1,10 +1,11 @@ package com.playkuround.playkuroundserver.domain.score.application; +import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.dto.NickNameAndBadge; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; -import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; -import com.playkuround.playkuroundserver.domain.user.dto.EmailAndNickname; +import com.playkuround.playkuroundserver.domain.user.dto.EmailAndNicknameAndBadge; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; @@ -40,27 +41,30 @@ public Long incrementTotalScore(User user, Long score) { } @Transactional(readOnly = true) - public ScoreRankingResponse getRankTop100(User user) { + public TotalScoreRankingResponse getRankTop100(User user) { Set> typedTuples = zSetOperations.reverseRangeWithScores(redisSetKey, 0, 99); if (typedTuples == null) { - return ScoreRankingResponse.createEmptyResponse(); + return TotalScoreRankingResponse.createEmptyResponse(); } ScoreRankService scoreRankService = new ScoreRankService(typedTuples); - Map emailBindingNickname = getNicknameBindingEmailMapList(scoreRankService.getRankUserEmails()); - ScoreRankingResponse response = scoreRankService.createScoreRankingResponse(emailBindingNickname); + Map emailBindingNickname = getNicknameBindingEmailMapList(scoreRankService.getRankUserEmails()); + TotalScoreRankingResponse response = scoreRankService.createScoreRankingResponse(emailBindingNickname); RankAndScore myRank = getMyRank(user); - response.setMyRank(myRank.ranking(), myRank.score()); + response.setMyRank(myRank.ranking(), myRank.score(), user.getRepresentBadge()); return response; } - private Map getNicknameBindingEmailMapList(List emails) { - List nicknameByEmailIn = userRepository.findNicknameByEmailIn(emails); + private Map getNicknameBindingEmailMapList(List emails) { + List nicknameByEmailIn = userRepository.findNicknameByEmailIn(emails); return nicknameByEmailIn.stream() - .collect(Collectors.toMap(EmailAndNickname::email, EmailAndNickname::nickname)); + .collect(Collectors.toMap( + EmailAndNicknameAndBadge::email, + data -> new NickNameAndBadge(data.nickname(), data.badgeType()) + )); } private RankAndScore getMyRank(User user) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NickNameAndBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NickNameAndBadge.java new file mode 100644 index 0000000..e33a050 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NickNameAndBadge.java @@ -0,0 +1,6 @@ +package com.playkuround.playkuroundserver.domain.score.dto; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; + +public record NickNameAndBadge(String nickname, BadgeType badgeType) { +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/dao/UserRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/dao/UserRepository.java index 166f1cd..4667f7e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/dao/UserRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/dao/UserRepository.java @@ -1,7 +1,7 @@ package com.playkuround.playkuroundserver.domain.user.dao; import com.playkuround.playkuroundserver.domain.user.domain.User; -import com.playkuround.playkuroundserver.domain.user.dto.EmailAndNickname; +import com.playkuround.playkuroundserver.domain.user.dto.EmailAndNicknameAndBadge; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -16,10 +16,10 @@ public interface UserRepository extends JpaRepository { Optional findByEmail(String email); - @Query("select new com.playkuround.playkuroundserver.domain.user.dto.EmailAndNickname(u.email, u.nickname) " + + @Query("select new com.playkuround.playkuroundserver.domain.user.dto.EmailAndNicknameAndBadge(u.email, u.nickname, u.representBadge) " + "from User u " + "where u.email in :emails") - List findNicknameByEmailIn(List emails); + List findNicknameByEmailIn(List emails); List findByEmailIn(List emailList); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java index 4d35d4b..95e3d16 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java @@ -43,6 +43,9 @@ public class User extends BaseTimeEntity { @Convert(converter = NotificationConverter.class) private Set notification; + @Enumerated(EnumType.STRING) + private BadgeType representBadge; + private User(String email, String nickname, Major major, Role role) { this.email = email; this.nickname = nickname; @@ -54,13 +57,6 @@ public static User create(String email, String nickname, Major major, Role role) return new User(email, nickname, major, role); } - public HighestScore getHighestScore() { - if (highestScore == null) { - highestScore = new HighestScore(); - } - return highestScore; - } - public void increaseAttendanceDay() { attendanceDays++; } @@ -82,4 +78,15 @@ public void updateHighestRank(long rank, long score) { HighestScore highestScore = getHighestScore(); highestScore.updateHighestTotalLank(rank, score); } + + public void updateRepresentBadge(BadgeType badgeType) { + this.representBadge = badgeType; + } + + public HighestScore getHighestScore() { + if (highestScore == null) { + highestScore = new HighestScore(); + } + return highestScore; + } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/dto/EmailAndNickname.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/dto/EmailAndNickname.java deleted file mode 100644 index 8c8de05..0000000 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/dto/EmailAndNickname.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.playkuround.playkuroundserver.domain.user.dto; - -public record EmailAndNickname(String email, String nickname) { -} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/dto/EmailAndNicknameAndBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/dto/EmailAndNicknameAndBadge.java new file mode 100644 index 0000000..f18420b --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/dto/EmailAndNicknameAndBadge.java @@ -0,0 +1,6 @@ +package com.playkuround.playkuroundserver.domain.user.dto; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; + +public record EmailAndNicknameAndBadge(String email, String nickname, BadgeType badgeType) { +} diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java index bffb5b3..27c48b5 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java @@ -6,8 +6,8 @@ import com.playkuround.playkuroundserver.domain.adventure.domain.Adventure; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.domain.ScoreType; -import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -92,8 +92,8 @@ void getRankTop100ByLandmark_2() throws Exception { assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (51 - i)); assertThat(rank.get(i - 1).getScore()).isEqualTo(51 - i); } - assertThat(response.getMyRank().getScore()).isEqualTo(0); - assertThat(response.getMyRank().getRanking()).isEqualTo(0); + assertThat(response.getMyRank().getScore()).isZero(); + assertThat(response.getMyRank().getRanking()).isZero(); } @Test diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java index 6575cbd..6b7190b 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java @@ -2,7 +2,7 @@ import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; -import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -86,8 +86,8 @@ void getRankTop100_2() throws Exception { assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (51 - i)); assertThat(rank.get(i - 1).getScore()).isEqualTo(51 - i); } - assertThat(response.getMyRank().getScore()).isEqualTo(0); - assertThat(response.getMyRank().getRanking()).isEqualTo(0); + assertThat(response.getMyRank().getScore()).isZero(); + assertThat(response.getMyRank().getRanking()).isZero(); } @Test diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java index 6681886..b740aa0 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; import com.playkuround.playkuroundserver.domain.common.DateTimeService; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; -import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.domain.User; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -53,8 +53,8 @@ void getRankTop100ByLandmark1() { // then assertThat(result.getRank()).isEmpty(); - assertThat(result.getMyRank().getRanking()).isEqualTo(0); - assertThat(result.getMyRank().getScore()).isEqualTo(0); + assertThat(result.getMyRank().getRanking()).isZero(); + assertThat(result.getMyRank().getScore()).isZero(); } @Test @@ -83,8 +83,8 @@ void getRankTop100ByLandmark2() { assertThat(rankList.get(50 - i).getScore()).isEqualTo(i); } - assertThat(result.getMyRank().getRanking()).isEqualTo(0); - assertThat(result.getMyRank().getScore()).isEqualTo(0); + assertThat(result.getMyRank().getRanking()).isZero(); + assertThat(result.getMyRank().getScore()).isZero(); } @Test diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java index 28505ca..1415f7d 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java @@ -2,7 +2,7 @@ import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; -import com.playkuround.playkuroundserver.domain.score.dto.response.ScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -62,10 +62,11 @@ void incrementTotalScore() { void getRankTop1001() { // expect User user = TestUtil.createUser(); - ScoreRankingResponse result = totalScoreService.getRankTop100(user); + TotalScoreRankingResponse result = totalScoreService.getRankTop100(user); + assertThat(result.getRank()).isEmpty(); - assertThat(result.getMyRank().getScore()).isEqualTo(0); - assertThat(result.getMyRank().getRanking()).isEqualTo(0); + assertThat(result.getMyRank().getScore()).isZero(); + assertThat(result.getMyRank().getRanking()).isZero(); } @Test @@ -79,17 +80,17 @@ void getRankTop1002() { } // when - ScoreRankingResponse result = totalScoreService.getRankTop100(TestUtil.createUser()); + TotalScoreRankingResponse result = totalScoreService.getRankTop100(TestUtil.createUser()); // then assertThat(result.getRank()).hasSize(50); - List rank = result.getRank(); - for (int i = 1; i <= 50; i++) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (51 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(51 - i); + List rank = result.getRank(); + for (int i = 0; i < 50; i++) { + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(50 - i); } - assertThat(result.getMyRank().getScore()).isEqualTo(0); - assertThat(result.getMyRank().getRanking()).isEqualTo(0); + assertThat(result.getMyRank().getScore()).isZero(); + assertThat(result.getMyRank().getRanking()).isZero(); } @Test @@ -106,23 +107,23 @@ void getRankTop1003() { totalScoreService.incrementTotalScore(user, (long) 13); // when - ScoreRankingResponse result = totalScoreService.getRankTop100(user); + TotalScoreRankingResponse result = totalScoreService.getRankTop100(user); // then assertThat(result.getRank()).hasSize(51); - List rank = result.getRank(); - for (int i = 1; i <= 51; i++) { - if (i < 39) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (51 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo((51 - i)); + List rank = result.getRank(); + for (int i = 0; i < 51; i++) { + if (i < 38) { + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); + assertThat(rank.get(i).getScore()).isEqualTo((50 - i)); } - else if (i == 39) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo(user.getNickname()); - assertThat(rank.get(i - 1).getScore()).isEqualTo(13); + else if (i == 38) { + assertThat(rank.get(i).getNickname()).isEqualTo(user.getNickname()); + assertThat(rank.get(i).getScore()).isEqualTo(13); } else { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (52 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(52 - i); + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (51 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(51 - i); } } assertThat(result.getMyRank().getScore()).isEqualTo(13); @@ -143,11 +144,11 @@ void getRankTop1004() { totalScoreService.incrementTotalScore(user, (long) 51); // when - ScoreRankingResponse result = totalScoreService.getRankTop100(user); + TotalScoreRankingResponse result = totalScoreService.getRankTop100(user); // then assertThat(result.getRank()).hasSize(100); - List rank = result.getRank(); + List rank = result.getRank(); assertThat(rank.get(0).getNickname()).isEqualTo("user100"); assertThat(rank.get(0).getScore()).isEqualTo(100); assertThat(rank.get(99).getNickname()).isEqualTo("user2"); @@ -175,11 +176,11 @@ void getRankTop1005() { } // when - ScoreRankingResponse result = totalScoreService.getRankTop100(me); + TotalScoreRankingResponse result = totalScoreService.getRankTop100(me); // then assertThat(result.getRank()).hasSize(100); - List rank = result.getRank(); + List rank = result.getRank(); assertThat(rank.get(0).getNickname()).isEqualTo("user1"); assertThat(rank.get(0).getScore()).isEqualTo(999); assertThat(rank.get(99).getNickname()).isEqualTo("user105"); From ee5abc6958cf1f284d7867ae1147b2d453ef8f22 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sat, 17 Aug 2024 20:26:40 +0900 Subject: [PATCH 22/79] =?UTF-8?q?refactor:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/score/api/ScoreApi.java | 8 +- ...java => LandmarkScoreRankingResponse.java} | 6 +- .../application/LandmarkRankService.java | 6 +- .../score/api/LandmarkScoreRankApiTest.java | 78 +++++++++---------- .../score/api/ScoreTotalRankApiTest.java | 42 +++++----- .../application/LandmarkRankServiceTest.java | 16 ++-- 6 files changed, 78 insertions(+), 78 deletions(-) rename src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/{ScoreRankingResponse.java => LandmarkScoreRankingResponse.java} (86%) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java index 318950d..e396166 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java @@ -1,6 +1,6 @@ package com.playkuround.playkuroundserver.domain.score.api; -import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.LandmarkScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.application.LandmarkRankService; import com.playkuround.playkuroundserver.domain.score.application.TotalScoreService; @@ -36,9 +36,9 @@ public ApiResponse getScoreTop100(@AuthenticationPrin @GetMapping("/rank/{landmarkId}") @Operation(summary = "해당 랜드마크의 점수 탑100 얻기", description = "해당 랜드마크 점수 탑100과 내 점수, 등수를 반환합니다. 내 점수가 0점이면 등수는 0등으로 반환됩니다.") - public ApiResponse getScoreTop100ByLandmark(@AuthenticationPrincipal UserDetailsImpl userDetails, - @PathVariable Long landmarkId) { - ScoreRankingResponse response = landmarkRankService.getRankTop100ByLandmark(userDetails.getUser(), landmarkId); + public ApiResponse getScoreTop100ByLandmark(@AuthenticationPrincipal UserDetailsImpl userDetails, + @PathVariable Long landmarkId) { + LandmarkScoreRankingResponse response = landmarkRankService.getRankTop100ByLandmark(userDetails.getUser(), landmarkId); return ApiUtils.success(response); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/LandmarkScoreRankingResponse.java similarity index 86% rename from src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java rename to src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/LandmarkScoreRankingResponse.java index 8d027a1..6d90897 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/LandmarkScoreRankingResponse.java @@ -10,13 +10,13 @@ @Getter @NoArgsConstructor(access = AccessLevel.PRIVATE) -public class ScoreRankingResponse { +public class LandmarkScoreRankingResponse { private MyRank myRank; private final List rank = new ArrayList<>(); - public static ScoreRankingResponse createEmptyResponse() { - return new ScoreRankingResponse(); + public static LandmarkScoreRankingResponse createEmptyResponse() { + return new LandmarkScoreRankingResponse(); } public void addRank(String nickname, int score) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java index b7426ab..811b7c2 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java @@ -2,7 +2,7 @@ import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; import com.playkuround.playkuroundserver.domain.common.DateTimeService; -import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.LandmarkScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -22,8 +22,8 @@ public class LandmarkRankService { private final DateTimeService dateTimeService; @Transactional(readOnly = true) - public ScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId) { - ScoreRankingResponse response = ScoreRankingResponse.createEmptyResponse(); + public LandmarkScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId) { + LandmarkScoreRankingResponse response = LandmarkScoreRankingResponse.createEmptyResponse(); LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.getLocalDateNow()); List nicknameAndScores = adventureRepository.findRankTop100DescByLandmarkId(landmarkId, monthStartDateTime); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java index 27c48b5..09f5a1b 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java @@ -6,7 +6,7 @@ import com.playkuround.playkuroundserver.domain.adventure.domain.Adventure; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; -import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.LandmarkScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.domain.ScoreType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; @@ -83,14 +83,14 @@ void getRankTop100ByLandmark_2() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); + LandmarkScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, LandmarkScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(50); - List rank = response.getRank(); - for (int i = 1; i <= 50; i++) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (51 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(51 - i); + List rank = response.getRank(); + for (int i = 0; i < 50; i++) { + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(50 - i); } assertThat(response.getMyRank().getScore()).isZero(); assertThat(response.getMyRank().getRanking()).isZero(); @@ -120,23 +120,23 @@ void getRankTop100ByLandmark_3() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); + LandmarkScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, LandmarkScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(51); - List rank = response.getRank(); - for (int i = 1; i <= 51; i++) { - if (i < 15) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (51 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(51 - i); + List rank = response.getRank(); + for (int i = 0; i < 51; i++) { + if (i < 14) { + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(50 - i); } - else if (i == 15) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("tester"); - assertThat(rank.get(i - 1).getScore()).isEqualTo(37); + else if (i == 14) { + assertThat(rank.get(i).getNickname()).isEqualTo("tester"); + assertThat(rank.get(i).getScore()).isEqualTo(37); } else { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (52 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(52 - i); + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (51 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(51 - i); } } assertThat(response.getMyRank().getScore()).isEqualTo(37); @@ -167,23 +167,23 @@ void getRankTop100ByLandmark_4() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); + LandmarkScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, LandmarkScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(100); - List rank = response.getRank(); - for (int i = 1; i <= 100; i++) { - if (i < 41) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (102 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(102 - i); + List rank = response.getRank(); + for (int i = 0; i < 100; i++) { + if (i < 40) { + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (101 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(101 - i); } - else if (i == 41) { // 랭킹은 점수, 닉네임 내림차순 - assertThat(rank.get(i - 1).getNickname()).isEqualTo("tester"); - assertThat(rank.get(i - 1).getScore()).isEqualTo(62); + else if (i == 40) { + assertThat(rank.get(i).getNickname()).isEqualTo("tester"); + assertThat(rank.get(i).getScore()).isEqualTo(62); } else { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (103 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(103 - i); + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (102 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(102 - i); } } assertThat(response.getMyRank().getScore()).isEqualTo(62); @@ -216,23 +216,23 @@ void getRankTop100ByLandmark_5() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); + LandmarkScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, LandmarkScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(100); - List rank = response.getRank(); - for (int i = 1; i <= 100; i++) { - if (i < 42) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (102 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(103 - i); + List rank = response.getRank(); + for (int i = 0; i < 100; i++) { + if (i < 41) { + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (101 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(102 - i); } - else if (i == 42) { // 랭킹은 점수, 닉네임 내림차순 - assertThat(rank.get(i - 1).getNickname()).isEqualTo("tester"); - assertThat(rank.get(i - 1).getScore()).isEqualTo(62); + else if (i == 41) { + assertThat(rank.get(i).getNickname()).isEqualTo("tester"); + assertThat(rank.get(i).getScore()).isEqualTo(62); } else { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (103 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(104 - i); + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (102 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(103 - i); } } assertThat(response.getMyRank().getScore()).isEqualTo(62); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java index 6b7190b..765fccb 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java @@ -2,7 +2,7 @@ import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; -import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -77,14 +77,14 @@ void getRankTop100_2() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); + TotalScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, TotalScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(50); - List rank = response.getRank(); - for (int i = 1; i <= 50; i++) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (51 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(51 - i); + List rank = response.getRank(); + for (int i = 0; i < 50; i++) { + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(50 - i); } assertThat(response.getMyRank().getScore()).isZero(); assertThat(response.getMyRank().getRanking()).isZero(); @@ -111,23 +111,23 @@ void getRankTop100_3() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); + TotalScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, TotalScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(51); - List rank = response.getRank(); - for (int i = 1; i <= 51; i++) { - if (i < 39) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (51 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo((51 - i)); + List rank = response.getRank(); + for (int i = 0; i < 51; i++) { + if (i < 38) { + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); + assertThat(rank.get(i).getScore()).isEqualTo((50 - i)); } - else if (i == 39) { - assertThat(rank.get(i - 1).getNickname()).isEqualTo(user.getNickname()); - assertThat(rank.get(i - 1).getScore()).isEqualTo(13); + else if (i == 38) { + assertThat(rank.get(i).getNickname()).isEqualTo(user.getNickname()); + assertThat(rank.get(i).getScore()).isEqualTo(13); } else { - assertThat(rank.get(i - 1).getNickname()).isEqualTo("user" + (52 - i)); - assertThat(rank.get(i - 1).getScore()).isEqualTo(52 - i); + assertThat(rank.get(i).getNickname()).isEqualTo("user" + (51 - i)); + assertThat(rank.get(i).getScore()).isEqualTo(51 - i); } } assertThat(response.getMyRank().getScore()).isEqualTo(13); @@ -155,11 +155,11 @@ void getRankTop100_4() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); + TotalScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, TotalScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(100); - List rank = response.getRank(); + List rank = response.getRank(); assertThat(rank.get(0).getNickname()).isEqualTo("user100"); assertThat(rank.get(0).getScore()).isEqualTo(100); assertThat(rank.get(99).getNickname()).isEqualTo("user2"); @@ -193,11 +193,11 @@ void getRankTop100_5() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); + TotalScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, TotalScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(100); - List rank = response.getRank(); + List rank = response.getRank(); assertThat(rank.get(0).getNickname()).isEqualTo("user1"); assertThat(rank.get(0).getScore()).isEqualTo(999); assertThat(rank.get(99).getNickname()).isEqualTo("user105"); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java index b740aa0..72cbd56 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java @@ -3,7 +3,7 @@ import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; import com.playkuround.playkuroundserver.domain.common.DateTimeService; -import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.LandmarkScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -49,7 +49,7 @@ void getRankTop100ByLandmark1() { // when User user = TestUtil.createUser(); - ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + LandmarkScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); // then assertThat(result.getRank()).isEmpty(); @@ -73,10 +73,10 @@ void getRankTop100ByLandmark2() { // when User user = TestUtil.createUser(); - ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + LandmarkScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); // then - List rankList = result.getRank(); + List rankList = result.getRank(); assertThat(rankList).hasSize(50); for (int i = 50; i > 0; i--) { assertThat(rankList.get(50 - i).getNickname()).isEqualTo("nickname" + i); @@ -103,10 +103,10 @@ void getRankTop100ByLandmark3() { // when User user = TestUtil.createUser(); - ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + LandmarkScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); // then - List rankList = result.getRank(); + List rankList = result.getRank(); assertThat(rankList).hasSize(50); for (int i = 50; i > 0; i--) { assertThat(rankList.get(50 - i).getNickname()).isEqualTo("nickname" + i); @@ -132,10 +132,10 @@ void getRankTop100ByLandmark4() { // when User user = TestUtil.createUser(); - ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + LandmarkScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); // then - List rankList = result.getRank(); + List rankList = result.getRank(); assertThat(rankList).hasSize(101); for (int i = 101; i > 0; i--) { assertThat(rankList.get(101 - i).getNickname()).isEqualTo("nickname" + i); From 8eeefca5f96deafa407d3b547b1310e67d487068 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sat, 17 Aug 2024 22:17:37 +0900 Subject: [PATCH 23/79] =?UTF-8?q?feat:=20=EB=8C=80=ED=91=9C=20=EB=B1=83?= =?UTF-8?q?=EC=A7=80=20=EC=84=A4=EC=A0=95=20API=20=EC=B6=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/badge/api/BadgeApi.java | 15 +++++++++++++++ .../request/RepresentationBadgeRequest.java | 19 +++++++++++++++++++ .../badge/application/BadgeService.java | 12 ++++++++++++ .../domain/badge/domain/BadgeType.java | 16 +++++++++++++++- .../exception/BadgeNotHaveException.java | 12 ++++++++++++ .../exception/BadgeTypeNotFoundException.java | 9 ++++----- .../api/response/UserProfileResponse.java | 4 ++++ .../global/error/ErrorCode.java | 3 ++- 8 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/RepresentationBadgeRequest.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeNotHaveException.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java index 3101367..b1540f9 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java @@ -1,13 +1,17 @@ package com.playkuround.playkuroundserver.domain.badge.api; +import com.playkuround.playkuroundserver.domain.badge.api.request.RepresentationBadgeRequest; import com.playkuround.playkuroundserver.domain.badge.api.response.BadgeFindResponse; import com.playkuround.playkuroundserver.domain.badge.application.BadgeService; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.domain.badge.exception.BadgeTypeNotFoundException; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; import com.playkuround.playkuroundserver.global.security.UserDetailsImpl; import com.playkuround.playkuroundserver.global.util.ApiUtils; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -40,4 +44,15 @@ public ApiResponse saveTheDreamOfDuckBadge(@AuthenticationPrincipal Use return ApiUtils.success(response); } + @PostMapping("/representation") + @Operation(summary = "대표 뱃지 설정", description = "사용자를 대표하는 뱃지를 설정합니다.") + public ApiResponse representationBadge(@AuthenticationPrincipal UserDetailsImpl userDetails, + @RequestBody @Valid RepresentationBadgeRequest request) { + BadgeType badgeType = BadgeType.fromString(request.getBadgeType()) + .orElseThrow(BadgeTypeNotFoundException::new); + + badgeService.representationBadge(userDetails.getUser(), badgeType); + return ApiUtils.success(null); + } + } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/RepresentationBadgeRequest.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/RepresentationBadgeRequest.java new file mode 100644 index 0000000..0349f79 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/RepresentationBadgeRequest.java @@ -0,0 +1,19 @@ +package com.playkuround.playkuroundserver.domain.badge.api.request; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.global.validation.ValidEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) +@AllArgsConstructor +public class RepresentationBadgeRequest { + + @ValidEnum(enumClass = BadgeType.class, message = "잘못된 badge type 입니다.") + @Schema(description = "설정할 뱃지 타입", example = "ATTENDANCE_CHILDREN_DAY", requiredMode = Schema.RequiredMode.REQUIRED) + private String badgeType; + +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java index f6d4001..886ffbb 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java @@ -8,6 +8,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.badge.exception.BadgeNotHaveException; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; @@ -122,4 +123,15 @@ public boolean saveManualBadge(String userEmail, BadgeType badgeType, boolean re } return true; } + + @Transactional + public void representationBadge(User user, BadgeType badgeType) { + if (!badgeRepository.existsByUserAndBadgeType(user, badgeType)) { + throw new BadgeNotHaveException(); + } + + user.updateRepresentBadge(badgeType); + userRepository.save(user); + } + } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java index ad6d2a0..14e1f03 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java @@ -3,6 +3,12 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.toMap; + @Getter @RequiredArgsConstructor public enum BadgeType { @@ -66,8 +72,16 @@ public enum BadgeType { MONTHLY_RANKING_1("월간 랭킹 1등"), // 수동 MONTHLY_RANKING_2("월간 랭킹 2등"), // 수동 MONTHLY_RANKING_3("월간 랭킹 3등"), // 수동 - ; private final String description; + + private static final Map stringToEnum = + Stream.of(values()) + .collect(toMap(Object::toString, e -> e)); + + public static Optional fromString(String source) { + return Optional.ofNullable(stringToEnum.get(source)); + } + } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeNotHaveException.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeNotHaveException.java new file mode 100644 index 0000000..47e6099 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeNotHaveException.java @@ -0,0 +1,12 @@ +package com.playkuround.playkuroundserver.domain.badge.exception; + +import com.playkuround.playkuroundserver.global.error.ErrorCode; +import com.playkuround.playkuroundserver.global.error.exception.InvalidValueException; + +public class BadgeNotHaveException extends InvalidValueException { + + public BadgeNotHaveException() { + super(ErrorCode.NOT_HAVE_BADGE); + } +} + diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeTypeNotFoundException.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeTypeNotFoundException.java index e709d6c..2ea8118 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeTypeNotFoundException.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeTypeNotFoundException.java @@ -1,13 +1,12 @@ package com.playkuround.playkuroundserver.domain.badge.exception; import com.playkuround.playkuroundserver.global.error.ErrorCode; -import com.playkuround.playkuroundserver.global.error.exception.InvalidValueException; +import com.playkuround.playkuroundserver.global.error.exception.NotFoundException; +public class BadgeTypeNotFoundException extends NotFoundException { -public class BadgeTypeNotFoundException extends InvalidValueException { - - public BadgeTypeNotFoundException(ErrorCode errorCode) { - super(errorCode); + public BadgeTypeNotFoundException() { + super(ErrorCode.INVALID_BADGE_TYPE); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java index d902665..63d2b7e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java @@ -30,6 +30,9 @@ public class UserProfileResponse { @Schema(description = "출석한 횟수", example = "28", requiredMode = RequiredMode.REQUIRED) private int attendanceDays; + @Schema(description = "대표 뱃지(대표 뱃지가 없다면 null 리턴)", example = "MONTHLY_RANKING_1", requiredMode = RequiredMode.REQUIRED) + private String badge; + public static UserProfileResponse from(User user) { return UserProfileResponse.builder() .email(user.getEmail()) @@ -38,6 +41,7 @@ public static UserProfileResponse from(User user) { .attendanceDays(user.getAttendanceDays()) .highestScore(user.getHighestScore() == null ? null : user.getHighestScore().getHighestTotalScore()) .highestRank(user.getHighestScore() == null ? null : user.getHighestScore().getHighestTotalRank()) + .badge(user.getRepresentBadge() == null ? null : user.getRepresentBadge().name()) .build(); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/global/error/ErrorCode.java b/src/main/java/com/playkuround/playkuroundserver/global/error/ErrorCode.java index 700046e..3ba7941 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/error/ErrorCode.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/error/ErrorCode.java @@ -48,7 +48,8 @@ public enum ErrorCode { EMAIL_NOT_FOUND(HttpStatus.BAD_REQUEST, "E006", "인증 대기 중인 이메일이 아닙니다."), // Badge - INVALID_Badge_TYPE(HttpStatus.BAD_REQUEST, "B001", "올바르지 않은 BadgeType입니다."), + INVALID_BADGE_TYPE(HttpStatus.BAD_REQUEST, "B001", "올바르지 않은 BadgeType입니다."), + NOT_HAVE_BADGE(HttpStatus.BAD_REQUEST, "B002", "사용자가 가지고 있지 않은 뱃지입니다."), // Attendance DUPLICATE_ATTENDANCE(HttpStatus.BAD_REQUEST, "AT01", "이미 오늘 출석한 회원입니다."), From b0688df44fe04751bb450f114c7225c029a6b85e Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sat, 17 Aug 2024 22:44:11 +0900 Subject: [PATCH 24/79] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=8B=9C=20=EC=9E=90=EB=8F=99=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=8B=A8=EA=B3=BC=EB=8C=80=20=EB=B1=83=EC=A7=80=20=ED=9A=8D?= =?UTF-8?q?=EB=93=9D=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/application/UserRegisterService.java | 12 ++ .../domain/user/domain/Major.java | 161 +++++++++++------- 2 files changed, 110 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterService.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterService.java index 3dc9f01..b9e428c 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterService.java @@ -1,7 +1,11 @@ package com.playkuround.playkuroundserver.domain.user.application; import com.playkuround.playkuroundserver.domain.auth.token.dto.TokenDto; +import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; +import com.playkuround.playkuroundserver.domain.badge.domain.Badge; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; +import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.Role; import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.domain.user.dto.UserRegisterDto; @@ -19,6 +23,7 @@ public class UserRegisterService { private final UserRepository userRepository; private final UserLoginService userLoginService; + private final BadgeRepository badgeRepository; @Transactional public TokenDto registerUser(UserRegisterDto userRegisterDto) { @@ -28,6 +33,13 @@ public TokenDto registerUser(UserRegisterDto userRegisterDto) { User user = User.create(userRegisterDto.email(), userRegisterDto.nickname(), userRegisterDto.major(), Role.ROLE_USER); userRepository.save(user); + Major major = userRegisterDto.major(); + BadgeType collageBadgeType = major.getCollageBadgeType(); + Badge badge = new Badge(user, collageBadgeType); + badgeRepository.save(badge); + + user.updateRepresentBadge(collageBadgeType); + return userLoginService.login(user.getEmail()); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java index 2caf690..ab6acb5 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java @@ -1,94 +1,129 @@ package com.playkuround.playkuroundserver.domain.user.domain; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; + @SuppressWarnings("NonAsciiCharacters") public enum Major { // 문과대학 - 국어국문학과, - 영어영문학과, - 중어중문학과, - 철학과, - 사학과, - 지리학과, - 미디어커뮤니케이션학과, - 문화콘텐츠학과, + 국어국문학과(Collage.문과대학), + 영어영문학과(Collage.문과대학), + 중어중문학과(Collage.문과대학), + 철학과(Collage.문과대학), + 사학과(Collage.문과대학), + 지리학과(Collage.문과대학), + 미디어커뮤니케이션학과(Collage.문과대학), + 문화콘텐츠학과(Collage.문과대학), // 이과대학 - 수학과, - 물리학과, - 화학과, + 수학과(Collage.이과대학), + 물리학과(Collage.이과대학), + 화학과(Collage.이과대학), // 건축대학 - 건축학부, + 건축학부(Collage.건축대학), // 공과대학 - 사회환경공학부, - 기계항공공학부, - 전기전자공학부, - 화학공학부, - 컴퓨터공학부, - 산업경영공학부_산업공학과, - 산업경영공학부_신산업융합학과, - 생물공학과, - K뷰티산업융합학과, + 사회환경공학부(Collage.공과대학), + 기계항공공학부(Collage.공과대학), + 전기전자공학부(Collage.공과대학), + 화학공학부(Collage.공과대학), + 컴퓨터공학부(Collage.공과대학), + 산업경영공학부_산업공학과(Collage.공과대학), + 산업경영공학부_신산업융합학과(Collage.공과대학), + 생물공학과(Collage.공과대학), + K뷰티산업융합학과(Collage.공과대학), // 사회과학대학 - 정치외교학과, - 경제학과, - 행정학과, - 국제무역학과, - 응용통계학과, - 융합인재학과, - 글로벌비즈니스학과, + 정치외교학과(Collage.사회과학대학), + 경제학과(Collage.사회과학대학), + 행정학과(Collage.사회과학대학), + 국제무역학과(Collage.사회과학대학), + 응용통계학과(Collage.사회과학대학), + 융합인재학과(Collage.사회과학대학), + 글로벌비즈니스학과(Collage.사회과학대학), // 경영대학 - 경영학과, - 기술경영학과, + 경영학과(Collage.경영대학), + 기술경영학과(Collage.경영대학), // 부동산과학원 - 부동산학과, + 부동산학과(Collage.부동산과학원), // KU융합과학기술원 - 미래에너지공학과, - 스마트운행체공학과, - 스마트ICT융합공학과, - 화장품공학과, - 줄기세포재생공학과, - 의생명공학과, - 시스템생명공학과, - 융합생명공학과, + 미래에너지공학과(Collage.KU융합과학기술원), + 스마트운행체공학과(Collage.KU융합과학기술원), + 스마트ICT융합공학과(Collage.KU융합과학기술원), + 화장품공학과(Collage.KU융합과학기술원), + 줄기세포재생공학과(Collage.KU융합과학기술원), + 의생명공학과(Collage.KU융합과학기술원), + 시스템생명공학과(Collage.KU융합과학기술원), + 융합생명공학과(Collage.KU융합과학기술원), // 상허생명과학대학 - 생명과학특성학과, - 동물자원과학과, - 식량자원과학과, - 축산식품생명공학과, - 식품유통공학과, - 환경보건과학과, - 산림조경학과, + 생명과학특성학과(Collage.상허생명과학대학), + 동물자원과학과(Collage.상허생명과학대학), + 식량자원과학과(Collage.상허생명과학대학), + 축산식품생명공학과(Collage.상허생명과학대학), + 식품유통공학과(Collage.상허생명과학대학), + 환경보건과학과(Collage.상허생명과학대학), + 산림조경학과(Collage.상허생명과학대학), // 수의과대학 - 수의예과, - 수의학과, + 수의예과(Collage.수의과대학), + 수의학과(Collage.수의과대학), // 예술디자인대학 - 커뮤니케이션디자인학과, - 산업디자인학과, - 의상디자인학과, - 리빙디자인학과, - 현대미술학과, - 영상영화학과, + 커뮤니케이션디자인학과(Collage.예술디자인대학), + 산업디자인학과(Collage.예술디자인대학), + 의상디자인학과(Collage.예술디자인대학), + 리빙디자인학과(Collage.예술디자인대학), + 현대미술학과(Collage.예술디자인대학), + 영상영화학과(Collage.예술디자인대학), // 사범대학 - 일어교육과, - 수학교육과, - 체육교육과, - 음악교육과, - 교육공학과, - 영어교육과, - 교직과, - + 일어교육과(Collage.사범대학), + 수학교육과(Collage.사범대학), + 체육교육과(Collage.사범대학), + 음악교육과(Collage.사범대학), + 교육공학과(Collage.사범대학), + 영어교육과(Collage.사범대학), + 교직과(Collage.사범대학), + ; // 상허교양대학 - 국제학부 + //국제학부(Collage.상허교양대학); + + private final Collage collage; + + Major(Collage collage) { + this.collage = collage; + } + + public BadgeType getCollageBadgeType() { + return collage.collageBadgeType; + } + + enum Collage { + 문과대학(BadgeType.COLLEGE_OF_LIBERAL_ARTS), + 이과대학(BadgeType.COLLEGE_OF_SCIENCES), + 건축대학(BadgeType.COLLEGE_OF_ARCHITECTURE), + 공과대학(BadgeType.COLLEGE_OF_ENGINEERING), + 사회과학대학(BadgeType.COLLEGE_OF_SOCIAL_SCIENCES), + 경영대학(BadgeType.COLLEGE_OF_BUSINESS_ADMINISTRATION), + 부동산과학원(BadgeType.COLLEGE_OF_REAL_ESTATE), + KU융합과학기술원(BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY), + 상허생명과학대학(BadgeType.COLLEGE_OF_BIOLOGICAL_SCIENCES), + 수의과대학(BadgeType.COLLEGE_OF_VETERINARY_MEDICINE), + 예술디자인대학(BadgeType.COLLEGE_OF_ART_AND_DESIGN), + 사범대학(BadgeType.COLLEGE_OF_EDUCATION), + //상허교양대학 + ; + + private final BadgeType collageBadgeType; + + Collage(BadgeType collageBadgeType) { + this.collageBadgeType = collageBadgeType; + } + } } From 2ca2dc35edbc0a5c9098851be8d17361747232ad Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sat, 17 Aug 2024 22:44:51 +0900 Subject: [PATCH 25/79] =?UTF-8?q?test:=20=EB=A1=9C=EC=A7=81=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/UserRegisterServiceTest.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterServiceTest.java index 668e9e1..655780b 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterServiceTest.java @@ -1,6 +1,9 @@ package com.playkuround.playkuroundserver.domain.user.application; import com.playkuround.playkuroundserver.domain.auth.token.dto.TokenDto; +import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; +import com.playkuround.playkuroundserver.domain.badge.domain.Badge; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -14,17 +17,16 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.test.util.ReflectionTestUtils; import java.util.Date; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class UserRegisterServiceTest { @@ -38,6 +40,9 @@ class UserRegisterServiceTest { @Mock private UserLoginService userLoginService; + @Mock + private BadgeRepository badgeRepository; + private final String nickname = "tester"; private final String major = "컴퓨터공학부"; private final String email = "tester@konkuk.ac.kr"; @@ -61,12 +66,6 @@ void success_1() { .thenReturn(false); when(userRepository.existsByNickname(nickname)) .thenReturn(false); - when(userRepository.save(any(User.class))) - .then(invocation -> { - User savedUser = invocation.getArgument(0); - ReflectionTestUtils.setField(savedUser, "id", 1L); - return savedUser; - }); when(userLoginService.login(email)) .thenReturn(tokenDto); @@ -78,6 +77,12 @@ void success_1() { assertThat(result.getGrantType()).isEqualTo(tokenDto.getGrantType()); assertThat(result.getAccessToken()).isEqualTo(tokenDto.getAccessToken()); assertThat(result.getRefreshToken()).isEqualTo(tokenDto.getRefreshToken()); + + verify(userRepository, times(1)).save(any(User.class)); + + ArgumentCaptor badgeArgument = ArgumentCaptor.forClass(Badge.class); + verify(badgeRepository, times(1)).save(badgeArgument.capture()); + assertThat(badgeArgument.getValue().getBadgeType()).isEqualTo(BadgeType.COLLEGE_OF_ENGINEERING); } @Test From 813c33c7d68f809171d14ef2d700886ac6f5ccc3 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sun, 18 Aug 2024 00:29:08 +0900 Subject: [PATCH 26/79] =?UTF-8?q?test:=20=EC=A2=85=ED=95=A9=20=EC=A0=90?= =?UTF-8?q?=EC=88=98=20=EB=9E=AD=ED=82=B9=20=EC=8B=9C=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=91=9C=20=EB=B1=83=EC=A7=80=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EA=B0=80=20=ED=8F=AC=ED=95=A8=EB=90=98=EB=8A=94=EC=A7=80=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../score/api/ScoreTotalRankApiTest.java | 59 ++++++++++++++++--- .../securityConfig/WithMockCustomUser.java | 4 ++ ...hMockCustomUserSecurityContextFactory.java | 1 + 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java index 765fccb..010d3c9 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java @@ -2,6 +2,7 @@ import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; @@ -19,6 +20,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -91,7 +93,7 @@ void getRankTop100_2() throws Exception { } @Test - @WithMockCustomUser + @WithMockCustomUser(email = "tester@konkuk.ac.kr") @DisplayName("탑 100명 랭킹 조회하기 : 전체 유저 100명 미만 + 내 랭킹 존재") void getRankTop100_3() throws Exception { // given @@ -101,8 +103,7 @@ void getRankTop100_3() throws Exception { userRepository.save(user); zSetOperations.incrementScore(redisSetKey, user.getEmail(), i); } - User user = TestUtil.createUser(); - zSetOperations.incrementScore(redisSetKey, user.getEmail(), 13); + zSetOperations.incrementScore(redisSetKey, "tester@konkuk.ac.kr", 13); // when MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank")) @@ -122,7 +123,7 @@ void getRankTop100_3() throws Exception { assertThat(rank.get(i).getScore()).isEqualTo((50 - i)); } else if (i == 38) { - assertThat(rank.get(i).getNickname()).isEqualTo(user.getNickname()); + assertThat(rank.get(i).getNickname()).isEqualTo("tester"); assertThat(rank.get(i).getScore()).isEqualTo(13); } else { @@ -135,7 +136,7 @@ else if (i == 38) { } @Test - @WithMockCustomUser + @WithMockCustomUser(email = "tester@konkuk.ac.kr") @DisplayName("탑 100명 랭킹 조회하기 : 전체 유저 100명 초과 + 내 랭킹 공동 50위") void getRankTop100_4() throws Exception { // given @@ -145,8 +146,7 @@ void getRankTop100_4() throws Exception { userRepository.save(user); zSetOperations.incrementScore(redisSetKey, user.getEmail(), i); } - User user = TestUtil.createUser(); - zSetOperations.incrementScore(redisSetKey, user.getEmail(), 51); + zSetOperations.incrementScore(redisSetKey, "tester@konkuk.ac.kr", 51); // when MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank")) @@ -206,4 +206,49 @@ void getRankTop100_5() throws Exception { assertThat(response.getMyRank().getScore()).isEqualTo(110); assertThat(response.getMyRank().getRanking()).isEqualTo(91); } + + @Test + @WithMockCustomUser + @DisplayName("랭킹 조회 API에는 사용자 대표 뱃지 데이터가 포함되어 있다.") + void getRankTop100_6() throws Exception { + // given + ZSetOperations zSetOperations = redisTemplate.opsForZSet(); + + { + zSetOperations.incrementScore(redisSetKey, "tester@konkuk.ac.kr", 13); + } + { + User user1 = TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.건축학부); + user1.updateRepresentBadge(BadgeType.ATTENDANCE_1); + userRepository.save(user1); + zSetOperations.incrementScore(redisSetKey, user1.getEmail(), 10); + } + { + User user2 = TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부); + user2.updateRepresentBadge(BadgeType.MONTHLY_RANKING_1); + userRepository.save(user2); + zSetOperations.incrementScore(redisSetKey, user2.getEmail(), 15); + } + + // when + MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isSuccess").value(true)) + .andDo(print()) + .andReturn(); + String json = mvcResult.getResponse().getContentAsString(); + TotalScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, TotalScoreRankingResponse.class); + + // then + assertThat(response.getRank()).hasSize(3) + .extracting("nickname", "badgeType", "score") + .containsExactly( + tuple("user2", BadgeType.MONTHLY_RANKING_1.name(), 15), + tuple("tester", BadgeType.COLLEGE_OF_ENGINEERING.name(), 13), + tuple("user1", BadgeType.ATTENDANCE_1.name(), 10) + ); + assertThat(response.getMyRank().getScore()).isEqualTo(13); + assertThat(response.getMyRank().getRanking()).isEqualTo(2); + assertThat(response.getMyRank().getBadgeType()).isEqualTo(BadgeType.COLLEGE_OF_ENGINEERING.name()); + } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUser.java b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUser.java index e0094f1..0ecf19d 100644 --- a/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUser.java +++ b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUser.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.securityConfig; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.Role; import org.springframework.security.test.context.support.WithSecurityContext; @@ -19,4 +20,7 @@ Major major() default Major.컴퓨터공학부; Role role() default Role.ROLE_USER; + + BadgeType badgeType() default BadgeType.COLLEGE_OF_ENGINEERING; + } diff --git a/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java index 9037bc6..aeb34a8 100644 --- a/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java +++ b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java @@ -26,6 +26,7 @@ public class WithMockCustomUserSecurityContextFactory public SecurityContext createSecurityContext(WithMockCustomUser annotation) { User user = User.create(annotation.email(), annotation.nickname(), annotation.major(), annotation.role()); + user.updateRepresentBadge(annotation.badgeType()); userRepository.save(user); String roleName = user.getRole().toString(); List role = Arrays.stream(roleName.split(",")).toList(); From 8d6bfbacbe2127c80097065ab2761e412a180a64 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sun, 18 Aug 2024 22:44:14 +0900 Subject: [PATCH 27/79] =?UTF-8?q?test:=20/api/users=20GET=20API=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=EB=B0=94=EB=93=9C=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../playkuroundserver/domain/user/api/UserProfileApiTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java index 7714c13..65cb2b3 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java @@ -5,6 +5,7 @@ import com.playkuround.playkuroundserver.domain.appversion.dao.AppVersionRepository; import com.playkuround.playkuroundserver.domain.appversion.domain.AppVersion; import com.playkuround.playkuroundserver.domain.appversion.domain.OperationSystem; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.systemcheck.dao.SystemCheckRepository; import com.playkuround.playkuroundserver.domain.systemcheck.domain.SystemCheck; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; @@ -57,6 +58,7 @@ void userProfileSuccess() throws Exception { .andExpect(jsonPath("$.response.major").value(Major.컴퓨터공학부.name())) .andExpect(jsonPath("$.response.nickname").value("tester")) .andExpect(jsonPath("$.response.email").value("tester@konkuk.ac.kr")) + .andExpect(jsonPath("$.response.badge").value(BadgeType.COLLEGE_OF_ENGINEERING.name())) .andDo(print()); } From cf5a70aa5a177f1a615bd3349772788e0b8e8aac Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sun, 18 Aug 2024 22:58:59 +0900 Subject: [PATCH 28/79] test: /api/badges/representation POST API integration test --- .../domain/badge/api/BadgeApi.java | 4 +- .../domain/badge/api/BadgeApiTest.java | 72 ++++++++++++++++++- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java index b1540f9..b1d9d91 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java @@ -46,8 +46,8 @@ public ApiResponse saveTheDreamOfDuckBadge(@AuthenticationPrincipal Use @PostMapping("/representation") @Operation(summary = "대표 뱃지 설정", description = "사용자를 대표하는 뱃지를 설정합니다.") - public ApiResponse representationBadge(@AuthenticationPrincipal UserDetailsImpl userDetails, - @RequestBody @Valid RepresentationBadgeRequest request) { + public ApiResponse setRepresentationBadge(@AuthenticationPrincipal UserDetailsImpl userDetails, + @RequestBody @Valid RepresentationBadgeRequest request) { BadgeType badgeType = BadgeType.fromString(request.getBadgeType()) .orElseThrow(BadgeTypeNotFoundException::new); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java index 2624bb8..450d616 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java @@ -1,17 +1,21 @@ package com.playkuround.playkuroundserver.domain.badge.api; +import com.fasterxml.jackson.databind.ObjectMapper; import com.playkuround.playkuroundserver.IntegrationControllerTest; +import com.playkuround.playkuroundserver.domain.badge.api.request.RepresentationBadgeRequest; import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; +import com.playkuround.playkuroundserver.global.error.ErrorCode; import com.playkuround.playkuroundserver.securityConfig.WithMockCustomUser; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import java.util.List; @@ -30,6 +34,9 @@ class BadgeApiTest { @Autowired private MockMvc mockMvc; + @Autowired + private ObjectMapper objectMapper; + @Autowired private UserRepository userRepository; @@ -98,7 +105,6 @@ void success_1() throws Exception { } @Test - @WithMockCustomUser @DisplayName("기존에 이미 가지고 있었다면 false가 반환된다") void fail_1() throws Exception { // given @@ -113,4 +119,68 @@ void fail_1() throws Exception { } } + @Nested + @WithMockCustomUser + @DisplayName("대표 뱃지 설정") + class RepresentationBadge { + + @Test + @DisplayName("사용자가 가지고 있는 뱃지는 정상적으로 대표 뱃지로 설정이 가능하다.") + void success_1() throws Exception { + // given + User user = userRepository.findAll().get(0); + Badge badge = new Badge(user, BadgeType.ATTENDANCE_FOUNDATION_DAY); + badgeRepository.save(badge); + + RepresentationBadgeRequest representationBadgeRequest = new RepresentationBadgeRequest(BadgeType.ATTENDANCE_FOUNDATION_DAY.name()); + String request = objectMapper.writeValueAsString(representationBadgeRequest); + + // expect + mockMvc.perform(post("/api/badges/representation") + .contentType(MediaType.APPLICATION_JSON) + .content(request)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isSuccess").value(true)) + .andDo(print()); + + User findUser = userRepository.findAll().get(0); + assertThat(findUser.getRepresentBadge()).isEqualTo(BadgeType.ATTENDANCE_FOUNDATION_DAY); + } + + @Test + @DisplayName("올바르지 않는 BadgeType을 요청하면 에러가 발생한다.") + void fail_1() throws Exception { + // given + RepresentationBadgeRequest representationBadgeRequest = new RepresentationBadgeRequest("notFound"); + String request = objectMapper.writeValueAsString(representationBadgeRequest); + + // expect + mockMvc.perform(post("/api/badges/representation") + .contentType(MediaType.APPLICATION_JSON) + .content(request)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.isSuccess").value(false)) + .andDo(print()); + } + + @Test + @DisplayName("사용자가 가지고 있지 않는 BadgeType이면 에러가 발생한다.") + void fail_2() throws Exception { + // given + RepresentationBadgeRequest representationBadgeRequest = new RepresentationBadgeRequest(BadgeType.ATTENDANCE_FOUNDATION_DAY.name()); + String request = objectMapper.writeValueAsString(representationBadgeRequest); + + // expect + mockMvc.perform(post("/api/badges/representation") + .contentType(MediaType.APPLICATION_JSON) + .content(request)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.isSuccess").value(false)) + .andExpect(jsonPath("$.errorResponse.status").value(ErrorCode.NOT_HAVE_BADGE.getStatus().value())) + .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.NOT_HAVE_BADGE.getCode())) + .andExpect(jsonPath("$.errorResponse.message").value(ErrorCode.NOT_HAVE_BADGE.getMessage())) + .andDo(print()); + } + } + } \ No newline at end of file From 0df3ad91e3ff9288863d5596917aae63c3a52ba6 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sun, 18 Aug 2024 23:06:12 +0900 Subject: [PATCH 29/79] =?UTF-8?q?test:=20=EB=8C=80=ED=91=9C=20=EB=B1=83?= =?UTF-8?q?=EC=A7=80=20=EC=84=A4=EC=A0=95=20service=20unit=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../badge/application/BadgeServiceTest.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java index a211056..7b54936 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java @@ -6,6 +6,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.badge.exception.BadgeNotHaveException; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; @@ -38,6 +39,7 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @@ -407,4 +409,39 @@ void success_2() { } } + @Nested + @DisplayName("대표 뱃지 설정") + class representationBadge { + + @Test + @DisplayName("사용자가 가지고 있는 뱃지는 정상적으로 대표 뱃지로 설정이 가능하다.") + void success_1() { + // given + User user = TestUtil.createUser(); + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; + when(badgeRepository.existsByUserAndBadgeType(user, badgeType)) + .thenReturn(true); + + // when + badgeService.representationBadge(user, badgeType); + + // then + assertThat(user.getRepresentBadge()).isEqualTo(badgeType); + } + + @Test + @DisplayName("사용자가 가지고 있지 않는 BadgeType이면 에러가 발생한다.") + void fail_1() { + // given + User user = TestUtil.createUser(); + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; + when(badgeRepository.existsByUserAndBadgeType(user, badgeType)) + .thenReturn(false); + + // expect + assertThatThrownBy(() -> { + badgeService.representationBadge(user, badgeType); + }).isInstanceOf(BadgeNotHaveException.class); + } + } } \ No newline at end of file From 42786229dc6822a6adee57cd68adb2724c4586cf Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 20 Aug 2024 10:59:08 +0900 Subject: [PATCH 30/79] =?UTF-8?q?feat:=20=EC=A0=84=EA=B3=B5,=20=EB=8B=A8?= =?UTF-8?q?=EA=B3=BC=EB=8C=80,=20=EC=A0=84=EC=9A=A9=20=EB=B1=83=EC=A7=80?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/badge/domain/BadgeType.java | 2 ++ .../playkuroundserver/domain/user/domain/Major.java | 12 ++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java index 14e1f03..7df7290 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java @@ -47,6 +47,8 @@ public enum BadgeType { COLLEGE_OF_VETERINARY_MEDICINE("수의과대학 1회 이상 탐험"), COLLEGE_OF_ART_AND_DESIGN("예술디자인대학 1회 이상 탐험"), COLLEGE_OF_EDUCATION("사범대학 1회 이상 탐험"), + COLLEGE_OF_SANG_HUH("산학협동관 1회 이상 탐험"), + COLLEGE_OF_INTERNATIONAL("법학관 1회 이상 탐험"), // 경영대 특별 COLLEGE_OF_BUSINESS_ADMINISTRATION_10("경영대학 10회 이상 탐험"), diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java index ab6acb5..92fc5f2 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java @@ -89,9 +89,13 @@ public enum Major { 교육공학과(Collage.사범대학), 영어교육과(Collage.사범대학), 교직과(Collage.사범대학), - ; + // 상허교양대학 - //국제학부(Collage.상허교양대학); + 국제학부(Collage.상허교양대학), + + // 국제대학 + 국제통상학과(Collage.국제대학), + 문화미디어학과(Collage.국제대학); private final Collage collage; @@ -116,8 +120,8 @@ enum Collage { 수의과대학(BadgeType.COLLEGE_OF_VETERINARY_MEDICINE), 예술디자인대학(BadgeType.COLLEGE_OF_ART_AND_DESIGN), 사범대학(BadgeType.COLLEGE_OF_EDUCATION), - //상허교양대학 - ; + 상허교양대학(BadgeType.COLLEGE_OF_SANG_HUH), + 국제대학(BadgeType.COLLEGE_OF_INTERNATIONAL); private final BadgeType collageBadgeType; From 4ff69f117117af94694dcaf659fb1a5e754f281c Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 20 Aug 2024 11:12:10 +0900 Subject: [PATCH 31/79] =?UTF-8?q?feat:=20=EB=9E=9C=EB=93=9C=EB=A7=88?= =?UTF-8?q?=ED=81=AC=20=EB=9E=AD=ED=82=B9=20=EC=A1=B0=ED=9A=8C=EC=8B=9C?= =?UTF-8?q?=EC=97=90=20=ED=94=84=EB=A1=9C=ED=95=84=20=EB=B1=83=EC=A7=80?= =?UTF-8?q?=EB=8F=84=20=EB=B0=98=ED=99=98=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adventure/dao/AdventureRepository.java | 6 +++--- .../domain/score/api/ScoreApi.java | 5 ++--- .../response/TotalScoreRankingResponse.java | 18 +++++------------- .../score/application/LandmarkRankService.java | 14 +++++++------- .../domain/score/dto/NicknameAndScore.java | 4 ---- .../dto/NicknameAndScoreAndBadgeType.java | 6 ++++++ 6 files changed, 23 insertions(+), 30 deletions(-) delete mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NicknameAndScore.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NicknameAndScoreAndBadgeType.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java index 10c2ce2..fbc5896 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java @@ -2,7 +2,7 @@ import com.playkuround.playkuroundserver.domain.adventure.domain.Adventure; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; -import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore; +import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScoreAndBadgeType; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; import com.playkuround.playkuroundserver.domain.user.domain.User; import org.springframework.data.jpa.repository.JpaRepository; @@ -15,13 +15,13 @@ public interface AdventureRepository extends JpaRepository { - @Query("SELECT new com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore(a.user.nickname, cast(SUM(a.score) as integer)) " + + @Query("SELECT new com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScoreAndBadgeType(a.user.nickname, cast(SUM(a.score) as integer), a.user.representBadge) " + "FROM Adventure a " + "where a.landmark.id=:landmark AND a.createdAt >= :from " + "GROUP BY a.user.id " + "ORDER BY SUM(a.score) DESC, a.user.nickname DESC " + "LIMIT 100") - List findRankTop100DescByLandmarkId(@Param(value = "landmark") Long landmarkId, @Param(value = "from") LocalDateTime from); + List findRankTop100DescByLandmarkId(@Param(value = "landmark") Long landmarkId, @Param(value = "from") LocalDateTime from); @Query("SELECT new com.playkuround.playkuroundserver.domain.score.dto.RankAndScore(cast(user_rank as integer), cast(score as integer)) FROM " + "(SELECT a.user.id as user_id, (RANK() over (order by SUM(a.score) desc)) as user_rank, SUM(a.score) as score " + diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java index e396166..5573395 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java @@ -1,6 +1,5 @@ package com.playkuround.playkuroundserver.domain.score.api; -import com.playkuround.playkuroundserver.domain.score.api.response.LandmarkScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.application.LandmarkRankService; import com.playkuround.playkuroundserver.domain.score.application.TotalScoreService; @@ -36,9 +35,9 @@ public ApiResponse getScoreTop100(@AuthenticationPrin @GetMapping("/rank/{landmarkId}") @Operation(summary = "해당 랜드마크의 점수 탑100 얻기", description = "해당 랜드마크 점수 탑100과 내 점수, 등수를 반환합니다. 내 점수가 0점이면 등수는 0등으로 반환됩니다.") - public ApiResponse getScoreTop100ByLandmark(@AuthenticationPrincipal UserDetailsImpl userDetails, + public ApiResponse getScoreTop100ByLandmark(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable Long landmarkId) { - LandmarkScoreRankingResponse response = landmarkRankService.getRankTop100ByLandmark(userDetails.getUser(), landmarkId); + TotalScoreRankingResponse response = landmarkRankService.getRankTop100ByLandmark(userDetails.getUser(), landmarkId); return ApiUtils.success(response); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java index c0f53eb..8ba2f22 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java @@ -13,29 +13,21 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class TotalScoreRankingResponse { - private final List rank = new ArrayList<>(); private MyRank myRank; + private final List rank = new ArrayList<>(); public static TotalScoreRankingResponse createEmptyResponse() { return new TotalScoreRankingResponse(); } public void addRank(String nickname, int score, BadgeType badgeType) { - if (badgeType != null) { - this.rank.add(new RankList(nickname, badgeType.name(), score)); - } - else { - this.rank.add(new RankList(nickname, null, score)); - } + String badgeTypeName = badgeType != null ? badgeType.name() : null; + this.rank.add(new RankList(nickname, badgeTypeName, score)); } public void setMyRank(int ranking, int score, BadgeType badgeType) { - if (badgeType != null) { - this.myRank = new MyRank(ranking, score, badgeType.name()); - } - else { - this.myRank = new MyRank(ranking, score, null); - } + String badgeTypeName = badgeType != null ? badgeType.name() : null; + this.myRank = new MyRank(ranking, score, badgeTypeName); } @Getter diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java index 811b7c2..b01ea86 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java @@ -2,8 +2,8 @@ import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; import com.playkuround.playkuroundserver.domain.common.DateTimeService; -import com.playkuround.playkuroundserver.domain.score.api.response.LandmarkScoreRankingResponse; -import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore; +import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScoreAndBadgeType; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; @@ -22,17 +22,17 @@ public class LandmarkRankService { private final DateTimeService dateTimeService; @Transactional(readOnly = true) - public LandmarkScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId) { - LandmarkScoreRankingResponse response = LandmarkScoreRankingResponse.createEmptyResponse(); + public TotalScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId) { + TotalScoreRankingResponse response = TotalScoreRankingResponse.createEmptyResponse(); LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.getLocalDateNow()); - List nicknameAndScores = adventureRepository.findRankTop100DescByLandmarkId(landmarkId, monthStartDateTime); + List nicknameAndScores = adventureRepository.findRankTop100DescByLandmarkId(landmarkId, monthStartDateTime); nicknameAndScores.forEach(nicknameAndScore -> - response.addRank(nicknameAndScore.nickname(), nicknameAndScore.score())); + response.addRank(nicknameAndScore.nickname(), nicknameAndScore.score(), nicknameAndScore.badgeType())); RankAndScore rankAndScore = adventureRepository.findMyRankByLandmarkId(user, landmarkId, monthStartDateTime) .orElseGet(() -> new RankAndScore(0, 0)); - response.setMyRank(rankAndScore.ranking(), rankAndScore.score()); + response.setMyRank(rankAndScore.ranking(), rankAndScore.score(), user.getRepresentBadge()); return response; } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NicknameAndScore.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NicknameAndScore.java deleted file mode 100644 index da5a6bc..0000000 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NicknameAndScore.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.playkuround.playkuroundserver.domain.score.dto; - -public record NicknameAndScore(String nickname, int score) { -} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NicknameAndScoreAndBadgeType.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NicknameAndScoreAndBadgeType.java new file mode 100644 index 0000000..9f91326 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/dto/NicknameAndScoreAndBadgeType.java @@ -0,0 +1,6 @@ +package com.playkuround.playkuroundserver.domain.score.dto; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; + +public record NicknameAndScoreAndBadgeType(String nickname, int score, BadgeType badgeType) { +} From 0a84a6885353cedde3e4ef27e505ebab15797419 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 20 Aug 2024 11:13:42 +0900 Subject: [PATCH 32/79] =?UTF-8?q?refactor:=20=EB=9E=AD=ED=82=B9=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20response=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/score/api/ScoreApi.java | 12 ++--- .../LandmarkScoreRankingResponse.java | 45 ------------------- ...esponse.java => ScoreRankingResponse.java} | 6 +-- .../application/LandmarkRankService.java | 6 +-- .../score/application/ScoreRankService.java | 6 +-- .../score/application/TotalScoreService.java | 8 ++-- 6 files changed, 19 insertions(+), 64 deletions(-) delete mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/LandmarkScoreRankingResponse.java rename src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/{TotalScoreRankingResponse.java => ScoreRankingResponse.java} (90%) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java index 5573395..6ac8712 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java @@ -1,6 +1,6 @@ package com.playkuround.playkuroundserver.domain.score.api; -import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.application.LandmarkRankService; import com.playkuround.playkuroundserver.domain.score.application.TotalScoreService; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; @@ -27,17 +27,17 @@ public class ScoreApi { @GetMapping("/rank") @Operation(summary = "종합 점수 탑100 얻기", description = "토탈 점수 탑100과 내 점수, 등수를 반환합니다. 내 점수가 0점이면 등수는 0등으로 반환됩니다.") - public ApiResponse getScoreTop100(@AuthenticationPrincipal UserDetailsImpl userDetails) { - TotalScoreRankingResponse response = totalScoreService.getRankTop100(userDetails.getUser()); + public ApiResponse getScoreTop100(@AuthenticationPrincipal UserDetailsImpl userDetails) { + ScoreRankingResponse response = totalScoreService.getRankTop100(userDetails.getUser()); return ApiUtils.success(response); } @GetMapping("/rank/{landmarkId}") @Operation(summary = "해당 랜드마크의 점수 탑100 얻기", description = "해당 랜드마크 점수 탑100과 내 점수, 등수를 반환합니다. 내 점수가 0점이면 등수는 0등으로 반환됩니다.") - public ApiResponse getScoreTop100ByLandmark(@AuthenticationPrincipal UserDetailsImpl userDetails, - @PathVariable Long landmarkId) { - TotalScoreRankingResponse response = landmarkRankService.getRankTop100ByLandmark(userDetails.getUser(), landmarkId); + public ApiResponse getScoreTop100ByLandmark(@AuthenticationPrincipal UserDetailsImpl userDetails, + @PathVariable Long landmarkId) { + ScoreRankingResponse response = landmarkRankService.getRankTop100ByLandmark(userDetails.getUser(), landmarkId); return ApiUtils.success(response); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/LandmarkScoreRankingResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/LandmarkScoreRankingResponse.java deleted file mode 100644 index 6d90897..0000000 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/LandmarkScoreRankingResponse.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.playkuround.playkuroundserver.domain.score.api.response; - -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.util.ArrayList; -import java.util.List; - -@Getter -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class LandmarkScoreRankingResponse { - - private MyRank myRank; - private final List rank = new ArrayList<>(); - - public static LandmarkScoreRankingResponse createEmptyResponse() { - return new LandmarkScoreRankingResponse(); - } - - public void addRank(String nickname, int score) { - this.rank.add(new RankList(nickname, score)); - } - - public void setMyRank(int ranking, int score) { - this.myRank = new MyRank(ranking, score); - } - - @Getter - @AllArgsConstructor(access = AccessLevel.PRIVATE) - @NoArgsConstructor(access = AccessLevel.PROTECTED) - public static class RankList { - private String nickname; - private int score; - } - - @Getter - @AllArgsConstructor(access = AccessLevel.PRIVATE) - @NoArgsConstructor(access = AccessLevel.PROTECTED) - public static class MyRank { - private int ranking; - private int score; - } -} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java similarity index 90% rename from src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java rename to src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java index 8ba2f22..60978a6 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/TotalScoreRankingResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java @@ -11,13 +11,13 @@ @Getter @NoArgsConstructor(access = AccessLevel.PRIVATE) -public class TotalScoreRankingResponse { +public class ScoreRankingResponse { private MyRank myRank; private final List rank = new ArrayList<>(); - public static TotalScoreRankingResponse createEmptyResponse() { - return new TotalScoreRankingResponse(); + public static ScoreRankingResponse createEmptyResponse() { + return new ScoreRankingResponse(); } public void addRank(String nickname, int score, BadgeType badgeType) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java index b01ea86..0be6716 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java @@ -2,7 +2,7 @@ import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; import com.playkuround.playkuroundserver.domain.common.DateTimeService; -import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScoreAndBadgeType; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -22,8 +22,8 @@ public class LandmarkRankService { private final DateTimeService dateTimeService; @Transactional(readOnly = true) - public TotalScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId) { - TotalScoreRankingResponse response = TotalScoreRankingResponse.createEmptyResponse(); + public ScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId) { + ScoreRankingResponse response = ScoreRankingResponse.createEmptyResponse(); LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.getLocalDateNow()); List nicknameAndScores = adventureRepository.findRankTop100DescByLandmarkId(landmarkId, monthStartDateTime); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java index cf71807..fd0f552 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java @@ -1,6 +1,6 @@ package com.playkuround.playkuroundserver.domain.score.application; -import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.dto.NickNameAndBadge; import org.springframework.data.redis.core.ZSetOperations; @@ -25,8 +25,8 @@ public List getRankUserEmails() { .toList(); } - public TotalScoreRankingResponse createScoreRankingResponse(Map emailBindingData) { - TotalScoreRankingResponse response = TotalScoreRankingResponse.createEmptyResponse(); + public ScoreRankingResponse createScoreRankingResponse(Map emailBindingData) { + ScoreRankingResponse response = ScoreRankingResponse.createEmptyResponse(); rankDataList.forEach(rankData -> { NickNameAndBadge nickNameAndBadge = emailBindingData.get(rankData.email); if (nickNameAndBadge.nickname() == null) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java index ace7fd5..b42b72b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java @@ -1,6 +1,6 @@ package com.playkuround.playkuroundserver.domain.score.application; -import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.dto.NickNameAndBadge; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; @@ -41,16 +41,16 @@ public Long incrementTotalScore(User user, Long score) { } @Transactional(readOnly = true) - public TotalScoreRankingResponse getRankTop100(User user) { + public ScoreRankingResponse getRankTop100(User user) { Set> typedTuples = zSetOperations.reverseRangeWithScores(redisSetKey, 0, 99); if (typedTuples == null) { - return TotalScoreRankingResponse.createEmptyResponse(); + return ScoreRankingResponse.createEmptyResponse(); } ScoreRankService scoreRankService = new ScoreRankService(typedTuples); Map emailBindingNickname = getNicknameBindingEmailMapList(scoreRankService.getRankUserEmails()); - TotalScoreRankingResponse response = scoreRankService.createScoreRankingResponse(emailBindingNickname); + ScoreRankingResponse response = scoreRankService.createScoreRankingResponse(emailBindingNickname); RankAndScore myRank = getMyRank(user); response.setMyRank(myRank.ranking(), myRank.score(), user.getRepresentBadge()); From 1192a3ba6aa9470412145274f4b8112802982429 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 20 Aug 2024 11:17:22 +0900 Subject: [PATCH 33/79] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=ED=86=B5=EA=B3=BC=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../score/api/LandmarkScoreRankApiTest.java | 18 +++++------ .../score/api/ScoreTotalRankApiTest.java | 20 ++++++------- .../application/LandmarkRankServiceTest.java | 30 +++++++++---------- .../application/TotalScoreServiceTest.java | 20 ++++++------- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java index 09f5a1b..f6fb1f6 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java @@ -6,7 +6,7 @@ import com.playkuround.playkuroundserver.domain.adventure.domain.Adventure; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; -import com.playkuround.playkuroundserver.domain.score.api.response.LandmarkScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.domain.ScoreType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; @@ -83,11 +83,11 @@ void getRankTop100ByLandmark_2() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - LandmarkScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, LandmarkScoreRankingResponse.class); + ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(50); - List rank = response.getRank(); + List rank = response.getRank(); for (int i = 0; i < 50; i++) { assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); assertThat(rank.get(i).getScore()).isEqualTo(50 - i); @@ -120,11 +120,11 @@ void getRankTop100ByLandmark_3() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - LandmarkScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, LandmarkScoreRankingResponse.class); + ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(51); - List rank = response.getRank(); + List rank = response.getRank(); for (int i = 0; i < 51; i++) { if (i < 14) { assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); @@ -167,11 +167,11 @@ void getRankTop100ByLandmark_4() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - LandmarkScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, LandmarkScoreRankingResponse.class); + ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(100); - List rank = response.getRank(); + List rank = response.getRank(); for (int i = 0; i < 100; i++) { if (i < 40) { assertThat(rank.get(i).getNickname()).isEqualTo("user" + (101 - i)); @@ -216,11 +216,11 @@ void getRankTop100ByLandmark_5() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - LandmarkScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, LandmarkScoreRankingResponse.class); + ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(100); - List rank = response.getRank(); + List rank = response.getRank(); for (int i = 0; i < 100; i++) { if (i < 41) { assertThat(rank.get(i).getNickname()).isEqualTo("user" + (101 - i)); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java index 010d3c9..aeeea9b 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java @@ -3,7 +3,7 @@ import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -79,11 +79,11 @@ void getRankTop100_2() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - TotalScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, TotalScoreRankingResponse.class); + ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(50); - List rank = response.getRank(); + List rank = response.getRank(); for (int i = 0; i < 50; i++) { assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); assertThat(rank.get(i).getScore()).isEqualTo(50 - i); @@ -112,11 +112,11 @@ void getRankTop100_3() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - TotalScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, TotalScoreRankingResponse.class); + ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(51); - List rank = response.getRank(); + List rank = response.getRank(); for (int i = 0; i < 51; i++) { if (i < 38) { assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); @@ -155,11 +155,11 @@ void getRankTop100_4() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - TotalScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, TotalScoreRankingResponse.class); + ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(100); - List rank = response.getRank(); + List rank = response.getRank(); assertThat(rank.get(0).getNickname()).isEqualTo("user100"); assertThat(rank.get(0).getScore()).isEqualTo(100); assertThat(rank.get(99).getNickname()).isEqualTo("user2"); @@ -193,11 +193,11 @@ void getRankTop100_5() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - TotalScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, TotalScoreRankingResponse.class); + ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(100); - List rank = response.getRank(); + List rank = response.getRank(); assertThat(rank.get(0).getNickname()).isEqualTo("user1"); assertThat(rank.get(0).getScore()).isEqualTo(999); assertThat(rank.get(99).getNickname()).isEqualTo("user105"); @@ -237,7 +237,7 @@ void getRankTop100_6() throws Exception { .andDo(print()) .andReturn(); String json = mvcResult.getResponse().getContentAsString(); - TotalScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, TotalScoreRankingResponse.class); + ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); // then assertThat(response.getRank()).hasSize(3) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java index 72cbd56..41318f2 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java @@ -3,8 +3,8 @@ import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; import com.playkuround.playkuroundserver.domain.common.DateTimeService; -import com.playkuround.playkuroundserver.domain.score.api.response.LandmarkScoreRankingResponse; -import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScore; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScoreAndBadgeType; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; import com.playkuround.playkuroundserver.domain.user.domain.User; import org.junit.jupiter.api.DisplayName; @@ -49,7 +49,7 @@ void getRankTop100ByLandmark1() { // when User user = TestUtil.createUser(); - LandmarkScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); // then assertThat(result.getRank()).isEmpty(); @@ -61,8 +61,8 @@ void getRankTop100ByLandmark1() { @DisplayName("전체 유저 100명 미만 + 내 랭킹은 없음") void getRankTop100ByLandmark2() { // given - List nicknameAndScores = IntStream.rangeClosed(1, 50) - .mapToObj(i -> new NicknameAndScore("nickname" + (51 - i), 51 - i)) + List nicknameAndScores = IntStream.rangeClosed(1, 50) + .mapToObj(i -> new NicknameAndScoreAndBadgeType("nickname" + (51 - i), 51 - i, null)) .toList(); when(adventureRepository.findRankTop100DescByLandmarkId(any(Long.class), any(LocalDateTime.class))) .thenReturn(nicknameAndScores); @@ -73,10 +73,10 @@ void getRankTop100ByLandmark2() { // when User user = TestUtil.createUser(); - LandmarkScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); // then - List rankList = result.getRank(); + List rankList = result.getRank(); assertThat(rankList).hasSize(50); for (int i = 50; i > 0; i--) { assertThat(rankList.get(50 - i).getNickname()).isEqualTo("nickname" + i); @@ -91,8 +91,8 @@ void getRankTop100ByLandmark2() { @DisplayName("전체 유저 100명 미만 + 내 랭킹 존재") void getRankTop100ByLandmark3() { // given - List nicknameAndScores = IntStream.rangeClosed(1, 50) - .mapToObj(i -> new NicknameAndScore("nickname" + (51 - i), 51 - i)) + List nicknameAndScores = IntStream.rangeClosed(1, 50) + .mapToObj(i -> new NicknameAndScoreAndBadgeType("nickname" + (51 - i), 51 - i, null)) .toList(); when(adventureRepository.findRankTop100DescByLandmarkId(any(Long.class), any(LocalDateTime.class))) .thenReturn(nicknameAndScores); @@ -103,10 +103,10 @@ void getRankTop100ByLandmark3() { // when User user = TestUtil.createUser(); - LandmarkScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); // then - List rankList = result.getRank(); + List rankList = result.getRank(); assertThat(rankList).hasSize(50); for (int i = 50; i > 0; i--) { assertThat(rankList.get(50 - i).getNickname()).isEqualTo("nickname" + i); @@ -120,8 +120,8 @@ void getRankTop100ByLandmark3() { @DisplayName("전체 유저 100명 초과 + 내 랭킹 중간에 존재") void getRankTop100ByLandmark4() { // given - List nicknameAndScores = IntStream.rangeClosed(1, 101) - .mapToObj(i -> new NicknameAndScore("nickname" + (102 - i), 102 - i)) + List nicknameAndScores = IntStream.rangeClosed(1, 101) + .mapToObj(i -> new NicknameAndScoreAndBadgeType("nickname" + (102 - i), 102 - i, null)) .toList(); when(adventureRepository.findRankTop100DescByLandmarkId(any(Long.class), any(LocalDateTime.class))) .thenReturn(nicknameAndScores); @@ -132,10 +132,10 @@ void getRankTop100ByLandmark4() { // when User user = TestUtil.createUser(); - LandmarkScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); // then - List rankList = result.getRank(); + List rankList = result.getRank(); assertThat(rankList).hasSize(101); for (int i = 101; i > 0; i--) { assertThat(rankList.get(101 - i).getNickname()).isEqualTo("nickname" + i); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java index 1415f7d..4d040ac 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java @@ -2,7 +2,7 @@ import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; -import com.playkuround.playkuroundserver.domain.score.api.response.TotalScoreRankingResponse; +import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -62,7 +62,7 @@ void incrementTotalScore() { void getRankTop1001() { // expect User user = TestUtil.createUser(); - TotalScoreRankingResponse result = totalScoreService.getRankTop100(user); + ScoreRankingResponse result = totalScoreService.getRankTop100(user); assertThat(result.getRank()).isEmpty(); assertThat(result.getMyRank().getScore()).isZero(); @@ -80,11 +80,11 @@ void getRankTop1002() { } // when - TotalScoreRankingResponse result = totalScoreService.getRankTop100(TestUtil.createUser()); + ScoreRankingResponse result = totalScoreService.getRankTop100(TestUtil.createUser()); // then assertThat(result.getRank()).hasSize(50); - List rank = result.getRank(); + List rank = result.getRank(); for (int i = 0; i < 50; i++) { assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); assertThat(rank.get(i).getScore()).isEqualTo(50 - i); @@ -107,11 +107,11 @@ void getRankTop1003() { totalScoreService.incrementTotalScore(user, (long) 13); // when - TotalScoreRankingResponse result = totalScoreService.getRankTop100(user); + ScoreRankingResponse result = totalScoreService.getRankTop100(user); // then assertThat(result.getRank()).hasSize(51); - List rank = result.getRank(); + List rank = result.getRank(); for (int i = 0; i < 51; i++) { if (i < 38) { assertThat(rank.get(i).getNickname()).isEqualTo("user" + (50 - i)); @@ -144,11 +144,11 @@ void getRankTop1004() { totalScoreService.incrementTotalScore(user, (long) 51); // when - TotalScoreRankingResponse result = totalScoreService.getRankTop100(user); + ScoreRankingResponse result = totalScoreService.getRankTop100(user); // then assertThat(result.getRank()).hasSize(100); - List rank = result.getRank(); + List rank = result.getRank(); assertThat(rank.get(0).getNickname()).isEqualTo("user100"); assertThat(rank.get(0).getScore()).isEqualTo(100); assertThat(rank.get(99).getNickname()).isEqualTo("user2"); @@ -176,11 +176,11 @@ void getRankTop1005() { } // when - TotalScoreRankingResponse result = totalScoreService.getRankTop100(me); + ScoreRankingResponse result = totalScoreService.getRankTop100(me); // then assertThat(result.getRank()).hasSize(100); - List rank = result.getRank(); + List rank = result.getRank(); assertThat(rank.get(0).getNickname()).isEqualTo("user1"); assertThat(rank.get(0).getScore()).isEqualTo(999); assertThat(rank.get(99).getNickname()).isEqualTo("user105"); From c5b291eb39e82019f810d4653f556f81155032b6 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 20 Aug 2024 14:35:37 +0900 Subject: [PATCH 34/79] =?UTF-8?q?test:=20=EB=9E=9C=EB=93=9C=EB=A7=88?= =?UTF-8?q?=ED=81=AC=20=EB=9E=AD=ED=82=B9=20=EC=A1=B0=ED=9A=8C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../score/api/LandmarkScoreRankApiTest.java | 56 +++++++++++++++++-- .../application/LandmarkRankServiceTest.java | 48 ++++++++++++++-- ...hMockCustomUserSecurityContextFactory.java | 4 +- 3 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java index f6fb1f6..ec85c72 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java @@ -4,6 +4,7 @@ import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; import com.playkuround.playkuroundserver.domain.adventure.domain.Adventure; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; @@ -22,6 +23,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -200,14 +202,11 @@ void getRankTop100ByLandmark_5() throws Exception { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); userRepository.save(user); - Adventure adventure = new Adventure(user, landmark, ScoreType.CATCH, (long) i); - adventureRepository.save(adventure); - adventure = new Adventure(user, landmark, ScoreType.BOOK, 1L); - adventureRepository.save(adventure); + adventureRepository.save(new Adventure(user, landmark, ScoreType.CATCH, (long) i)); + adventureRepository.save(new Adventure(user, landmark, ScoreType.BOOK, 1L)); } User me = userRepository.findByEmail("test@konkuk.ac.kr").get(); - Adventure adventure = new Adventure(me, landmark, ScoreType.CATCH, 62L); - adventureRepository.save(adventure); + adventureRepository.save(new Adventure(me, landmark, ScoreType.CATCH, 62L)); // when MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank/{landmarkId}", 1)) @@ -238,4 +237,49 @@ else if (i == 41) { assertThat(response.getMyRank().getScore()).isEqualTo(62); assertThat(response.getMyRank().getRanking()).isEqualTo(41); // 공동등수 } + + @Test + @WithMockCustomUser(email = "test@konkuk.ac.kr", badgeType = BadgeType.COLLEGE_OF_ENGINEERING) + @DisplayName("랭킹 조회 API에는 사용자 대표 뱃지 데이터가 포함되어 있다.") + void getRankTop100ByLandmark_6() throws Exception { + // given + Landmark landmark = landmarkRepository.findById(1L).get(); + { + User me = userRepository.findByEmail("test@konkuk.ac.kr").get(); + adventureRepository.save(new Adventure(me, landmark, ScoreType.CATCH, 10L)); + } + { + User user1 = TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.건축학부); + user1.updateRepresentBadge(BadgeType.ATTENDANCE_1); + userRepository.save(user1); + adventureRepository.save(new Adventure(user1, landmark, ScoreType.CATCH, 5L)); + } + { + User user2 = TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부); + user2.updateRepresentBadge(BadgeType.MONTHLY_RANKING_1); + userRepository.save(user2); + adventureRepository.save(new Adventure(user2, landmark, ScoreType.CATCH, 15L)); + } + + // when + MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank/{landmarkId}", 1)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isSuccess").value(true)) + .andDo(print()) + .andReturn(); + String json = mvcResult.getResponse().getContentAsString(); + ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); + + // then + assertThat(response.getRank()).hasSize(3) + .extracting("nickname", "badgeType", "score") + .containsExactly( + tuple("user2", BadgeType.MONTHLY_RANKING_1.name(), 15), + tuple("tester", BadgeType.COLLEGE_OF_ENGINEERING.name(), 10), + tuple("user1", BadgeType.ATTENDANCE_1.name(), 5) + ); + assertThat(response.getMyRank().getScore()).isEqualTo(10); + assertThat(response.getMyRank().getRanking()).isEqualTo(2); + assertThat(response.getMyRank().getBadgeType()).isEqualTo(BadgeType.COLLEGE_OF_ENGINEERING.name()); + } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java index 41318f2..5f3bbf0 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java @@ -2,6 +2,7 @@ import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScoreAndBadgeType; @@ -21,6 +22,7 @@ import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @@ -38,7 +40,7 @@ class LandmarkRankServiceTest { @Test @DisplayName("랭킹 유저가 한명도 없을 때") - void getRankTop100ByLandmark1() { + void getRankTop100ByLandmark_1() { // given when(adventureRepository.findRankTop100DescByLandmarkId(any(Long.class), any(LocalDateTime.class))) .thenReturn(List.of()); @@ -59,7 +61,7 @@ void getRankTop100ByLandmark1() { @Test @DisplayName("전체 유저 100명 미만 + 내 랭킹은 없음") - void getRankTop100ByLandmark2() { + void getRankTop100ByLandmark_2() { // given List nicknameAndScores = IntStream.rangeClosed(1, 50) .mapToObj(i -> new NicknameAndScoreAndBadgeType("nickname" + (51 - i), 51 - i, null)) @@ -89,7 +91,7 @@ void getRankTop100ByLandmark2() { @Test @DisplayName("전체 유저 100명 미만 + 내 랭킹 존재") - void getRankTop100ByLandmark3() { + void getRankTop100ByLandmark_3() { // given List nicknameAndScores = IntStream.rangeClosed(1, 50) .mapToObj(i -> new NicknameAndScoreAndBadgeType("nickname" + (51 - i), 51 - i, null)) @@ -118,7 +120,7 @@ void getRankTop100ByLandmark3() { @Test @DisplayName("전체 유저 100명 초과 + 내 랭킹 중간에 존재") - void getRankTop100ByLandmark4() { + void getRankTop100ByLandmark_4() { // given List nicknameAndScores = IntStream.rangeClosed(1, 101) .mapToObj(i -> new NicknameAndScoreAndBadgeType("nickname" + (102 - i), 102 - i, null)) @@ -144,4 +146,42 @@ void getRankTop100ByLandmark4() { assertThat(result.getMyRank().getScore()).isEqualTo(62); assertThat(result.getMyRank().getRanking()).isEqualTo(40); } + + @Test + @DisplayName("랜드마크 랭킹 조회 결과에는 사용자 프로필 뱃지 데이터가 포함되어 있다.") + void getRankTop100ByLandmark_5() { + // given + LocalDate now = LocalDate.of(2024, 7, 1); + when(dateTimeService.getLocalDateNow()) + .thenReturn(now); + + List rankData = List.of( + new NicknameAndScoreAndBadgeType("user1", 10, BadgeType.ATTENDANCE_1), + new NicknameAndScoreAndBadgeType("user2", 5, BadgeType.MONTHLY_RANKING_1) + ); + + Long landmarkId = 1L; + when(adventureRepository.findRankTop100DescByLandmarkId(landmarkId, now.atStartOfDay())) + .thenReturn(rankData); + + User user = TestUtil.createUser(); + user.updateRepresentBadge(BadgeType.ATTENDANCE_CHRISTMAS_DAY); + when(adventureRepository.findMyRankByLandmarkId(user, landmarkId, now.atStartOfDay())) + .thenReturn(Optional.of(new RankAndScore(2, 7))); + + + // when + ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, landmarkId); + + // then + assertThat(result.getRank()).hasSize(2) + .extracting("nickname", "badgeType", "score") + .containsExactly( + tuple("user1", BadgeType.ATTENDANCE_1.name(), 10), + tuple("user2", BadgeType.MONTHLY_RANKING_1.name(), 5) + ); + assertThat(result.getMyRank().getScore()).isEqualTo(7); + assertThat(result.getMyRank().getRanking()).isEqualTo(2); + assertThat(result.getMyRank().getBadgeType()).isEqualTo(BadgeType.ATTENDANCE_CHRISTMAS_DAY.name()); + } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java index aeb34a8..7dcf95e 100644 --- a/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java +++ b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java @@ -18,8 +18,7 @@ import java.util.List; @Component -public class WithMockCustomUserSecurityContextFactory - implements WithSecurityContextFactory { +public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory { @Autowired private UserRepository userRepository; @@ -28,6 +27,7 @@ public SecurityContext createSecurityContext(WithMockCustomUser annotation) { User user = User.create(annotation.email(), annotation.nickname(), annotation.major(), annotation.role()); user.updateRepresentBadge(annotation.badgeType()); userRepository.save(user); + String roleName = user.getRole().toString(); List role = Arrays.stream(roleName.split(",")).toList(); UserDetailsImpl userDetails = new UserDetailsImpl(user, "", role); From 25aebd3872710fd4e4b2dd94ee31da59af926b90 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 20 Aug 2024 15:09:50 +0900 Subject: [PATCH 35/79] =?UTF-8?q?test:=20=ED=86=A0=ED=83=88=20=EB=9E=AD?= =?UTF-8?q?=ED=82=B9=20=EC=A1=B0=ED=9A=8C=20service=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/TotalScoreServiceTest.java | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java index 4d040ac..6217129 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java @@ -2,6 +2,7 @@ import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; @@ -18,6 +19,7 @@ import java.util.Random; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; @SpringBootTest @ActiveProfiles("test") @@ -38,8 +40,8 @@ class TotalScoreServiceTest { @AfterEach void tearDown() { redisTemplate.delete("ranking"); - adventureRepository.deleteAll(); - userRepository.deleteAll(); + adventureRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); } @Test @@ -59,7 +61,7 @@ void incrementTotalScore() { @Test @DisplayName("탑 100명 랭킹 조회하기 : 랭킹 유저가 한명도 없을 때") - void getRankTop1001() { + void getRankTop100_1() { // expect User user = TestUtil.createUser(); ScoreRankingResponse result = totalScoreService.getRankTop100(user); @@ -71,7 +73,7 @@ void getRankTop1001() { @Test @DisplayName("탑 100명 랭킹 조회하기 : 전체 유저 100명 미만 + 내 랭킹은 없음") - void getRankTop1002() { + void getRankTop100_2() { // given for (int i = 1; i <= 50; i++) { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); @@ -95,7 +97,7 @@ void getRankTop1002() { @Test @DisplayName("탑 100명 랭킹 조회하기 : 전체 유저 100명 미만 + 내 랭킹 존재") - void getRankTop1003() { + void getRankTop100_3() { // given for (int i = 1; i <= 50; i++) { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); @@ -132,7 +134,7 @@ else if (i == 38) { @Test @DisplayName("탑 100명 랭킹 조회하기 : 전체 유저 100명 초과 + 내 랭킹 공동 50위") - void getRankTop1004() { + void getRankTop100_4() { // given for (int i = 1; i <= 100; i++) { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); @@ -160,7 +162,7 @@ void getRankTop1004() { @Test @DisplayName("탑 100명 랭킹 조회하기 : 전체 유저 100명 초과 + 내 랭킹 공동 91위") - void getRankTop1005() { + void getRankTop100_5() { // given for (int i = 1; i <= 90; i++) { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); @@ -190,5 +192,41 @@ void getRankTop1005() { assertThat(result.getMyRank().getRanking()).isEqualTo(91); } + @Test + @DisplayName("전체 랭킹 조회 결과에는 사용자 프로필 뱃지 데이터가 포함되어 있다.") + void getRankTop100_6() { + // given + User user1 = TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과); + User user2 = TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.건축학부); + User user3 = TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.컴퓨터공학부); + + user1.updateRepresentBadge(BadgeType.ATTENDANCE_CHRISTMAS_DAY); + user2.updateRepresentBadge(BadgeType.MONTHLY_RANKING_1); + user3.updateRepresentBadge(BadgeType.ATTENDANCE_1); + + userRepository.save(user1); + userRepository.save(user2); + userRepository.save(user3); + + totalScoreService.incrementTotalScore(user1, 15L); + totalScoreService.incrementTotalScore(user2, 5L); + totalScoreService.incrementTotalScore(user3, 10L); + + // when + ScoreRankingResponse result = totalScoreService.getRankTop100(user1); + + // then + assertThat(result.getRank()).hasSize(3) + .extracting("nickname", "badgeType", "score") + .containsExactly( + tuple(user1.getNickname(), user1.getRepresentBadge().name(), 15), + tuple(user3.getNickname(), user3.getRepresentBadge().name(), 10), + tuple(user2.getNickname(), user2.getRepresentBadge().name(), 5) + + ); + assertThat(result.getMyRank().getScore()).isEqualTo(15); + assertThat(result.getMyRank().getRanking()).isEqualTo(1); + assertThat(result.getMyRank().getBadgeType()).isEqualTo(user1.getRepresentBadge().name()); + } } \ No newline at end of file From 72251afdc396b19f48fed6a6989f580339097e3c Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 20 Aug 2024 15:51:42 +0900 Subject: [PATCH 36/79] =?UTF-8?q?feat:=20=EB=9E=9C=EB=93=9C=EB=A7=88?= =?UTF-8?q?=ED=81=AC=201=EB=93=B1=20=EC=9C=A0=EC=A0=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=8B=9C=20=ED=94=84=EB=A1=9C=ED=95=84=20=EB=B1=83?= =?UTF-8?q?=EC=A7=80=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20=ED=8F=AC?= =?UTF-8?q?=ED=95=A8=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/landmark/api/LandmarkApi.java | 8 +++++-- .../LandmarkHighestScoreUserResponse.java | 13 ++++++++---- .../application/LandmarkScoreService.java | 14 ++++++++++--- .../dto/LandmarkHighestScoreUser.java | 21 ++----------------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java index 322a28d..1061a43 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java @@ -16,6 +16,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; +import java.util.Optional; + @RestController @RequestMapping("/api/landmarks") @RequiredArgsConstructor @@ -41,7 +43,9 @@ public ApiResponse LandmarkFindNear(@RequestParam @Lati description = "해당 랜드마크에서 가장 높은 점수를 획득한 사용자를 반환합니다. " + "방문한 유저가 한명도 없으면 아무것도 반환하지 않습니다. 점수가 같은 유저가 있다면 먼저 해당 점수를 달성한 유저를 반환합니다.") public ApiResponse findHighestUserByLandmark(@PathVariable Long landmarkId) { - LandmarkHighestScoreUser highestScoreUserByLandmark = landmarkScoreService.findHighestScoreUserByLandmark(landmarkId); - return ApiUtils.success(LandmarkHighestScoreUserResponse.from(highestScoreUserByLandmark)); + Optional highestScoreUser = landmarkScoreService.findHighestScoreUserByLandmark(landmarkId); + return highestScoreUser + .map(user -> ApiUtils.success(LandmarkHighestScoreUserResponse.from(user))) + .orElseGet(() -> ApiUtils.success(LandmarkHighestScoreUserResponse.createEmptyResponse())); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java index 6de07d5..a90a8a6 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java @@ -19,10 +19,15 @@ public class LandmarkHighestScoreUserResponse { @Schema(description = "최고 점수", example = "294") private Long score; - public static LandmarkHighestScoreUserResponse from(LandmarkHighestScoreUser landmarkHighestScoreUser) { - if (landmarkHighestScoreUser.isHasResult()) { - return new LandmarkHighestScoreUserResponse(landmarkHighestScoreUser.getNickname(), landmarkHighestScoreUser.getScore()); - } + @Schema(description = "해당 사용자의 뱃지타입", example = "COLLEGE_OF_ENGINEERING") + private String badgeType; + + public static LandmarkHighestScoreUserResponse from(LandmarkHighestScoreUser firstUserData) { + String badgeTypeName = firstUserData.badgeType() == null ? null : firstUserData.badgeType().name(); + return new LandmarkHighestScoreUserResponse(firstUserData.nickname(), firstUserData.score(), badgeTypeName); + } + + public static LandmarkHighestScoreUserResponse createEmptyResponse() { return new LandmarkHighestScoreUserResponse(); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreService.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreService.java index bc31f57..c7185fb 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreService.java @@ -9,6 +9,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + @Service @RequiredArgsConstructor public class LandmarkScoreService { @@ -16,14 +18,20 @@ public class LandmarkScoreService { private final LandmarkRepository landmarkRepository; @Transactional(readOnly = true) - public LandmarkHighestScoreUser findHighestScoreUserByLandmark(Long landmarkId) { + public Optional findHighestScoreUserByLandmark(Long landmarkId) { Landmark landmark = landmarkRepository.findById(landmarkId) .orElseThrow(() -> new LandmarkNotFoundException(landmarkId)); User firstUser = landmark.getFirstUser(); if (firstUser == null) { - return LandmarkHighestScoreUser.createEmpty(); + return Optional.empty(); } - return LandmarkHighestScoreUser.of(firstUser.getNickname(), landmark.getHighestScore()); + + LandmarkHighestScoreUser highestScoreUser = new LandmarkHighestScoreUser( + landmark.getHighestScore(), + firstUser.getNickname(), + firstUser.getRepresentBadge() + ); + return Optional.of(highestScoreUser); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/dto/LandmarkHighestScoreUser.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/dto/LandmarkHighestScoreUser.java index 5b7b065..3753b15 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/dto/LandmarkHighestScoreUser.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/dto/LandmarkHighestScoreUser.java @@ -1,23 +1,6 @@ package com.playkuround.playkuroundserver.domain.landmark.dto; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -@Getter -@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) -@AllArgsConstructor(access = lombok.AccessLevel.PRIVATE) -public class LandmarkHighestScoreUser { - - private Long score; - private String nickname; - private boolean hasResult; - - public static LandmarkHighestScoreUser createEmpty() { - return new LandmarkHighestScoreUser(); - } - - public static LandmarkHighestScoreUser of(String nickname, Long score) { - return new LandmarkHighestScoreUser(score, nickname, true); - } +public record LandmarkHighestScoreUser(long score, String nickname, BadgeType badgeType) { } From 7a7f95566c554811f01a65d69f57a0a651ada360 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 20 Aug 2024 15:52:08 +0900 Subject: [PATCH 37/79] =?UTF-8?q?test:=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EB=B1=83=EC=A7=80=20=EA=B2=80=EC=A6=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/landmark/api/LandmarkApiTest.java | 12 ++++++-- .../application/LandmarkScoreServiceTest.java | 28 +++++++++++++++---- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java index 6a164d2..18ebe68 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.domain.landmark.api; import com.playkuround.playkuroundserver.IntegrationControllerTest; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; @@ -13,7 +14,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.transaction.annotation.Transactional; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; @@ -89,11 +89,13 @@ void success_3() throws Exception { class findHighestUserByLandmark { @Test - @Transactional @DisplayName("랜드마크에 최고점 유저가 있다면 반환한다") void success_1() throws Exception { // given User user = userRepository.findAll().get(0); + user.updateRepresentBadge(BadgeType.ATTENDANCE_50); + userRepository.save(user); + Landmark landmark = landmarkRepository.findById(1L).get(); landmark.updateFirstUser(user, 1000); landmarkRepository.save(landmark); @@ -103,11 +105,15 @@ void success_1() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.response.score").value(1000)) .andExpect(jsonPath("$.response.nickname").value(user.getNickname())) + .andExpect(jsonPath("$.response.badgeType").value(user.getRepresentBadge().name())) .andDo(print()); + + // tear down + landmark.deleteRank(); + landmarkRepository.save(landmark); } @Test - @WithMockCustomUser @DisplayName("랜드마크에 최고점 유저가 없다면 빈 응답을 반환한다") void success_2() throws Exception { // expected diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreServiceTest.java index 49d7a96..35ed872 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreServiceTest.java @@ -4,6 +4,7 @@ import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.dto.LandmarkHighestScoreUser; +import com.playkuround.playkuroundserver.domain.landmark.exception.LandmarkNotFoundException; import com.playkuround.playkuroundserver.domain.user.domain.User; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -15,6 +16,7 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -38,12 +40,14 @@ void findHighestScoreUserByLandmark() { when(landmarkRepository.findById(1L)).thenReturn(Optional.of(mockLandmark)); // when - LandmarkHighestScoreUser result = landmarkScoreService.findHighestScoreUserByLandmark(1L); + Optional result = landmarkScoreService.findHighestScoreUserByLandmark(1L); // then - assertThat(result.isHasResult()).isTrue(); - assertThat(result.getScore()).isEqualTo(1234L); - assertThat(result.getNickname()).isEqualTo(user.getNickname()); + assertThat(result).isPresent() + .hasValueSatisfying(firstUserData -> { + assertThat(firstUserData.score()).isEqualTo(1234L); + assertThat(firstUserData.nickname()).isEqualTo(user.getNickname()); + }); } @Test @@ -55,10 +59,22 @@ void findHighestScoreUserByLandmarkEmpty() { when(landmarkRepository.findById(1L)).thenReturn(Optional.of(mockLandmark)); // when - LandmarkHighestScoreUser result = landmarkScoreService.findHighestScoreUserByLandmark(1L); + Optional result = landmarkScoreService.findHighestScoreUserByLandmark(1L); // then - assertThat(result.isHasResult()).isFalse(); + assertThat(result).isEmpty(); + } + + @Test + @DisplayName("존재하지 않는 랜드마크 ID로 조회 시 예외 발생") + void findHighestScoreUserByNonExistentLandmark() { + // given + when(landmarkRepository.findById(999L)).thenReturn(Optional.empty()); + + // expect + assertThatThrownBy( + () -> landmarkScoreService.findHighestScoreUserByLandmark(999L) + ).isInstanceOf(LandmarkNotFoundException.class); } } \ No newline at end of file From 374ade94d6877c86129d35f25cca2a6715966f2a Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Wed, 21 Aug 2024 18:34:49 +0900 Subject: [PATCH 38/79] =?UTF-8?q?feat:=20=EC=83=88=EB=A1=9C=EC=9A=B4=20?= =?UTF-8?q?=EB=B1=83=EC=A7=80=EB=A5=BC=20=ED=83=90=ED=97=98=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/college/CollegeBadgeList.java | 6 ++++-- .../college/InternationalBadge.java | 20 +++++++++++++++++++ .../application/college/SangHuhBadge.java | 20 +++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InternationalBadge.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SangHuhBadge.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/CollegeBadgeList.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/CollegeBadgeList.java index 2a59e1d..72bbc6b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/CollegeBadgeList.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/CollegeBadgeList.java @@ -7,7 +7,7 @@ public class CollegeBadgeList { @Getter - private final static List collegeBadges = List.of( + private static final List collegeBadges = List.of( new LiberalArtsBadge(), new AdministrationBadge(), new EducationBadge(), @@ -19,7 +19,9 @@ public class CollegeBadgeList { new VeterinaryMedicineBadge(), new BiologicalSciencesBadge(), new ArchitectureBadge(), - new InstituteTechnologyBadge() + new InstituteTechnologyBadge(), + new SangHuhBadge(), + new InternationalBadge() ); private CollegeBadgeList() { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InternationalBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InternationalBadge.java new file mode 100644 index 0000000..5da2c5a --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InternationalBadge.java @@ -0,0 +1,20 @@ +package com.playkuround.playkuroundserver.domain.badge.application.college; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; + +public class InternationalBadge implements CollegeBadge { + + protected InternationalBadge() { + } + + @Override + public boolean supports(LandmarkType landmarkType) { + return landmarkType == LandmarkType.법학관; + } + + @Override + public BadgeType getBadge() { + return BadgeType.COLLEGE_OF_INTERNATIONAL; + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SangHuhBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SangHuhBadge.java new file mode 100644 index 0000000..a032dc3 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SangHuhBadge.java @@ -0,0 +1,20 @@ +package com.playkuround.playkuroundserver.domain.badge.application.college; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; + +public class SangHuhBadge implements CollegeBadge { + + protected SangHuhBadge() { + } + + @Override + public boolean supports(LandmarkType landmarkType) { + return landmarkType == LandmarkType.산학협동관; + } + + @Override + public BadgeType getBadge() { + return BadgeType.COLLEGE_OF_SANG_HUH; + } +} From 6a8f18608f6f1c4c8fd46fac7c0589d3853a731b Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Wed, 21 Aug 2024 18:35:03 +0900 Subject: [PATCH 39/79] test: refactor test --- .../badge/application/CollegeBadgeTest.java | 120 +++++++----------- 1 file changed, 45 insertions(+), 75 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/CollegeBadgeTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/CollegeBadgeTest.java index bffe782..8d41612 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/CollegeBadgeTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/CollegeBadgeTest.java @@ -5,88 +5,58 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; -import java.util.Map; +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; class CollegeBadgeTest { - @Test - @DisplayName("뱃지 개수가 0개이면 빈리스트가 반환된다") - void CollegeBadge() { - Map map = Map.ofEntries( - Map.entry(LandmarkType.인문학관, BadgeType.COLLEGE_OF_LIBERAL_ARTS), - Map.entry(LandmarkType.과학관, BadgeType.COLLEGE_OF_SCIENCES), - Map.entry(LandmarkType.건축관, BadgeType.COLLEGE_OF_ARCHITECTURE), - Map.entry(LandmarkType.신공학관, BadgeType.COLLEGE_OF_ENGINEERING), - Map.entry(LandmarkType.상허연구관, BadgeType.COLLEGE_OF_SOCIAL_SCIENCES), - Map.entry(LandmarkType.경영관, BadgeType.COLLEGE_OF_BUSINESS_ADMINISTRATION), - Map.entry(LandmarkType.부동산학관, BadgeType.COLLEGE_OF_REAL_ESTATE), - Map.entry(LandmarkType.생명과학관, BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY), - Map.entry(LandmarkType.동물생명과학관, BadgeType.COLLEGE_OF_BIOLOGICAL_SCIENCES), - Map.entry(LandmarkType.수의학관, BadgeType.COLLEGE_OF_VETERINARY_MEDICINE), - Map.entry(LandmarkType.예디대, BadgeType.COLLEGE_OF_ART_AND_DESIGN), - Map.entry(LandmarkType.공예관, BadgeType.COLLEGE_OF_ART_AND_DESIGN), - Map.entry(LandmarkType.교육과학관, BadgeType.COLLEGE_OF_EDUCATION) - ); - - // 공학관 A, B, C를 제외한 랜드마크 테스트 - for (LandmarkType landmarkType : LandmarkType.values()) { - if (landmarkType == LandmarkType.공학관A || - landmarkType == LandmarkType.공학관B || - landmarkType == LandmarkType.공학관C) { - continue; - } - - int flag = 0; - for (CollegeBadge collegeBadge : CollegeBadgeList.getCollegeBadges()) { - if (collegeBadge.supports(landmarkType)) { - BadgeType badge = collegeBadge.getBadge(); - assertThat(badge).isEqualTo(map.get(landmarkType)); - flag++; - } - } - - if (flag == 0) { - assertThat(map.get(landmarkType)).isNull(); - } - else if (flag > 1) { - throw new IllegalStateException("뱃지가 2개 이상입니다."); - } - } - - // 공학관 A, B, C는 해당 뱃지가 2개이다. - int a = 0, b = 0, c = 0; - BadgeType[] badgeTypes = new BadgeType[6]; - - for (CollegeBadge collegeBadge : CollegeBadgeList.getCollegeBadges()) { - if (collegeBadge.supports(LandmarkType.공학관A)) { - badgeTypes[a] = collegeBadge.getBadge(); - a++; - } - if (collegeBadge.supports(LandmarkType.공학관B)) { - badgeTypes[2 + b] = collegeBadge.getBadge(); - b++; - } - if (collegeBadge.supports(LandmarkType.공학관C)) { - badgeTypes[4 + c] = collegeBadge.getBadge(); - c++; - } - } - assertThat(a).isEqualTo(2); - assertThat(b).isEqualTo(2); - assertThat(c).isEqualTo(2); - - for (int i = 0; i < 3; i++) { - boolean case1 = badgeTypes[i * 2] == BadgeType.COLLEGE_OF_ENGINEERING && - badgeTypes[i * 2 + 1] == BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY; - boolean case2 = badgeTypes[i * 2] == BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY && - badgeTypes[i * 2 + 1] == BadgeType.COLLEGE_OF_ENGINEERING; + // 기획에서 정한 건물별 뱃지 + private final List answer = List.of( + new CollegeBadgeRecord(LandmarkType.인문학관, BadgeType.COLLEGE_OF_LIBERAL_ARTS), + new CollegeBadgeRecord(LandmarkType.과학관, BadgeType.COLLEGE_OF_SCIENCES), + new CollegeBadgeRecord(LandmarkType.건축관, BadgeType.COLLEGE_OF_ARCHITECTURE), + new CollegeBadgeRecord(LandmarkType.신공학관, BadgeType.COLLEGE_OF_ENGINEERING), + new CollegeBadgeRecord(LandmarkType.상허연구관, BadgeType.COLLEGE_OF_SOCIAL_SCIENCES), + new CollegeBadgeRecord(LandmarkType.경영관, BadgeType.COLLEGE_OF_BUSINESS_ADMINISTRATION), + new CollegeBadgeRecord(LandmarkType.부동산학관, BadgeType.COLLEGE_OF_REAL_ESTATE), + new CollegeBadgeRecord(LandmarkType.생명과학관, BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY), + new CollegeBadgeRecord(LandmarkType.동물생명과학관, BadgeType.COLLEGE_OF_BIOLOGICAL_SCIENCES), + new CollegeBadgeRecord(LandmarkType.수의학관, BadgeType.COLLEGE_OF_VETERINARY_MEDICINE), + new CollegeBadgeRecord(LandmarkType.예디대, BadgeType.COLLEGE_OF_ART_AND_DESIGN), + new CollegeBadgeRecord(LandmarkType.공예관, BadgeType.COLLEGE_OF_ART_AND_DESIGN), + new CollegeBadgeRecord(LandmarkType.교육과학관, BadgeType.COLLEGE_OF_EDUCATION), + new CollegeBadgeRecord(LandmarkType.산학협동관, BadgeType.COLLEGE_OF_SANG_HUH), + new CollegeBadgeRecord(LandmarkType.법학관, BadgeType.COLLEGE_OF_INTERNATIONAL), + new CollegeBadgeRecord(LandmarkType.공학관A, BadgeType.COLLEGE_OF_ENGINEERING), + new CollegeBadgeRecord(LandmarkType.공학관A, BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY), + new CollegeBadgeRecord(LandmarkType.공학관B, BadgeType.COLLEGE_OF_ENGINEERING), + new CollegeBadgeRecord(LandmarkType.공학관B, BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY), + new CollegeBadgeRecord(LandmarkType.공학관C, BadgeType.COLLEGE_OF_ENGINEERING), + new CollegeBadgeRecord(LandmarkType.공학관C, BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY) + ); + + @ParameterizedTest + @DisplayName("랜드마크 탐험 뱃지 테스트") + @EnumSource(value = LandmarkType.class) + void collegeBadge(LandmarkType landmarkType) { + List answerBadeType = answer.stream() + .filter(collegeBadgeRecord -> collegeBadgeRecord.landmarkType() == landmarkType) + .map(CollegeBadgeRecord::badgeType) + .toList(); + + List badgeTypes = CollegeBadgeList.getCollegeBadges().stream() + .filter(collegeBadge -> collegeBadge.supports(landmarkType)) + .map(CollegeBadge::getBadge) + .toList(); + + assertThat(badgeTypes).containsExactlyInAnyOrderElementsOf(answerBadeType); + } - assertThat(case1 | case2).isTrue(); - } + private record CollegeBadgeRecord(LandmarkType landmarkType, BadgeType badgeType) { } } \ No newline at end of file From 0238f9bf47e0b1d312a1acc9a6294210bbb916a0 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Wed, 21 Aug 2024 19:51:18 +0900 Subject: [PATCH 40/79] =?UTF-8?q?feat:=20'=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EB=B1=83=EC=A7=80',=20'profileBadge'=20=EC=9A=A9=EC=96=B4=20?= =?UTF-8?q?=ED=86=B5=EC=9D=BC,=20=ED=94=84=EB=A1=9C=ED=95=84=20=EB=B1=83?= =?UTF-8?q?=EC=A7=80=20=EC=84=A4=EC=A0=95=20API=20endpoint=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adventure/dao/AdventureRepository.java | 2 +- .../domain/badge/api/BadgeApi.java | 15 ---- ...eRequest.java => ProfileBadgeRequest.java} | 6 +- .../badge/application/BadgeService.java | 11 --- .../domain/landmark/api/LandmarkApi.java | 4 +- .../LandmarkHighestScoreUserResponse.java | 4 +- .../application/LandmarkScoreService.java | 2 +- .../api/response/ScoreRankingResponse.java | 4 +- .../application/LandmarkRankService.java | 2 +- .../score/application/TotalScoreService.java | 2 +- .../domain/user/api/UserProfileApi.java | 22 +++-- .../api/response/UserProfileResponse.java | 10 +-- .../user/application/UserProfileService.java | 14 ++++ .../user/application/UserRegisterService.java | 2 +- .../domain/user/dao/UserRepository.java | 2 +- .../domain/user/domain/User.java | 6 +- .../domain/badge/api/BadgeApiTest.java | 71 ---------------- .../badge/application/BadgeServiceTest.java | 37 --------- .../domain/landmark/api/LandmarkApiTest.java | 4 +- .../score/api/LandmarkScoreRankApiTest.java | 8 +- .../score/api/ScoreTotalRankApiTest.java | 8 +- .../application/LandmarkRankServiceTest.java | 6 +- .../application/TotalScoreServiceTest.java | 16 ++-- .../domain/user/api/UserProfileApiTest.java | 81 ++++++++++++++++++- .../application/UserProfileServiceTest.java | 41 ++++++++++ ...hMockCustomUserSecurityContextFactory.java | 2 +- 26 files changed, 197 insertions(+), 185 deletions(-) rename src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/{RepresentationBadgeRequest.java => ProfileBadgeRequest.java} (81%) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java index fbc5896..1939210 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java @@ -15,7 +15,7 @@ public interface AdventureRepository extends JpaRepository { - @Query("SELECT new com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScoreAndBadgeType(a.user.nickname, cast(SUM(a.score) as integer), a.user.representBadge) " + + @Query("SELECT new com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScoreAndBadgeType(a.user.nickname, cast(SUM(a.score) as integer), a.user.profileBadge) " + "FROM Adventure a " + "where a.landmark.id=:landmark AND a.createdAt >= :from " + "GROUP BY a.user.id " + diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java index b1d9d91..3101367 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java @@ -1,17 +1,13 @@ package com.playkuround.playkuroundserver.domain.badge.api; -import com.playkuround.playkuroundserver.domain.badge.api.request.RepresentationBadgeRequest; import com.playkuround.playkuroundserver.domain.badge.api.response.BadgeFindResponse; import com.playkuround.playkuroundserver.domain.badge.application.BadgeService; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; -import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.badge.exception.BadgeTypeNotFoundException; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; import com.playkuround.playkuroundserver.global.security.UserDetailsImpl; import com.playkuround.playkuroundserver.global.util.ApiUtils; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -44,15 +40,4 @@ public ApiResponse saveTheDreamOfDuckBadge(@AuthenticationPrincipal Use return ApiUtils.success(response); } - @PostMapping("/representation") - @Operation(summary = "대표 뱃지 설정", description = "사용자를 대표하는 뱃지를 설정합니다.") - public ApiResponse setRepresentationBadge(@AuthenticationPrincipal UserDetailsImpl userDetails, - @RequestBody @Valid RepresentationBadgeRequest request) { - BadgeType badgeType = BadgeType.fromString(request.getBadgeType()) - .orElseThrow(BadgeTypeNotFoundException::new); - - badgeService.representationBadge(userDetails.getUser(), badgeType); - return ApiUtils.success(null); - } - } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/RepresentationBadgeRequest.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/ProfileBadgeRequest.java similarity index 81% rename from src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/RepresentationBadgeRequest.java rename to src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/ProfileBadgeRequest.java index 0349f79..9683ad4 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/RepresentationBadgeRequest.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/ProfileBadgeRequest.java @@ -10,10 +10,10 @@ @Getter @NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) @AllArgsConstructor -public class RepresentationBadgeRequest { +public class ProfileBadgeRequest { @ValidEnum(enumClass = BadgeType.class, message = "잘못된 badge type 입니다.") - @Schema(description = "설정할 뱃지 타입", example = "ATTENDANCE_CHILDREN_DAY", requiredMode = Schema.RequiredMode.REQUIRED) - private String badgeType; + @Schema(description = "설정할 뱃지 이름", example = "ATTENDANCE_CHILDREN_DAY", requiredMode = Schema.RequiredMode.REQUIRED) + private String profileBadge; } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java index 886ffbb..98e8e07 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java @@ -8,7 +8,6 @@ import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; -import com.playkuround.playkuroundserver.domain.badge.exception.BadgeNotHaveException; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; @@ -124,14 +123,4 @@ public boolean saveManualBadge(String userEmail, BadgeType badgeType, boolean re return true; } - @Transactional - public void representationBadge(User user, BadgeType badgeType) { - if (!badgeRepository.existsByUserAndBadgeType(user, badgeType)) { - throw new BadgeNotHaveException(); - } - - user.updateRepresentBadge(badgeType); - userRepository.save(user); - } - } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java index 1061a43..a718b17 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java @@ -31,8 +31,8 @@ public class LandmarkApi { @Operation(summary = "가장 가까운 랜드마크 찾기", description = "인식 반경 내에 있는 랜드마크 중 가장 가까운 랜드마크를 반환합니다. " + "인식 반경에 랜드마크가 없을 경우 아무것도 반환하지 않습니다.") - public ApiResponse LandmarkFindNear(@RequestParam @Latitude Double latitude, - @RequestParam @Longitude Double longitude) { + public ApiResponse findNearestLandmark(@RequestParam @Latitude Double latitude, + @RequestParam @Longitude Double longitude) { Location location = new Location(latitude, longitude); NearestLandmark nearestLandmark = landmarkFindNearService.findNearestLandmark(location); return ApiUtils.success(NearestLandmarkResponse.from(nearestLandmark)); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java index a90a8a6..c3d02b1 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java @@ -19,8 +19,8 @@ public class LandmarkHighestScoreUserResponse { @Schema(description = "최고 점수", example = "294") private Long score; - @Schema(description = "해당 사용자의 뱃지타입", example = "COLLEGE_OF_ENGINEERING") - private String badgeType; + @Schema(description = "해당 사용자의 프로필 뱃지", example = "COLLEGE_OF_ENGINEERING") + private String profileBadge; public static LandmarkHighestScoreUserResponse from(LandmarkHighestScoreUser firstUserData) { String badgeTypeName = firstUserData.badgeType() == null ? null : firstUserData.badgeType().name(); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreService.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreService.java index c7185fb..56b8411 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkScoreService.java @@ -30,7 +30,7 @@ public Optional findHighestScoreUserByLandmark(Long la LandmarkHighestScoreUser highestScoreUser = new LandmarkHighestScoreUser( landmark.getHighestScore(), firstUser.getNickname(), - firstUser.getRepresentBadge() + firstUser.getProfileBadge() ); return Optional.of(highestScoreUser); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java index 60978a6..e39e175 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java @@ -35,7 +35,7 @@ public void setMyRank(int ranking, int score, BadgeType badgeType) { @NoArgsConstructor(access = AccessLevel.PROTECTED) public static class RankList { private String nickname; - private String badgeType; + private String profileBadge; private int score; } @@ -45,6 +45,6 @@ public static class RankList { public static class MyRank { private int ranking; private int score; - private String badgeType; + private String profileBadge; } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java index 0be6716..f157820 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java @@ -32,7 +32,7 @@ public ScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId) RankAndScore rankAndScore = adventureRepository.findMyRankByLandmarkId(user, landmarkId, monthStartDateTime) .orElseGet(() -> new RankAndScore(0, 0)); - response.setMyRank(rankAndScore.ranking(), rankAndScore.score(), user.getRepresentBadge()); + response.setMyRank(rankAndScore.ranking(), rankAndScore.score(), user.getProfileBadge()); return response; } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java index b42b72b..c130932 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java @@ -53,7 +53,7 @@ public ScoreRankingResponse getRankTop100(User user) { ScoreRankingResponse response = scoreRankService.createScoreRankingResponse(emailBindingNickname); RankAndScore myRank = getMyRank(user); - response.setMyRank(myRank.ranking(), myRank.score(), user.getRepresentBadge()); + response.setMyRank(myRank.ranking(), myRank.score(), user.getProfileBadge()); return response; } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java index 219bc13..5b501de 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java @@ -2,6 +2,9 @@ import com.playkuround.playkuroundserver.domain.appversion.application.AppVersionService; import com.playkuround.playkuroundserver.domain.appversion.domain.OperationSystem; +import com.playkuround.playkuroundserver.domain.badge.api.request.ProfileBadgeRequest; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.domain.badge.exception.BadgeTypeNotFoundException; import com.playkuround.playkuroundserver.domain.systemcheck.application.SystemCheckService; import com.playkuround.playkuroundserver.domain.user.api.response.UserGameHighestScoreResponse; import com.playkuround.playkuroundserver.domain.user.api.response.UserNotificationResponse; @@ -16,12 +19,10 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @@ -31,8 +32,8 @@ @Tag(name = "User", description = "User API") public class UserProfileApi { - private final AppVersionService appVersionService; private final UserProfileService userProfileService; + private final AppVersionService appVersionService; private final SystemCheckService systemCheckService; @GetMapping @@ -55,6 +56,17 @@ public ApiResponse isAvailableNickname(@RequestParam("nickname") String return ApiUtils.success(isAvailable); } + @PostMapping("/profile-badge") + @Operation(summary = "프로필 뱃지 설정", description = "사용자 프로필 뱃지를 설정합니다.") + public ApiResponse setProfileBadge(@AuthenticationPrincipal UserDetailsImpl userDetails, + @RequestBody @Valid ProfileBadgeRequest request) { + BadgeType badgeType = BadgeType.fromString(request.getProfileBadge()) + .orElseThrow(BadgeTypeNotFoundException::new); + + userProfileService.setProfileBadge(userDetails.getUser(), badgeType); + return ApiUtils.success(null); + } + @GetMapping("/notification") @Operation(summary = "유저 알림 얻기", description = "유저 개인 알림을 얻습니다. 저장된 메시지는 (정상적인) 호출 이후 삭제됩니다.
" + diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java index 63d2b7e..9881a97 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java @@ -21,17 +21,17 @@ public class UserProfileResponse { @Schema(description = "학과", example = "컴퓨터공학부", requiredMode = RequiredMode.REQUIRED) private String major; - @Schema(description = "자신의 토탈 스코어 최고점(점수가 없다면 null 리턴)", example = "1500", requiredMode = RequiredMode.REQUIRED) + @Schema(description = "자신의 토탈 스코어 최고점(점수가 없다면 null 리턴)", example = "1500") private Long highestScore; - @Schema(description = "자신의 토탈 등수 최고점(등수가 없다면 null 리턴)", example = "13", requiredMode = RequiredMode.REQUIRED) + @Schema(description = "자신의 토탈 등수 최고점(등수가 없다면 null 리턴)", example = "13") private Long highestRank; @Schema(description = "출석한 횟수", example = "28", requiredMode = RequiredMode.REQUIRED) private int attendanceDays; - @Schema(description = "대표 뱃지(대표 뱃지가 없다면 null 리턴)", example = "MONTHLY_RANKING_1", requiredMode = RequiredMode.REQUIRED) - private String badge; + @Schema(description = "프로필 뱃지(프로필 뱃지가 없다면 null 리턴)", example = "MONTHLY_RANKING_1") + private String profileBadge; public static UserProfileResponse from(User user) { return UserProfileResponse.builder() @@ -41,7 +41,7 @@ public static UserProfileResponse from(User user) { .attendanceDays(user.getAttendanceDays()) .highestScore(user.getHighestScore() == null ? null : user.getHighestScore().getHighestTotalScore()) .highestRank(user.getHighestScore() == null ? null : user.getHighestScore().getHighestTotalRank()) - .badge(user.getRepresentBadge() == null ? null : user.getRepresentBadge().name()) + .profileBadge(user.getProfileBadge() == null ? null : user.getProfileBadge().name()) .build(); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileService.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileService.java index ab66063..ced8c6e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileService.java @@ -1,5 +1,8 @@ package com.playkuround.playkuroundserver.domain.user.application; +import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.domain.badge.exception.BadgeNotHaveException; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.HighestScore; import com.playkuround.playkuroundserver.domain.user.domain.Notification; @@ -19,6 +22,7 @@ public class UserProfileService { private final UserRepository userRepository; + private final BadgeRepository badgeRepository; private final Pattern nicknamePattern = Pattern.compile("^[0-9a-zA-Z가-힣]{2,8}$"); @Transactional(readOnly = true) @@ -28,6 +32,16 @@ public boolean isAvailableNickname(String nickname) { !userRepository.existsByNickname(nickname); } + @Transactional + public void setProfileBadge(User user, BadgeType badgeType) { + if (!badgeRepository.existsByUserAndBadgeType(user, badgeType)) { + throw new BadgeNotHaveException(); + } + + user.updateProfileBadge(badgeType); + userRepository.save(user); + } + @Transactional(readOnly = true) public HighestScore getUserGameHighestScore(User user) { return user.getHighestScore(); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterService.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterService.java index b9e428c..6462b95 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserRegisterService.java @@ -38,7 +38,7 @@ public TokenDto registerUser(UserRegisterDto userRegisterDto) { Badge badge = new Badge(user, collageBadgeType); badgeRepository.save(badge); - user.updateRepresentBadge(collageBadgeType); + user.updateProfileBadge(collageBadgeType); return userLoginService.login(user.getEmail()); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/dao/UserRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/dao/UserRepository.java index 4667f7e..eb44bc0 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/dao/UserRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/dao/UserRepository.java @@ -16,7 +16,7 @@ public interface UserRepository extends JpaRepository { Optional findByEmail(String email); - @Query("select new com.playkuround.playkuroundserver.domain.user.dto.EmailAndNicknameAndBadge(u.email, u.nickname, u.representBadge) " + + @Query("select new com.playkuround.playkuroundserver.domain.user.dto.EmailAndNicknameAndBadge(u.email, u.nickname, u.profileBadge) " + "from User u " + "where u.email in :emails") List findNicknameByEmailIn(List emails); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java index 95e3d16..118f247 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java @@ -44,7 +44,7 @@ public class User extends BaseTimeEntity { private Set notification; @Enumerated(EnumType.STRING) - private BadgeType representBadge; + private BadgeType profileBadge; private User(String email, String nickname, Major major, Role role) { this.email = email; @@ -79,8 +79,8 @@ public void updateHighestRank(long rank, long score) { highestScore.updateHighestTotalLank(rank, score); } - public void updateRepresentBadge(BadgeType badgeType) { - this.representBadge = badgeType; + public void updateProfileBadge(BadgeType badgeType) { + this.profileBadge = badgeType; } public HighestScore getHighestScore() { diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java index 450d616..52b44ec 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java @@ -1,21 +1,17 @@ package com.playkuround.playkuroundserver.domain.badge.api; -import com.fasterxml.jackson.databind.ObjectMapper; import com.playkuround.playkuroundserver.IntegrationControllerTest; -import com.playkuround.playkuroundserver.domain.badge.api.request.RepresentationBadgeRequest; import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; -import com.playkuround.playkuroundserver.global.error.ErrorCode; import com.playkuround.playkuroundserver.securityConfig.WithMockCustomUser; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import java.util.List; @@ -34,9 +30,6 @@ class BadgeApiTest { @Autowired private MockMvc mockMvc; - @Autowired - private ObjectMapper objectMapper; - @Autowired private UserRepository userRepository; @@ -119,68 +112,4 @@ void fail_1() throws Exception { } } - @Nested - @WithMockCustomUser - @DisplayName("대표 뱃지 설정") - class RepresentationBadge { - - @Test - @DisplayName("사용자가 가지고 있는 뱃지는 정상적으로 대표 뱃지로 설정이 가능하다.") - void success_1() throws Exception { - // given - User user = userRepository.findAll().get(0); - Badge badge = new Badge(user, BadgeType.ATTENDANCE_FOUNDATION_DAY); - badgeRepository.save(badge); - - RepresentationBadgeRequest representationBadgeRequest = new RepresentationBadgeRequest(BadgeType.ATTENDANCE_FOUNDATION_DAY.name()); - String request = objectMapper.writeValueAsString(representationBadgeRequest); - - // expect - mockMvc.perform(post("/api/badges/representation") - .contentType(MediaType.APPLICATION_JSON) - .content(request)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess").value(true)) - .andDo(print()); - - User findUser = userRepository.findAll().get(0); - assertThat(findUser.getRepresentBadge()).isEqualTo(BadgeType.ATTENDANCE_FOUNDATION_DAY); - } - - @Test - @DisplayName("올바르지 않는 BadgeType을 요청하면 에러가 발생한다.") - void fail_1() throws Exception { - // given - RepresentationBadgeRequest representationBadgeRequest = new RepresentationBadgeRequest("notFound"); - String request = objectMapper.writeValueAsString(representationBadgeRequest); - - // expect - mockMvc.perform(post("/api/badges/representation") - .contentType(MediaType.APPLICATION_JSON) - .content(request)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.isSuccess").value(false)) - .andDo(print()); - } - - @Test - @DisplayName("사용자가 가지고 있지 않는 BadgeType이면 에러가 발생한다.") - void fail_2() throws Exception { - // given - RepresentationBadgeRequest representationBadgeRequest = new RepresentationBadgeRequest(BadgeType.ATTENDANCE_FOUNDATION_DAY.name()); - String request = objectMapper.writeValueAsString(representationBadgeRequest); - - // expect - mockMvc.perform(post("/api/badges/representation") - .contentType(MediaType.APPLICATION_JSON) - .content(request)) - .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.isSuccess").value(false)) - .andExpect(jsonPath("$.errorResponse.status").value(ErrorCode.NOT_HAVE_BADGE.getStatus().value())) - .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.NOT_HAVE_BADGE.getCode())) - .andExpect(jsonPath("$.errorResponse.message").value(ErrorCode.NOT_HAVE_BADGE.getMessage())) - .andDo(print()); - } - } - } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java index 7b54936..a211056 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java @@ -6,7 +6,6 @@ import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; -import com.playkuround.playkuroundserver.domain.badge.exception.BadgeNotHaveException; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; @@ -39,7 +38,6 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @@ -409,39 +407,4 @@ void success_2() { } } - @Nested - @DisplayName("대표 뱃지 설정") - class representationBadge { - - @Test - @DisplayName("사용자가 가지고 있는 뱃지는 정상적으로 대표 뱃지로 설정이 가능하다.") - void success_1() { - // given - User user = TestUtil.createUser(); - BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; - when(badgeRepository.existsByUserAndBadgeType(user, badgeType)) - .thenReturn(true); - - // when - badgeService.representationBadge(user, badgeType); - - // then - assertThat(user.getRepresentBadge()).isEqualTo(badgeType); - } - - @Test - @DisplayName("사용자가 가지고 있지 않는 BadgeType이면 에러가 발생한다.") - void fail_1() { - // given - User user = TestUtil.createUser(); - BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; - when(badgeRepository.existsByUserAndBadgeType(user, badgeType)) - .thenReturn(false); - - // expect - assertThatThrownBy(() -> { - badgeService.representationBadge(user, badgeType); - }).isInstanceOf(BadgeNotHaveException.class); - } - } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java index 18ebe68..dfc6ddc 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java @@ -93,7 +93,7 @@ class findHighestUserByLandmark { void success_1() throws Exception { // given User user = userRepository.findAll().get(0); - user.updateRepresentBadge(BadgeType.ATTENDANCE_50); + user.updateProfileBadge(BadgeType.ATTENDANCE_50); userRepository.save(user); Landmark landmark = landmarkRepository.findById(1L).get(); @@ -105,7 +105,7 @@ void success_1() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.response.score").value(1000)) .andExpect(jsonPath("$.response.nickname").value(user.getNickname())) - .andExpect(jsonPath("$.response.badgeType").value(user.getRepresentBadge().name())) + .andExpect(jsonPath("$.response.profileBadge").value(user.getProfileBadge().name())) .andDo(print()); // tear down diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java index ec85c72..7f6ca65 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java @@ -250,13 +250,13 @@ void getRankTop100ByLandmark_6() throws Exception { } { User user1 = TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.건축학부); - user1.updateRepresentBadge(BadgeType.ATTENDANCE_1); + user1.updateProfileBadge(BadgeType.ATTENDANCE_1); userRepository.save(user1); adventureRepository.save(new Adventure(user1, landmark, ScoreType.CATCH, 5L)); } { User user2 = TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부); - user2.updateRepresentBadge(BadgeType.MONTHLY_RANKING_1); + user2.updateProfileBadge(BadgeType.MONTHLY_RANKING_1); userRepository.save(user2); adventureRepository.save(new Adventure(user2, landmark, ScoreType.CATCH, 15L)); } @@ -272,7 +272,7 @@ void getRankTop100ByLandmark_6() throws Exception { // then assertThat(response.getRank()).hasSize(3) - .extracting("nickname", "badgeType", "score") + .extracting("nickname", "profileBadge", "score") .containsExactly( tuple("user2", BadgeType.MONTHLY_RANKING_1.name(), 15), tuple("tester", BadgeType.COLLEGE_OF_ENGINEERING.name(), 10), @@ -280,6 +280,6 @@ void getRankTop100ByLandmark_6() throws Exception { ); assertThat(response.getMyRank().getScore()).isEqualTo(10); assertThat(response.getMyRank().getRanking()).isEqualTo(2); - assertThat(response.getMyRank().getBadgeType()).isEqualTo(BadgeType.COLLEGE_OF_ENGINEERING.name()); + assertThat(response.getMyRank().getProfileBadge()).isEqualTo(BadgeType.COLLEGE_OF_ENGINEERING.name()); } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java index aeeea9b..ab78077 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java @@ -219,13 +219,13 @@ void getRankTop100_6() throws Exception { } { User user1 = TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.건축학부); - user1.updateRepresentBadge(BadgeType.ATTENDANCE_1); + user1.updateProfileBadge(BadgeType.ATTENDANCE_1); userRepository.save(user1); zSetOperations.incrementScore(redisSetKey, user1.getEmail(), 10); } { User user2 = TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부); - user2.updateRepresentBadge(BadgeType.MONTHLY_RANKING_1); + user2.updateProfileBadge(BadgeType.MONTHLY_RANKING_1); userRepository.save(user2); zSetOperations.incrementScore(redisSetKey, user2.getEmail(), 15); } @@ -241,7 +241,7 @@ void getRankTop100_6() throws Exception { // then assertThat(response.getRank()).hasSize(3) - .extracting("nickname", "badgeType", "score") + .extracting("nickname", "profileBadge", "score") .containsExactly( tuple("user2", BadgeType.MONTHLY_RANKING_1.name(), 15), tuple("tester", BadgeType.COLLEGE_OF_ENGINEERING.name(), 13), @@ -249,6 +249,6 @@ void getRankTop100_6() throws Exception { ); assertThat(response.getMyRank().getScore()).isEqualTo(13); assertThat(response.getMyRank().getRanking()).isEqualTo(2); - assertThat(response.getMyRank().getBadgeType()).isEqualTo(BadgeType.COLLEGE_OF_ENGINEERING.name()); + assertThat(response.getMyRank().getProfileBadge()).isEqualTo(BadgeType.COLLEGE_OF_ENGINEERING.name()); } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java index 5f3bbf0..47e2478 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java @@ -165,7 +165,7 @@ void getRankTop100ByLandmark_5() { .thenReturn(rankData); User user = TestUtil.createUser(); - user.updateRepresentBadge(BadgeType.ATTENDANCE_CHRISTMAS_DAY); + user.updateProfileBadge(BadgeType.ATTENDANCE_CHRISTMAS_DAY); when(adventureRepository.findMyRankByLandmarkId(user, landmarkId, now.atStartOfDay())) .thenReturn(Optional.of(new RankAndScore(2, 7))); @@ -175,13 +175,13 @@ void getRankTop100ByLandmark_5() { // then assertThat(result.getRank()).hasSize(2) - .extracting("nickname", "badgeType", "score") + .extracting("nickname", "profileBadge", "score") .containsExactly( tuple("user1", BadgeType.ATTENDANCE_1.name(), 10), tuple("user2", BadgeType.MONTHLY_RANKING_1.name(), 5) ); assertThat(result.getMyRank().getScore()).isEqualTo(7); assertThat(result.getMyRank().getRanking()).isEqualTo(2); - assertThat(result.getMyRank().getBadgeType()).isEqualTo(BadgeType.ATTENDANCE_CHRISTMAS_DAY.name()); + assertThat(result.getMyRank().getProfileBadge()).isEqualTo(BadgeType.ATTENDANCE_CHRISTMAS_DAY.name()); } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java index 6217129..186049a 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java @@ -200,9 +200,9 @@ void getRankTop100_6() { User user2 = TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.건축학부); User user3 = TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.컴퓨터공학부); - user1.updateRepresentBadge(BadgeType.ATTENDANCE_CHRISTMAS_DAY); - user2.updateRepresentBadge(BadgeType.MONTHLY_RANKING_1); - user3.updateRepresentBadge(BadgeType.ATTENDANCE_1); + user1.updateProfileBadge(BadgeType.ATTENDANCE_CHRISTMAS_DAY); + user2.updateProfileBadge(BadgeType.MONTHLY_RANKING_1); + user3.updateProfileBadge(BadgeType.ATTENDANCE_1); userRepository.save(user1); userRepository.save(user2); @@ -217,16 +217,16 @@ void getRankTop100_6() { // then assertThat(result.getRank()).hasSize(3) - .extracting("nickname", "badgeType", "score") + .extracting("nickname", "profileBadge", "score") .containsExactly( - tuple(user1.getNickname(), user1.getRepresentBadge().name(), 15), - tuple(user3.getNickname(), user3.getRepresentBadge().name(), 10), - tuple(user2.getNickname(), user2.getRepresentBadge().name(), 5) + tuple(user1.getNickname(), user1.getProfileBadge().name(), 15), + tuple(user3.getNickname(), user3.getProfileBadge().name(), 10), + tuple(user2.getNickname(), user2.getProfileBadge().name(), 5) ); assertThat(result.getMyRank().getScore()).isEqualTo(15); assertThat(result.getMyRank().getRanking()).isEqualTo(1); - assertThat(result.getMyRank().getBadgeType()).isEqualTo(user1.getRepresentBadge().name()); + assertThat(result.getMyRank().getProfileBadge()).isEqualTo(user1.getProfileBadge().name()); } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java index 65cb2b3..4950602 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java @@ -1,25 +1,33 @@ package com.playkuround.playkuroundserver.domain.user.api; +import com.fasterxml.jackson.databind.ObjectMapper; import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.appversion.dao.AppVersionRepository; import com.playkuround.playkuroundserver.domain.appversion.domain.AppVersion; import com.playkuround.playkuroundserver.domain.appversion.domain.OperationSystem; +import com.playkuround.playkuroundserver.domain.badge.api.request.ProfileBadgeRequest; +import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; +import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.systemcheck.dao.SystemCheckRepository; import com.playkuround.playkuroundserver.domain.systemcheck.domain.SystemCheck; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.User; +import com.playkuround.playkuroundserver.global.error.ErrorCode; import com.playkuround.playkuroundserver.securityConfig.WithMockCustomUser; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -30,6 +38,12 @@ class UserProfileApiTest { @Autowired private MockMvc mockMvc; + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private BadgeRepository badgeRepository; + @Autowired private UserRepository userRepository; @@ -41,6 +55,7 @@ class UserProfileApiTest { @AfterEach void afterEach() { + badgeRepository.deleteAllInBatch(); userRepository.deleteAllInBatch(); appVersionRepository.deleteAllInBatch(); systemCheckRepository.deleteAllInBatch(); @@ -58,7 +73,7 @@ void userProfileSuccess() throws Exception { .andExpect(jsonPath("$.response.major").value(Major.컴퓨터공학부.name())) .andExpect(jsonPath("$.response.nickname").value("tester")) .andExpect(jsonPath("$.response.email").value("tester@konkuk.ac.kr")) - .andExpect(jsonPath("$.response.badge").value(BadgeType.COLLEGE_OF_ENGINEERING.name())) + .andExpect(jsonPath("$.response.profileBadge").value(BadgeType.COLLEGE_OF_ENGINEERING.name())) .andDo(print()); } @@ -137,5 +152,69 @@ void success_2() throws Exception { .andDo(print()); } } + + @Nested + @WithMockCustomUser + @DisplayName("프로필 뱃지 설정") + class setProfileBadge { + + @Test + @DisplayName("사용자가 가지고 있는 뱃지는 정상적으로 프로필 뱃지로 설정이 가능하다.") + void success_1() throws Exception { + // given + User user = userRepository.findAll().get(0); + Badge badge = new Badge(user, BadgeType.ATTENDANCE_FOUNDATION_DAY); + badgeRepository.save(badge); + + ProfileBadgeRequest profileBadgeRequest = new ProfileBadgeRequest(BadgeType.ATTENDANCE_FOUNDATION_DAY.name()); + String request = objectMapper.writeValueAsString(profileBadgeRequest); + + // expect + mockMvc.perform(post("/api/users/profile-badge") + .contentType(MediaType.APPLICATION_JSON) + .content(request)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isSuccess").value(true)) + .andDo(print()); + + User findUser = userRepository.findAll().get(0); + assertThat(findUser.getProfileBadge()).isEqualTo(BadgeType.ATTENDANCE_FOUNDATION_DAY); + } + + @Test + @DisplayName("올바르지 않는 BadgeType을 요청하면 에러가 발생한다.") + void fail_1() throws Exception { + // given + ProfileBadgeRequest profileBadgeRequest = new ProfileBadgeRequest("notFound"); + String request = objectMapper.writeValueAsString(profileBadgeRequest); + + // expect + mockMvc.perform(post("/api/users/profile-badge") + .contentType(MediaType.APPLICATION_JSON) + .content(request)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.isSuccess").value(false)) + .andDo(print()); + } + + @Test + @DisplayName("사용자가 가지고 있지 않는 BadgeType이면 에러가 발생한다.") + void fail_2() throws Exception { + // given + ProfileBadgeRequest profileBadgeRequest = new ProfileBadgeRequest(BadgeType.ATTENDANCE_FOUNDATION_DAY.name()); + String request = objectMapper.writeValueAsString(profileBadgeRequest); + + // expect + mockMvc.perform(post("/api/users/profile-badge") + .contentType(MediaType.APPLICATION_JSON) + .content(request)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.isSuccess").value(false)) + .andExpect(jsonPath("$.errorResponse.status").value(ErrorCode.NOT_HAVE_BADGE.getStatus().value())) + .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.NOT_HAVE_BADGE.getCode())) + .andExpect(jsonPath("$.errorResponse.message").value(ErrorCode.NOT_HAVE_BADGE.getMessage())) + .andDo(print()); + } + } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileServiceTest.java index 1125d77..fffe51f 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileServiceTest.java @@ -1,7 +1,9 @@ package com.playkuround.playkuroundserver.domain.user.application; import com.playkuround.playkuroundserver.TestUtil; +import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.domain.badge.exception.BadgeNotHaveException; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.Notification; import com.playkuround.playkuroundserver.domain.user.domain.NotificationEnum; @@ -20,6 +22,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -31,6 +34,9 @@ class UserProfileServiceTest { @Mock private UserRepository userRepository; + @Mock + private BadgeRepository badgeRepository; + @Nested @DisplayName("닉네임 사용 가능 테스트") class isAvailableNickname { @@ -138,6 +144,41 @@ void success_3() { ); assertThat(user.getNotification()).isEmpty(); } + } + + @Nested + @DisplayName("프로필 뱃지 설정") + class setProfileBadge { + + @Test + @DisplayName("사용자가 가지고 있는 뱃지는 정상적으로 프로필 뱃지로 설정이 가능하다.") + void success_1() { + // given + User user = TestUtil.createUser(); + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; + when(badgeRepository.existsByUserAndBadgeType(user, badgeType)) + .thenReturn(true); + + // when + userProfileService.setProfileBadge(user, badgeType); + + // then + assertThat(user.getProfileBadge()).isEqualTo(badgeType); + } + @Test + @DisplayName("사용자가 가지고 있지 않는 BadgeType이면 에러가 발생한다.") + void fail_1() { + // given + User user = TestUtil.createUser(); + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; + when(badgeRepository.existsByUserAndBadgeType(user, badgeType)) + .thenReturn(false); + + // expect + assertThatThrownBy( + () -> userProfileService.setProfileBadge(user, badgeType) + ).isInstanceOf(BadgeNotHaveException.class); + } } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java index 7dcf95e..e9a0d07 100644 --- a/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java +++ b/src/test/java/com/playkuround/playkuroundserver/securityConfig/WithMockCustomUserSecurityContextFactory.java @@ -25,7 +25,7 @@ public class WithMockCustomUserSecurityContextFactory implements WithSecurityCon public SecurityContext createSecurityContext(WithMockCustomUser annotation) { User user = User.create(annotation.email(), annotation.nickname(), annotation.major(), annotation.role()); - user.updateRepresentBadge(annotation.badgeType()); + user.updateProfileBadge(annotation.badgeType()); userRepository.save(user); String roleName = user.getRole().toString(); From d9cf8fe7502d013d4b9d1afcecbed2fd79a6ac74 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Thu, 22 Aug 2024 00:06:10 +0900 Subject: [PATCH 41/79] =?UTF-8?q?feat:=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=B1=83=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../playkuroundserver/domain/badge/domain/BadgeType.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java index 7df7290..e0a274b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java @@ -74,6 +74,11 @@ public enum BadgeType { MONTHLY_RANKING_1("월간 랭킹 1등"), // 수동 MONTHLY_RANKING_2("월간 랭킹 2등"), // 수동 MONTHLY_RANKING_3("월간 랭킹 3등"), // 수동 + + // 이벤트 + BUSINESS_ARCHITECTURE_EVENT_BUSINESS("경영X건축 경영 뱃지"), + BUSINESS_ARCHITECTURE_EVENT_ARCHITECTURE("경영X건축 건축 뱃지"), + ; private final String description; From 690f5481ed382e2d4505235fac0cbdbb1dcab263 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Thu, 22 Aug 2024 00:38:16 +0900 Subject: [PATCH 42/79] =?UTF-8?q?feat:=20Landmark=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/landmark/domain/Landmark.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java index c898c4d..0f5389e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java @@ -36,6 +36,15 @@ public class Landmark { private long highestScore; + public Landmark(LandmarkType landmarkType, double latitude, double longitude, int recognitionRadius) { + this.name = landmarkType; + this.latitude = latitude; + this.longitude = longitude; + this.recognitionRadius = recognitionRadius; + this.firstUser = null; + this.highestScore = 0; + } + public void updateFirstUser(User user, long score) { if (score == 0) return; if (firstUser == null || this.highestScore < score) { From f8a521c7e974e031010500212124597c4f3b8b42 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Thu, 22 Aug 2024 00:39:36 +0900 Subject: [PATCH 43/79] =?UTF-8?q?feat:=20sql=20=EB=8C=80=EC=8B=A0=20given?= =?UTF-8?q?=20=EC=A0=88=EC=97=90=EC=84=9C=20=EB=9E=9C=EB=93=9C=EB=A7=88?= =?UTF-8?q?=ED=81=AC=EB=A5=BC=20=EC=A7=81=EC=A0=91=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adventure/api/AdventureApiTest.java | 15 +++-- .../application/AdventureServiceTest.java | 33 ++++++--- .../domain/landmark/api/LandmarkApiTest.java | 58 +++++++++------- .../score/api/LandmarkScoreRankApiTest.java | 67 ++++++++++++------- 4 files changed, 110 insertions(+), 63 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java index ed43b12..7437193 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java @@ -9,6 +9,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; +import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; import com.playkuround.playkuroundserver.domain.score.domain.ScoreType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; @@ -20,7 +21,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.MediaType; -import org.springframework.test.context.jdbc.Sql; import org.springframework.test.web.servlet.MockMvc; import java.util.List; @@ -34,7 +34,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @IntegrationControllerTest -@Sql(scripts = {"/data-mysql.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) class AdventureApiTest { @Autowired @@ -74,7 +73,8 @@ void clean() { @DisplayName("탐험을 하게 되면 total score 증가, adventure 저장, 랜드마크별 최고기록과 유저별 게임 최고기록이 업데이트 된다.") void saveAdventure_1() throws Exception { // given - Landmark landmark = landmarkRepository.findById(3L).get(); + Landmark landmark = new Landmark(LandmarkType.수의학관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); AdventureSaveRequest adventureSaveRequest = new AdventureSaveRequest(landmark.getId(), landmark.getLatitude(), landmark.getLongitude(), 100L, ScoreType.BOOK.name()); @@ -116,7 +116,8 @@ void saveAdventure_1() throws Exception { @DisplayName("랜드마크가 존재하지 않으면 에러가 발생한다.") void saveAdventure_2() throws Exception { // given - Landmark landmark = landmarkRepository.findById(3L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); AdventureSaveRequest adventureSaveRequest = new AdventureSaveRequest(-1L, landmark.getLatitude(), landmark.getLongitude(), 100L, ScoreType.BOOK.name()); @@ -141,7 +142,8 @@ void saveAdventure_2() throws Exception { @DisplayName("인식 거리 밖에 있으면 에러가 발생한다.") void saveAdventure_3() throws Exception { // given - Landmark landmark = landmarkRepository.findById(3L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); AdventureSaveRequest adventureSaveRequest = new AdventureSaveRequest(landmark.getId(), 0.0, 0.0, 100L, ScoreType.BOOK.name()); @@ -167,7 +169,8 @@ void saveAdventure_3() throws Exception { @DisplayName("정상적인 ScoreType이 아니면 에러가 발생한다.") void saveAdventure_4() throws Exception { // given - Landmark landmark = landmarkRepository.findById(3L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); AdventureSaveRequest adventureSaveRequest = new AdventureSaveRequest(landmark.getId(), landmark.getLatitude(), landmark.getLongitude(), 100L, "notFound"); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java index 2d59584..dc28cdc 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java @@ -7,9 +7,9 @@ import com.playkuround.playkuroundserver.domain.adventure.dto.AdventureSaveDto; import com.playkuround.playkuroundserver.domain.adventure.exception.InvalidLandmarkLocationException; import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; -import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; +import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; import com.playkuround.playkuroundserver.domain.landmark.exception.LandmarkNotFoundException; import com.playkuround.playkuroundserver.domain.score.domain.ScoreType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; @@ -21,7 +21,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.test.context.jdbc.Sql; import java.util.List; import java.util.Optional; @@ -29,23 +28,28 @@ import static org.assertj.core.api.Assertions.*; @IntegrationServiceTest -@Sql(scripts = {"/data-mysql.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) class AdventureServiceTest { - private final String redisSetKey = "ranking"; @Autowired private BadgeRepository badgeRepository; + @Autowired private UserRepository userRepository; + @Autowired private AdventureRepository adventureRepository; + @Autowired private RedisTemplate redisTemplate; + @Autowired private LandmarkRepository landmarkRepository; + @Autowired private AdventureService adventureService; + private final String redisSetKey = "ranking"; + @AfterEach void clean() { badgeRepository.deleteAllInBatch(); @@ -61,12 +65,14 @@ void saveAdventure_1() { // given User user = TestUtil.createUser(); - Landmark landmark = landmarkRepository.findById(3L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + Location location = new Location(landmark.getLatitude(), landmark.getLongitude()); AdventureSaveDto adventureSaveDto = new AdventureSaveDto(user, landmark.getId(), location, 100, ScoreType.BOOK); // when - NewlyRegisteredBadge newlyRegisteredBadge = adventureService.saveAdventure(adventureSaveDto); + adventureService.saveAdventure(adventureSaveDto); // then // Total Score 저장 및 최고 점수 갱신 @@ -95,7 +101,9 @@ void saveAdventure_2() { // given User user = TestUtil.createUser(); - Landmark landmark = landmarkRepository.findById(3L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + Location location = new Location(landmark.getLatitude(), landmark.getLongitude()); AdventureSaveDto adventureSaveDto = new AdventureSaveDto(user, -1L, location, 100, ScoreType.BOOK); @@ -114,7 +122,9 @@ void saveAdventure_3() { // given User user = TestUtil.createUser(); - Landmark landmark = landmarkRepository.findById(3L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + Location location = new Location(0, 0); AdventureSaveDto adventureSaveDto = new AdventureSaveDto(user, landmark.getId(), location, 100, ScoreType.BOOK); @@ -132,19 +142,20 @@ void saveAdventure_3() { void saveAdventure_4() { // given User user = TestUtil.createUser(); + User otherUser = TestUtil.createUser("other@test.com", "other", Major.건축학부); userRepository.saveAll(List.of(user, otherUser)); long highestScore = 1000; - Landmark landmark = landmarkRepository.findById(3L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); landmark.updateFirstUser(otherUser, highestScore); - landmarkRepository.save(landmark); // update + landmarkRepository.save(landmark); Location location = new Location(landmark.getLatitude(), landmark.getLongitude()); AdventureSaveDto adventureSaveDto = new AdventureSaveDto(user, landmark.getId(), location, 100, ScoreType.BOOK); // when - NewlyRegisteredBadge newlyRegisteredBadge = adventureService.saveAdventure(adventureSaveDto); + adventureService.saveAdventure(adventureSaveDto); // then Optional optionalLandmark = landmarkRepository.findById(landmark.getId()); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java index dfc6ddc..2a2cf2c 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApiTest.java @@ -34,6 +34,7 @@ class LandmarkApiTest { @AfterEach void clear() { + landmarkRepository.deleteAllInBatch(); userRepository.deleteAllInBatch(); } @@ -45,38 +46,48 @@ class findNearestLandmark { @Test @DisplayName("위치 완전 동일") void success_1() throws Exception { + // given + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + + // expected mockMvc.perform(get("/api/landmarks") - .param("latitude", "37.542602") - .param("longitude", "127.078250") - ) + .param("latitude", String.valueOf(landmark.getLatitude())) + .param("longitude", String.valueOf(landmark.getLongitude()))) .andExpect(status().isOk()) - .andExpect(jsonPath("$.response.distance").value(0.0)) - .andExpect(jsonPath("$.response.landmarkId").value(19)) - .andExpect(jsonPath("$.response.name").value(LandmarkType.인문학관.name())) + .andExpect(jsonPath("$.response.landmarkId").value(landmark.getId())) + .andExpect(jsonPath("$.response.name").value(landmark.getName().name())) .andDo(print()); } @Test @DisplayName("허용 범위 내에서 조회") void success_2() throws Exception { + // given + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 1000); + landmarkRepository.save(landmark); + + // expected mockMvc.perform(get("/api/landmarks") - .param("latitude", "37.542600") - .param("longitude", "127.078200") - ) + .param("latitude", String.valueOf(landmark.getLatitude() + 0.0001)) + .param("longitude", String.valueOf(landmark.getLongitude()))) .andExpect(status().isOk()) - .andExpect(jsonPath("$.response.landmarkId").value(19)) - .andExpect(jsonPath("$.response.name").value(LandmarkType.인문학관.name())) - .andExpect(jsonPath("$.response.distance").value(4.4130028352636055)) + .andExpect(jsonPath("$.response.landmarkId").value(landmark.getId())) + .andExpect(jsonPath("$.response.name").value(landmark.getName().name())) .andDo(print()); } @Test @DisplayName("허용 범위 밖에서 조회") void success_3() throws Exception { + // given + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + + // expected mockMvc.perform(get("/api/landmarks") .param("latitude", "13") - .param("longitude", "13") - ) + .param("longitude", "13")) .andExpect(status().isOk()) .andExpect(jsonPath("$.response").isEmpty()) .andDo(print()); @@ -96,28 +107,29 @@ void success_1() throws Exception { user.updateProfileBadge(BadgeType.ATTENDANCE_50); userRepository.save(user); - Landmark landmark = landmarkRepository.findById(1L).get(); - landmark.updateFirstUser(user, 1000); + long score = 1000; + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmark.updateFirstUser(user, score); landmarkRepository.save(landmark); // expected - mockMvc.perform(get("/api/landmarks/{landmarkId}/highest", 1L)) + mockMvc.perform(get("/api/landmarks/{landmarkId}/highest", landmark.getId())) .andExpect(status().isOk()) - .andExpect(jsonPath("$.response.score").value(1000)) + .andExpect(jsonPath("$.response.score").value(score)) .andExpect(jsonPath("$.response.nickname").value(user.getNickname())) .andExpect(jsonPath("$.response.profileBadge").value(user.getProfileBadge().name())) .andDo(print()); - - // tear down - landmark.deleteRank(); - landmarkRepository.save(landmark); } @Test @DisplayName("랜드마크에 최고점 유저가 없다면 빈 응답을 반환한다") void success_2() throws Exception { + // given + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + // expected - mockMvc.perform(get("/api/landmarks/{landmarkId}/highest", 1L)) + mockMvc.perform(get("/api/landmarks/{landmarkId}/highest", landmark.getId())) .andExpect(status().isOk()) .andExpect(jsonPath("$.response").isEmpty()) .andDo(print()); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java index 7f6ca65..13a0b4a 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java @@ -7,6 +7,7 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; +import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; import com.playkuround.playkuroundserver.domain.score.api.response.ScoreRankingResponse; import com.playkuround.playkuroundserver.domain.score.domain.ScoreType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; @@ -47,6 +48,7 @@ class LandmarkScoreRankApiTest { @AfterEach void clean() { adventureRepository.deleteAllInBatch(); + landmarkRepository.deleteAllInBatch(); userRepository.deleteAllInBatch(); } @@ -54,8 +56,12 @@ void clean() { @WithMockCustomUser @DisplayName("랭킹 유저가 한명도 없을 때") void getRankTop100ByLandmark_1() throws Exception { + // given + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + // expected - mockMvc.perform(get("/api/scores/rank/{landmarkId}", 1)) + mockMvc.perform(get("/api/scores/rank/{landmarkId}", landmark.getId())) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess").value(true)) .andExpect(jsonPath("$.response.rank").isEmpty()) @@ -69,7 +75,9 @@ void getRankTop100ByLandmark_1() throws Exception { @DisplayName("전체 유저 100명 미만 + 내 랭킹은 없음") void getRankTop100ByLandmark_2() throws Exception { // given - Landmark landmark = landmarkRepository.findById(1L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + for (int i = 1; i <= 50; i++) { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); userRepository.save(user); @@ -79,11 +87,12 @@ void getRankTop100ByLandmark_2() throws Exception { } // when - MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank/{landmarkId}", 1)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess").value(true)) - .andDo(print()) - .andReturn(); + MvcResult mvcResult = + mockMvc.perform(get("/api/scores/rank/{landmarkId}", landmark.getId())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isSuccess").value(true)) + .andDo(print()) + .andReturn(); String json = mvcResult.getResponse().getContentAsString(); ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); @@ -103,7 +112,9 @@ void getRankTop100ByLandmark_2() throws Exception { @DisplayName("전체 유저 100명 미만 + 내 랭킹 존재") void getRankTop100ByLandmark_3() throws Exception { // given - Landmark landmark = landmarkRepository.findById(1L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + for (int i = 1; i <= 50; i++) { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); userRepository.save(user); @@ -111,16 +122,18 @@ void getRankTop100ByLandmark_3() throws Exception { Adventure adventure = new Adventure(user, landmark, ScoreType.CATCH, (long) i); adventureRepository.save(adventure); } + User me = userRepository.findByEmail("test@konkuk.ac.kr").get(); Adventure adventure = new Adventure(me, landmark, ScoreType.CATCH, 37L); adventureRepository.save(adventure); // when - MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank/{landmarkId}", 1)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess").value(true)) - .andDo(print()) - .andReturn(); + MvcResult mvcResult = + mockMvc.perform(get("/api/scores/rank/{landmarkId}", landmark.getId())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isSuccess").value(true)) + .andDo(print()) + .andReturn(); String json = mvcResult.getResponse().getContentAsString(); ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); @@ -150,7 +163,9 @@ else if (i == 14) { @DisplayName("전체 유저 100명 초과 + 내 랭킹 중간에 존재") void getRankTop100ByLandmark_4() throws Exception { // given - Landmark landmark = landmarkRepository.findById(1L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + for (int i = 1; i <= 101; i++) { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); userRepository.save(user); @@ -158,12 +173,13 @@ void getRankTop100ByLandmark_4() throws Exception { Adventure adventure = new Adventure(user, landmark, ScoreType.CATCH, (long) i); adventureRepository.save(adventure); } + User me = userRepository.findByEmail("test@konkuk.ac.kr").get(); Adventure adventure = new Adventure(me, landmark, ScoreType.CATCH, 62L); adventureRepository.save(adventure); // when - MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank/{landmarkId}", 1)) + MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank/{landmarkId}", landmark.getId())) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess").value(true)) .andDo(print()) @@ -197,7 +213,9 @@ else if (i == 40) { @DisplayName("점수는 SUM으로 계산된 결과로 비교된다") void getRankTop100ByLandmark_5() throws Exception { // given - Landmark landmark = landmarkRepository.findById(1L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); + for (int i = 1; i <= 101; i++) { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); userRepository.save(user); @@ -205,11 +223,12 @@ void getRankTop100ByLandmark_5() throws Exception { adventureRepository.save(new Adventure(user, landmark, ScoreType.CATCH, (long) i)); adventureRepository.save(new Adventure(user, landmark, ScoreType.BOOK, 1L)); } + User me = userRepository.findByEmail("test@konkuk.ac.kr").get(); adventureRepository.save(new Adventure(me, landmark, ScoreType.CATCH, 62L)); // when - MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank/{landmarkId}", 1)) + MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank/{landmarkId}", landmark.getId())) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess").value(true)) .andDo(print()) @@ -243,7 +262,8 @@ else if (i == 41) { @DisplayName("랭킹 조회 API에는 사용자 대표 뱃지 데이터가 포함되어 있다.") void getRankTop100ByLandmark_6() throws Exception { // given - Landmark landmark = landmarkRepository.findById(1L).get(); + Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); + landmarkRepository.save(landmark); { User me = userRepository.findByEmail("test@konkuk.ac.kr").get(); adventureRepository.save(new Adventure(me, landmark, ScoreType.CATCH, 10L)); @@ -262,11 +282,12 @@ void getRankTop100ByLandmark_6() throws Exception { } // when - MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank/{landmarkId}", 1)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.isSuccess").value(true)) - .andDo(print()) - .andReturn(); + MvcResult mvcResult = + mockMvc.perform(get("/api/scores/rank/{landmarkId}", landmark.getId())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.isSuccess").value(true)) + .andDo(print()) + .andReturn(); String json = mvcResult.getResponse().getContentAsString(); ScoreRankingResponse response = TestUtil.convertFromJsonStringToObject(json, ScoreRankingResponse.class); From 3a470c4eb3d8dc1e093da2bf3c74d722f2cca476 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 23 Aug 2024 23:49:23 +0900 Subject: [PATCH 44/79] =?UTF-8?q?refactor:=20stream=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/domain/NotificationConverter.java | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/NotificationConverter.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/NotificationConverter.java index 0305fe2..8a698e1 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/NotificationConverter.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/NotificationConverter.java @@ -3,7 +3,10 @@ import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; -import java.util.*; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; import java.util.stream.Collectors; @Converter @@ -11,20 +14,13 @@ public class NotificationConverter implements AttributeConverter notifications) { - if (notifications == null) { + if (notifications == null || notifications.isEmpty()) { return null; } - StringBuilder sb = new StringBuilder(); - for (Notification notification : notifications) { - if (!sb.isEmpty()) { - sb.append("@"); - } - sb.append(notification.getName()) - .append("#") - .append(notification.getDescription()); - } - return sb.toString(); + return notifications.stream() + .map(notification -> notification.getName() + "#" + notification.getDescription()) + .collect(Collectors.joining("@")); } @Override @@ -32,15 +28,13 @@ public Set convertToEntityAttribute(String notifications) { if (notifications == null || notifications.isEmpty()) { return new HashSet<>(); } + return Arrays.stream(notifications.split("@")) .map(notification -> notification.split("#")) .filter(nameAndDescription -> nameAndDescription.length == 2) - .map(nameAndDescription -> { - Optional notificationEnum = NotificationEnum.fromString(nameAndDescription[0]); - return notificationEnum - .map(anEnum -> new Notification(anEnum, nameAndDescription[1])) - .orElse(null); - }) + .map(nameAndDescription -> NotificationEnum.fromString(nameAndDescription[0]) + .map(notificationEnum -> new Notification(notificationEnum, nameAndDescription[1])) + .orElse(null)) .filter(Objects::nonNull) .collect(Collectors.toSet()); } From 30df4e0eb024e254081c6ef62e8bbcfd1915689f Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 23 Aug 2024 23:49:40 +0900 Subject: [PATCH 45/79] test: NotificationConverter unit test --- .../domain/NotificationConverterTest.java | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/test/java/com/playkuround/playkuroundserver/domain/user/domain/NotificationConverterTest.java diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/domain/NotificationConverterTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/domain/NotificationConverterTest.java new file mode 100644 index 0000000..8e76e04 --- /dev/null +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/domain/NotificationConverterTest.java @@ -0,0 +1,131 @@ +package com.playkuround.playkuroundserver.domain.user.domain; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.HashSet; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class NotificationConverterTest { + + @Test + @DisplayName("Set이 null이면 null을 반환한다") + void convertToDatabase_1() { + // given + NotificationConverter converter = new NotificationConverter(); + + // when + String result = converter.convertToDatabaseColumn(null); + + // then + assertThat(result).isNull(); + } + + @Test + @DisplayName("Set이 empty이면 null을 반환한다") + void convertToDatabase_2() { + // given + NotificationConverter converter = new NotificationConverter(); + + // when + String result = converter.convertToDatabaseColumn(new HashSet<>()); + + // then + assertThat(result).isNull(); + } + + @Test + @DisplayName("메시지끼리는 '@'으로 구분되고, 하나의 메시지에서 notification enum과 detail message는 '#'으로 구분된다.") + void convertToDatabase_3() { + // given + NotificationConverter converter = new NotificationConverter(); + + String alarmMessage = "alarm notification"; + String systemCheckMessage = "system check notification"; + Set notifications = Set.of( + new Notification(NotificationEnum.ALARM, alarmMessage), + new Notification(NotificationEnum.SYSTEM_CHECK, systemCheckMessage) + ); + + // when + String result = converter.convertToDatabaseColumn(notifications); + + // then + assertThat(result.split("@")).containsExactlyInAnyOrder( + NotificationEnum.ALARM.getName() + "#" + alarmMessage, + NotificationEnum.SYSTEM_CHECK.getName() + "#" + systemCheckMessage + ); + } + + + @Test + @DisplayName("올바르게 구성된 String이라면 Set으로 변환된다.") + void convertToEntity_1() { + // given + NotificationConverter converter = new NotificationConverter(); + + String alarmMessage = "alarm notification"; + String systemCheckMessage = "system check notification"; + String notifications = NotificationEnum.ALARM.getName() + "#" + alarmMessage + "@" + + NotificationEnum.SYSTEM_CHECK.getName() + "#" + systemCheckMessage; + + // when + Set result = converter.convertToEntityAttribute(notifications); + + // then + assertThat(result).containsExactlyInAnyOrder( + new Notification(NotificationEnum.ALARM, alarmMessage), + new Notification(NotificationEnum.SYSTEM_CHECK, systemCheckMessage) + ); + } + + @ParameterizedTest + @NullAndEmptySource + @ValueSource(strings = { + "#", + "@", + "alarm", + "#mesage", + "alarm##notification", + "NOT_FOUND#message", + "NOT_FOUND#message@", + "NOT_FOUND#message@alarm##message", + }) + @DisplayName("올바르지 못한 구성으로만 이루어진 문자열은 빈 Set을 반환한다.") + void convertToEntity_2(String notifications) { + // given + NotificationConverter converter = new NotificationConverter(); + + // when + Set result = converter.convertToEntityAttribute(notifications); + + // when + assertThat(result).isEmpty(); + } + + @ParameterizedTest + @ValueSource(strings = { + "alarm#message@", + "#mesage@alarm#message", + "NOT_FOUND#message@alarm#message", + "alarm#message@NOT_FOUND#message", + }) + @DisplayName("'@'을 기준으로 정상적인 부분은 올바르게 변환된다.") + void convertToEntity_3(String notifications) { + // given + NotificationConverter converter = new NotificationConverter(); + + // when + Set result = converter.convertToEntityAttribute(notifications); + + // when + assertThat(result).containsExactlyInAnyOrder( + new Notification(NotificationEnum.ALARM, "message") + ); + } +} \ No newline at end of file From 0a5c286f5dd71d3828f763f912edeb69bf355d31 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 23 Aug 2024 23:50:27 +0900 Subject: [PATCH 46/79] =?UTF-8?q?feat:=20exception=20=EC=A1=B0=EA=B1=B4=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/score/application/ScoreRankService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java index fd0f552..8a28014 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/ScoreRankService.java @@ -29,8 +29,8 @@ public ScoreRankingResponse createScoreRankingResponse(Map { NickNameAndBadge nickNameAndBadge = emailBindingData.get(rankData.email); - if (nickNameAndBadge.nickname() == null) { - throw new IllegalArgumentException("rank nickname is null"); + if (nickNameAndBadge == null) { + throw new IllegalArgumentException("Not found nickname and badge for email: " + rankData.email); } response.addRank(nickNameAndBadge.nickname(), rankData.score, nickNameAndBadge.badgeType()); }); From 1c6d77fa594fd39022dbb9f61e1aacf43969e4a5 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 27 Aug 2024 12:48:54 +0900 Subject: [PATCH 47/79] =?UTF-8?q?feat:=20event=20=EC=A1=B0=ED=9A=8C=20API?= =?UTF-8?q?=20=EC=B6=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/event/api/EventController.java | 29 +++++++++++++++ .../event/api/response/EventResponse.java | 32 +++++++++++++++++ .../event/application/EventService.java | 21 +++++++++++ .../domain/event/dao/EventRepository.java | 12 +++++++ .../domain/event/domain/Event.java | 36 +++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/event/api/response/EventResponse.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/event/application/EventService.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/event/dao/EventRepository.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/event/domain/Event.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java new file mode 100644 index 0000000..04412e8 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java @@ -0,0 +1,29 @@ +package com.playkuround.playkuroundserver.domain.event.api; + +import com.playkuround.playkuroundserver.domain.event.api.response.EventResponse; +import com.playkuround.playkuroundserver.domain.event.application.EventService; +import com.playkuround.playkuroundserver.domain.event.domain.Event; +import com.playkuround.playkuroundserver.global.common.response.ApiResponse; +import com.playkuround.playkuroundserver.global.util.ApiUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("api/events") +@RequiredArgsConstructor +public class EventController { + + private final EventService eventService; + + @GetMapping + public ApiResponse> findDisplayEvents() { + List events = eventService.findEvents(true); + return ApiUtils.success(events.stream() + .map(EventResponse::from) + .toList()); + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/api/response/EventResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/response/EventResponse.java new file mode 100644 index 0000000..509fbd6 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/response/EventResponse.java @@ -0,0 +1,32 @@ +package com.playkuround.playkuroundserver.domain.event.api.response; + +import com.playkuround.playkuroundserver.domain.event.domain.Event; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor(access = lombok.AccessLevel.PRIVATE) +@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) +public class EventResponse { + + @Schema(description = "event id", example = "3", requiredMode = Schema.RequiredMode.REQUIRED) + private long id; + + @Schema(description = "이벤트 이름", example = "경영X건축 대전", requiredMode = Schema.RequiredMode.REQUIRED) + private String title; + + @Schema(description = "이미지 URL", example = "https://www.asdf.com/image") + private String imageUrl; + + @Schema(description = "내용", example = "경영과 건축의 대결이 펼쳐집니다!") + private String description; + + @Schema(description = "연결된 링크", example = "https://www.asdf.com/link") + private String referenceUrl; + + public static EventResponse from(Event event) { + return new EventResponse(event.getId(), event.getTitle(), event.getImageUrl(), event.getDescription(), event.getReferenceUrl()); + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/application/EventService.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/application/EventService.java new file mode 100644 index 0000000..02833f3 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/application/EventService.java @@ -0,0 +1,21 @@ +package com.playkuround.playkuroundserver.domain.event.application; + +import com.playkuround.playkuroundserver.domain.event.dao.EventRepository; +import com.playkuround.playkuroundserver.domain.event.domain.Event; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class EventService { + + private final EventRepository eventRepository; + + public List findEvents(boolean display) { + return eventRepository.findByDisplay(display); + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/dao/EventRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/dao/EventRepository.java new file mode 100644 index 0000000..4fb3c77 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/dao/EventRepository.java @@ -0,0 +1,12 @@ +package com.playkuround.playkuroundserver.domain.event.dao; + +import com.playkuround.playkuroundserver.domain.event.domain.Event; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface EventRepository extends JpaRepository { + + List findByDisplay(boolean display); + +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/domain/Event.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/domain/Event.java new file mode 100644 index 0000000..be0b4cd --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/domain/Event.java @@ -0,0 +1,36 @@ +package com.playkuround.playkuroundserver.domain.event.domain; + +import com.playkuround.playkuroundserver.domain.common.BaseTimeEntity; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Objects; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Event extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String title; + private String imageUrl; + private String description; + private String referenceUrl; + private boolean display; + + public Event(String title, String imageUrl, String description, String referenceUrl, boolean display) { + Objects.requireNonNull(title, "title must be provided."); + + this.title = title; + this.imageUrl = imageUrl; + this.description = description; + this.referenceUrl = referenceUrl; + this.display = display; + } +} From 48b30761a187b0c96fb4bb820965a69f7f328c9b Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 27 Aug 2024 12:49:05 +0900 Subject: [PATCH 48/79] =?UTF-8?q?test:=20event=20=EC=A1=B0=ED=9A=8C=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/event/api/EventControllerTest.java | 60 +++++++++++++++++++ .../event/application/EventServiceTest.java | 47 +++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java create mode 100644 src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java new file mode 100644 index 0000000..1b115d9 --- /dev/null +++ b/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java @@ -0,0 +1,60 @@ +package com.playkuround.playkuroundserver.domain.event.api; + +import com.playkuround.playkuroundserver.IntegrationControllerTest; +import com.playkuround.playkuroundserver.domain.event.dao.EventRepository; +import com.playkuround.playkuroundserver.domain.event.domain.Event; +import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; +import com.playkuround.playkuroundserver.securityConfig.WithMockCustomUser; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.List; + +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@IntegrationControllerTest +class EventControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private EventRepository eventRepository; + + @Autowired + private UserRepository userRepository; + + @AfterEach + void clear() { + eventRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); + } + + @Test + @WithMockCustomUser + @DisplayName("display가 true인 event만 조회된다.") + void findEvents() throws Exception { + // given + List events = List.of( + new Event("title1", "imageUrl1", "description1", "referenceUrl1", true), + new Event("title2", "imageUrl2", "description2", "referenceUrl2", false), + new Event("title3", "imageUrl2", "description2", "referenceUrl2", true) + ); + eventRepository.saveAll(events); + + // expected + mockMvc.perform(get("/api/events")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.response.size()").value(2)) + .andExpect(jsonPath("$.response.[*].title").value( + containsInAnyOrder(events.get(0).getTitle(), events.get(2).getTitle()))) + .andDo(print()); + } +} \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java new file mode 100644 index 0000000..5729cd7 --- /dev/null +++ b/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java @@ -0,0 +1,47 @@ +package com.playkuround.playkuroundserver.domain.event.application; + +import com.playkuround.playkuroundserver.domain.event.dao.EventRepository; +import com.playkuround.playkuroundserver.domain.event.domain.Event; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class EventServiceTest { + + @InjectMocks + private EventService eventService; + + @Mock + private EventRepository eventRepository; + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + @DisplayName("event 조회") + void findEvents_1(boolean display) { + // given + List events = List.of( + new Event("title1", "imageUrl1", "description1", "referenceUrl1", true), + new Event("title2", "imageUrl2", "description2", "referenceUrl2", true) + ); + when(eventRepository.findByDisplay(display)) + .thenReturn(events); + + // when + List result = eventService.findEvents(display); + + // then + assertThat(result).hasSize(2) + .containsExactlyInAnyOrderElementsOf(events); + } + +} \ No newline at end of file From 8c959cafd7395d4f72c4f8ae56719d9976a3124b Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 27 Aug 2024 22:11:43 +0900 Subject: [PATCH 49/79] =?UTF-8?q?feat:=20saveEvent=20API=20=EC=B6=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/event/api/EventController.java | 19 ++++++++---- .../event/api/request/EventSaveRequest.java | 30 +++++++++++++++++++ .../event/application/EventService.java | 8 +++++ 3 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/event/api/request/EventSaveRequest.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java index 04412e8..21ffb24 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java @@ -1,29 +1,38 @@ package com.playkuround.playkuroundserver.domain.event.api; +import com.playkuround.playkuroundserver.domain.event.api.request.EventSaveRequest; import com.playkuround.playkuroundserver.domain.event.api.response.EventResponse; import com.playkuround.playkuroundserver.domain.event.application.EventService; import com.playkuround.playkuroundserver.domain.event.domain.Event; +import com.playkuround.playkuroundserver.domain.event.dto.EventSaveDto; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; import com.playkuround.playkuroundserver.global.util.ApiUtils; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; @RestController -@RequestMapping("api/events") +@RequestMapping("api") @RequiredArgsConstructor public class EventController { private final EventService eventService; - @GetMapping + @GetMapping("events") public ApiResponse> findDisplayEvents() { List events = eventService.findEvents(true); return ApiUtils.success(events.stream() .map(EventResponse::from) .toList()); } + + @PostMapping("admin/events") + public ApiResponse saveEvent(@RequestBody EventSaveRequest request) { + EventSaveDto eventSaveDto = new EventSaveDto(request.getTitle(), request.getImageUrl(), request.getDescription(), + request.getReferenceUrl(), request.isDisplay()); + eventService.saveEvent(eventSaveDto); + + return ApiUtils.success(null); + } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/api/request/EventSaveRequest.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/request/EventSaveRequest.java new file mode 100644 index 0000000..ac209f2 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/request/EventSaveRequest.java @@ -0,0 +1,30 @@ +package com.playkuround.playkuroundserver.domain.event.api.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) +@AllArgsConstructor +public class EventSaveRequest { + + @NotNull + @Schema(description = "event title", example = "경영X건축 대전", requiredMode = Schema.RequiredMode.REQUIRED) + private String title; + + @Schema(description = "이미지 URL", example = "https://www.asdf.com/image") + private String imageUrl; + + @Schema(description = "내용", example = "경영과 건축의 대결이 펼쳐집니다!") + private String description; + + @Schema(description = "연결된 링크", example = "https://www.asdf.com/link") + private String referenceUrl; + + @Schema(description = "화면 노출 여부", example = "true", defaultValue = "false") + private boolean display; + +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/application/EventService.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/application/EventService.java index 02833f3..e2e3f7c 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/event/application/EventService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/application/EventService.java @@ -2,6 +2,7 @@ import com.playkuround.playkuroundserver.domain.event.dao.EventRepository; import com.playkuround.playkuroundserver.domain.event.domain.Event; +import com.playkuround.playkuroundserver.domain.event.dto.EventSaveDto; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,4 +19,11 @@ public class EventService { public List findEvents(boolean display) { return eventRepository.findByDisplay(display); } + + @Transactional + public void saveEvent(EventSaveDto eventSaveDto) { + Event event = new Event(eventSaveDto.title(), eventSaveDto.imageUrl(), eventSaveDto.description(), + eventSaveDto.referenceUrl(), eventSaveDto.display()); + eventRepository.save(event); + } } From 5a5b37f5f85ee210bd18486251e1c018ff447cea Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 27 Aug 2024 22:14:40 +0900 Subject: [PATCH 50/79] =?UTF-8?q?feat:=20saveEvent=20API=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../playkuroundserver/domain/event/dto/EventSaveDto.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/event/dto/EventSaveDto.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/dto/EventSaveDto.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/dto/EventSaveDto.java new file mode 100644 index 0000000..9137f5c --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/dto/EventSaveDto.java @@ -0,0 +1,8 @@ +package com.playkuround.playkuroundserver.domain.event.dto; + +public record EventSaveDto(String title, + String imageUrl, + String description, + String referenceUrl, + boolean display) { +} From 8bac4173e796e4f5e1412958adc7ee57625c34f7 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 27 Aug 2024 22:15:02 +0900 Subject: [PATCH 51/79] test: service unit, saveEvent API --- .../domain/event/api/EventControllerTest.java | 33 +++++++++++++++++++ .../event/application/EventServiceTest.java | 22 +++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java index 1b115d9..34620cc 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java @@ -1,18 +1,24 @@ package com.playkuround.playkuroundserver.domain.event.api; +import com.fasterxml.jackson.databind.ObjectMapper; import com.playkuround.playkuroundserver.IntegrationControllerTest; +import com.playkuround.playkuroundserver.domain.event.api.request.EventSaveRequest; import com.playkuround.playkuroundserver.domain.event.dao.EventRepository; import com.playkuround.playkuroundserver.domain.event.domain.Event; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; +import com.playkuround.playkuroundserver.domain.user.domain.Role; import com.playkuround.playkuroundserver.securityConfig.WithMockCustomUser; +import org.assertj.core.groups.Tuple; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; @@ -25,6 +31,9 @@ class EventControllerTest { @Autowired private MockMvc mockMvc; + @Autowired + private ObjectMapper objectMapper; + @Autowired private EventRepository eventRepository; @@ -57,4 +66,28 @@ void findEvents() throws Exception { containsInAnyOrder(events.get(0).getTitle(), events.get(2).getTitle()))) .andDo(print()); } + + @Test + @WithMockCustomUser(role = Role.ROLE_ADMIN) + @DisplayName("event 저장 성공") + void saveEvents() throws Exception { + // given + EventSaveRequest eventSaveRequest = new EventSaveRequest("title", "imageUrl", "description", "referenceUrl", true); + String request = objectMapper.writeValueAsString(eventSaveRequest); + + // expected + mockMvc.perform(get("/api/events") + .contentType(MediaType.APPLICATION_JSON) + .content(request)) + .andExpect(status().isOk()) + .andDo(print()); + + List result = eventRepository.findAll(); + assertThat(result).hasSize(1) + .extracting("title", "imageUrl", "description", "referenceUrl", "display") + .containsExactly( + Tuple.tuple(eventSaveRequest.getTitle(), eventSaveRequest.getImageUrl(), eventSaveRequest.getDescription(), + eventSaveRequest.getReferenceUrl(), eventSaveRequest.isDisplay()) + ); + } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java index 5729cd7..2de9e96 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java @@ -2,7 +2,10 @@ import com.playkuround.playkuroundserver.domain.event.dao.EventRepository; import com.playkuround.playkuroundserver.domain.event.domain.Event; +import com.playkuround.playkuroundserver.domain.event.dto.EventSaveDto; +import org.assertj.core.groups.Tuple; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -44,4 +47,23 @@ void findEvents_1(boolean display) { .containsExactlyInAnyOrderElementsOf(events); } + @Test + @DisplayName("event 저장") + void saveEvent_1() { + // given + EventSaveDto eventSaveDto = new EventSaveDto("title", "imageUrl", "description", "referenceUrl", true); + + // when + eventService.saveEvent(eventSaveDto); + + // then + List result = eventRepository.findAll(); + assertThat(result).hasSize(1) + .extracting("title", "imageUrl", "description", "referenceUrl", "display") + .containsExactly( + Tuple.tuple(eventSaveDto.title(), eventSaveDto.imageUrl(), eventSaveDto.description(), + eventSaveDto.referenceUrl(), eventSaveDto.display()) + ); + } + } \ No newline at end of file From fe47d99d67dfed463b78aff6f80641623d4d14a1 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 27 Aug 2024 22:15:50 +0900 Subject: [PATCH 52/79] add swagger description --- .../domain/event/api/EventController.java | 7 +++++++ .../domain/systemcheck/api/SystemCheckApi.java | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java index 21ffb24..4952740 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java @@ -7,7 +7,10 @@ import com.playkuround.playkuroundserver.domain.event.dto.EventSaveDto; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; import com.playkuround.playkuroundserver.global.util.ApiUtils; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -15,11 +18,13 @@ @RestController @RequestMapping("api") @RequiredArgsConstructor +@Tag(name = "Event", description = "이벤트 API") public class EventController { private final EventService eventService; @GetMapping("events") + @Operation(summary = "이벤트 조회하기", description = "화면에 노출이 필요한 이벤트를 반환합니다.") public ApiResponse> findDisplayEvents() { List events = eventService.findEvents(true); return ApiUtils.success(events.stream() @@ -28,6 +33,8 @@ public ApiResponse> findDisplayEvents() { } @PostMapping("admin/events") + @ResponseStatus(HttpStatus.CREATED) + @Operation(summary = "이벤트 저장하기(ADMIN)", description = "이벤트를 저장합니다.") public ApiResponse saveEvent(@RequestBody EventSaveRequest request) { EventSaveDto eventSaveDto = new EventSaveDto(request.getTitle(), request.getImageUrl(), request.getDescription(), request.getReferenceUrl(), request.isDisplay()); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java index 3fa81c8..002c556 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java @@ -13,7 +13,7 @@ @RestController @RequestMapping("api") @RequiredArgsConstructor -@Tag(name = "System Check") +@Tag(name = "System Check", description = "Client APP에서는 호출할 필요가 없습니다.") public class SystemCheckApi { private final SystemCheckService systemCheckService; From c7ff8ad0a96170ba4849329ca61648643d9bdf24 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 27 Aug 2024 22:23:35 +0900 Subject: [PATCH 53/79] fix test --- .../domain/event/api/EventControllerTest.java | 5 +++-- .../event/application/EventServiceTest.java | 15 +++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java index 34620cc..e9a29b3 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/event/api/EventControllerTest.java @@ -21,6 +21,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -76,10 +77,10 @@ void saveEvents() throws Exception { String request = objectMapper.writeValueAsString(eventSaveRequest); // expected - mockMvc.perform(get("/api/events") + mockMvc.perform(post("/api/admin/events") .contentType(MediaType.APPLICATION_JSON) .content(request)) - .andExpect(status().isOk()) + .andExpect(status().isCreated()) .andDo(print()); List result = eventRepository.findAll(); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java index 2de9e96..60e0ab6 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/event/application/EventServiceTest.java @@ -3,12 +3,12 @@ import com.playkuround.playkuroundserver.domain.event.dao.EventRepository; import com.playkuround.playkuroundserver.domain.event.domain.Event; import com.playkuround.playkuroundserver.domain.event.dto.EventSaveDto; -import org.assertj.core.groups.Tuple; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -16,7 +16,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class EventServiceTest { @@ -57,13 +57,12 @@ void saveEvent_1() { eventService.saveEvent(eventSaveDto); // then - List result = eventRepository.findAll(); - assertThat(result).hasSize(1) + ArgumentCaptor eventArgumentCaptor = ArgumentCaptor.forClass(Event.class); + verify(eventRepository, times(1)).save(eventArgumentCaptor.capture()); + assertThat(eventArgumentCaptor.getValue()) .extracting("title", "imageUrl", "description", "referenceUrl", "display") - .containsExactly( - Tuple.tuple(eventSaveDto.title(), eventSaveDto.imageUrl(), eventSaveDto.description(), - eventSaveDto.referenceUrl(), eventSaveDto.display()) - ); + .containsExactly(eventSaveDto.title(), eventSaveDto.imageUrl(), eventSaveDto.description(), + eventSaveDto.referenceUrl(), eventSaveDto.display()); } } \ No newline at end of file From 25d790532bab319541b183f81f33be6084f56dd6 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 30 Aug 2024 11:22:47 +0900 Subject: [PATCH 54/79] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=20=ED=83=88?= =?UTF-8?q?=ED=87=B4=20API=20=EC=B6=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adventure/dao/AdventureRepository.java | 13 ++++ .../domain/adventure/dto/UserAndScore.java | 6 ++ .../attendance/dao/AttendanceRepository.java | 2 + .../domain/badge/dao/BadgeRepository.java | 2 + .../fakedoor/dao/FakeDoorRepository.java | 2 + .../domain/landmark/domain/Landmark.java | 10 ++- .../domain/user/api/UserManagementApi.java | 9 +++ .../user/application/UserDeleteService.java | 76 +++++++++++++++++++ 8 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/adventure/dto/UserAndScore.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserDeleteService.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java index 1939210..71a82f4 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.domain.adventure.dao; import com.playkuround.playkuroundserver.domain.adventure.domain.Adventure; +import com.playkuround.playkuroundserver.domain.adventure.dto.UserAndScore; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScoreAndBadgeType; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; @@ -41,4 +42,16 @@ long getSumScoreByUserAndLandmarkAfter(@Param(value = "user") User user, @Param(value = "from") LocalDateTime from); long countByUserAndLandmark(User user, Landmark requestSaveLandmark); + + @Query("SELECT new com.playkuround.playkuroundserver.domain.adventure.dto.UserAndScore(a.user, cast(SUM(a.score) as long)) " + + "FROM Adventure a " + + "where a.landmark.id=:landmark AND a.createdAt >= :from " + + "GROUP BY a.user.id " + + "ORDER BY SUM(a.score) DESC, a.user.nickname DESC " + + "LIMIT :limit") + List findRankDescBy(@Param(value = "landmark") Long landmarkId, + @Param(value = "from") LocalDateTime from, + @Param(value = "limit") int limit); + + void deleteByUser(User user); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dto/UserAndScore.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dto/UserAndScore.java new file mode 100644 index 0000000..c0467a4 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dto/UserAndScore.java @@ -0,0 +1,6 @@ +package com.playkuround.playkuroundserver.domain.adventure.dto; + +import com.playkuround.playkuroundserver.domain.user.domain.User; + +public record UserAndScore(User user, long score) { +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java index b41b11a..41fda98 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java @@ -12,4 +12,6 @@ public interface AttendanceRepository extends JpaRepository { List findByUserAndAttendanceDateTimeAfter(User user, LocalDateTime localDateTime); boolean existsByUserAndAttendanceDateTimeAfter(User user, LocalDateTime localDateTime); + + void deleteByUser(User user); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/dao/BadgeRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/dao/BadgeRepository.java index d2e8327..de3a36b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/dao/BadgeRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/dao/BadgeRepository.java @@ -11,4 +11,6 @@ public interface BadgeRepository extends JpaRepository { List findByUser(User user); boolean existsByUserAndBadgeType(User user, BadgeType badgeType); + + void deleteByUser(User user); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/fakedoor/dao/FakeDoorRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/fakedoor/dao/FakeDoorRepository.java index 302ff83..9f23f65 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/fakedoor/dao/FakeDoorRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/fakedoor/dao/FakeDoorRepository.java @@ -1,7 +1,9 @@ package com.playkuround.playkuroundserver.domain.fakedoor.dao; import com.playkuround.playkuroundserver.domain.fakedoor.domain.FakeDoor; +import com.playkuround.playkuroundserver.domain.user.domain.User; import org.springframework.data.jpa.repository.JpaRepository; public interface FakeDoorRepository extends JpaRepository { + void deleteByUser(User user); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java index 0f5389e..b53ea60 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java @@ -8,6 +8,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.Objects; + @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -46,7 +48,6 @@ public Landmark(LandmarkType landmarkType, double latitude, double longitude, in } public void updateFirstUser(User user, long score) { - if (score == 0) return; if (firstUser == null || this.highestScore < score) { this.firstUser = user; this.highestScore = score; @@ -64,4 +65,11 @@ public boolean isInRecognitionRadius(Location location) { return distance <= recognitionRadius; } + + public boolean isFirstUser(Long userId) { + if (this.firstUser == null) { + return false; + } + return Objects.equals(this.firstUser.getId(), userId); + } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java index 95f4e11..07de7e0 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java @@ -4,6 +4,7 @@ import com.playkuround.playkuroundserver.domain.auth.token.dto.TokenDto; import com.playkuround.playkuroundserver.domain.user.api.request.UserRegisterRequest; import com.playkuround.playkuroundserver.domain.user.api.response.UserRegisterResponse; +import com.playkuround.playkuroundserver.domain.user.application.UserDeleteService; import com.playkuround.playkuroundserver.domain.user.application.UserLogoutService; import com.playkuround.playkuroundserver.domain.user.application.UserRegisterService; import com.playkuround.playkuroundserver.domain.user.domain.Major; @@ -28,6 +29,7 @@ public class UserManagementApi { private final TokenService tokenService; private final UserLogoutService userLogoutService; private final UserRegisterService userRegisterService; + private final UserDeleteService userDeleteService; @PostMapping("/register") @ResponseStatus(value = HttpStatus.CREATED) @@ -50,4 +52,11 @@ public ApiResponse userLogout(@AuthenticationPrincipal UserDetailsImpl use return ApiUtils.success(null); } + @DeleteMapping + @Operation(summary = "회원 탈퇴", description = "회원 정보를 삭제합니다.") + public ApiResponse deleteUser(@AuthenticationPrincipal UserDetailsImpl userDetails) { + userDeleteService.deleteUser(userDetails.getUser()); + return ApiUtils.success(null); + } + } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserDeleteService.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserDeleteService.java new file mode 100644 index 0000000..6d401a4 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserDeleteService.java @@ -0,0 +1,76 @@ +package com.playkuround.playkuroundserver.domain.user.application; + +import com.playkuround.playkuroundserver.domain.adventure.dao.AdventureRepository; +import com.playkuround.playkuroundserver.domain.adventure.dto.UserAndScore; +import com.playkuround.playkuroundserver.domain.attendance.dao.AttendanceRepository; +import com.playkuround.playkuroundserver.domain.auth.token.dao.RefreshTokenRepository; +import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; +import com.playkuround.playkuroundserver.domain.fakedoor.dao.FakeDoorRepository; +import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; +import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; +import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; +import com.playkuround.playkuroundserver.domain.user.domain.User; +import com.playkuround.playkuroundserver.global.util.DateTimeUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ZSetOperations; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class UserDeleteService { + + private final UserRepository userRepository; + private final BadgeRepository badgeRepository; + private final LandmarkRepository landmarkRepository; + private final FakeDoorRepository fakeDoorRepository; + private final AdventureRepository adventureRepository; + private final AttendanceRepository attendanceRepository; + private final RefreshTokenRepository refreshTokenRepository; + + private final String redisSetKey = "ranking"; + private final RedisTemplate redisTemplate; + private final DateTimeService dateTimeService; + + @Transactional + public void deleteUser(User user) { + badgeRepository.deleteByUser(user); + fakeDoorRepository.deleteByUser(user); + attendanceRepository.deleteByUser(user); + refreshTokenRepository.deleteByUserEmail(user.getEmail()); + updateLandmarkFirstUser(user); + adventureRepository.deleteByUser(user); + + deleteTotalScoreRank(user); + userRepository.delete(user); + } + + private void deleteTotalScoreRank(User user) { + ZSetOperations zSetOperations = redisTemplate.opsForZSet(); + zSetOperations.remove(redisSetKey, user.getEmail()); + } + + private void updateLandmarkFirstUser(User user) { + LocalDate now = dateTimeService.getLocalDateNow(); + LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(now); + + List landmarks = landmarkRepository.findAll(); + landmarks.stream() + .filter(landmark -> landmark.isFirstUser(user.getId())) + .forEach(landmark -> { + List rankDesc = adventureRepository.findRankDescBy(landmark.getId(), monthStartDateTime, 2); + landmark.deleteRank(); + + if (rankDesc.size() > 1) { + UserAndScore userAndScore = rankDesc.get(1); + landmark.updateFirstUser(userAndScore.user(), userAndScore.score()); + } + }); + } +} From 5bed40e617a2dab98dba6379987066e68f57d7e5 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 30 Aug 2024 12:53:26 +0900 Subject: [PATCH 55/79] =?UTF-8?q?feat:=20profile=EB=B3=84=20component=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=EC=B2=B4=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 +- .../domain/auth/email/api/AuthEmailApi.java | 1 + .../application/AuthEmailSendService.java | 81 +------------------ .../application/AuthEmailVerifyService.java | 56 +------------ .../application/AuthEmailSendServiceTest.java | 2 +- .../AuthEmailVerifyServiceTest.java | 2 +- 6 files changed, 12 insertions(+), 136 deletions(-) diff --git a/.gitignore b/.gitignore index c406bcb..81ea4eb 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,8 @@ application-prod.yml application-local.yml application-dev-log.properties -application-prod-log.properties \ No newline at end of file +application-prod-log.properties + +AuthEmailSendServiceDevImpl.java +AuthEmailVerifyServiceDevImpl.java +DebugEmail.java \ No newline at end of file diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java index 7871b5d..3dff7b3 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java @@ -5,6 +5,7 @@ import com.playkuround.playkuroundserver.domain.auth.email.api.response.AuthVerifyEmailResponse; import com.playkuround.playkuroundserver.domain.auth.email.application.AuthEmailSendService; import com.playkuround.playkuroundserver.domain.auth.email.application.AuthEmailVerifyService; +import com.playkuround.playkuroundserver.domain.auth.email.application.AuthEmailVerifyServiceImpl; import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthEmailInfo; import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthVerifyEmailResult; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendService.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendService.java index 803ef4f..ca506b8 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendService.java @@ -1,86 +1,9 @@ package com.playkuround.playkuroundserver.domain.auth.email.application; -import com.playkuround.playkuroundserver.domain.auth.email.dao.AuthEmailRepository; -import com.playkuround.playkuroundserver.domain.auth.email.domain.AuthEmail; import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthEmailInfo; -import com.playkuround.playkuroundserver.domain.auth.email.exception.NotKUEmailException; -import com.playkuround.playkuroundserver.domain.auth.email.exception.SendingLimitExceededException; -import com.playkuround.playkuroundserver.infra.email.EmailService; -import com.playkuround.playkuroundserver.infra.email.Mail; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.thymeleaf.TemplateEngine; -import org.thymeleaf.context.Context; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.EnumSet; +public interface AuthEmailSendService { -@Service -@RequiredArgsConstructor -public class AuthEmailSendService { + AuthEmailInfo sendAuthEmail(String target); - private final EmailService emailService; - private final AuthEmailRepository authEmailRepository; - private final TemplateEngine templateEngine; - - @Value("${authentication.email.domain}") - private String emailDomain; - - @Value("${authentication.email.max-send-count}") - private Long maxSendingCount; - - @Value("${authentication.email.code-length}") - private Long codeLength; - - @Value("${authentication.email.code-expiration-seconds}") - private Long codeExpirationSeconds; - - @Transactional - public AuthEmailInfo sendAuthEmail(String target) { - validateEmailDomain(target); - long sendingCount = validateSendingCount(target); - - CodeGenerator codeGenerator = new CodeGenerator(); - String authenticationCode = codeGenerator.generateCode(EnumSet.of(CodeGenerator.CodeType.NUMBER), codeLength); - LocalDateTime expiredAt = saveAuthEmail(target, authenticationCode); - sendEmail(target, authenticationCode); - - return new AuthEmailInfo(expiredAt, sendingCount + 1); - } - - private void validateEmailDomain(String target) { - String[] requestSplit = target.split("@"); - if (requestSplit.length != 2 || !requestSplit[1].equals(emailDomain)) { - throw new NotKUEmailException(); - } - } - - private long validateSendingCount(String target) { - LocalDateTime today = LocalDate.now().atStartOfDay(); - long sendingCount = authEmailRepository.countByTargetAndCreatedAtAfter(target, today); - if (sendingCount >= maxSendingCount) { - throw new SendingLimitExceededException(); - } - return sendingCount; - } - - private LocalDateTime saveAuthEmail(String target, String authenticationCode) { - LocalDateTime expiredAt = LocalDateTime.now().plusSeconds(codeExpirationSeconds); - AuthEmail authEmail = AuthEmail.createAuthEmail(target, authenticationCode, expiredAt); - authEmailRepository.save(authEmail); - return expiredAt; - } - - private void sendEmail(String target, String authenticationCode) { - String title = "[플레이쿠라운드] 회원가입 인증코드입니다."; - Context context = new Context(); - context.setVariable("code", authenticationCode); - String content = templateEngine.process("mail-template", context); - - Mail mail = new Mail(target, title, content); - emailService.sendMail(mail); - } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyService.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyService.java index e9be648..36ab5cc 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyService.java @@ -1,61 +1,9 @@ package com.playkuround.playkuroundserver.domain.auth.email.application; -import com.playkuround.playkuroundserver.domain.auth.email.dao.AuthEmailRepository; -import com.playkuround.playkuroundserver.domain.auth.email.domain.AuthEmail; import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthVerifyEmailResult; -import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthVerifyTokenResult; -import com.playkuround.playkuroundserver.domain.auth.email.dto.TokenDtoResult; -import com.playkuround.playkuroundserver.domain.auth.email.exception.AuthCodeExpiredException; -import com.playkuround.playkuroundserver.domain.auth.email.exception.AuthEmailNotFoundException; -import com.playkuround.playkuroundserver.domain.auth.email.exception.NotMatchAuthCodeException; -import com.playkuround.playkuroundserver.domain.auth.token.application.TokenService; -import com.playkuround.playkuroundserver.domain.auth.token.domain.AuthVerifyToken; -import com.playkuround.playkuroundserver.domain.auth.token.dto.TokenDto; -import com.playkuround.playkuroundserver.domain.common.DateTimeService; -import com.playkuround.playkuroundserver.domain.user.application.UserLoginService; -import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -@Service -@RequiredArgsConstructor -public class AuthEmailVerifyService { +public interface AuthEmailVerifyService { - private final TokenService tokenService; - private final UserRepository userRepository; - private final UserLoginService userLoginService; - private final AuthEmailRepository authEmailRepository; - private final DateTimeService dateTimeService; + AuthVerifyEmailResult verifyAuthEmail(String code, String email); - @Transactional - public AuthVerifyEmailResult verifyAuthEmail(String code, String email) { - AuthEmail authEmail = authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(email) - .orElseThrow(AuthEmailNotFoundException::new); - - validateEmailAndCode(authEmail, code); - authEmail.changeInvalidate(); - - boolean existsUser = userRepository.existsByEmail(email); - if (existsUser) { - TokenDto tokenDto = userLoginService.login(email); - return new TokenDtoResult(tokenDto); - } - else { - AuthVerifyToken authVerifyToken = tokenService.registerAuthVerifyToken(); - return new AuthVerifyTokenResult(authVerifyToken.getAuthVerifyToken()); - } - } - - private void validateEmailAndCode(AuthEmail authEmail, String code) { - if (!authEmail.isValidate()) { - throw new AuthEmailNotFoundException(); - } - if (authEmail.getExpiredAt().isBefore(dateTimeService.getLocalDateTimeNow())) { - throw new AuthCodeExpiredException(); - } - if (!authEmail.getCode().equals(code)) { - throw new NotMatchAuthCodeException(); - } - } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java index ef0758b..33e8ed6 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java @@ -32,7 +32,7 @@ class AuthEmailSendServiceTest { @InjectMocks - private AuthEmailSendService authEmailSendService; + private AuthEmailSendServiceImpl authEmailSendService; @Mock private EmailService emailService; diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java index e92dc21..e336278 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java @@ -35,7 +35,7 @@ class AuthEmailVerifyServiceTest { @InjectMocks - private AuthEmailVerifyService authEmailVerifyService; + private AuthEmailVerifyServiceImpl authEmailVerifyService; @Mock private TokenService tokenService; From 4aef3469bfdeb83817590f0b59dae5e4a259bbba Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 30 Aug 2024 13:12:11 +0900 Subject: [PATCH 56/79] =?UTF-8?q?refactor:=20'=EB=B1=83=EC=A7=80'=EB=A5=BC?= =?UTF-8?q?=20'=EB=B0=B0=EC=A7=80'=EB=A1=9C=20=EC=9A=A9=EC=96=B4=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 15 +++- .../domain/adventure/api/AdventureApi.java | 4 +- .../api/response/AdventureSaveResponse.java | 4 +- .../domain/attendance/api/AttendanceApi.java | 2 +- .../response/AttendanceRegisterResponse.java | 4 +- .../application/AuthEmailSendServiceImpl.java | 89 +++++++++++++++++++ .../AuthEmailVerifyServiceImpl.java | 63 +++++++++++++ .../domain/badge/api/BadgeApi.java | 4 +- .../api/request/ProfileBadgeRequest.java | 2 +- .../badge/api/response/BadgeFindResponse.java | 6 +- .../badge/application/BadgeService.java | 6 +- .../domain/badge/domain/Badge.java | 3 +- .../domain/badge/domain/BadgeType.java | 6 +- .../exception/BadgeNotFoundException.java | 11 --- .../LandmarkHighestScoreUserResponse.java | 2 +- .../domain/user/api/AdminApi.java | 4 +- .../domain/user/api/UserProfileApi.java | 4 +- .../api/request/ManualBadgeSaveRequest.java | 6 +- .../api/response/UserProfileResponse.java | 2 +- .../global/error/ErrorCode.java | 2 +- .../attendance/api/AttendanceApiTest.java | 6 +- .../AttendanceRegisterServiceTest.java | 2 +- .../domain/badge/api/BadgeApiTest.java | 6 +- .../badge/application/BadgeServiceTest.java | 28 +++--- .../badge/application/CollegeBadgeTest.java | 4 +- .../score/api/LandmarkScoreRankApiTest.java | 2 +- .../score/api/ScoreTotalRankApiTest.java | 2 +- .../application/LandmarkRankServiceTest.java | 2 +- .../application/TotalScoreServiceTest.java | 2 +- .../domain/user/api/AdminApiTest.java | 8 +- .../domain/user/api/UserProfileApiTest.java | 4 +- .../application/UserProfileServiceTest.java | 8 +- 32 files changed, 228 insertions(+), 85 deletions(-) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceImpl.java delete mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeNotFoundException.java diff --git a/build.gradle b/build.gradle index 30db5ff..cc5eb10 100644 --- a/build.gradle +++ b/build.gradle @@ -31,29 +31,36 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'javax.xml.bind:jaxb-api:2.3.1' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + // Lombok compileOnly 'org.projectlombok:lombok' testCompileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' + + // DB runtimeOnly 'com.h2database:h2' runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' runtimeOnly 'com.mysql:mysql-connector-j' - annotationProcessor 'org.projectlombok:lombok' - testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'it.ozimov:embedded-redis:0.7.2' + // JWT implementation 'io.jsonwebtoken:jjwt-api:0.11.5' implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' + // Security implementation 'org.springframework.boot:spring-boot-starter-security' testImplementation 'org.springframework.security:spring-security-test' + // Swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0' - implementation 'it.ozimov:embedded-redis:0.7.2' - + // BadWord Filtering implementation 'io.github.vaneproject:badwordfiltering:1.0.0' + // Monitoring implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-registry-prometheus' } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java index 85d2ac5..b9a0469 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java @@ -29,8 +29,8 @@ public class AdventureApi { @PostMapping @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "탐험하기", description = "탐험 점수를 저장합니다. 새롭게 얻은 뱃지가 있을 시 반환됩니다. " + - "새로 추가된 뱃지는 DB에 자동 반영됩니다. scoreType은 별도 문서 참고") + @Operation(summary = "탐험하기", description = "탐험 점수를 저장합니다. 새롭게 얻은 배지가 있을 시 반환됩니다. " + + "새로 추가된 배지는 DB에 자동 반영됩니다. scoreType은 별도 문서 참고") public ApiResponse saveAdventure(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody @Valid AdventureSaveRequest request) { ScoreType scoreType = ScoreType.fromString(request.getScoreType()) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java index c39471f..7f574d2 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java @@ -29,11 +29,11 @@ public static AdventureSaveResponse from(NewlyRegisteredBadge newlyRegisteredBad @AllArgsConstructor public static class BadgeInfo { @JsonProperty("name") - @Schema(description = "뱃지 이름", example = "ATTENDANCE_7", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "배지 이름", example = "ATTENDANCE_7", requiredMode = Schema.RequiredMode.REQUIRED) private String name; @JsonProperty("description") - @Schema(description = "뱃지 설명", example = "7일 연속 출석", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "배지 설명", example = "7일 연속 출석", requiredMode = Schema.RequiredMode.REQUIRED) private String description; } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java index ccda410..6531d85 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java @@ -31,7 +31,7 @@ public class AttendanceApi { @PostMapping @Operation(summary = "출석하기", description = "오늘 출석을 저장합니다. 출석은 하루에 한번만 가능하며, " + - "새롭게 얻은 뱃지가 있을 시 반환됩니다. 뱃지는 DB에 자동 반영됩니다.") + "새롭게 얻은 배지가 있을 시 반환됩니다. 배지는 DB에 자동 반영됩니다.") public ApiResponse saveAttendance(@AuthenticationPrincipal UserDetailsImpl userDetails, @Valid @RequestBody AttendanceRegisterRequest registerRequest) { Location location = new Location(registerRequest.getLatitude(), registerRequest.getLongitude()); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/response/AttendanceRegisterResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/response/AttendanceRegisterResponse.java index 5776af2..dd317c3 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/response/AttendanceRegisterResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/response/AttendanceRegisterResponse.java @@ -30,10 +30,10 @@ public static AttendanceRegisterResponse from(NewlyRegisteredBadge newlyRegister @AllArgsConstructor public static class BadgeInfo { - @Schema(description = "뱃지 이름", example = "ATTENDANCE_7", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "배지 이름", example = "ATTENDANCE_7", requiredMode = Schema.RequiredMode.REQUIRED) private String name; - @Schema(description = "뱃지 설명", example = "7일 연속 출석", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "배지 설명", example = "7일 연속 출석", requiredMode = Schema.RequiredMode.REQUIRED) private String description; } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java new file mode 100644 index 0000000..582a4d1 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java @@ -0,0 +1,89 @@ +package com.playkuround.playkuroundserver.domain.auth.email.application; + +import com.playkuround.playkuroundserver.domain.auth.email.dao.AuthEmailRepository; +import com.playkuround.playkuroundserver.domain.auth.email.domain.AuthEmail; +import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthEmailInfo; +import com.playkuround.playkuroundserver.domain.auth.email.exception.NotKUEmailException; +import com.playkuround.playkuroundserver.domain.auth.email.exception.SendingLimitExceededException; +import com.playkuround.playkuroundserver.infra.email.EmailService; +import com.playkuround.playkuroundserver.infra.email.Mail; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.thymeleaf.TemplateEngine; +import org.thymeleaf.context.Context; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.EnumSet; + +@Service +@RequiredArgsConstructor +@Profile("!dev") +public class AuthEmailSendServiceImpl implements AuthEmailSendService { + + private final EmailService emailService; + private final AuthEmailRepository authEmailRepository; + private final TemplateEngine templateEngine; + + @Value("${authentication.email.domain}") + private String emailDomain; + + @Value("${authentication.email.max-send-count}") + private Long maxSendingCount; + + @Value("${authentication.email.code-length}") + private Long codeLength; + + @Value("${authentication.email.code-expiration-seconds}") + private Long codeExpirationSeconds; + + @Transactional + @Override + public AuthEmailInfo sendAuthEmail(String target) { + validateEmailDomain(target); + long sendingCount = validateSendingCount(target); + + CodeGenerator codeGenerator = new CodeGenerator(); + String authenticationCode = codeGenerator.generateCode(EnumSet.of(CodeGenerator.CodeType.NUMBER), codeLength); + LocalDateTime expiredAt = saveAuthEmail(target, authenticationCode); + sendEmail(target, authenticationCode); + + return new AuthEmailInfo(expiredAt, sendingCount + 1); + } + + private void validateEmailDomain(String target) { + String[] requestSplit = target.split("@"); + if (requestSplit.length != 2 || !requestSplit[1].equals(emailDomain)) { + throw new NotKUEmailException(); + } + } + + private long validateSendingCount(String target) { + LocalDateTime today = LocalDate.now().atStartOfDay(); + long sendingCount = authEmailRepository.countByTargetAndCreatedAtAfter(target, today); + if (sendingCount >= maxSendingCount) { + throw new SendingLimitExceededException(); + } + return sendingCount; + } + + private LocalDateTime saveAuthEmail(String target, String authenticationCode) { + LocalDateTime expiredAt = LocalDateTime.now().plusSeconds(codeExpirationSeconds); + AuthEmail authEmail = AuthEmail.createAuthEmail(target, authenticationCode, expiredAt); + authEmailRepository.save(authEmail); + return expiredAt; + } + + private void sendEmail(String target, String authenticationCode) { + String title = "[플레이쿠라운드] 회원가입 인증코드입니다."; + Context context = new Context(); + context.setVariable("code", authenticationCode); + String content = templateEngine.process("mail-template", context); + + Mail mail = new Mail(target, title, content); + emailService.sendMail(mail); + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceImpl.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceImpl.java new file mode 100644 index 0000000..d9420e9 --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceImpl.java @@ -0,0 +1,63 @@ +package com.playkuround.playkuroundserver.domain.auth.email.application; + +import com.playkuround.playkuroundserver.domain.auth.email.dao.AuthEmailRepository; +import com.playkuround.playkuroundserver.domain.auth.email.domain.AuthEmail; +import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthVerifyEmailResult; +import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthVerifyTokenResult; +import com.playkuround.playkuroundserver.domain.auth.email.dto.TokenDtoResult; +import com.playkuround.playkuroundserver.domain.auth.email.exception.AuthCodeExpiredException; +import com.playkuround.playkuroundserver.domain.auth.email.exception.AuthEmailNotFoundException; +import com.playkuround.playkuroundserver.domain.auth.email.exception.NotMatchAuthCodeException; +import com.playkuround.playkuroundserver.domain.auth.token.application.TokenService; +import com.playkuround.playkuroundserver.domain.auth.token.domain.AuthVerifyToken; +import com.playkuround.playkuroundserver.domain.auth.token.dto.TokenDto; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; +import com.playkuround.playkuroundserver.domain.user.application.UserLoginService; +import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Profile("!dev") +public class AuthEmailVerifyServiceImpl implements AuthEmailVerifyService { + + private final TokenService tokenService; + private final UserRepository userRepository; + private final UserLoginService userLoginService; + private final AuthEmailRepository authEmailRepository; + private final DateTimeService dateTimeService; + + @Transactional + public AuthVerifyEmailResult verifyAuthEmail(String code, String email) { + AuthEmail authEmail = authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(email) + .orElseThrow(AuthEmailNotFoundException::new); + + validateEmailAndCode(authEmail, code); + authEmail.changeInvalidate(); + + boolean existsUser = userRepository.existsByEmail(email); + if (existsUser) { + TokenDto tokenDto = userLoginService.login(email); + return new TokenDtoResult(tokenDto); + } + else { + AuthVerifyToken authVerifyToken = tokenService.registerAuthVerifyToken(); + return new AuthVerifyTokenResult(authVerifyToken.getAuthVerifyToken()); + } + } + + private void validateEmailAndCode(AuthEmail authEmail, String code) { + if (!authEmail.isValidate()) { + throw new AuthEmailNotFoundException(); + } + if (authEmail.getExpiredAt().isBefore(dateTimeService.getLocalDateTimeNow())) { + throw new AuthCodeExpiredException(); + } + if (!authEmail.getCode().equals(code)) { + throw new NotMatchAuthCodeException(); + } + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java index 3101367..80fbfe8 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java @@ -24,7 +24,7 @@ public class BadgeApi { private final BadgeService badgeService; @GetMapping - @Operation(summary = "뱃지조회", description = "사용자가 획득한 뱃지를 조회합니다.") + @Operation(summary = "배지조회", description = "사용자가 획득한 배지를 조회합니다.") public ApiResponse> findBadge(@AuthenticationPrincipal UserDetailsImpl userDetails) { List badges = badgeService.findBadgeByEmail(userDetails.getUser()); return ApiUtils.success(badges.stream() @@ -34,7 +34,7 @@ public ApiResponse> findBadge(@AuthenticationPrincipal U @PostMapping("/dream-of-duck") @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "오리의꿈 뱃지 획득", description = "오리의 꿈 뱃지를 획득합니다. 이미 획득한 뱃지였다면 false를 반환합니다.") + @Operation(summary = "오리의꿈 배지 획득", description = "오리의 꿈 배지를 획득합니다. 이미 획득한 배지였다면 false를 반환합니다.") public ApiResponse saveTheDreamOfDuckBadge(@AuthenticationPrincipal UserDetailsImpl userDetails) { boolean response = badgeService.saveTheDreamOfDuckBadge(userDetails.getUser()); return ApiUtils.success(response); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/ProfileBadgeRequest.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/ProfileBadgeRequest.java index 9683ad4..007d871 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/ProfileBadgeRequest.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/request/ProfileBadgeRequest.java @@ -13,7 +13,7 @@ public class ProfileBadgeRequest { @ValidEnum(enumClass = BadgeType.class, message = "잘못된 badge type 입니다.") - @Schema(description = "설정할 뱃지 이름", example = "ATTENDANCE_CHILDREN_DAY", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "설정할 배지 이름", example = "ATTENDANCE_CHILDREN_DAY", requiredMode = Schema.RequiredMode.REQUIRED) private String profileBadge; } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/response/BadgeFindResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/response/BadgeFindResponse.java index 4630b96..994c374 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/response/BadgeFindResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/response/BadgeFindResponse.java @@ -14,14 +14,14 @@ @NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) public class BadgeFindResponse { - @Schema(description = "뱃지 이름", example = "ATTENDANCE_7", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "배지 이름", example = "ATTENDANCE_7", requiredMode = Schema.RequiredMode.REQUIRED) private String name; - @Schema(description = "뱃지 설명", example = "7일 연속 출석", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "배지 설명", example = "7일 연속 출석", requiredMode = Schema.RequiredMode.REQUIRED) private String description; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul") - @Schema(description = "뱃지를 획득한 날짜, 시각", example = "2023-12-20 11:13:21", type = "string", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "배지를 획득한 날짜, 시각", example = "2023-12-20 11:13:21", type = "string", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createdAt; public static BadgeFindResponse from(Badge badge) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java index 98e8e07..078e03c 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java @@ -42,7 +42,7 @@ public NewlyRegisteredBadge updateNewlyAttendanceBadges(User user) { NewlyRegisteredBadge newlyRegisteredBadge = new NewlyRegisteredBadge(); - // 출석일 기준 뱃지 + // 출석일 기준 배지 AttendanceBadgeList.getAttendanceBadges().stream() .filter(attendanceBadge -> attendanceBadge.supports(userBadgeSet, user)) .forEach(attendanceBadge -> { @@ -51,7 +51,7 @@ public NewlyRegisteredBadge updateNewlyAttendanceBadges(User user) { newlyRegisteredBadge.addBadge(badgeType); }); - // 기념일 기준 뱃지 + // 기념일 기준 배지 SpecialDayBadgeList.getSpecialDayBadges().stream() .filter(specialDayBadge -> specialDayBadge.supports(userBadgeSet, dateTimeService.getLocalDateNow())) .forEach(specialDayBadge -> { @@ -81,7 +81,7 @@ public NewlyRegisteredBadge updateNewlyAdventureBadges(User user, Landmark reque } }); - // 단과대 특별 뱃지 + // 단과대 특별 배지 collegeSpecialBadgeFactory.getBadgeType(user, userBadgeSet, requestSaveLandmark) .ifPresent(badgeType -> { newlyRegisteredBadge.addBadge(badgeType); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java index d5dbc4d..240815e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java @@ -2,6 +2,7 @@ import com.playkuround.playkuroundserver.domain.common.BaseTimeEntity; import com.playkuround.playkuroundserver.domain.user.domain.User; +import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -9,8 +10,6 @@ import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; -import jakarta.persistence.*; - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java index e0a274b..36f8428 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/BadgeType.java @@ -27,7 +27,7 @@ public enum BadgeType { ATTENDANCE_CHILDREN_DAY("05월 05일 어린이날에 출석"), ATTENDANCE_WHITE_DAY("03월 14일 화이트데이에 출석"), ATTENDANCE_DUCK_DAY("05월 02일 오리데이에 출석"), - // 가을학기 추가 뱃지 + // 가을학기 추가 배지 ATTENDANCE_CHUSEOK_DAY("09월 17일 추석날에 출석"), ATTENDANCE_KOREAN_DAY("10월 09일 한글날에 출석"), ATTENDANCE_DOKDO_DAY("10월 25일 독도의 날에 출석"), @@ -76,8 +76,8 @@ public enum BadgeType { MONTHLY_RANKING_3("월간 랭킹 3등"), // 수동 // 이벤트 - BUSINESS_ARCHITECTURE_EVENT_BUSINESS("경영X건축 경영 뱃지"), - BUSINESS_ARCHITECTURE_EVENT_ARCHITECTURE("경영X건축 건축 뱃지"), + BUSINESS_ARCHITECTURE_EVENT_BUSINESS("경영X건축 경영 배지"), + BUSINESS_ARCHITECTURE_EVENT_ARCHITECTURE("경영X건축 건축 배지"), ; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeNotFoundException.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeNotFoundException.java deleted file mode 100644 index 84b01af..0000000 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/exception/BadgeNotFoundException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.playkuround.playkuroundserver.domain.badge.exception; - -import com.playkuround.playkuroundserver.global.error.exception.NotFoundException; - -public class BadgeNotFoundException extends NotFoundException { - - public BadgeNotFoundException(String targetEmail) { - super(targetEmail + " 의 뱃지 조회에 실패하였습니다."); - } - -} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java index c3d02b1..981c378 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/LandmarkHighestScoreUserResponse.java @@ -19,7 +19,7 @@ public class LandmarkHighestScoreUserResponse { @Schema(description = "최고 점수", example = "294") private Long score; - @Schema(description = "해당 사용자의 프로필 뱃지", example = "COLLEGE_OF_ENGINEERING") + @Schema(description = "해당 사용자의 프로필 배지", example = "COLLEGE_OF_ENGINEERING") private String profileBadge; public static LandmarkHighestScoreUserResponse from(LandmarkHighestScoreUser firstUserData) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java index d6721be..90d3b2f 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java @@ -24,8 +24,8 @@ public class AdminApi { @PostMapping("badges/manual") @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "수동 뱃지 등록", description = "수동으로 뱃지를 등록합니다. 이미 획득한 뱃지였다면 false를 반환합니다. " + - "설정에 따라 개인 메시지로 등록할 수 있습니다.") + @Operation(summary = "수동 배지 등록", + description = "수동으로 배지를 등록합니다. 이미 획득한 배지였다면 false를 반환합니다. 설정에 따라 개인 메시지로 등록할 수 있습니다.") public ApiResponse saveManualBadge(@RequestBody @Valid ManualBadgeSaveRequest request) { BadgeType badgeType = BadgeType.valueOf(request.getBadge()); boolean response = badgeService.saveManualBadge(request.getUserEmail(), badgeType, request.isRegisterMessage()); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java index 5b501de..ec716f1 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java @@ -57,7 +57,7 @@ public ApiResponse isAvailableNickname(@RequestParam("nickname") String } @PostMapping("/profile-badge") - @Operation(summary = "프로필 뱃지 설정", description = "사용자 프로필 뱃지를 설정합니다.") + @Operation(summary = "프로필 배지 설정", description = "사용자 프로필 배지를 설정합니다.") public ApiResponse setProfileBadge(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody @Valid ProfileBadgeRequest request) { BadgeType badgeType = BadgeType.fromString(request.getProfileBadge()) @@ -73,7 +73,7 @@ public ApiResponse setProfileBadge(@AuthenticationPrincipal UserDetailsImp "=== name 명 리스트(new_badge는 description도 중요) ===
" + "1. 시스템 점검 중일 때(단독으로만 반환): system_check
" + "2. 앱 버전 업데이트가 필요할 때(단독으로만 반환): update
" + - "3. 새로운 뱃지 획득: new_badge(MONTHLY_RANKING_1, MONTHLY_RANKING_2, MONTHLY_RANKING_3, COLLEGE_OF_BUSINESS_ADMINISTRATION_100_AND_FIRST_PLACE)
" + + "3. 새로운 배지 획득: new_badge(MONTHLY_RANKING_1, MONTHLY_RANKING_2, MONTHLY_RANKING_3, COLLEGE_OF_BUSINESS_ADMINISTRATION_100_AND_FIRST_PLACE)
" + "4. 개인 알림: alarm", parameters = { @Parameter(name = "version", description = "현재 앱 버전", example = "2.0.2", required = true), diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/ManualBadgeSaveRequest.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/ManualBadgeSaveRequest.java index aa999dc..d45542b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/ManualBadgeSaveRequest.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/ManualBadgeSaveRequest.java @@ -17,11 +17,11 @@ public class ManualBadgeSaveRequest { @NotBlank(message = "이메일은 필수값입니다.") @Email(message = "올바른 이메일 형식이 아닙니다.") - @Schema(description = "뱃지를 부여할 유저 이메일", example = "tester@konkuk.ac.kr", requiredMode = RequiredMode.REQUIRED) + @Schema(description = "배지를 부여할 유저 이메일", example = "tester@konkuk.ac.kr", requiredMode = RequiredMode.REQUIRED) private String userEmail; - @ValidEnum(enumClass = BadgeType.class, message = "잘못된 뱃지타입입니다.") - @Schema(description = "뱃지타입. 뱃지타입명은 외부 문서 참고", example = "ATTENDANCE_FOUNDATION_DAY", requiredMode = RequiredMode.REQUIRED) + @ValidEnum(enumClass = BadgeType.class, message = "잘못된 배지타입입니다.") + @Schema(description = "배지타입. 배지타입명은 외부 문서 참고", example = "ATTENDANCE_FOUNDATION_DAY", requiredMode = RequiredMode.REQUIRED) private String badge; @Schema(description = "개인 메시지로 추가 여부", example = "true", defaultValue = "false") diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java index 9881a97..d3502f9 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/response/UserProfileResponse.java @@ -30,7 +30,7 @@ public class UserProfileResponse { @Schema(description = "출석한 횟수", example = "28", requiredMode = RequiredMode.REQUIRED) private int attendanceDays; - @Schema(description = "프로필 뱃지(프로필 뱃지가 없다면 null 리턴)", example = "MONTHLY_RANKING_1") + @Schema(description = "프로필 배지(프로필 배지가 없다면 null 리턴)", example = "MONTHLY_RANKING_1") private String profileBadge; public static UserProfileResponse from(User user) { diff --git a/src/main/java/com/playkuround/playkuroundserver/global/error/ErrorCode.java b/src/main/java/com/playkuround/playkuroundserver/global/error/ErrorCode.java index 3ba7941..5df3062 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/error/ErrorCode.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/error/ErrorCode.java @@ -49,7 +49,7 @@ public enum ErrorCode { // Badge INVALID_BADGE_TYPE(HttpStatus.BAD_REQUEST, "B001", "올바르지 않은 BadgeType입니다."), - NOT_HAVE_BADGE(HttpStatus.BAD_REQUEST, "B002", "사용자가 가지고 있지 않은 뱃지입니다."), + NOT_HAVE_BADGE(HttpStatus.BAD_REQUEST, "B002", "사용자가 가지고 있지 않은 배지입니다."), // Attendance DUPLICATE_ATTENDANCE(HttpStatus.BAD_REQUEST, "AT01", "이미 오늘 출석한 회원입니다."), diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java index bcea94e..76e6d63 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java @@ -4,7 +4,6 @@ import com.jayway.jsonpath.JsonPath; import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.domain.attendance.api.request.AttendanceRegisterRequest; -import com.playkuround.playkuroundserver.domain.attendance.application.AttendanceRegisterService; import com.playkuround.playkuroundserver.domain.attendance.dao.AttendanceRepository; import com.playkuround.playkuroundserver.domain.attendance.domain.Attendance; import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; @@ -83,7 +82,7 @@ class saveAttendance { @Test @WithMockCustomUser - @DisplayName("최초로 출석을 하면 뱃지를 받는다.") + @DisplayName("최초로 출석하면 BadgeType.ATTENDANCE_1 배지를 받는다.") void success_1() throws Exception { // given AttendanceRegisterRequest attendanceRegisterRequest = new AttendanceRegisterRequest(37.539927, 127.073006); @@ -179,9 +178,6 @@ void fail_2() throws Exception { @DisplayName("출석 조회하기") class searchAttendance { - @Autowired - private AttendanceRegisterService attendanceRegisterService; - @Test @WithMockCustomUser @DisplayName("지난 한달 출석 조회") diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java index f81d11a..3f0ea99 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java @@ -51,7 +51,7 @@ class AttendanceRegisterServiceTest { private DateTimeService dateTimeService; @Test - @DisplayName("출석 시 뱃지와 출석정보가 저장되고 유저의 출석횟수가 증가한다") + @DisplayName("출석 시 배지와 출석정보가 저장되고 유저의 출석횟수가 증가한다") void registerAttendance_1() { // given when(attendanceRepository.existsByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java index 52b44ec..926424e 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApiTest.java @@ -44,7 +44,7 @@ void clean() { @Nested @WithMockCustomUser - @DisplayName("뱃지 조회하기") + @DisplayName("배지 조회하기") class findBadge { @Test @@ -81,11 +81,11 @@ void success_2() throws Exception { @Nested @WithMockCustomUser - @DisplayName("오리의 꿈 뱃지 획득") + @DisplayName("오리의 꿈 배지 획득") class saveTheDreamOfDuckBadge { @Test - @DisplayName("기존에 안가지고 있었다면 새롭게 뱃지를 획득하고 true가 반환된다") + @DisplayName("기존에 안가지고 있었다면 새롭게 배지를 획득하고 true가 반환된다") void success_1() throws Exception { mockMvc.perform(post("/api/badges/dream-of-duck")) .andExpect(status().isCreated()) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java index a211056..032d116 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java @@ -60,11 +60,11 @@ class BadgeServiceTest { private DateTimeService dateTimeService; @Nested - @DisplayName("뱃지 조회하기") + @DisplayName("배지 조회하기") class findBadge { @Test - @DisplayName("뱃지 개수가 0개이면 빈리스트가 반환된다") + @DisplayName("배지 개수가 0개이면 빈리스트가 반환된다") void success_1() { // given User user = TestUtil.createUser(); @@ -78,7 +78,7 @@ void success_1() { } @Test - @DisplayName("뱃지 개수 3개 조회") + @DisplayName("배지 개수 3개 조회") void success_2() { // given User user = TestUtil.createUser(); @@ -104,7 +104,7 @@ void success_2() { } @Nested - @DisplayName("출석에 따른 뱃지 부여") + @DisplayName("출석에 따른 배지 부여") class updateNewlyAttendanceBadges { static Stream generateAttendanceBadgeTestData() { @@ -128,7 +128,7 @@ static Stream generateAttendanceBadgeTestData() { @ParameterizedTest @MethodSource("generateAttendanceBadgeTestData") - @DisplayName("출석 횟수에 따른 뱃지 획득") + @DisplayName("출석 횟수에 따른 배지 획득") void success_1(int attendanceDay, List expected) { // given User user = TestUtil.createUser(); @@ -161,7 +161,7 @@ void success_1(int attendanceDay, List expected) { } @Test - @DisplayName("기념일 출석 뱃지") + @DisplayName("기념일 출석 배지") void success_2() { // given User user = TestUtil.createUser(); @@ -189,7 +189,7 @@ void success_2() { } @Test - @DisplayName("이미 가지고 있는 뱃지는 부여하지 않는다") + @DisplayName("이미 가지고 있는 배지는 부여하지 않는다") void success_3() { // given User user = TestUtil.createUser(); @@ -232,7 +232,7 @@ void success_3() { } @Nested - @DisplayName("탐험 대학에 따른 뱃지 부여") + @DisplayName("탐험 대학에 따른 배지 부여") class updateNewlyAdventureBadges { static Stream generateAdventureBadgeTestData() { @@ -277,7 +277,7 @@ static Stream generateAdventureBadgeTestData() { @ParameterizedTest @MethodSource("generateAdventureBadgeTestData") - @DisplayName("대학별 뱃지") + @DisplayName("대학별 배지") void success_1(LandmarkType landmarkType, List badgeTypeList) throws Exception { // given User user = TestUtil.createUser(); @@ -300,7 +300,7 @@ void success_1(LandmarkType landmarkType, List badgeTypeList) throws Exc } @Test - @DisplayName("단과대 특별 뱃지") + @DisplayName("단과대 특별 배지") void success_2() throws Exception { // given User user = TestUtil.createUser(); @@ -342,12 +342,12 @@ private Landmark createLandmark(LandmarkType landmarkType) throws Exception { } @Nested - @DisplayName("The Dream of Duck 뱃지 부여") + @DisplayName("The Dream of Duck 배지 부여") class saveTheDreamOfDuckBadge { @ParameterizedTest @ValueSource(booleans = {true, false}) - @DisplayName("정상 저장되었다면 true, 이미 저장된 뱃지였으면 false를 반환한다.") + @DisplayName("정상 저장되었다면 true, 이미 저장된 배지였으면 false를 반환한다.") void success_1(boolean hasBadge) { // given User user = TestUtil.createUser(); @@ -363,12 +363,12 @@ void success_1(boolean hasBadge) { } @Nested - @DisplayName("뱃지 수동 등록") + @DisplayName("배지 수동 등록") class saveManualBadge { @ParameterizedTest @ValueSource(booleans = {true, false}) - @DisplayName("정상 저장되었다면 true, 이미 저장된 뱃지였으면 false를 반환한다.") + @DisplayName("정상 저장되었다면 true, 이미 저장된 배지였으면 false를 반환한다.") void success_1(boolean hasBadge) { // given User user = TestUtil.createUser(); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/CollegeBadgeTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/CollegeBadgeTest.java index 8d41612..da44bb1 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/CollegeBadgeTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/CollegeBadgeTest.java @@ -14,7 +14,7 @@ class CollegeBadgeTest { - // 기획에서 정한 건물별 뱃지 + // 기획에서 정한 건물별 배지 private final List answer = List.of( new CollegeBadgeRecord(LandmarkType.인문학관, BadgeType.COLLEGE_OF_LIBERAL_ARTS), new CollegeBadgeRecord(LandmarkType.과학관, BadgeType.COLLEGE_OF_SCIENCES), @@ -40,7 +40,7 @@ class CollegeBadgeTest { ); @ParameterizedTest - @DisplayName("랜드마크 탐험 뱃지 테스트") + @DisplayName("랜드마크 탐험 배지 테스트") @EnumSource(value = LandmarkType.class) void collegeBadge(LandmarkType landmarkType) { List answerBadeType = answer.stream() diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java index 13a0b4a..4043bf5 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java @@ -259,7 +259,7 @@ else if (i == 41) { @Test @WithMockCustomUser(email = "test@konkuk.ac.kr", badgeType = BadgeType.COLLEGE_OF_ENGINEERING) - @DisplayName("랭킹 조회 API에는 사용자 대표 뱃지 데이터가 포함되어 있다.") + @DisplayName("랭킹 조회 API에는 사용자 대표 배지 데이터가 포함되어 있다.") void getRankTop100ByLandmark_6() throws Exception { // given Landmark landmark = new Landmark(LandmarkType.경영관, 37.541, 127.079, 100); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java index ab78077..9765692 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java @@ -209,7 +209,7 @@ void getRankTop100_5() throws Exception { @Test @WithMockCustomUser - @DisplayName("랭킹 조회 API에는 사용자 대표 뱃지 데이터가 포함되어 있다.") + @DisplayName("랭킹 조회 API에는 사용자 대표 배지 데이터가 포함되어 있다.") void getRankTop100_6() throws Exception { // given ZSetOperations zSetOperations = redisTemplate.opsForZSet(); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java index 47e2478..504a291 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java @@ -148,7 +148,7 @@ void getRankTop100ByLandmark_4() { } @Test - @DisplayName("랜드마크 랭킹 조회 결과에는 사용자 프로필 뱃지 데이터가 포함되어 있다.") + @DisplayName("랜드마크 랭킹 조회 결과에는 사용자 프로필 배지 데이터가 포함되어 있다.") void getRankTop100ByLandmark_5() { // given LocalDate now = LocalDate.of(2024, 7, 1); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java index 186049a..1ef0ee3 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java @@ -193,7 +193,7 @@ void getRankTop100_5() { } @Test - @DisplayName("전체 랭킹 조회 결과에는 사용자 프로필 뱃지 데이터가 포함되어 있다.") + @DisplayName("전체 랭킹 조회 결과에는 사용자 프로필 배지 데이터가 포함되어 있다.") void getRankTop100_6() { // given User user1 = TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java index 5b65e96..aa07143 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java @@ -50,12 +50,12 @@ void clean() { } @Nested - @DisplayName("뱃지 수동 등록") + @DisplayName("배지 수동 등록") class saveManualBadge { @Test @WithMockCustomUser(role = Role.ROLE_ADMIN) - @DisplayName("정상 뱃지 수동 등록 : 개인 메시지 저장 안함") + @DisplayName("정상 배지 수동 등록 : 개인 메시지 저장 안함") void success_1() throws Exception { // given User user = TestUtil.createUser("aa@konkuk.ac.kr", "newNickname", Major.건축학부); @@ -82,7 +82,7 @@ void success_1() throws Exception { @Test @WithMockCustomUser(role = Role.ROLE_ADMIN) - @DisplayName("정상 뱃지 수동 등록 : 개인 메시지 저장") + @DisplayName("정상 배지 수동 등록 : 개인 메시지 저장") void success_2() throws Exception { // given User user = TestUtil.createUser("aa@konkuk.ac.kr", "test", Major.건축학부); @@ -113,7 +113,7 @@ void success_2() throws Exception { @Test @WithMockCustomUser(role = Role.ROLE_ADMIN) - @DisplayName("이미 가지고 있는 뱃지면 false를 반환한다") + @DisplayName("이미 가지고 있는 배지면 false를 반환한다") void fail_1() throws Exception { // given User user = TestUtil.createUser("aa@konkuk.ac.kr", "test", Major.건축학부); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java index 4950602..4fd5ec6 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApiTest.java @@ -155,11 +155,11 @@ void success_2() throws Exception { @Nested @WithMockCustomUser - @DisplayName("프로필 뱃지 설정") + @DisplayName("프로필 배지 설정") class setProfileBadge { @Test - @DisplayName("사용자가 가지고 있는 뱃지는 정상적으로 프로필 뱃지로 설정이 가능하다.") + @DisplayName("사용자가 가지고 있는 배지는 정상적으로 프로필 배지로 설정이 가능하다.") void success_1() throws Exception { // given User user = userRepository.findAll().get(0); diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileServiceTest.java index fffe51f..73dc1ef 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/application/UserProfileServiceTest.java @@ -110,7 +110,7 @@ void success_1() { } @Test - @DisplayName("뱃지 알림이 1개인 경우") + @DisplayName("배지 알림이 1개인 경우") void success_2() { // given User user = TestUtil.createUser(); @@ -127,7 +127,7 @@ void success_2() { } @Test - @DisplayName("뱃지 알림이 2개 이상인 경우") + @DisplayName("배지 알림이 2개 이상인 경우") void success_3() { // given User user = TestUtil.createUser(); @@ -147,11 +147,11 @@ void success_3() { } @Nested - @DisplayName("프로필 뱃지 설정") + @DisplayName("프로필 배지 설정") class setProfileBadge { @Test - @DisplayName("사용자가 가지고 있는 뱃지는 정상적으로 프로필 뱃지로 설정이 가능하다.") + @DisplayName("사용자가 가지고 있는 배지는 정상적으로 프로필 배지로 설정이 가능하다.") void success_1() { // given User user = TestUtil.createUser(); From 5b6c904d872a922f4842c13fc77ec7f4203f7e5d Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 30 Aug 2024 16:40:12 +0900 Subject: [PATCH 57/79] refactor: redis key properties --- .../score/application/TotalScoreService.java | 14 +-- .../application/NewMonthUpdateService.java | 5 +- .../user/application/UserDeleteService.java | 9 +- .../global/config/RedisConfig.java | 6 + .../adventure/api/AdventureApiTest.java | 4 +- .../application/AdventureServiceTest.java | 4 +- .../attendance/api/AttendanceApiTest.java | 4 +- .../score/api/ScoreTotalRankApiTest.java | 6 +- .../application/TotalScoreServiceTest.java | 6 +- .../learning/redis/RedisTest.java | 115 ++++++++---------- 10 files changed, 91 insertions(+), 82 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java index c130932..cf0d29c 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreService.java @@ -6,7 +6,8 @@ import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.domain.user.dto.EmailAndNicknameAndBadge; -import org.springframework.data.redis.core.RedisTemplate; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -17,18 +18,15 @@ import java.util.stream.Collectors; @Service +@RequiredArgsConstructor public class TotalScoreService { - private final String redisSetKey; + @Value("${redis-key}") + private String redisSetKey; + private final UserRepository userRepository; private final ZSetOperations zSetOperations; - public TotalScoreService(UserRepository userRepository, RedisTemplate redisTemplate) { - this.redisSetKey = "ranking"; - this.userRepository = userRepository; - this.zSetOperations = redisTemplate.opsForZSet(); - } - @Transactional public Long incrementTotalScore(User user, Long score) { zSetOperations.incrementScore(redisSetKey, user.getEmail(), score); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/NewMonthUpdateService.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/NewMonthUpdateService.java index 9c34b33..aecfdb2 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/NewMonthUpdateService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/NewMonthUpdateService.java @@ -9,6 +9,7 @@ import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.domain.user.exception.UserNotFoundException; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; @@ -26,7 +27,9 @@ @RequiredArgsConstructor public class NewMonthUpdateService { - private final String redisSetKey = "ranking"; + @Value("${redis-key}") + private String redisSetKey; + private final RedisTemplate redisTemplate; private final UserRepository userRepository; private final BadgeRepository badgeRepository; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserDeleteService.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserDeleteService.java index 6d401a4..7805667 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserDeleteService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserDeleteService.java @@ -13,7 +13,7 @@ import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import lombok.RequiredArgsConstructor; -import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,8 +34,10 @@ public class UserDeleteService { private final AttendanceRepository attendanceRepository; private final RefreshTokenRepository refreshTokenRepository; - private final String redisSetKey = "ranking"; - private final RedisTemplate redisTemplate; + @Value("${redis-key}") + private String redisSetKey; + private final ZSetOperations zSetOperations; + private final DateTimeService dateTimeService; @Transactional @@ -52,7 +54,6 @@ public void deleteUser(User user) { } private void deleteTotalScoreRank(User user) { - ZSetOperations zSetOperations = redisTemplate.opsForZSet(); zSetOperations.remove(redisSetKey, user.getEmail()); } diff --git a/src/main/java/com/playkuround/playkuroundserver/global/config/RedisConfig.java b/src/main/java/com/playkuround/playkuroundserver/global/config/RedisConfig.java index a9d3377..d054655 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/config/RedisConfig.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/config/RedisConfig.java @@ -6,6 +6,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ZSetOperations; import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; import org.springframework.data.redis.serializer.StringRedisSerializer; @@ -32,4 +33,9 @@ public RedisTemplate redisTemplate() { redisTemplate.setValueSerializer(new StringRedisSerializer()); return redisTemplate; } + + @Bean + public ZSetOperations redisZSet() { + return redisTemplate().opsForZSet(); + } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java index 7437193..d1f52c8 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApiTest.java @@ -19,6 +19,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; @@ -57,7 +58,8 @@ class AdventureApiTest { @Autowired private LandmarkRepository landmarkRepository; - private final String redisSetKey = "ranking"; + @Value("${redis-key}") + private String redisSetKey; @AfterEach void clean() { diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java index dc28cdc..034539d 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureServiceTest.java @@ -20,6 +20,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import java.util.List; @@ -48,7 +49,8 @@ class AdventureServiceTest { @Autowired private AdventureService adventureService; - private final String redisSetKey = "ranking"; + @Value("${redis-key}") + private String redisSetKey; @AfterEach void clean() { diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java index 76e6d63..62a5ab1 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java @@ -20,6 +20,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; @@ -66,7 +67,8 @@ class AttendanceApiTest { @Autowired private RedisTemplate redisTemplate; - private final String redisSetKey = "ranking"; + @Value("${redis-key}") + private String redisSetKey; @AfterEach void clean() { diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java index 9765692..0dedaff 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/ScoreTotalRankApiTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.test.web.servlet.MockMvc; @@ -38,12 +39,13 @@ class ScoreTotalRankApiTest { @Autowired private RedisTemplate redisTemplate; - private final String redisSetKey = "ranking"; + @Value("${redis-key}") + private String redisSetKey; @AfterEach void clean() { userRepository.deleteAllInBatch(); - redisTemplate.delete("ranking"); + redisTemplate.delete(redisSetKey); } @Test diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java index 1ef0ee3..76e501d 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/TotalScoreServiceTest.java @@ -11,6 +11,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.ActiveProfiles; @@ -37,9 +38,12 @@ class TotalScoreServiceTest { @Autowired private AdventureRepository adventureRepository; + @Value("${redis-key}") + private String redisSetKey; + @AfterEach void tearDown() { - redisTemplate.delete("ranking"); + redisTemplate.delete(redisSetKey); adventureRepository.deleteAllInBatch(); userRepository.deleteAllInBatch(); } diff --git a/src/test/java/com/playkuround/playkuroundserver/learning/redis/RedisTest.java b/src/test/java/com/playkuround/playkuroundserver/learning/redis/RedisTest.java index 7e1a967..8d9367e 100644 --- a/src/test/java/com/playkuround/playkuroundserver/learning/redis/RedisTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/learning/redis/RedisTest.java @@ -20,25 +20,26 @@ @Disabled @DisplayName("Redis ZSet 테스트") @SpringBootTest(properties = "spring.profiles.active=test") -public class RedisTest { +class RedisTest { @Autowired private RedisTemplate redisTemplate; + final String redisKey = "testKey"; + @AfterEach void tearDown() { - redisTemplate.delete("ranking"); + redisTemplate.delete(redisKey); } @Test void 점수_오름차순_정렬() { ZSetOperations zSetOperations = redisTemplate.opsForZSet(); - final String key = "ranking"; - zSetOperations.add(key, "a", 1); - zSetOperations.add(key, "c", 2); - zSetOperations.add(key, "b", 3); + zSetOperations.add(redisKey, "a", 1); + zSetOperations.add(redisKey, "c", 2); + zSetOperations.add(redisKey, "b", 3); - Set> typedTuples = zSetOperations.reverseRangeWithScores(key, 0, 9); + Set> typedTuples = zSetOperations.reverseRangeWithScores(redisKey, 0, 9); int i = 1; for (ZSetOperations.TypedTuple typedTuple : typedTuples) { String value = typedTuple.getValue(); @@ -64,13 +65,13 @@ void tearDown() { @Test void 점수_증가시키기() { ZSetOperations zSetOperations = redisTemplate.opsForZSet(); - final String key = "ranking"; - zSetOperations.add(key, "a", 1); - zSetOperations.add(key, "c", 2); - zSetOperations.add(key, "b", 3); - zSetOperations.incrementScore(key, "a", 10); - Set> typedTuples = zSetOperations.reverseRangeWithScores(key, 0, 9); + zSetOperations.add(redisKey, "a", 1); + zSetOperations.add(redisKey, "c", 2); + zSetOperations.add(redisKey, "b", 3); + zSetOperations.incrementScore(redisKey, "a", 10); + + Set> typedTuples = zSetOperations.reverseRangeWithScores(redisKey, 0, 9); int i = 1; for (ZSetOperations.TypedTuple typedTuple : typedTuples) { String value = typedTuple.getValue(); @@ -96,9 +97,9 @@ void tearDown() { @Test void value가_존재하지_않을때도_increment_수행하면_score가_0에서_증가() { ZSetOperations zSetOperations = redisTemplate.opsForZSet(); - final String key = "ranking"; - zSetOperations.incrementScore(key, "a", 10); - Set> typedTuples = zSetOperations.reverseRangeWithScores(key, 0, 9); + zSetOperations.incrementScore(redisKey, "a", 10); + + Set> typedTuples = zSetOperations.reverseRangeWithScores(redisKey, 0, 9); for (ZSetOperations.TypedTuple typedTuple : typedTuples) { String value = typedTuple.getValue(); Double score = typedTuple.getScore(); @@ -111,13 +112,12 @@ void tearDown() { @Test void 이미_존재하는_value를_add하면_덮어써진다() { ZSetOperations zSetOperations = redisTemplate.opsForZSet(); - final String key = "ranking"; - zSetOperations.add(key, "a", 1); - zSetOperations.add(key, "c", 2); - zSetOperations.add(key, "b", 3); + zSetOperations.add(redisKey, "a", 1); + zSetOperations.add(redisKey, "c", 2); + zSetOperations.add(redisKey, "b", 3); + zSetOperations.add(redisKey, "a", 10); - zSetOperations.add(key, "a", 10); - Set> typedTuples = zSetOperations.reverseRangeWithScores(key, 0, 9); + Set> typedTuples = zSetOperations.reverseRangeWithScores(redisKey, 0, 9); int i = 1; for (ZSetOperations.TypedTuple typedTuple : typedTuples) { String value = typedTuple.getValue(); @@ -143,12 +143,11 @@ void tearDown() { @Test void 동점자가_존재하면_value_순으로_정렬된다() { ZSetOperations zSetOperations = redisTemplate.opsForZSet(); - final String key = "ranking"; - zSetOperations.add(key, "a", 1); - zSetOperations.add(key, "c", 1); - zSetOperations.add(key, "b", 1); + zSetOperations.add(redisKey, "a", 1); + zSetOperations.add(redisKey, "c", 1); + zSetOperations.add(redisKey, "b", 1); - Set> typedTuples = zSetOperations.reverseRangeWithScores(key, 0, 9); + Set> typedTuples = zSetOperations.reverseRangeWithScores(redisKey, 0, 9); int i = 1; for (ZSetOperations.TypedTuple typedTuple : typedTuples) { String value = typedTuple.getValue(); @@ -174,19 +173,18 @@ void tearDown() { @Test void 내_등수_얻기() { ZSetOperations zSetOperations = redisTemplate.opsForZSet(); - final String key = "ranking"; - zSetOperations.add(key, "a", 1); - zSetOperations.add(key, "c", 3); - zSetOperations.add(key, "me", 2); - zSetOperations.add(key, "b", 4); + zSetOperations.add(redisKey, "a", 1); + zSetOperations.add(redisKey, "c", 3); + zSetOperations.add(redisKey, "me", 2); + zSetOperations.add(redisKey, "b", 4); - Double myTotalScore = zSetOperations.score(key, "me"); + Double myTotalScore = zSetOperations.score(redisKey, "me"); assertThat(myTotalScore).isEqualTo(2.0); - Set values = zSetOperations.reverseRangeByScore(key, myTotalScore, myTotalScore, 0, 1); + Set values = zSetOperations.reverseRangeByScore(redisKey, myTotalScore, myTotalScore, 0, 1); assertThat(values.size()).isEqualTo(1); for (String value : values) { - Long myRank = zSetOperations.reverseRank(key, value); + Long myRank = zSetOperations.reverseRank(redisKey, value); assertThat(myRank).isEqualTo(2L); // 3등 System.out.println("나의 등수는 " + myRank + 1 + "입니다."); } @@ -195,19 +193,18 @@ void tearDown() { @Test void 동점자가_존재할_때_내_등수() { ZSetOperations zSetOperations = redisTemplate.opsForZSet(); - final String key = "ranking"; - zSetOperations.add(key, "z", 1); - zSetOperations.add(key, "c", 3); - zSetOperations.add(key, "me", 1); - zSetOperations.add(key, "b", 4); + zSetOperations.add(redisKey, "z", 1); + zSetOperations.add(redisKey, "c", 3); + zSetOperations.add(redisKey, "me", 1); + zSetOperations.add(redisKey, "b", 4); - Double myTotalScore = zSetOperations.score(key, "me"); + Double myTotalScore = zSetOperations.score(redisKey, "me"); assertThat(myTotalScore).isEqualTo(1.0); - Set values = zSetOperations.reverseRangeByScore(key, myTotalScore, myTotalScore, 0, 1); + Set values = zSetOperations.reverseRangeByScore(redisKey, myTotalScore, myTotalScore, 0, 1); assertThat(values.size()).isEqualTo(1); // 정렬 기준이 높은 사람만 1명 나온다. for (String value : values) { - Long myRank = zSetOperations.reverseRank(key, value); + Long myRank = zSetOperations.reverseRank(redisKey, value); assertThat(value).isEqualTo("z"); assertThat(myRank).isEqualTo(2L); // 3등 System.out.println("나의 등수는 " + (myRank + 1) + "입니다."); @@ -217,13 +214,12 @@ void tearDown() { @Test void 여러명_존재할_때_테스트() { ZSetOperations zSetOperations = redisTemplate.opsForZSet(); - final String key = "ranking"; + Random random = new Random(); List> list = new ArrayList<>(); for (int i = 1; i <= 100; i++) { - int randomInt = random.nextInt(50); - double score = (double) randomInt; - zSetOperations.add(key, "user" + i, score); + double score = random.nextInt(50); + zSetOperations.add(redisKey, "user" + i, score); list.add(Pair.of("user" + i, score)); } @@ -234,16 +230,10 @@ void tearDown() { list.forEach(System.out::println); // 전체 랭킹 - Set> typedTuples = zSetOperations.reverseRangeWithScores(key, 0, 99); - int i = 0; - assertThat(typedTuples.size()).isEqualTo(100); - for (ZSetOperations.TypedTuple typedTuple : typedTuples) { - String value = typedTuple.getValue(); - Double score = typedTuple.getScore(); - assertThat(value).isEqualTo(list.get(i).getFirst()); - assertThat(score).isEqualTo(list.get(i).getSecond()); - i++; - } + Set> typedTuples = zSetOperations.reverseRangeWithScores(redisKey, 0, 99); + assertThat(typedTuples).hasSize(100) + .map(v -> Pair.of(v.getValue(), v.getScore())) + .containsExactlyElementsOf(list); // 특정 유저의 등수 for (int j = 1; j <= 50; j++) { @@ -265,12 +255,12 @@ void tearDown() { } System.out.println("해당 점수를 가진 유저 수: " + duplicateCount + "명, 최우선순위(value내림차순): " + firstUser); - Double myScore = zSetOperations.score(key, user); - Set values = zSetOperations.reverseRangeByScore(key, myScore, myScore, 0, 1); + Double myScore = zSetOperations.score(redisKey, user); + Set values = zSetOperations.reverseRangeByScore(redisKey, myScore, myScore, 0, 1); assertThat(myScore).isEqualTo(myRealScore); - assertThat(values.size()).isEqualTo(1); + assertThat(values).hasSize(1); for (String value : values) { - Long myRank = zSetOperations.reverseRank(key, value); + Long myRank = zSetOperations.reverseRank(redisKey, value); assertThat(value).isEqualTo(firstUser); assertThat(myRank).isEqualTo(myRealRank); } @@ -280,8 +270,7 @@ void tearDown() { @Test void 저장안된_value이면_null이_반환된다() { ZSetOperations zSetOperations = redisTemplate.opsForZSet(); - final String key = "ranking"; - Double myScore = zSetOperations.score(key, "notSavedUser"); + Double myScore = zSetOperations.score(redisKey, "notSavedUser"); assertThat(myScore).isNull(); } } From d5c02444ec7c18ab04d118f987b7b3684cdf355f Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 30 Aug 2024 16:52:05 +0900 Subject: [PATCH 58/79] correction swagger description --- .../domain/adventure/api/AdventureApi.java | 2 +- .../domain/appversion/api/AppVersionApi.java | 4 +--- .../playkuroundserver/domain/badge/api/BadgeApi.java | 2 +- .../playkuroundserver/domain/event/api/EventController.java | 6 ++---- .../playkuroundserver/domain/landmark/api/LandmarkApi.java | 2 +- .../playkuroundserver/domain/score/api/ScoreApi.java | 2 +- .../domain/systemcheck/api/SystemCheckApi.java | 6 ++---- .../domain/user/api/UserManagementApi.java | 2 +- .../playkuroundserver/domain/user/api/UserProfileApi.java | 2 +- 9 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java index b9a0469..0c20432 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java @@ -22,7 +22,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("/api/adventures") -@Tag(name = "Adventure", description = "Adventure API") +@Tag(name = "Adventure", description = "탐험하기 API") public class AdventureApi { private final AdventureService adventureService; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java index 691166e..5ed91ca 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java @@ -7,7 +7,6 @@ import com.playkuround.playkuroundserver.global.common.response.ApiResponse; import com.playkuround.playkuroundserver.global.util.ApiUtils; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; @@ -21,13 +20,12 @@ @RestController @RequestMapping("/api/admin/app-version") @RequiredArgsConstructor -@Tag(name = "APP Version") public class AppVersionApi { private final AppVersionService appVersionService; @PostMapping - @Operation(summary = "지원하는 앱 버전 업데이트", description = "지원하는 앱 버전 업데이트합니다.(덮어쓰기)") + @Operation(summary = "지원하는 앱 버전 업데이트", description = "지원하는 앱 버전 업데이트합니다.(덮어쓰기)", tags = "Admin") public ApiResponse updateAppVersion(@RequestBody @Valid UpdateAppVersionRequest request) { Set requestSet = request.getOsAndVersions().stream() .map(osAndVersion -> { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java index 80fbfe8..02db454 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java @@ -18,7 +18,7 @@ @RestController @RequestMapping("/api/badges") @RequiredArgsConstructor -@Tag(name = "Badge", description = "Badge API") +@Tag(name = "Badge", description = "배지 API") public class BadgeApi { private final BadgeService badgeService; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java index 4952740..377a800 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/event/api/EventController.java @@ -8,7 +8,6 @@ import com.playkuround.playkuroundserver.global.common.response.ApiResponse; import com.playkuround.playkuroundserver.global.util.ApiUtils; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; @@ -18,13 +17,12 @@ @RestController @RequestMapping("api") @RequiredArgsConstructor -@Tag(name = "Event", description = "이벤트 API") public class EventController { private final EventService eventService; @GetMapping("events") - @Operation(summary = "이벤트 조회하기", description = "화면에 노출이 필요한 이벤트를 반환합니다.") + @Operation(summary = "이벤트 조회하기", description = "화면에 노출이 필요한 이벤트를 반환합니다.", tags = "Event") public ApiResponse> findDisplayEvents() { List events = eventService.findEvents(true); return ApiUtils.success(events.stream() @@ -34,7 +32,7 @@ public ApiResponse> findDisplayEvents() { @PostMapping("admin/events") @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "이벤트 저장하기(ADMIN)", description = "이벤트를 저장합니다.") + @Operation(summary = "이벤트 저장하기", description = "이벤트를 저장합니다.", tags = "Admin") public ApiResponse saveEvent(@RequestBody EventSaveRequest request) { EventSaveDto eventSaveDto = new EventSaveDto(request.getTitle(), request.getImageUrl(), request.getDescription(), request.getReferenceUrl(), request.isDisplay()); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java index a718b17..55649ff 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java @@ -21,7 +21,7 @@ @RestController @RequestMapping("/api/landmarks") @RequiredArgsConstructor -@Tag(name = "Landmark", description = "Landmark API") +@Tag(name = "Landmark", description = "랜드마크 API") public class LandmarkApi { private final LandmarkScoreService landmarkScoreService; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java index 6ac8712..589a5bf 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java @@ -18,7 +18,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("/api/scores") -@Tag(name = "Score", description = "Score API") +@Tag(name = "Score", description = "랭킹 API") public class ScoreApi { private final TotalScoreService totalScoreService; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java index 002c556..9f9aa82 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java @@ -6,27 +6,25 @@ import com.playkuround.playkuroundserver.global.common.response.ApiResponse; import com.playkuround.playkuroundserver.global.util.ApiUtils; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("api") @RequiredArgsConstructor -@Tag(name = "System Check", description = "Client APP에서는 호출할 필요가 없습니다.") public class SystemCheckApi { private final SystemCheckService systemCheckService; @PostMapping("/admin/system-available") - @Operation(summary = "시스템 사용가능 여부 변경하기", description = "시스템 점검 유무를 변경합니다.") + @Operation(summary = "시스템 사용가능 여부 변경하기", description = "시스템 점검 유무를 변경합니다.", tags = "Admin") public ApiResponse changeSystemAvailable(@RequestParam("available") boolean appVersion) { systemCheckService.changeSystemAvailable(appVersion); return ApiUtils.success(null); } @GetMapping("/system-available") - @Operation(summary = "시스템 사용가능 여부 체크", description = "현재 서버의 상태를 점검합니다.") + @Operation(summary = "시스템 사용가능 여부 체크", description = "현재 서버의 상태를 점검합니다.", tags = "System Check") public ApiResponse healthCheck() { HealthCheckDto healthCheckDto = systemCheckService.healthCheck(); HealthCheckResponse response = new HealthCheckResponse(healthCheckDto.systemAvailable(), healthCheckDto.supportAppVersionList()); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java index 07de7e0..28a9adf 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java @@ -23,7 +23,7 @@ @RestController @RequestMapping("/api/users") @RequiredArgsConstructor -@Tag(name = "User", description = "User API") +@Tag(name = "User", description = "유저 API") public class UserManagementApi { private final TokenService tokenService; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java index ec716f1..b7b2822 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java @@ -29,7 +29,7 @@ @RestController @RequestMapping("/api/users") @RequiredArgsConstructor -@Tag(name = "User", description = "User API") +@Tag(name = "User") public class UserProfileApi { private final UserProfileService userProfileService; From ba87bec08edb529d382988e0da4466d028d871f9 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 30 Aug 2024 16:56:12 +0900 Subject: [PATCH 59/79] refactor: mapping URL --- .../domain/adventure/api/AdventureApi.java | 2 +- .../domain/appversion/api/AppVersionApi.java | 2 +- .../domain/attendance/api/AttendanceApi.java | 2 +- .../domain/auth/email/api/AuthEmailApi.java | 3 +-- .../domain/auth/token/api/TokenApi.java | 2 +- .../playkuroundserver/domain/badge/api/BadgeApi.java | 4 ++-- .../domain/fakedoor/api/FakeDoorApi.java | 2 +- .../domain/landmark/api/LandmarkApi.java | 4 ++-- .../score/api/{ScoreApi.java => ScoreRankApi.java} | 8 ++++---- .../domain/systemcheck/api/SystemCheckApi.java | 4 ++-- .../playkuroundserver/domain/user/api/AdminApi.java | 2 +- .../domain/user/api/UserManagementApi.java | 6 +++--- .../domain/user/api/UserProfileApi.java | 10 +++++----- 13 files changed, 25 insertions(+), 26 deletions(-) rename src/main/java/com/playkuround/playkuroundserver/domain/score/api/{ScoreApi.java => ScoreRankApi.java} (95%) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java index 0c20432..c71572f 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java @@ -21,7 +21,7 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/api/adventures") +@RequestMapping("api/adventures") @Tag(name = "Adventure", description = "탐험하기 API") public class AdventureApi { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java index 5ed91ca..eeba74b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java @@ -18,7 +18,7 @@ import java.util.stream.Collectors; @RestController -@RequestMapping("/api/admin/app-version") +@RequestMapping("api/admin/app-version") @RequiredArgsConstructor public class AppVersionApi { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java index 6531d85..57deed1 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java @@ -22,7 +22,7 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/api/attendances") +@RequestMapping("api/attendances") @Tag(name = "Attendance", description = "출석 관련 API") public class AttendanceApi { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java index 3dff7b3..6c60564 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java @@ -5,7 +5,6 @@ import com.playkuround.playkuroundserver.domain.auth.email.api.response.AuthVerifyEmailResponse; import com.playkuround.playkuroundserver.domain.auth.email.application.AuthEmailSendService; import com.playkuround.playkuroundserver.domain.auth.email.application.AuthEmailVerifyService; -import com.playkuround.playkuroundserver.domain.auth.email.application.AuthEmailVerifyServiceImpl; import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthEmailInfo; import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthVerifyEmailResult; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; @@ -18,7 +17,7 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/api/auth/emails") +@RequestMapping("api/auth/emails") @Tag(name = "Auth", description = "인증, 토큰 서비스") public class AuthEmailApi { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/api/TokenApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/api/TokenApi.java index cfbc6a4..61bddce 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/api/TokenApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/api/TokenApi.java @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/api/auth") +@RequestMapping("api/auth") @RequiredArgsConstructor @Tag(name = "Auth", description = "인증, 토큰 서비스") public class TokenApi { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java index 02db454..9f4c7f2 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/api/BadgeApi.java @@ -16,7 +16,7 @@ import java.util.List; @RestController -@RequestMapping("/api/badges") +@RequestMapping("api/badges") @RequiredArgsConstructor @Tag(name = "Badge", description = "배지 API") public class BadgeApi { @@ -32,7 +32,7 @@ public ApiResponse> findBadge(@AuthenticationPrincipal U .toList()); } - @PostMapping("/dream-of-duck") + @PostMapping("dream-of-duck") @ResponseStatus(HttpStatus.CREATED) @Operation(summary = "오리의꿈 배지 획득", description = "오리의 꿈 배지를 획득합니다. 이미 획득한 배지였다면 false를 반환합니다.") public ApiResponse saveTheDreamOfDuckBadge(@AuthenticationPrincipal UserDetailsImpl userDetails) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/fakedoor/api/FakeDoorApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/fakedoor/api/FakeDoorApi.java index 520ffeb..50812cd 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/fakedoor/api/FakeDoorApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/fakedoor/api/FakeDoorApi.java @@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/api/fake-door") +@RequestMapping("api/fake-door") @RequiredArgsConstructor @Tag(name = "fakeDoor API", description = "광고보고 쿠라운드 응원하기 버튼 클릭 API") public class FakeDoorApi { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java index 55649ff..61989a6 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/LandmarkApi.java @@ -19,7 +19,7 @@ import java.util.Optional; @RestController -@RequestMapping("/api/landmarks") +@RequestMapping("api/landmarks") @RequiredArgsConstructor @Tag(name = "Landmark", description = "랜드마크 API") public class LandmarkApi { @@ -38,7 +38,7 @@ public ApiResponse findNearestLandmark(@RequestParam @L return ApiUtils.success(NearestLandmarkResponse.from(nearestLandmark)); } - @GetMapping("/{landmarkId}/highest") + @GetMapping("{landmarkId}/highest") @Operation(summary = "해당 랜드마크의 최고점 사용자 찾기", description = "해당 랜드마크에서 가장 높은 점수를 획득한 사용자를 반환합니다. " + "방문한 유저가 한명도 없으면 아무것도 반환하지 않습니다. 점수가 같은 유저가 있다면 먼저 해당 점수를 달성한 유저를 반환합니다.") diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreRankApi.java similarity index 95% rename from src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java rename to src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreRankApi.java index 589a5bf..67077d6 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/ScoreRankApi.java @@ -17,14 +17,14 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/api/scores") +@RequestMapping("api/scores/rank") @Tag(name = "Score", description = "랭킹 API") -public class ScoreApi { +public class ScoreRankApi { private final TotalScoreService totalScoreService; private final LandmarkRankService landmarkRankService; - @GetMapping("/rank") + @GetMapping @Operation(summary = "종합 점수 탑100 얻기", description = "토탈 점수 탑100과 내 점수, 등수를 반환합니다. 내 점수가 0점이면 등수는 0등으로 반환됩니다.") public ApiResponse getScoreTop100(@AuthenticationPrincipal UserDetailsImpl userDetails) { @@ -32,7 +32,7 @@ public ApiResponse getScoreTop100(@AuthenticationPrincipal return ApiUtils.success(response); } - @GetMapping("/rank/{landmarkId}") + @GetMapping("{landmarkId}") @Operation(summary = "해당 랜드마크의 점수 탑100 얻기", description = "해당 랜드마크 점수 탑100과 내 점수, 등수를 반환합니다. 내 점수가 0점이면 등수는 0등으로 반환됩니다.") public ApiResponse getScoreTop100ByLandmark(@AuthenticationPrincipal UserDetailsImpl userDetails, diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java index 9f9aa82..f8ccf1d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/api/SystemCheckApi.java @@ -16,14 +16,14 @@ public class SystemCheckApi { private final SystemCheckService systemCheckService; - @PostMapping("/admin/system-available") + @PostMapping("admin/system-available") @Operation(summary = "시스템 사용가능 여부 변경하기", description = "시스템 점검 유무를 변경합니다.", tags = "Admin") public ApiResponse changeSystemAvailable(@RequestParam("available") boolean appVersion) { systemCheckService.changeSystemAvailable(appVersion); return ApiUtils.success(null); } - @GetMapping("/system-available") + @GetMapping("system-available") @Operation(summary = "시스템 사용가능 여부 체크", description = "현재 서버의 상태를 점검합니다.", tags = "System Check") public ApiResponse healthCheck() { HealthCheckDto healthCheckDto = systemCheckService.healthCheck(); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java index 90d3b2f..e22a5d6 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java @@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping("/api/admin") +@RequestMapping("api/admin") @RequiredArgsConstructor @Tag(name = "Admin", description = "Admin API(관리자 권한이 없는 경우 403 에러가 발생합니다.)") public class AdminApi { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java index 28a9adf..4f6bd4b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java @@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.*; @RestController -@RequestMapping("/api/users") +@RequestMapping("api/users") @RequiredArgsConstructor @Tag(name = "User", description = "유저 API") public class UserManagementApi { @@ -31,7 +31,7 @@ public class UserManagementApi { private final UserRegisterService userRegisterService; private final UserDeleteService userDeleteService; - @PostMapping("/register") + @PostMapping("register") @ResponseStatus(value = HttpStatus.CREATED) @Operation(summary = "회원가입", description = "신규 회원가입 합니다.") public ApiResponse registerUser(@RequestBody @Valid UserRegisterRequest request) { @@ -45,7 +45,7 @@ public ApiResponse registerUser(@RequestBody @Valid UserRe return ApiUtils.success(UserRegisterResponse.from(tokenDto)); } - @PostMapping("/logout") + @PostMapping("logout") @Operation(summary = "로그아웃", description = "서버에서 refresh token을 삭제합니다. 앱 내에서 accessToken을 지워야합니다.") public ApiResponse userLogout(@AuthenticationPrincipal UserDetailsImpl userDetails) { userLogoutService.logout(userDetails.getUser()); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java index b7b2822..2e56442 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java @@ -27,7 +27,7 @@ import java.util.List; @RestController -@RequestMapping("/api/users") +@RequestMapping("api/users") @RequiredArgsConstructor @Tag(name = "User") public class UserProfileApi { @@ -42,21 +42,21 @@ public ApiResponse getUserProfile(@AuthenticationPrincipal return ApiUtils.success(UserProfileResponse.from(userDetails.getUser())); } - @GetMapping("/game-score") + @GetMapping("game-score") @Operation(summary = "게임별 최고 점수 얻기", description = "로그인 유저의 게임별 최고 점수를 얻습니다. 플레이한적이 없는 게임은 null이 반환됩니다.") public ApiResponse getUserGameHighestScore(@AuthenticationPrincipal UserDetailsImpl userDetails) { HighestScore userGameHighestScore = userProfileService.getUserGameHighestScore(userDetails.getUser()); return ApiUtils.success(UserGameHighestScoreResponse.from(userGameHighestScore)); } - @GetMapping("/availability") + @GetMapping("availability") @Operation(summary = "해당 닉네임이 사용 가능한지 체크", description = "사용 가능하다면 true가 반환됩니다.") public ApiResponse isAvailableNickname(@RequestParam("nickname") String nickname) { boolean isAvailable = userProfileService.isAvailableNickname(nickname); return ApiUtils.success(isAvailable); } - @PostMapping("/profile-badge") + @PostMapping("profile-badge") @Operation(summary = "프로필 배지 설정", description = "사용자 프로필 배지를 설정합니다.") public ApiResponse setProfileBadge(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody @Valid ProfileBadgeRequest request) { @@ -67,7 +67,7 @@ public ApiResponse setProfileBadge(@AuthenticationPrincipal UserDetailsImp return ApiUtils.success(null); } - @GetMapping("/notification") + @GetMapping("notification") @Operation(summary = "유저 알림 얻기", description = "유저 개인 알림을 얻습니다. 저장된 메시지는 (정상적인) 호출 이후 삭제됩니다.
" + "=== name 명 리스트(new_badge는 description도 중요) ===
" + From ab47683b73e7f86d22d9f8edddd617ae4aae71df Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 30 Aug 2024 17:04:44 +0900 Subject: [PATCH 60/79] server application version up --- build.gradle | 2 +- .../global/config/SwaggerConfig.java | 26 +++++++++++-------- .../global/config/WebSecurityConfig.java | 14 ---------- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/build.gradle b/build.gradle index cc5eb10..1e414cc 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { } group = 'com.playkuround' -version = '2.0.6' +version = '2.0.7' java { sourceCompatibility = '17' diff --git a/src/main/java/com/playkuround/playkuroundserver/global/config/SwaggerConfig.java b/src/main/java/com/playkuround/playkuroundserver/global/config/SwaggerConfig.java index 9229894..bb8801f 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/config/SwaggerConfig.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/config/SwaggerConfig.java @@ -1,5 +1,6 @@ package com.playkuround.playkuroundserver.global.config; +import com.playkuround.playkuroundserver.domain.auth.token.domain.GrantType; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.models.Components; @@ -13,25 +14,28 @@ @OpenAPIDefinition( info = @Info( title = "playkuround API 명세서", - description = "playkuround에 사용되는 API 명세서", - version = "v2" + version = "v2.0.7" ) ) @Configuration public class SwaggerConfig { - private static final String BEARER_TOKEN_PREFIX = "Bearer"; - @Bean - @Profile("!Prod") + @Profile("!prod") public OpenAPI openAPI() { String jwtSchemeName = "Authorization"; - SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwtSchemeName); - Components components = new Components() - .addSecuritySchemes(jwtSchemeName, new SecurityScheme() - .name(jwtSchemeName) - .type(SecurityScheme.Type.HTTP) - .scheme(BEARER_TOKEN_PREFIX)); + + SecurityRequirement securityRequirement = new SecurityRequirement(); + securityRequirement.addList(jwtSchemeName); + + SecurityScheme securityScheme = new SecurityScheme(); + securityScheme.name(jwtSchemeName) + .type(SecurityScheme.Type.HTTP) + .scheme(GrantType.BEARER.getType()); + + Components components = new Components(); + components.addSecuritySchemes(jwtSchemeName, securityScheme); + return new OpenAPI() .addSecurityItem(securityRequirement) .components(components); diff --git a/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java b/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java index cd67535..bd2bd6c 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java @@ -62,19 +62,5 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .userDetailsService(userDetailsService) .build(); } -// -// @Bean -// public CorsConfigurationSource corsConfigurationSource() { -// CorsConfiguration configuration = new CorsConfiguration(); -// -// configuration.setAllowCredentials(true); -// configuration.setAllowedOriginPatterns(List.of("*")); -// configuration.setAllowedMethods(List.of("HEAD", "POST", "GET", "DELETE", "PUT")); -// configuration.setAllowedHeaders(List.of("*")); -// -// UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); -// source.registerCorsConfiguration("/**", configuration); -// return source; -// } } From ef24e9cfd7e6cbb1ab9b21c84c7c53891cc73869 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Fri, 30 Aug 2024 23:58:45 +0900 Subject: [PATCH 61/79] =?UTF-8?q?feat:=20Adventure=20entity=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../playkuroundserver/domain/adventure/domain/Adventure.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/domain/Adventure.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/domain/Adventure.java index 27e22f2..73b3cde 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/domain/Adventure.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/domain/Adventure.java @@ -8,8 +8,6 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; @Entity @Getter @@ -22,7 +20,6 @@ public class Adventure extends BaseTimeEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") - @OnDelete(action = OnDeleteAction.CASCADE) private User user; @ManyToOne(fetch = FetchType.LAZY) @@ -33,6 +30,7 @@ public class Adventure extends BaseTimeEntity { private Long score; @Column(nullable = false) + @Enumerated(EnumType.STRING) private ScoreType scoreType; public Adventure(User user, Landmark landmark, ScoreType scoreType, Long score) { From 81e322a4de384d0c6b7e7bb0f39b50ec3cd881ca Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sat, 31 Aug 2024 23:15:09 +0900 Subject: [PATCH 62/79] refactor: BadgeService --- .../adventure/dao/AdventureRepository.java | 2 +- .../badge/application/BadgeService.java | 113 ++++++++++++------ .../attendance_badge/AttendanceBadge.java | 5 +- .../attendance_badge/AttendanceBadgeList.java | 2 +- .../attendance_badge/Attendance_1.java | 10 +- .../attendance_badge/Attendance_10.java | 10 +- .../attendance_badge/Attendance_100.java | 10 +- .../attendance_badge/Attendance_30.java | 10 +- .../attendance_badge/Attendance_5.java | 10 +- .../college/AdministrationBadge.java | 4 +- .../college/ArchitectureBadge.java | 4 +- .../college/ArtAndDesignBadge.java | 7 +- .../college/BiologicalSciencesBadge.java | 4 +- .../application/college/EducationBadge.java | 4 +- .../application/college/EngineeringBadge.java | 4 +- .../college/InstituteTechnologyBadge.java | 4 +- .../college/InternationalBadge.java | 4 +- .../application/college/LiberalArtsBadge.java | 4 +- .../application/college/RealEstateBadge.java | 4 +- .../application/college/SangHuhBadge.java | 4 +- .../application/college/SciencesBadge.java | 4 +- .../college/SocialSciencesBadge.java | 4 +- .../college/VeterinaryMedicineBadge.java | 4 +- .../ArtAndDesignBadgeService.java | 42 ------- .../ArtAndDesignSpecialBadge.java | 42 +++++++ ...> BusinessAdministrationSpecialBadge.java} | 23 ++-- .../CollegeSpecialBadge.java | 27 +++++ .../CollegeSpecialBadgeFactory.java | 29 ----- .../CollegeSpecialBadgeService.java | 3 +- ...vice.java => EngineeringSpecialBadge.java} | 14 +-- .../specialday_badge/ArborDayBadge.java | 8 +- .../specialday_badge/ChildrenDayBadge.java | 8 +- .../specialday_badge/ChristmasDayBadge.java | 8 +- .../specialday_badge/ChuseokDayBadge.java | 8 +- .../specialday_badge/DokdoDayBadge.java | 8 +- .../specialday_badge/DuckDayBadge.java | 8 +- .../specialday_badge/FoundationDayBadge.java | 8 +- .../specialday_badge/KimchiDayBadge.java | 8 +- .../specialday_badge/KoreanDayBadge.java | 8 +- .../specialday_badge/SpecialDayBadge.java | 3 +- .../specialday_badge/WhiteDayBadge.java | 8 +- .../badge/dto/NewlyRegisteredBadge.java | 4 + .../domain/score/domain/ScoreType.java | 1 - .../global/config/WebSecurityConfig.java | 34 +++--- .../badge/application/BadgeServiceTest.java | 13 +- 45 files changed, 267 insertions(+), 279 deletions(-) delete mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/ArtAndDesignBadgeService.java create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/ArtAndDesignSpecialBadge.java rename src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/{BusinessAdministrationBadgeService.java => BusinessAdministrationSpecialBadge.java} (67%) create mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadge.java delete mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadgeFactory.java rename src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/{EngineeringBadgeService.java => EngineeringSpecialBadge.java} (73%) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java index 71a82f4..c8b0711 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java @@ -41,7 +41,7 @@ long getSumScoreByUserAndLandmarkAfter(@Param(value = "user") User user, @Param(value = "landmark") Landmark landmark, @Param(value = "from") LocalDateTime from); - long countByUserAndLandmark(User user, Landmark requestSaveLandmark); + long countByUserAndLandmark(User user, Landmark landmark); @Query("SELECT new com.playkuround.playkuroundserver.domain.adventure.dto.UserAndScore(a.user, cast(SUM(a.score) as long)) " + "FROM Adventure a " + diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java index 078e03c..44f0764 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java @@ -1,8 +1,11 @@ package com.playkuround.playkuroundserver.domain.badge.application; +import com.playkuround.playkuroundserver.domain.badge.application.attendance_badge.AttendanceBadge; import com.playkuround.playkuroundserver.domain.badge.application.attendance_badge.AttendanceBadgeList; +import com.playkuround.playkuroundserver.domain.badge.application.college.CollegeBadge; import com.playkuround.playkuroundserver.domain.badge.application.college.CollegeBadgeList; -import com.playkuround.playkuroundserver.domain.badge.application.college_special_badge.CollegeSpecialBadgeFactory; +import com.playkuround.playkuroundserver.domain.badge.application.college_special_badge.CollegeSpecialBadge; +import com.playkuround.playkuroundserver.domain.badge.application.specialday_badge.SpecialDayBadge; import com.playkuround.playkuroundserver.domain.badge.application.specialday_badge.SpecialDayBadgeList; import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; @@ -18,86 +21,121 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; +import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @Service +@Transactional @RequiredArgsConstructor public class BadgeService { private final UserRepository userRepository; private final BadgeRepository badgeRepository; private final DateTimeService dateTimeService; - private final CollegeSpecialBadgeFactory collegeSpecialBadgeFactory; + private final CollegeSpecialBadge collegeSpecialBadge; @Transactional(readOnly = true) public List findBadgeByEmail(User user) { return badgeRepository.findByUser(user); } - @Transactional + private Set getUserBadgeSet(User user) { + return badgeRepository.findByUser(user).stream() + .map(Badge::getBadgeType) + .collect(Collectors.toSet()); + } + public NewlyRegisteredBadge updateNewlyAttendanceBadges(User user) { + NewlyRegisteredBadge newlyRegisteredBadge = new NewlyRegisteredBadge(); + Set userBadgeSet = getUserBadgeSet(user); - NewlyRegisteredBadge newlyRegisteredBadge = new NewlyRegisteredBadge(); + List attendanceBadges = saveAttendanceBadges(user, userBadgeSet); + newlyRegisteredBadge.addBadges(attendanceBadges); + + List specialDayBadges = saveSpecialDayBadges(user, userBadgeSet); + newlyRegisteredBadge.addBadges(specialDayBadges); + + return newlyRegisteredBadge; + } + + private List saveAttendanceBadges(User user, Set userBadgeSet) { + List newBadges = new ArrayList<>(); - // 출석일 기준 배지 AttendanceBadgeList.getAttendanceBadges().stream() - .filter(attendanceBadge -> attendanceBadge.supports(userBadgeSet, user)) - .forEach(attendanceBadge -> { - BadgeType badgeType = attendanceBadge.getBadgeType(); + .filter(attendanceBadge -> attendanceBadge.supports(user.getAttendanceDays())) + .map(AttendanceBadge::getBadgeType) + .filter(badgeType -> !userBadgeSet.contains(badgeType)) + .forEach(badgeType -> { + newBadges.add(badgeType); badgeRepository.save(Badge.createBadge(user, badgeType)); - newlyRegisteredBadge.addBadge(badgeType); }); - // 기념일 기준 배지 + return newBadges; + } + + private List saveSpecialDayBadges(User user, Set userBadgeSet) { + List newBadges = new ArrayList<>(); + LocalDate now = dateTimeService.getLocalDateNow(); + SpecialDayBadgeList.getSpecialDayBadges().stream() - .filter(specialDayBadge -> specialDayBadge.supports(userBadgeSet, dateTimeService.getLocalDateNow())) - .forEach(specialDayBadge -> { - BadgeType badgeType = specialDayBadge.getBadgeType(); + .filter(specialDayBadge -> specialDayBadge.supports(now)) + .map(SpecialDayBadge::getBadgeType) + .filter(badgeType -> !userBadgeSet.contains(badgeType)) + .forEach(badgeType -> { + newBadges.add(badgeType); badgeRepository.save(Badge.createBadge(user, badgeType)); - newlyRegisteredBadge.addBadge(badgeType); }); - return newlyRegisteredBadge; + return newBadges; } - @Transactional public NewlyRegisteredBadge updateNewlyAdventureBadges(User user, Landmark requestSaveLandmark) { + NewlyRegisteredBadge newlyRegisteredBadge = new NewlyRegisteredBadge(); + Set userBadgeSet = getUserBadgeSet(user); - LandmarkType requestLandmarkType = requestSaveLandmark.getName(); - NewlyRegisteredBadge newlyRegisteredBadge = new NewlyRegisteredBadge(); + List collegeBadges = saveCollegeBadges(user, requestSaveLandmark.getName(), userBadgeSet); + newlyRegisteredBadge.addBadges(collegeBadges); + + List collegeSpecialBadges = saveCollegeSpecialBadges(user, requestSaveLandmark, userBadgeSet); + newlyRegisteredBadge.addBadges(collegeSpecialBadges); + + return newlyRegisteredBadge; + } + + private List saveCollegeBadges(User user, LandmarkType requestLandmarkType, Set userBadgeSet) { + List newBadges = new ArrayList<>(); - // 대학별 CollegeBadgeList.getCollegeBadges().stream() .filter(collegeBadge -> collegeBadge.supports(requestLandmarkType)) - .forEach(collegeBadge -> { - BadgeType badge = collegeBadge.getBadge(); - if (!userBadgeSet.contains(badge)) { - newlyRegisteredBadge.addBadge(badge); - badgeRepository.save(Badge.createBadge(user, badge)); - } - }); - - // 단과대 특별 배지 - collegeSpecialBadgeFactory.getBadgeType(user, userBadgeSet, requestSaveLandmark) - .ifPresent(badgeType -> { - newlyRegisteredBadge.addBadge(badgeType); + .map(CollegeBadge::getBadge) + .filter(badgeType -> !userBadgeSet.contains(badgeType)) + .forEach(badgeType -> { + newBadges.add(badgeType); badgeRepository.save(Badge.createBadge(user, badgeType)); }); - return newlyRegisteredBadge; + return newBadges; } - private Set getUserBadgeSet(User user) { - return badgeRepository.findByUser(user).stream() - .map(Badge::getBadgeType) - .collect(Collectors.toSet()); + private List saveCollegeSpecialBadges(User user, Landmark requestSaveLandmark, Set userBadgeSet) { + List newBadges = new ArrayList<>(); + + List candidates = collegeSpecialBadge.getBadgeTypes(user, requestSaveLandmark); + candidates.stream() + .filter(badgeType -> !userBadgeSet.contains(badgeType)) + .forEach(badgeType -> { + newBadges.add(badgeType); + badgeRepository.save(Badge.createBadge(user, badgeType)); + }); + + return newBadges; } - @Transactional public boolean saveTheDreamOfDuckBadge(User user) { if (badgeRepository.existsByUserAndBadgeType(user, BadgeType.THE_DREAM_OF_DUCK)) { return false; @@ -107,7 +145,6 @@ public boolean saveTheDreamOfDuckBadge(User user) { return true; } - @Transactional public boolean saveManualBadge(String userEmail, BadgeType badgeType, boolean registerMessage) { User user = userRepository.findByEmail(userEmail) .orElseThrow(UserNotFoundException::new); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/AttendanceBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/AttendanceBadge.java index db01fe9..cb4f441 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/AttendanceBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/AttendanceBadge.java @@ -1,13 +1,10 @@ package com.playkuround.playkuroundserver.domain.badge.application.attendance_badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.user.domain.User; - -import java.util.Set; public interface AttendanceBadge { - boolean supports(Set userBadgeSet, User user); + boolean supports(int attendanceDays); BadgeType getBadgeType(); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/AttendanceBadgeList.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/AttendanceBadgeList.java index abe5431..feaf38d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/AttendanceBadgeList.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/AttendanceBadgeList.java @@ -7,7 +7,7 @@ public class AttendanceBadgeList { @Getter - private final static List attendanceBadges = List.of( + private static final List attendanceBadges = List.of( new Attendance_1(), new Attendance_5(), new Attendance_10(), diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_1.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_1.java index 7a21cf8..d1269a8 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_1.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_1.java @@ -1,19 +1,15 @@ package com.playkuround.playkuroundserver.domain.badge.application.attendance_badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.user.domain.User; -import java.util.Set; - -public class Attendance_1 implements AttendanceBadge { +class Attendance_1 implements AttendanceBadge { Attendance_1() { } @Override - public boolean supports(Set userBadgeSet, User user) { - BadgeType badgeType = getBadgeType(); - return !userBadgeSet.contains(badgeType) && user.getAttendanceDays() >= 1; + public boolean supports(int attendanceDays) { + return attendanceDays >= 1; } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_10.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_10.java index 1e34750..1c6bf00 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_10.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_10.java @@ -1,19 +1,15 @@ package com.playkuround.playkuroundserver.domain.badge.application.attendance_badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.user.domain.User; -import java.util.Set; - -public class Attendance_10 implements AttendanceBadge { +class Attendance_10 implements AttendanceBadge { Attendance_10() { } @Override - public boolean supports(Set userBadgeSet, User user) { - BadgeType badgeType = getBadgeType(); - return !userBadgeSet.contains(badgeType) && user.getAttendanceDays() >= 10; + public boolean supports(int attendanceDays) { + return attendanceDays >= 10; } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_100.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_100.java index 787371f..48017ce 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_100.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_100.java @@ -1,19 +1,15 @@ package com.playkuround.playkuroundserver.domain.badge.application.attendance_badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.user.domain.User; -import java.util.Set; - -public class Attendance_100 implements AttendanceBadge { +class Attendance_100 implements AttendanceBadge { Attendance_100() { } @Override - public boolean supports(Set userBadgeSet, User user) { - BadgeType badgeType = getBadgeType(); - return !userBadgeSet.contains(badgeType) && user.getAttendanceDays() >= 100; + public boolean supports(int attendanceDays) { + return attendanceDays >= 100; } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_30.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_30.java index 2eb5ef0..4214dac 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_30.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_30.java @@ -1,19 +1,15 @@ package com.playkuround.playkuroundserver.domain.badge.application.attendance_badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.user.domain.User; -import java.util.Set; - -public class Attendance_30 implements AttendanceBadge { +class Attendance_30 implements AttendanceBadge { Attendance_30() { } @Override - public boolean supports(Set userBadgeSet, User user) { - BadgeType badgeType = getBadgeType(); - return !userBadgeSet.contains(badgeType) && user.getAttendanceDays() >= 30; + public boolean supports(int attendanceDays) { + return attendanceDays >= 30; } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_5.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_5.java index 4eca776..5ee6ef4 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_5.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/attendance_badge/Attendance_5.java @@ -1,19 +1,15 @@ package com.playkuround.playkuroundserver.domain.badge.application.attendance_badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.user.domain.User; -import java.util.Set; - -public class Attendance_5 implements AttendanceBadge { +class Attendance_5 implements AttendanceBadge { Attendance_5() { } @Override - public boolean supports(Set userBadgeSet, User user) { - BadgeType badgeType = getBadgeType(); - return !userBadgeSet.contains(badgeType) && user.getAttendanceDays() >= 5; + public boolean supports(int attendanceDays) { + return attendanceDays >= 5; } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/AdministrationBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/AdministrationBadge.java index cf67eee..1efb62b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/AdministrationBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/AdministrationBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class AdministrationBadge implements CollegeBadge { +class AdministrationBadge implements CollegeBadge { - protected AdministrationBadge() { + AdministrationBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/ArchitectureBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/ArchitectureBadge.java index 0a47986..888f5a3 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/ArchitectureBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/ArchitectureBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class ArchitectureBadge implements CollegeBadge { +class ArchitectureBadge implements CollegeBadge { - protected ArchitectureBadge() { + ArchitectureBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/ArtAndDesignBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/ArtAndDesignBadge.java index b7e2e0d..ac6253d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/ArtAndDesignBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/ArtAndDesignBadge.java @@ -3,15 +3,14 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class ArtAndDesignBadge implements CollegeBadge { +class ArtAndDesignBadge implements CollegeBadge { - protected ArtAndDesignBadge() { + ArtAndDesignBadge() { } @Override public boolean supports(LandmarkType landmarkType) { - return landmarkType == LandmarkType.예디대 || - landmarkType == LandmarkType.공예관; + return landmarkType == LandmarkType.예디대 || landmarkType == LandmarkType.공예관; } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/BiologicalSciencesBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/BiologicalSciencesBadge.java index 64ae39f..767b168 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/BiologicalSciencesBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/BiologicalSciencesBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class BiologicalSciencesBadge implements CollegeBadge { +class BiologicalSciencesBadge implements CollegeBadge { - protected BiologicalSciencesBadge() { + BiologicalSciencesBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/EducationBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/EducationBadge.java index cfb1af6..a643a7e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/EducationBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/EducationBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class EducationBadge implements CollegeBadge { +class EducationBadge implements CollegeBadge { - protected EducationBadge() { + EducationBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/EngineeringBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/EngineeringBadge.java index 1639f72..26b70b3 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/EngineeringBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/EngineeringBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class EngineeringBadge implements CollegeBadge { +class EngineeringBadge implements CollegeBadge { - protected EngineeringBadge() { + EngineeringBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InstituteTechnologyBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InstituteTechnologyBadge.java index fc2d845..63acf79 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InstituteTechnologyBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InstituteTechnologyBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class InstituteTechnologyBadge implements CollegeBadge { +class InstituteTechnologyBadge implements CollegeBadge { - protected InstituteTechnologyBadge() { + InstituteTechnologyBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InternationalBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InternationalBadge.java index 5da2c5a..e781b29 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InternationalBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/InternationalBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class InternationalBadge implements CollegeBadge { +class InternationalBadge implements CollegeBadge { - protected InternationalBadge() { + InternationalBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/LiberalArtsBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/LiberalArtsBadge.java index fbb41f7..995ae9b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/LiberalArtsBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/LiberalArtsBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class LiberalArtsBadge implements CollegeBadge { +class LiberalArtsBadge implements CollegeBadge { - protected LiberalArtsBadge() { + LiberalArtsBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/RealEstateBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/RealEstateBadge.java index e10a232..610f7a8 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/RealEstateBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/RealEstateBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class RealEstateBadge implements CollegeBadge { +class RealEstateBadge implements CollegeBadge { - protected RealEstateBadge() { + RealEstateBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SangHuhBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SangHuhBadge.java index a032dc3..4e5334e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SangHuhBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SangHuhBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class SangHuhBadge implements CollegeBadge { +class SangHuhBadge implements CollegeBadge { - protected SangHuhBadge() { + SangHuhBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SciencesBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SciencesBadge.java index d1f6383..577de0c 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SciencesBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SciencesBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class SciencesBadge implements CollegeBadge { +class SciencesBadge implements CollegeBadge { - protected SciencesBadge() { + SciencesBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SocialSciencesBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SocialSciencesBadge.java index cfb4453..688e676 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SocialSciencesBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/SocialSciencesBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class SocialSciencesBadge implements CollegeBadge { +class SocialSciencesBadge implements CollegeBadge { - protected SocialSciencesBadge() { + SocialSciencesBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/VeterinaryMedicineBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/VeterinaryMedicineBadge.java index 6ea19c1..ecd2399 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/VeterinaryMedicineBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college/VeterinaryMedicineBadge.java @@ -3,9 +3,9 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -public class VeterinaryMedicineBadge implements CollegeBadge { +class VeterinaryMedicineBadge implements CollegeBadge { - protected VeterinaryMedicineBadge() { + VeterinaryMedicineBadge() { } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/ArtAndDesignBadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/ArtAndDesignBadgeService.java deleted file mode 100644 index 4b9ef5f..0000000 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/ArtAndDesignBadgeService.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.playkuround.playkuroundserver.domain.badge.application.college_special_badge; - -import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; -import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; -import com.playkuround.playkuroundserver.domain.user.domain.User; -import org.springframework.stereotype.Component; - -import java.time.LocalTime; -import java.util.Optional; -import java.util.Set; - -@Component -class ArtAndDesignBadgeService implements CollegeSpecialBadgeService { - - @Override - public boolean supports(LandmarkType landmarkType) { - return LandmarkType.예디대.equals(landmarkType) || - LandmarkType.공예관.equals(landmarkType); - } - - @Override - public Optional getBadgeType(User user, Set userHadBadgeSet, Landmark landmark) { - LocalTime now = LocalTime.now(); - if (now.isAfter(LocalTime.of(9, 0)) && now.isBefore(LocalTime.of(12, 0))) { - if (!userHadBadgeSet.contains(BadgeType.COLLEGE_OF_ART_AND_DESIGN_BEFORE_NOON)) { - return Optional.of(BadgeType.COLLEGE_OF_ART_AND_DESIGN_BEFORE_NOON); - } - } - else if (now.isAfter(LocalTime.of(12, 0)) && now.isBefore(LocalTime.of(18, 0))) { - if (!userHadBadgeSet.contains(BadgeType.COLLEGE_OF_ART_AND_DESIGN_AFTER_NOON)) { - return Optional.of(BadgeType.COLLEGE_OF_ART_AND_DESIGN_AFTER_NOON); - } - } - else if (now.isAfter(LocalTime.of(23, 0)) || now.isBefore(LocalTime.of(4, 0))) { - if (!userHadBadgeSet.contains(BadgeType.COLLEGE_OF_ART_AND_DESIGN_NIGHT)) { - return Optional.of(BadgeType.COLLEGE_OF_ART_AND_DESIGN_NIGHT); - } - } - return Optional.empty(); - } -} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/ArtAndDesignSpecialBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/ArtAndDesignSpecialBadge.java new file mode 100644 index 0000000..dbeadbb --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/ArtAndDesignSpecialBadge.java @@ -0,0 +1,42 @@ +package com.playkuround.playkuroundserver.domain.badge.application.college_special_badge; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; +import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; +import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; +import com.playkuround.playkuroundserver.domain.user.domain.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.Optional; + +@Component +@RequiredArgsConstructor +class ArtAndDesignSpecialBadge implements CollegeSpecialBadgeService { + + private final DateTimeService dateTimeService; + + @Override + public boolean supports(LandmarkType landmarkType) { + return LandmarkType.예디대 == landmarkType || LandmarkType.공예관 == landmarkType; + } + + @Override + public Optional getBadgeType(User user, Landmark landmark) { + LocalDateTime nowDateTime = dateTimeService.getLocalDateTimeNow(); + LocalTime now = nowDateTime.toLocalTime(); + + if (now.isAfter(LocalTime.of(9, 0)) && now.isBefore(LocalTime.of(12, 0))) { + return Optional.of(BadgeType.COLLEGE_OF_ART_AND_DESIGN_BEFORE_NOON); + } + if (now.isAfter(LocalTime.of(12, 0)) && now.isBefore(LocalTime.of(18, 0))) { + return Optional.of(BadgeType.COLLEGE_OF_ART_AND_DESIGN_AFTER_NOON); + } + if (now.isAfter(LocalTime.of(23, 0)) || now.isBefore(LocalTime.of(4, 0))) { + return Optional.of(BadgeType.COLLEGE_OF_ART_AND_DESIGN_NIGHT); + } + return Optional.empty(); + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/BusinessAdministrationBadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/BusinessAdministrationSpecialBadge.java similarity index 67% rename from src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/BusinessAdministrationBadgeService.java rename to src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/BusinessAdministrationSpecialBadge.java index 1b4ee02..38754af 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/BusinessAdministrationBadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/BusinessAdministrationSpecialBadge.java @@ -10,11 +10,12 @@ import java.util.List; import java.util.Optional; -import java.util.Set; @Component @RequiredArgsConstructor -class BusinessAdministrationBadgeService implements CollegeSpecialBadgeService { +class BusinessAdministrationSpecialBadge implements CollegeSpecialBadgeService { + + private final AdventureRepository adventureRepository; private final List badgeAndRequiredCounts = List.of( new BadgeAndRequiredCount(BadgeType.COLLEGE_OF_BUSINESS_ADMINISTRATION_10, 10), @@ -23,22 +24,18 @@ class BusinessAdministrationBadgeService implements CollegeSpecialBadgeService { new BadgeAndRequiredCount(BadgeType.COLLEGE_OF_BUSINESS_ADMINISTRATION_70, 70) ); - private final AdventureRepository adventureRepository; - @Override public boolean supports(LandmarkType landmarkType) { - return LandmarkType.경영관.equals(landmarkType); + return LandmarkType.경영관 == landmarkType; } @Override - public Optional getBadgeType(User user, Set userHadBadgeSet, Landmark landmark) { - for (BadgeAndRequiredCount badgeAndRequiredCount : badgeAndRequiredCounts) { - if (!userHadBadgeSet.contains(badgeAndRequiredCount.badgeType) && - adventureRepository.countByUserAndLandmark(user, landmark) == badgeAndRequiredCount.requiredCount) { - return Optional.of(badgeAndRequiredCount.badgeType); - } - } - return Optional.empty(); + public Optional getBadgeType(User user, Landmark landmark) { + long visitedNumber = adventureRepository.countByUserAndLandmark(user, landmark); + return badgeAndRequiredCounts.stream() + .filter(badgeAndRequiredCount -> badgeAndRequiredCount.requiredCount == visitedNumber) + .findFirst() + .map(BadgeAndRequiredCount::badgeType); } private record BadgeAndRequiredCount(BadgeType badgeType, int requiredCount) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadge.java new file mode 100644 index 0000000..79a5e9e --- /dev/null +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadge.java @@ -0,0 +1,27 @@ +package com.playkuround.playkuroundserver.domain.badge.application.college_special_badge; + +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; +import com.playkuround.playkuroundserver.domain.user.domain.User; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Objects; + +@Component +public class CollegeSpecialBadge { + + private final List collegeSpecialBadgeServices; + + public CollegeSpecialBadge(List collegeSpecialBadgeServices) { + this.collegeSpecialBadgeServices = collegeSpecialBadgeServices; + } + + public List getBadgeTypes(User user, Landmark landmark) { + return collegeSpecialBadgeServices.stream() + .filter(service -> service.supports(landmark.getName())) + .map(service -> service.getBadgeType(user, landmark).orElse(null)) + .filter(Objects::nonNull) + .toList(); + } +} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadgeFactory.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadgeFactory.java deleted file mode 100644 index 81a63a7..0000000 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadgeFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.playkuround.playkuroundserver.domain.badge.application.college_special_badge; - -import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; -import com.playkuround.playkuroundserver.domain.user.domain.User; -import org.springframework.stereotype.Component; - -import java.util.List; -import java.util.Optional; -import java.util.Set; - -@Component -public class CollegeSpecialBadgeFactory { - - private final List collegeSpecialBadgeServices; - - public CollegeSpecialBadgeFactory(List collegeSpecialBadgeServices) { - this.collegeSpecialBadgeServices = collegeSpecialBadgeServices; - } - - public Optional getBadgeType(User user, Set userHadBadgeSet, Landmark landmark) { - for (CollegeSpecialBadgeService collegeSpecialBadgeService : collegeSpecialBadgeServices) { - if (collegeSpecialBadgeService.supports(landmark.getName())) { - return collegeSpecialBadgeService.getBadgeType(user, userHadBadgeSet, landmark); - } - } - return Optional.empty(); - } -} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadgeService.java index 046145a..0154eb4 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/CollegeSpecialBadgeService.java @@ -6,11 +6,10 @@ import com.playkuround.playkuroundserver.domain.user.domain.User; import java.util.Optional; -import java.util.Set; public interface CollegeSpecialBadgeService { boolean supports(LandmarkType landmarkType); - Optional getBadgeType(User user, Set userHadBadgeSet, Landmark landmark); + Optional getBadgeType(User user, Landmark landmark); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/EngineeringBadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/EngineeringSpecialBadge.java similarity index 73% rename from src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/EngineeringBadgeService.java rename to src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/EngineeringSpecialBadge.java index f90e1dd..d3e8094 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/EngineeringBadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/college_special_badge/EngineeringSpecialBadge.java @@ -10,11 +10,10 @@ import java.util.Map; import java.util.Optional; -import java.util.Set; @Component @RequiredArgsConstructor -class EngineeringBadgeService implements CollegeSpecialBadgeService { +class EngineeringSpecialBadge implements CollegeSpecialBadgeService { private final Map landmarkTypeAndBadge = Map.of( LandmarkType.공학관A, new BadgeAndRequiredCount(BadgeType.COLLEGE_OF_ENGINEERING_A, 10), @@ -26,20 +25,19 @@ class EngineeringBadgeService implements CollegeSpecialBadgeService { @Override public boolean supports(LandmarkType landmarkType) { - return LandmarkType.공학관A.equals(landmarkType) || - LandmarkType.공학관B.equals(landmarkType) || - LandmarkType.공학관C.equals(landmarkType); + return landmarkTypeAndBadge.containsKey(landmarkType); } @Override - public Optional getBadgeType(User user, Set userHadBadgeSet, Landmark landmark) { + public Optional getBadgeType(User user, Landmark landmark) { BadgeAndRequiredCount badgeAndRequiredCount = landmarkTypeAndBadge.get(landmark.getName()); if (badgeAndRequiredCount != null) { - if (!userHadBadgeSet.contains(badgeAndRequiredCount.badgeType) && - adventureRepository.countByUserAndLandmark(user, landmark) == badgeAndRequiredCount.requiredCount) { + long visitedNumber = adventureRepository.countByUserAndLandmark(user, landmark); + if (visitedNumber == badgeAndRequiredCount.requiredCount) { return Optional.of(badgeAndRequiredCount.badgeType); } } + return Optional.empty(); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ArborDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ArborDayBadge.java index 8da1613..17efe1d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ArborDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ArborDayBadge.java @@ -4,17 +4,15 @@ import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import java.time.LocalDate; -import java.util.Set; -public class ArborDayBadge implements SpecialDayBadge { +class ArborDayBadge implements SpecialDayBadge { ArborDayBadge() { } @Override - public boolean supports(Set userBadgeSet, LocalDate localDate) { - BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isArborDay(localDate) && !userBadgeSet.contains(badgeType); + public boolean supports(LocalDate localDate) { + return DateTimeUtils.isArborDay(localDate); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChildrenDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChildrenDayBadge.java index 4add59e..4d45ae8 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChildrenDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChildrenDayBadge.java @@ -4,17 +4,15 @@ import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import java.time.LocalDate; -import java.util.Set; -public class ChildrenDayBadge implements SpecialDayBadge { +class ChildrenDayBadge implements SpecialDayBadge { ChildrenDayBadge() { } @Override - public boolean supports(Set userBadgeSet, LocalDate localDate) { - BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isChildrenDay(localDate) && !userBadgeSet.contains(badgeType); + public boolean supports(LocalDate localDate) { + return DateTimeUtils.isChildrenDay(localDate); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChristmasDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChristmasDayBadge.java index 0962137..88c58cc 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChristmasDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChristmasDayBadge.java @@ -4,17 +4,15 @@ import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import java.time.LocalDate; -import java.util.Set; -public class ChristmasDayBadge implements SpecialDayBadge { +class ChristmasDayBadge implements SpecialDayBadge { ChristmasDayBadge() { } @Override - public boolean supports(Set userBadgeSet, LocalDate localDate) { - BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isChristmasDay(localDate) && !userBadgeSet.contains(badgeType); + public boolean supports(LocalDate localDate) { + return DateTimeUtils.isChristmasDay(localDate); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChuseokDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChuseokDayBadge.java index f51bc2b..0b3ab40 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChuseokDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/ChuseokDayBadge.java @@ -4,17 +4,15 @@ import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import java.time.LocalDate; -import java.util.Set; -public class ChuseokDayBadge implements SpecialDayBadge { +class ChuseokDayBadge implements SpecialDayBadge { ChuseokDayBadge() { } @Override - public boolean supports(Set userBadgeSet, LocalDate localDate) { - BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isChuseokDay(localDate) && !userBadgeSet.contains(badgeType); + public boolean supports(LocalDate localDate) { + return DateTimeUtils.isChuseokDay(localDate); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DokdoDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DokdoDayBadge.java index 9fafdcc..f2f3293 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DokdoDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DokdoDayBadge.java @@ -4,17 +4,15 @@ import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import java.time.LocalDate; -import java.util.Set; -public class DokdoDayBadge implements SpecialDayBadge { +class DokdoDayBadge implements SpecialDayBadge { DokdoDayBadge() { } @Override - public boolean supports(Set userBadgeSet, LocalDate localDate) { - BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isDokdoDay(localDate) && !userBadgeSet.contains(badgeType); + public boolean supports(LocalDate localDate) { + return DateTimeUtils.isDokdoDay(localDate); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DuckDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DuckDayBadge.java index 6dc2b3b..8b38fe4 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DuckDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/DuckDayBadge.java @@ -4,17 +4,15 @@ import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import java.time.LocalDate; -import java.util.Set; -public class DuckDayBadge implements SpecialDayBadge { +class DuckDayBadge implements SpecialDayBadge { DuckDayBadge() { } @Override - public boolean supports(Set userBadgeSet, LocalDate localDate) { - BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isDuckDay(localDate) && !userBadgeSet.contains(badgeType); + public boolean supports(LocalDate localDate) { + return DateTimeUtils.isDuckDay(localDate); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/FoundationDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/FoundationDayBadge.java index 024217d..db4b2ed 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/FoundationDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/FoundationDayBadge.java @@ -4,17 +4,15 @@ import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import java.time.LocalDate; -import java.util.Set; -public class FoundationDayBadge implements SpecialDayBadge { +class FoundationDayBadge implements SpecialDayBadge { FoundationDayBadge() { } @Override - public boolean supports(Set userBadgeSet, LocalDate localDate) { - BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isFoundationDay(localDate) && !userBadgeSet.contains(badgeType); + public boolean supports(LocalDate localDate) { + return DateTimeUtils.isFoundationDay(localDate); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KimchiDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KimchiDayBadge.java index 6e84a7c..fb46b85 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KimchiDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KimchiDayBadge.java @@ -4,17 +4,15 @@ import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import java.time.LocalDate; -import java.util.Set; -public class KimchiDayBadge implements SpecialDayBadge { +class KimchiDayBadge implements SpecialDayBadge { KimchiDayBadge() { } @Override - public boolean supports(Set userBadgeSet, LocalDate localDate) { - BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isKimchiDay(localDate) && !userBadgeSet.contains(badgeType); + public boolean supports(LocalDate localDate) { + return DateTimeUtils.isKimchiDay(localDate); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KoreanDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KoreanDayBadge.java index 254ac02..71e3799 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KoreanDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/KoreanDayBadge.java @@ -4,17 +4,15 @@ import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import java.time.LocalDate; -import java.util.Set; -public class KoreanDayBadge implements SpecialDayBadge { +class KoreanDayBadge implements SpecialDayBadge { KoreanDayBadge() { } @Override - public boolean supports(Set userBadgeSet, LocalDate localDate) { - BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isKoreanDay(localDate) && !userBadgeSet.contains(badgeType); + public boolean supports(LocalDate localDate) { + return DateTimeUtils.isKoreanDay(localDate); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadge.java index 9e2e144..e3c8a3f 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/SpecialDayBadge.java @@ -3,11 +3,10 @@ import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import java.time.LocalDate; -import java.util.Set; public interface SpecialDayBadge { - boolean supports(Set userBadgeSet, LocalDate localDate); + boolean supports(LocalDate localDate); BadgeType getBadgeType(); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/WhiteDayBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/WhiteDayBadge.java index ab03f6a..b7e5814 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/WhiteDayBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/specialday_badge/WhiteDayBadge.java @@ -4,17 +4,15 @@ import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import java.time.LocalDate; -import java.util.Set; -public class WhiteDayBadge implements SpecialDayBadge { +class WhiteDayBadge implements SpecialDayBadge { WhiteDayBadge() { } @Override - public boolean supports(Set userBadgeSet, LocalDate localDate) { - BadgeType badgeType = getBadgeType(); - return DateTimeUtils.isWhiteDay(localDate) && !userBadgeSet.contains(badgeType); + public boolean supports(LocalDate localDate) { + return DateTimeUtils.isWhiteDay(localDate); } @Override diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/dto/NewlyRegisteredBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/dto/NewlyRegisteredBadge.java index 659d8fc..83c436f 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/dto/NewlyRegisteredBadge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/dto/NewlyRegisteredBadge.java @@ -16,6 +16,10 @@ public void addBadge(BadgeType badgeType) { newlyBadges.add(badgeInfo); } + public void addBadges(List newCollegeBadges) { + newCollegeBadges.forEach(this::addBadge); + } + public record BadgeInfo(String name, String description) { } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/domain/ScoreType.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/domain/ScoreType.java index f1ba1c8..ed6d0d7 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/domain/ScoreType.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/domain/ScoreType.java @@ -8,7 +8,6 @@ public enum ScoreType { - ATTENDANCE, QUIZ, TIME, MOON, BOOK, CATCH, CUPID, ALL_CLEAR, SURVIVE; private static final Map stringToEnum = diff --git a/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java b/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java index bd2bd6c..f7dff95 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java @@ -16,7 +16,6 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @Configuration @EnableWebSecurity @@ -37,23 +36,26 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .authorizeHttpRequests(request -> request .requestMatchers( //PathRequest.toH2Console(), - PathRequest.toStaticResources().atCommonLocations(), - AntPathRequestMatcher.antMatcher("/"), - AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/users/register"), - AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/users/login"), - AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api/users/availability"), - AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/auth/tokens"), - AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api/auth/emails"), - AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/auth/emails"), - AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/auth/reissue"), - AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/swagger-ui/**"), - AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/swagger-ui.html"), - AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api-docs/**"), - AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api/system-available"), - AntPathRequestMatcher.antMatcher("/actu/**") + PathRequest.toStaticResources().atCommonLocations() ).permitAll() .requestMatchers( - AntPathRequestMatcher.antMatcher("/api/admin/**") + HttpMethod.GET, + "/", "/swagger-ui/**", "/api-docs/**", "/actu/**", + "/api/users/availability", + "/api/auth/emails", + "/api/system-available" + ).permitAll() + .requestMatchers( + HttpMethod.POST, + "/", "/actu/**", + "/api/users/register", + "/api/users/login", + "/api/auth/tokens", + "/api/auth/emails", + "/api/auth/reissue" + ).permitAll() + .requestMatchers( + "/api/admin/**" ).hasRole("ADMIN") .anyRequest().authenticated() ) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java index 032d116..8ec5dcc 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java @@ -1,7 +1,7 @@ package com.playkuround.playkuroundserver.domain.badge.application; import com.playkuround.playkuroundserver.TestUtil; -import com.playkuround.playkuroundserver.domain.badge.application.college_special_badge.CollegeSpecialBadgeFactory; +import com.playkuround.playkuroundserver.domain.badge.application.college_special_badge.CollegeSpecialBadge; import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; @@ -34,7 +34,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.Set; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -54,7 +53,7 @@ class BadgeServiceTest { private UserRepository userRepository; @Mock - private CollegeSpecialBadgeFactory collegeSpecialBadgeFactory; + private CollegeSpecialBadge collegeSpecialBadge; @Mock private DateTimeService dateTimeService; @@ -283,8 +282,8 @@ void success_1(LandmarkType landmarkType, List badgeTypeList) throws Exc User user = TestUtil.createUser(); when(badgeRepository.findByUser(user)) .thenReturn(new ArrayList<>()); - when(collegeSpecialBadgeFactory.getBadgeType(any(User.class), any(Set.class), any(Landmark.class))) - .thenReturn(Optional.empty()); + when(collegeSpecialBadge.getBadgeTypes(any(User.class), any(Landmark.class))) + .thenReturn(List.of()); Landmark landmark = createLandmark(landmarkType); @@ -306,8 +305,8 @@ void success_2() throws Exception { User user = TestUtil.createUser(); when(badgeRepository.findByUser(user)) .thenReturn(new ArrayList<>()); - when(collegeSpecialBadgeFactory.getBadgeType(any(User.class), any(Set.class), any(Landmark.class))) - .thenReturn(Optional.of(BadgeType.COLLEGE_OF_ENGINEERING_A)); + when(collegeSpecialBadge.getBadgeTypes(any(User.class), any(Landmark.class))) + .thenReturn(List.of(BadgeType.COLLEGE_OF_ENGINEERING_A)); Landmark landmark = createLandmark(LandmarkType.공학관A); From 49a42c5c6c48e177e433d7d3f126503d90774b1a Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sun, 1 Sep 2024 19:07:53 +0900 Subject: [PATCH 63/79] add code deploy 2 --- .github/workflows/server2-cd.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/server2-cd.yml b/.github/workflows/server2-cd.yml index 8e1705f..80d32d6 100644 --- a/.github/workflows/server2-cd.yml +++ b/.github/workflows/server2-cd.yml @@ -1,4 +1,4 @@ -name: Spring Code deploy(home) +name: Spring Code deploy 2 on: workflow_dispatch: @@ -53,11 +53,11 @@ jobs: run: ./gradlew clean build - name: Deliver JAR File - uses: appleboy/scp-action@v0.1.7 + uses: appleboy/scp-action@master with: host: ${{ secrets.SSH_HOST2 }} username: ${{ secrets.SSH_USERNAME2 }} - password: ${{ secrets.SSH_PASSWORD2 }} + key: ${{ secrets.SSH_PRVATE_KEY2 }} port: ${{ secrets.SSH_PORT2 }} source: "build/libs/*.jar" target: "source" @@ -68,7 +68,7 @@ jobs: with: host: ${{ secrets.SSH_HOST2 }} username: ${{ secrets.SSH_USERNAME2 }} - password: ${{ secrets.SSH_PASSWORD2 }} + key: ${{ secrets.SSH_PRVATE_KEY2 }} port: ${{ secrets.SSH_PORT2 }} script: | SOURCE_DIR=source/build/libs From 05e75111bc6ebeebdb2c38223ca229d06898f4de Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 2 Sep 2024 01:17:56 +0900 Subject: [PATCH 64/79] =?UTF-8?q?refactor:=20JPA=20entity=20=EC=86=8D?= =?UTF-8?q?=EC=84=B1=20=EB=B3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/adventure/domain/Adventure.java | 5 ++- .../domain/attendance/domain/Attendance.java | 7 +--- .../domain/auth/email/domain/AuthEmail.java | 1 - .../domain/badge/domain/Badge.java | 1 - .../domain/landmark/domain/Landmark.java | 2 +- .../domain/user/domain/User.java | 1 - src/main/resources/data-mysql.sql | 33 ++++++++++++++++++- .../score/api/LandmarkScoreRankApiTest.java | 22 ++++++------- 8 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/domain/Adventure.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/domain/Adventure.java index 73b3cde..1eb8b1d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/domain/Adventure.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/domain/Adventure.java @@ -26,14 +26,13 @@ public class Adventure extends BaseTimeEntity { @JoinColumn(name = "landmark_id") private Landmark landmark; - @Column(nullable = false) - private Long score; + private long score; @Column(nullable = false) @Enumerated(EnumType.STRING) private ScoreType scoreType; - public Adventure(User user, Landmark landmark, ScoreType scoreType, Long score) { + public Adventure(User user, Landmark landmark, ScoreType scoreType, long score) { this.user = user; this.landmark = landmark; this.scoreType = scoreType; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/domain/Attendance.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/domain/Attendance.java index 536ce64..2cac563 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/domain/Attendance.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/domain/Attendance.java @@ -7,8 +7,6 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; import java.time.LocalDateTime; @@ -21,17 +19,14 @@ public class Attendance extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(nullable = false) private double latitude; - - @Column(nullable = false) private double longitude; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") - @OnDelete(action = OnDeleteAction.CASCADE) private User user; + @Column(nullable = false) private LocalDateTime attendanceDateTime; private Attendance(User user, double latitude, double longitude, LocalDateTime attendanceDateTime) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/domain/AuthEmail.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/domain/AuthEmail.java index 04fb2f2..45ac152 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/domain/AuthEmail.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/domain/AuthEmail.java @@ -26,7 +26,6 @@ public class AuthEmail extends BaseTimeEntity { @Column(nullable = false) private LocalDateTime expiredAt; - @Column(nullable = false) private boolean validate; private AuthEmail(String target, String code, LocalDateTime expiredAt) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java index 240815e..8f925f4 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java @@ -21,7 +21,6 @@ public class Badge extends BaseTimeEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") - @OnDelete(action = OnDeleteAction.CASCADE) private User user; @Column(nullable = false) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java index b53ea60..4381bb4 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java @@ -19,7 +19,7 @@ public class Landmark { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(nullable = false) + @Column(nullable = false, unique = true) @Enumerated(EnumType.STRING) private LandmarkType name; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java index 118f247..593d575 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java @@ -30,7 +30,6 @@ public class User extends BaseTimeEntity { @Column(nullable = false) private Major major; - @Column(nullable = false) private int attendanceDays; @Enumerated(EnumType.STRING) diff --git a/src/main/resources/data-mysql.sql b/src/main/resources/data-mysql.sql index b2767db..d2d818f 100644 --- a/src/main/resources/data-mysql.sql +++ b/src/main/resources/data-mysql.sql @@ -1,4 +1,5 @@ -- 랜드마크 초기 데이터입니다. mysql, mariadb 문법에 맞춰져 있습니다. +-- landmark insert into landmark (id, latitude, longitude, recognition_radius, name, user_id, highest_score) values (1, 37.539765, 127.073215, 40, '산학협동관', NULL, 0); insert into landmark (id, latitude, longitude, recognition_radius, name, user_id, highest_score) @@ -86,4 +87,34 @@ values (42, 37.539692, 127.072491, 25, '상허문', NULL, 0); insert into landmark (id, latitude, longitude, recognition_radius, name, user_id, highest_score) values (43, 37.541584, 127.082226, 15, '구의역쪽문', NULL, 0); insert into landmark (id, latitude, longitude, recognition_radius, name, user_id, highest_score) -values (44, 37.539255, 127.076741, 20, '기숙사쪽문', NULL, 0); \ No newline at end of file +values (44, 37.539255, 127.076741, 20, '기숙사쪽문', NULL, 0); + +-- event +-- insert into event (id, title, image_url, description, reference_url, display, created_at, updated_at) values (1, '이미지+설명+링크', 'https://health.chosun.com/site/data/img_dir/2023/07/17/2023071701753_0.jpg', '설명설명', 'https://naver.com', true, NOW(), NOW()); +-- insert into event (id, title, image_url, description, reference_url, display, created_at, updated_at) values (2, '설명+링크', null, '설명설명', 'https://naver.com', true, NOW(), NOW()); +-- insert into event (id, title, image_url, description, reference_url, display, created_at, updated_at) values (3, '설명', null, '설명설명', null, true, NOW(), NOW()); +-- insert into event (id, title, image_url, description, reference_url, display, created_at, updated_at) values (4, '이미지+링크', 'https://health.chosun.com/site/data/img_dir/2023/07/17/2023071701753_0.jpg', null,'https://naver.com', true, NOW(), NOW()); +-- insert into event (id, title, image_url, description, reference_url, display, created_at, updated_at) values (5, '이미지', 'https://health.chosun.com/site/data/img_dir/2023/07/17/2023071701753_0.jpg', null, null, true, NOW(),NOW()); +-- insert into event (id, title, image_url, description, reference_url, display, created_at, updated_at) values (6, '이미지+설명', 'https://health.chosun.com/site/data/img_dir/2023/07/17/2023071701753_0.jpg', '설명설명', null, true, NOW(), NOW()); +-- insert into event (id, title, image_url, description, reference_url, display, created_at, updated_at) values (7, 'non display', null, '이 이벤트는 반환되면 안됩니다.', null, false, NOW(), NOW()); + +-- system_check +insert into SYSTEM_CHECK (id, available, created_at, updated_at) +values (1, true, NOW(), NOW()); + +-- app_version +insert into APP_VERSION (id, os, version, created_at, updated_at) +values (1, 'ANDROID', '2.0.4', NOW(), NOW()); +insert into APP_VERSION (id, os, version, created_at, updated_at) +values (2, 'IOS', '2.0.4', NOW(), NOW()); + +-- insert into badge(id, user_id, badge_type, created_at, updated_at) values (8, 2, 'BUSINESS_ARCHITECTURE_EVENT_BUSINESS', NOW(), NOW()); +-- insert into badge(id, user_id, badge_type, created_at, updated_at) values (9, 2, 'COLLEGE_OF_ENGINEERING_A', NOW(), NOW()); +-- insert into badge(id, user_id, badge_type, created_at, updated_at) values (10, 2, 'MONTHLY_RANKING_2', NOW(), NOW()); +-- insert into badge(id, user_id, badge_type, created_at, updated_at) values (11, 2, 'COLLEGE_OF_BUSINESS_ADMINISTRATION_100_AND_FIRST_PLACE', NOW(), NOW()); +-- insert into badge(id, user_id, badge_type, created_at, updated_at) values (12, 2, 'COLLEGE_OF_INTERNATIONAL', NOW(), NOW()); +-- insert into badge(id, user_id, badge_type, created_at, updated_at) values (13, 2, 'COLLEGE_OF_REAL_ESTATE', NOW(), NOW()); +-- insert into badge(id, user_id, badge_type, created_at, updated_at) values (14, 2, 'THE_DREAM_OF_DUCK', NOW(), NOW()); +-- insert into badge(id, user_id, badge_type, created_at, updated_at) values (15, 2, 'BUSINESS_ARCHITECTURE_EVENT_ARCHITECTURE', NOW(), NOW()); +-- insert into badge(id, user_id, badge_type, created_at, updated_at) values (16, 2, 'COLLEGE_OF_SOCIAL_SCIENCES', NOW(), NOW()); +-- insert into badge(id, user_id, badge_type, created_at, updated_at) values (17, 2, 'ATTENDANCE_CHRISTMAS_DAY', NOW(), NOW()); \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java index 4043bf5..dbbbc5c 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/api/LandmarkScoreRankApiTest.java @@ -82,7 +82,7 @@ void getRankTop100ByLandmark_2() throws Exception { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); userRepository.save(user); - Adventure adventure = new Adventure(user, landmark, ScoreType.CATCH, (long) i); + Adventure adventure = new Adventure(user, landmark, ScoreType.CATCH, i); adventureRepository.save(adventure); } @@ -119,12 +119,12 @@ void getRankTop100ByLandmark_3() throws Exception { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); userRepository.save(user); - Adventure adventure = new Adventure(user, landmark, ScoreType.CATCH, (long) i); + Adventure adventure = new Adventure(user, landmark, ScoreType.CATCH, i); adventureRepository.save(adventure); } User me = userRepository.findByEmail("test@konkuk.ac.kr").get(); - Adventure adventure = new Adventure(me, landmark, ScoreType.CATCH, 37L); + Adventure adventure = new Adventure(me, landmark, ScoreType.CATCH, 37); adventureRepository.save(adventure); // when @@ -170,12 +170,12 @@ void getRankTop100ByLandmark_4() throws Exception { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); userRepository.save(user); - Adventure adventure = new Adventure(user, landmark, ScoreType.CATCH, (long) i); + Adventure adventure = new Adventure(user, landmark, ScoreType.CATCH, i); adventureRepository.save(adventure); } User me = userRepository.findByEmail("test@konkuk.ac.kr").get(); - Adventure adventure = new Adventure(me, landmark, ScoreType.CATCH, 62L); + Adventure adventure = new Adventure(me, landmark, ScoreType.CATCH, 62); adventureRepository.save(adventure); // when @@ -220,12 +220,12 @@ void getRankTop100ByLandmark_5() throws Exception { User user = TestUtil.createUser("user" + i + "@konkuk.ac.kr", "user" + i, Major.건축학부); userRepository.save(user); - adventureRepository.save(new Adventure(user, landmark, ScoreType.CATCH, (long) i)); - adventureRepository.save(new Adventure(user, landmark, ScoreType.BOOK, 1L)); + adventureRepository.save(new Adventure(user, landmark, ScoreType.CATCH, i)); + adventureRepository.save(new Adventure(user, landmark, ScoreType.BOOK, 1)); } User me = userRepository.findByEmail("test@konkuk.ac.kr").get(); - adventureRepository.save(new Adventure(me, landmark, ScoreType.CATCH, 62L)); + adventureRepository.save(new Adventure(me, landmark, ScoreType.CATCH, 62)); // when MvcResult mvcResult = mockMvc.perform(get("/api/scores/rank/{landmarkId}", landmark.getId())) @@ -266,19 +266,19 @@ void getRankTop100ByLandmark_6() throws Exception { landmarkRepository.save(landmark); { User me = userRepository.findByEmail("test@konkuk.ac.kr").get(); - adventureRepository.save(new Adventure(me, landmark, ScoreType.CATCH, 10L)); + adventureRepository.save(new Adventure(me, landmark, ScoreType.CATCH, 10)); } { User user1 = TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.건축학부); user1.updateProfileBadge(BadgeType.ATTENDANCE_1); userRepository.save(user1); - adventureRepository.save(new Adventure(user1, landmark, ScoreType.CATCH, 5L)); + adventureRepository.save(new Adventure(user1, landmark, ScoreType.CATCH, 5)); } { User user2 = TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부); user2.updateProfileBadge(BadgeType.MONTHLY_RANKING_1); userRepository.save(user2); - adventureRepository.save(new Adventure(user2, landmark, ScoreType.CATCH, 15L)); + adventureRepository.save(new Adventure(user2, landmark, ScoreType.CATCH, 15)); } // when From 386c7347de8ef10321795d414325a8dfa54dfbc9 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 2 Sep 2024 01:19:10 +0900 Subject: [PATCH 65/79] =?UTF-8?q?refactor:=20JPA=20entity=20=EC=86=8D?= =?UTF-8?q?=EC=84=B1=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../playkuroundserver/domain/landmark/domain/Landmark.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java index 4381bb4..67eec89 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/domain/Landmark.java @@ -23,13 +23,8 @@ public class Landmark { @Enumerated(EnumType.STRING) private LandmarkType name; - @Column(nullable = false) private double latitude; - - @Column(nullable = false) private double longitude; - - @Column(nullable = false) private int recognitionRadius; @ManyToOne(fetch = FetchType.LAZY) From 9155b2e59ddbb9d8c3ee5bbf1be6da277c225ab4 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 2 Sep 2024 13:06:59 +0900 Subject: [PATCH 66/79] refactor: Adventure domain --- .../domain/adventure/api/AdventureApi.java | 1 + .../api/response/AdventureSaveResponse.java | 2 +- .../application/AdventureService.java | 22 +++++++++++++------ .../adventure/dao/AdventureRepository.java | 14 +++++++----- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java index c71572f..f1b6c48 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java @@ -40,6 +40,7 @@ public ApiResponse saveAdventure(@AuthenticationPrincipal = new AdventureSaveDto(userDetails.getUser(), request.getLandmarkId(), location, request.getScore(), scoreType); NewlyRegisteredBadge newlyRegisteredBadge = adventureService.saveAdventure(adventureSaveDto); + return ApiUtils.success(AdventureSaveResponse.from(newlyRegisteredBadge)); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java index 7f574d2..72fefef 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java @@ -17,7 +17,7 @@ public class AdventureSaveResponse { private AdventureSaveResponse(NewlyRegisteredBadge newlyRegisteredBadge) { this.newBadges = newlyRegisteredBadge.getNewlyBadges().stream() .map(badgeInfo -> BadgeType.valueOf(badgeInfo.name())) - .map(it -> new BadgeInfo(it.name(), it.getDescription())) + .map(badgeType -> new BadgeInfo(badgeType.name(), badgeType.getDescription())) .toList(); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java index 0afb147..63c4633 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java @@ -13,6 +13,7 @@ import com.playkuround.playkuroundserver.domain.score.application.TotalScoreService; import com.playkuround.playkuroundserver.domain.score.domain.ScoreType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; +import com.playkuround.playkuroundserver.domain.user.domain.HighestScore; import com.playkuround.playkuroundserver.domain.user.domain.User; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import com.playkuround.playkuroundserver.global.util.Location; @@ -20,6 +21,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; import java.time.LocalDateTime; @Service @@ -40,10 +42,13 @@ public NewlyRegisteredBadge saveAdventure(AdventureSaveDto adventureSaveDto) { validateLocation(landmark, adventureSaveDto.requestLocation()); User user = adventureSaveDto.user(); + ScoreType scoreType = adventureSaveDto.scoreType(); + long score = adventureSaveDto.score(); - updateUserScore(user, adventureSaveDto.scoreType(), adventureSaveDto.score()); - saveAdventure(user, landmark, adventureSaveDto.scoreType(), adventureSaveDto.score()); + updateUserScore(user, scoreType, score); + saveAdventure(user, landmark, scoreType, score); updateLandmarkHighestScore(user, landmark); + return badgeService.updateNewlyAdventureBadges(user, landmark); } @@ -54,10 +59,11 @@ private void validateLocation(Landmark landmark, Location location) { } private void updateUserScore(User user, ScoreType scoreType, long score) { - totalScoreService.incrementTotalScore(user, score); - user.getHighestScore() - .updateGameHighestScore(scoreType, score); + HighestScore highestScore = user.getHighestScore(); + highestScore.updateGameHighestScore(scoreType, score); userRepository.save(user); + + totalScoreService.incrementTotalScore(user, score); } private void saveAdventure(User user, Landmark landmark, ScoreType scoreType, long score) { @@ -66,8 +72,10 @@ private void saveAdventure(User user, Landmark landmark, ScoreType scoreType, lo } private void updateLandmarkHighestScore(User user, Landmark landmark) { - LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.getLocalDateNow()); - long sumScore = adventureRepository.getSumScoreByUserAndLandmarkAfter(user, landmark, monthStartDateTime); + LocalDate now = dateTimeService.getLocalDateNow(); + LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(now); + + long sumScore = adventureRepository.sumScoreByUserAndLandmarkAfter(user, landmark, monthStartDateTime); landmark.updateFirstUser(user, sumScore); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java index c8b0711..e69e78e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/dao/AdventureRepository.java @@ -34,12 +34,14 @@ Optional findMyRankByLandmarkId(@Param(value = "user") User user, @Param(value = "landmark") Long landmarkId, @Param(value = "from") LocalDateTime from); - @Query("SELECT SUM(a.score) " + - "FROM Adventure a " + - "WHERE a.user.id=:#{#user.id} AND a.landmark.id=:#{#landmark.id} AND a.createdAt >= :from") - long getSumScoreByUserAndLandmarkAfter(@Param(value = "user") User user, - @Param(value = "landmark") Landmark landmark, - @Param(value = "from") LocalDateTime from); + @Query(""" + SELECT SUM(a.score) + FROM Adventure a + WHERE a.user.id=:#{#user.id} AND a.landmark.id=:#{#landmark.id} AND a.createdAt >= :from + """) + long sumScoreByUserAndLandmarkAfter(@Param(value = "user") User user, + @Param(value = "landmark") Landmark landmark, + @Param(value = "from") LocalDateTime from); long countByUserAndLandmark(User user, Landmark landmark); From dfafbc9663abbe87d213f41b88db553f1a0d2d17 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 2 Sep 2024 17:52:22 +0900 Subject: [PATCH 67/79] refactor: appVersion, attendance --- .../domain/adventure/api/AdventureApi.java | 6 +- .../api/response/AdventureSaveResponse.java | 10 +- .../application/AdventureService.java | 5 +- .../domain/appversion/api/AppVersionApi.java | 9 +- .../application/AppVersionService.java | 17 +-- .../appversion/domain/OperationSystem.java | 10 +- .../domain/attendance/api/AttendanceApi.java | 4 +- .../response/AttendanceRegisterResponse.java | 12 +- .../AttendanceRegisterService.java | 21 ++- .../application/AttendanceSearchService.java | 4 +- .../attendance/dao/AttendanceRepository.java | 4 +- .../badge/application/BadgeService.java | 17 ++- .../domain/badge/domain/Badge.java | 1 + .../badge/dto/NewlyRegisteredBadge.java | 25 ---- .../domain/user/api/UserProfileApi.java | 3 +- .../global/util/LocationUtils.java | 4 +- .../appversion/api/AppVersionApiTest.java | 10 +- .../application/AppVersionServiceTest.java | 31 +++-- .../attendance/api/AttendanceApiTest.java | 63 +++++---- .../AttendanceRegisterServiceTest.java | 39 +++--- .../AttendanceSearchServiceTest.java | 57 +++++---- .../badge/application/BadgeServiceTest.java | 120 +++++++----------- 22 files changed, 211 insertions(+), 261 deletions(-) delete mode 100644 src/main/java/com/playkuround/playkuroundserver/domain/badge/dto/NewlyRegisteredBadge.java diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java index f1b6c48..3800878 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/AdventureApi.java @@ -4,7 +4,7 @@ import com.playkuround.playkuroundserver.domain.adventure.api.response.AdventureSaveResponse; import com.playkuround.playkuroundserver.domain.adventure.application.AdventureService; import com.playkuround.playkuroundserver.domain.adventure.dto.AdventureSaveDto; -import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.score.domain.ScoreType; import com.playkuround.playkuroundserver.domain.score.exception.ScoreTypeNotMatchException; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; @@ -19,6 +19,8 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RestController @RequiredArgsConstructor @RequestMapping("api/adventures") @@ -39,7 +41,7 @@ public ApiResponse saveAdventure(@AuthenticationPrincipal AdventureSaveDto adventureSaveDto = new AdventureSaveDto(userDetails.getUser(), request.getLandmarkId(), location, request.getScore(), scoreType); - NewlyRegisteredBadge newlyRegisteredBadge = adventureService.saveAdventure(adventureSaveDto); + List newlyRegisteredBadge = adventureService.saveAdventure(adventureSaveDto); return ApiUtils.success(AdventureSaveResponse.from(newlyRegisteredBadge)); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java index 72fefef..7dd3d77 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/api/response/AdventureSaveResponse.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; @@ -14,15 +13,14 @@ public class AdventureSaveResponse { private final List newBadges; - private AdventureSaveResponse(NewlyRegisteredBadge newlyRegisteredBadge) { - this.newBadges = newlyRegisteredBadge.getNewlyBadges().stream() - .map(badgeInfo -> BadgeType.valueOf(badgeInfo.name())) + private AdventureSaveResponse(List badgeTypes) { + this.newBadges = badgeTypes.stream() .map(badgeType -> new BadgeInfo(badgeType.name(), badgeType.getDescription())) .toList(); } - public static AdventureSaveResponse from(NewlyRegisteredBadge newlyRegisteredBadge) { - return new AdventureSaveResponse(newlyRegisteredBadge); + public static AdventureSaveResponse from(List badgeTypes) { + return new AdventureSaveResponse(badgeTypes); } @Getter diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java index 63c4633..4a40804 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/adventure/application/AdventureService.java @@ -5,7 +5,7 @@ import com.playkuround.playkuroundserver.domain.adventure.dto.AdventureSaveDto; import com.playkuround.playkuroundserver.domain.adventure.exception.InvalidLandmarkLocationException; import com.playkuround.playkuroundserver.domain.badge.application.BadgeService; -import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.landmark.dao.LandmarkRepository; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; @@ -23,6 +23,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.List; @Service @RequiredArgsConstructor @@ -36,7 +37,7 @@ public class AdventureService { private final DateTimeService dateTimeService; @Transactional - public NewlyRegisteredBadge saveAdventure(AdventureSaveDto adventureSaveDto) { + public List saveAdventure(AdventureSaveDto adventureSaveDto) { Landmark landmark = landmarkRepository.findById(adventureSaveDto.landmarkId()) .orElseThrow(() -> new LandmarkNotFoundException(adventureSaveDto.landmarkId())); validateLocation(landmark, adventureSaveDto.requestLocation()); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java index eeba74b..3788975 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApi.java @@ -4,6 +4,7 @@ import com.playkuround.playkuroundserver.domain.appversion.application.AppVersionService; import com.playkuround.playkuroundserver.domain.appversion.domain.OperationSystem; import com.playkuround.playkuroundserver.domain.appversion.dto.OSAndVersion; +import com.playkuround.playkuroundserver.domain.common.NotSupportOSException; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; import com.playkuround.playkuroundserver.global.util.ApiUtils; import io.swagger.v3.oas.annotations.Operation; @@ -28,11 +29,11 @@ public class AppVersionApi { @Operation(summary = "지원하는 앱 버전 업데이트", description = "지원하는 앱 버전 업데이트합니다.(덮어쓰기)", tags = "Admin") public ApiResponse updateAppVersion(@RequestBody @Valid UpdateAppVersionRequest request) { Set requestSet = request.getOsAndVersions().stream() - .map(osAndVersion -> { - OperationSystem operationSystem = OperationSystem.fromString(osAndVersion.getOs()); - return new OSAndVersion(operationSystem, osAndVersion.getVersion()); - }) + .map(osAndVersion -> OperationSystem.fromString(osAndVersion.getOs()) + .map(operationSystem -> new OSAndVersion(operationSystem, osAndVersion.getVersion())) + .orElseThrow(NotSupportOSException::new)) .collect(Collectors.toSet()); + appVersionService.changeSupportedList(requestSet); return ApiUtils.success(null); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/appversion/application/AppVersionService.java b/src/main/java/com/playkuround/playkuroundserver/domain/appversion/application/AppVersionService.java index 36ce780..63eb07b 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/appversion/application/AppVersionService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/appversion/application/AppVersionService.java @@ -26,20 +26,17 @@ public boolean isSupportedVersion(OperationSystem os, String version) { public void changeSupportedList(Set osAndVersions) { Set osAndVersionHashSet = new HashSet<>(osAndVersions); - List appVersions = appVersionRepository.findAll(); - for (AppVersion appVersion : appVersions) { + List currentSupportedAppVersions = appVersionRepository.findAll(); + for (AppVersion appVersion : currentSupportedAppVersions) { OSAndVersion osAndVersion = new OSAndVersion(appVersion.getOs(), appVersion.getVersion()); - if (osAndVersionHashSet.contains(osAndVersion)) { - osAndVersionHashSet.remove(osAndVersion); - } - else { + if (!osAndVersionHashSet.remove(osAndVersion)) { appVersionRepository.delete(appVersion); } } - for (OSAndVersion osAndVersion : osAndVersionHashSet) { - AppVersion appVersion = new AppVersion(osAndVersion.os(), osAndVersion.version()); - appVersionRepository.save(appVersion); - } + List newAppVersions = osAndVersionHashSet.stream() + .map(osAndVersion -> new AppVersion(osAndVersion.os(), osAndVersion.version())) + .toList(); + appVersionRepository.saveAll(newAppVersions); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/appversion/domain/OperationSystem.java b/src/main/java/com/playkuround/playkuroundserver/domain/appversion/domain/OperationSystem.java index 49c5f67..72da4ce 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/appversion/domain/OperationSystem.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/appversion/domain/OperationSystem.java @@ -1,8 +1,7 @@ package com.playkuround.playkuroundserver.domain.appversion.domain; -import com.playkuround.playkuroundserver.domain.common.NotSupportOSException; - import java.util.Map; +import java.util.Optional; import java.util.stream.Stream; import static java.util.stream.Collectors.toMap; @@ -14,11 +13,8 @@ public enum OperationSystem { Stream.of(values()) .collect(toMap(Object::toString, e -> e)); - public static OperationSystem fromString(String os) { + public static Optional fromString(String os) { OperationSystem appVersion = stringToEnum.get(os.toUpperCase()); - if (appVersion == null) { - throw new NotSupportOSException(); - } - return appVersion; + return Optional.ofNullable(appVersion); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java index 57deed1..28ea133 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApi.java @@ -5,7 +5,7 @@ import com.playkuround.playkuroundserver.domain.attendance.api.response.AttendanceSearchResponse; import com.playkuround.playkuroundserver.domain.attendance.application.AttendanceRegisterService; import com.playkuround.playkuroundserver.domain.attendance.application.AttendanceSearchService; -import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.global.common.response.ApiResponse; import com.playkuround.playkuroundserver.global.security.UserDetailsImpl; import com.playkuround.playkuroundserver.global.util.ApiUtils; @@ -35,7 +35,7 @@ public class AttendanceApi { public ApiResponse saveAttendance(@AuthenticationPrincipal UserDetailsImpl userDetails, @Valid @RequestBody AttendanceRegisterRequest registerRequest) { Location location = new Location(registerRequest.getLatitude(), registerRequest.getLongitude()); - NewlyRegisteredBadge newlyRegisteredBadge = attendanceRegisterService.registerAttendance(userDetails.getUser(), location); + List newlyRegisteredBadge = attendanceRegisterService.registerAttendance(userDetails.getUser(), location); return ApiUtils.success(AttendanceRegisterResponse.from(newlyRegisteredBadge)); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/response/AttendanceRegisterResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/response/AttendanceRegisterResponse.java index dd317c3..1638a94 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/response/AttendanceRegisterResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/api/response/AttendanceRegisterResponse.java @@ -1,7 +1,6 @@ package com.playkuround.playkuroundserver.domain.attendance.api.response; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; @@ -13,16 +12,13 @@ public class AttendanceRegisterResponse { private final List newBadges; - private AttendanceRegisterResponse(NewlyRegisteredBadge newlyRegisteredBadge) { - this.newBadges = newlyRegisteredBadge.getNewlyBadges().stream() - .map(badgeInfo -> { - BadgeType badgeType = BadgeType.valueOf(badgeInfo.name()); - return new BadgeInfo(badgeType.name(), badgeType.getDescription()); - }) + private AttendanceRegisterResponse(List newlyRegisteredBadge) { + this.newBadges = newlyRegisteredBadge.stream() + .map(badgeType -> new BadgeInfo(badgeType.name(), badgeType.getDescription())) .toList(); } - public static AttendanceRegisterResponse from(NewlyRegisteredBadge newlyRegisteredBadge) { + public static AttendanceRegisterResponse from(List newlyRegisteredBadge) { return new AttendanceRegisterResponse(newlyRegisteredBadge); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java index b6d8298..83c2336 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterService.java @@ -5,7 +5,7 @@ import com.playkuround.playkuroundserver.domain.attendance.exception.DuplicateAttendanceException; import com.playkuround.playkuroundserver.domain.attendance.exception.InvalidAttendanceLocationException; import com.playkuround.playkuroundserver.domain.badge.application.BadgeService; -import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; +import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.score.application.TotalScoreService; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; @@ -16,6 +16,10 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + @Service @RequiredArgsConstructor public class AttendanceRegisterService { @@ -28,7 +32,7 @@ public class AttendanceRegisterService { private final long attendanceScore = 10; @Transactional - public NewlyRegisteredBadge registerAttendance(User user, Location location) { + public List registerAttendance(User user, Location location) { validateAttendance(user, location); saveAttendance(user, location); @@ -45,20 +49,25 @@ private void validateAttendance(User user, Location location) { } private void validateLocation(Location location) { - boolean isLocatedInKU = LocationUtils.isLocatedInKU(location); - if (!isLocatedInKU) { + boolean isNotLocatedInKU = LocationUtils.isNotLocatedInKU(location); + if (isNotLocatedInKU) { throw new InvalidAttendanceLocationException(); } } private void validateDuplicateAttendance(User user) { - if (attendanceRepository.existsByUserAndAttendanceDateTimeAfter(user, dateTimeService.getLocalDateNow().atStartOfDay())) { + LocalDate now = dateTimeService.getLocalDateNow(); + LocalDateTime startTimeOfNow = now.atStartOfDay(); + + boolean isAlreadyAttendance = attendanceRepository.existsByUserAndAttendanceDateTimeGreaterThanEqual(user, startTimeOfNow); + if (isAlreadyAttendance) { throw new DuplicateAttendanceException(); } } private void saveAttendance(User user, Location location) { - Attendance attendance = Attendance.of(user, location, dateTimeService.getLocalDateTimeNow()); + LocalDateTime now = dateTimeService.getLocalDateTimeNow(); + Attendance attendance = Attendance.of(user, location, now); attendanceRepository.save(attendance); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java index e48c5aa..60c9fcb 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchService.java @@ -21,10 +21,10 @@ public class AttendanceSearchService { @Transactional(readOnly = true) public List findAttendance(User user, int agoDays) { LocalDateTime monthAgo = dateTimeService.getLocalDateNow() - .minusMonths(agoDays) + .minusDays(agoDays) .atStartOfDay(); - List attendances = attendanceRepository.findByUserAndAttendanceDateTimeAfter(user, monthAgo); + List attendances = attendanceRepository.findByUserAndAttendanceDateTimeGreaterThanEqual(user, monthAgo); return attendances.stream() .map(Attendance::getAttendanceDateTime) .sorted() diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java index 41fda98..9806839 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/attendance/dao/AttendanceRepository.java @@ -9,9 +9,9 @@ public interface AttendanceRepository extends JpaRepository { - List findByUserAndAttendanceDateTimeAfter(User user, LocalDateTime localDateTime); + List findByUserAndAttendanceDateTimeGreaterThanEqual(User user, LocalDateTime localDateTime); - boolean existsByUserAndAttendanceDateTimeAfter(User user, LocalDateTime localDateTime); + boolean existsByUserAndAttendanceDateTimeGreaterThanEqual(User user, LocalDateTime localDateTime); void deleteByUser(User user); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java index 44f0764..9b382a0 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java @@ -10,7 +10,6 @@ import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; @@ -48,16 +47,16 @@ private Set getUserBadgeSet(User user) { .collect(Collectors.toSet()); } - public NewlyRegisteredBadge updateNewlyAttendanceBadges(User user) { - NewlyRegisteredBadge newlyRegisteredBadge = new NewlyRegisteredBadge(); + public List updateNewlyAttendanceBadges(User user) { + List newlyRegisteredBadge = new ArrayList<>(); Set userBadgeSet = getUserBadgeSet(user); List attendanceBadges = saveAttendanceBadges(user, userBadgeSet); - newlyRegisteredBadge.addBadges(attendanceBadges); + newlyRegisteredBadge.addAll(attendanceBadges); List specialDayBadges = saveSpecialDayBadges(user, userBadgeSet); - newlyRegisteredBadge.addBadges(specialDayBadges); + newlyRegisteredBadge.addAll(specialDayBadges); return newlyRegisteredBadge; } @@ -93,16 +92,16 @@ private List saveSpecialDayBadges(User user, Set userBadge return newBadges; } - public NewlyRegisteredBadge updateNewlyAdventureBadges(User user, Landmark requestSaveLandmark) { - NewlyRegisteredBadge newlyRegisteredBadge = new NewlyRegisteredBadge(); + public List updateNewlyAdventureBadges(User user, Landmark requestSaveLandmark) { + List newlyRegisteredBadge = new ArrayList<>(); Set userBadgeSet = getUserBadgeSet(user); List collegeBadges = saveCollegeBadges(user, requestSaveLandmark.getName(), userBadgeSet); - newlyRegisteredBadge.addBadges(collegeBadges); + newlyRegisteredBadge.addAll(collegeBadges); List collegeSpecialBadges = saveCollegeSpecialBadges(user, requestSaveLandmark, userBadgeSet); - newlyRegisteredBadge.addBadges(collegeSpecialBadges); + newlyRegisteredBadge.addAll(collegeSpecialBadges); return newlyRegisteredBadge; } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java index 8f925f4..240815e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/domain/Badge.java @@ -21,6 +21,7 @@ public class Badge extends BaseTimeEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") + @OnDelete(action = OnDeleteAction.CASCADE) private User user; @Column(nullable = false) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/dto/NewlyRegisteredBadge.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/dto/NewlyRegisteredBadge.java deleted file mode 100644 index 83c436f..0000000 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/dto/NewlyRegisteredBadge.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.playkuround.playkuroundserver.domain.badge.dto; - -import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import lombok.Getter; - -import java.util.ArrayList; -import java.util.List; - -@Getter -public class NewlyRegisteredBadge { - - private final List newlyBadges = new ArrayList<>(); - - public void addBadge(BadgeType badgeType) { - BadgeInfo badgeInfo = new BadgeInfo(badgeType.name(), badgeType.getDescription()); - newlyBadges.add(badgeInfo); - } - - public void addBadges(List newCollegeBadges) { - newCollegeBadges.forEach(this::addBadge); - } - - public record BadgeInfo(String name, String description) { - } -} diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java index 2e56442..e34da7e 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserProfileApi.java @@ -83,7 +83,8 @@ public ApiResponse setProfileBadge(@AuthenticationPrincipal UserDetailsImp public ApiResponse> getNotification(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestParam("version") String appVersion, @RequestParam(name = "os", required = false, defaultValue = "android") String os) { - OperationSystem operationSystem = OperationSystem.fromString(os.toUpperCase()); + OperationSystem operationSystem = OperationSystem.fromString(os.toUpperCase()) + .orElseThrow(UnsupportedOperationException::new); List response; if (!systemCheckService.isSystemAvailable()) { diff --git a/src/main/java/com/playkuround/playkuroundserver/global/util/LocationUtils.java b/src/main/java/com/playkuround/playkuroundserver/global/util/LocationUtils.java index 8ab67f2..77236a8 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/util/LocationUtils.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/util/LocationUtils.java @@ -57,8 +57,8 @@ public class LocationUtils { polygonKU.closePath(); } - public static boolean isLocatedInKU(Location location) { - return polygonKU.contains(location.latitude(), location.longitude()); + public static boolean isNotLocatedInKU(Location location) { + return !polygonKU.contains(location.latitude(), location.longitude()); } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java index 6c9f1a8..d13484e 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/appversion/api/AppVersionApiTest.java @@ -88,12 +88,10 @@ void success_1() throws Exception { @DisplayName("기존에 지원하던 앱 버전을 완전히 덮어쓴다.") void success_2() throws Exception { // given - appVersionRepository.saveAll( - List.of( - new AppVersion(OperationSystem.ANDROID, "2.0.3"), - new AppVersion(OperationSystem.IOS, "1.4.3") - ) - ); + appVersionRepository.saveAll(List.of( + new AppVersion(OperationSystem.ANDROID, "2.0.3"), + new AppVersion(OperationSystem.IOS, "1.4.3") + )); List osAndVersions = List.of( new UpdateAppVersionRequest.OsAndVersion("android", "2.0.3"), diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/appversion/application/AppVersionServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/appversion/application/AppVersionServiceTest.java index 8ef3739..9f572de 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/appversion/application/AppVersionServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/appversion/application/AppVersionServiceTest.java @@ -16,7 +16,9 @@ import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.*; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class AppVersionServiceTest { @@ -37,32 +39,21 @@ void success_1() { new AppVersion(OperationSystem.IOS, "2.0.0"), new AppVersion(OperationSystem.IOS, "2.0.1") ); - when(appVersionRepository.findAll()) .thenReturn(appVersionList); - // when Set osAndVersions = Set.of( new OSAndVersion(OperationSystem.ANDROID, "1.0.1"), new OSAndVersion(OperationSystem.ANDROID, "1.2.0"), new OSAndVersion(OperationSystem.IOS, "2.0.2") ); + // when appVersionService.changeSupportedList(osAndVersions); // then - ArgumentCaptor saveArgument = ArgumentCaptor.forClass(AppVersion.class); - verify(appVersionRepository, times(2)).save(saveArgument.capture()); - List saveList = saveArgument.getAllValues().stream() - .map(appVersion -> new OSAndVersion(appVersion.getOs(), appVersion.getVersion())) - .toList(); - assertThat(saveList).containsExactlyInAnyOrder( - new OSAndVersion(OperationSystem.ANDROID, "1.0.1"), - new OSAndVersion(OperationSystem.IOS, "2.0.2") - ); - ArgumentCaptor deleteArgument = ArgumentCaptor.forClass(AppVersion.class); - verify(appVersionRepository, times(3)).delete(deleteArgument.capture()); + then(appVersionRepository).should(times(3)).delete(deleteArgument.capture()); List deleteList = deleteArgument.getAllValues().stream() .map(appVersion -> new OSAndVersion(appVersion.getOs(), appVersion.getVersion())) .toList(); @@ -71,5 +62,17 @@ void success_1() { new OSAndVersion(OperationSystem.IOS, "2.0.0"), new OSAndVersion(OperationSystem.IOS, "2.0.1") ); + + ArgumentCaptor> saveArgument = ArgumentCaptor.forClass(List.class); + then(appVersionRepository).should(times(1)).saveAll(saveArgument.capture()); + List saveList = saveArgument.getValue().stream() + .map(appVersion -> new OSAndVersion(appVersion.getOs(), appVersion.getVersion())) + .toList(); + assertThat(saveList).containsExactlyInAnyOrder( + new OSAndVersion(OperationSystem.ANDROID, "1.0.1"), + new OSAndVersion(OperationSystem.IOS, "2.0.2") + ); + + then(appVersionRepository).shouldHaveNoMoreInteractions(); } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java index 62a5ab1..3473ed5 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/api/AttendanceApiTest.java @@ -1,7 +1,6 @@ package com.playkuround.playkuroundserver.domain.attendance.api; import com.fasterxml.jackson.databind.ObjectMapper; -import com.jayway.jsonpath.JsonPath; import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.domain.attendance.api.request.AttendanceRegisterRequest; import com.playkuround.playkuroundserver.domain.attendance.dao.AttendanceRepository; @@ -26,12 +25,9 @@ import org.springframework.data.redis.core.ZSetOperations; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -70,6 +66,8 @@ class AttendanceApiTest { @Value("${redis-key}") private String redisSetKey; + private final Location locationInKU = new Location(37.539927, 127.073006); + @AfterEach void clean() { attendanceRepository.deleteAllInBatch(); @@ -79,15 +77,15 @@ void clean() { } @Nested + @WithMockCustomUser @DisplayName("출석 저장하기") class saveAttendance { @Test - @WithMockCustomUser @DisplayName("최초로 출석하면 BadgeType.ATTENDANCE_1 배지를 받는다.") void success_1() throws Exception { // given - AttendanceRegisterRequest attendanceRegisterRequest = new AttendanceRegisterRequest(37.539927, 127.073006); + AttendanceRegisterRequest attendanceRegisterRequest = new AttendanceRegisterRequest(locationInKU.latitude(), locationInKU.longitude()); String request = objectMapper.writeValueAsString(attendanceRegisterRequest); // expected @@ -120,17 +118,15 @@ void success_1() throws Exception { } @Test - @WithMockCustomUser @DisplayName("출석은 하루에 한번만 가능하다.") void fail_1() throws Exception { // given + LocalDate localDate = LocalDate.of(2024, 7, 1); when(dateTimeService.getLocalDateNow()) - .thenReturn(LocalDate.of(2024, 7, 1)); + .thenReturn(localDate); - Attendance attendance = Attendance.of( - userRepository.findAll().get(0), - new Location(37.539927, 127.073006), - LocalDateTime.of(2024, 7, 1, 1, 0)); + User user = userRepository.findAll().get(0); + Attendance attendance = Attendance.of(user, locationInKU, localDate.atStartOfDay()); attendanceRepository.save(attendance); AttendanceRegisterRequest attendanceRegisterRequest = new AttendanceRegisterRequest(37.539927, 127.073006); @@ -152,7 +148,6 @@ void fail_1() throws Exception { } @Test - @WithMockCustomUser @DisplayName("출석은 건대 내부에서 해야한다.") void fail_2() throws Exception { // given @@ -177,40 +172,40 @@ void fail_2() throws Exception { @Nested + @WithMockCustomUser @DisplayName("출석 조회하기") class searchAttendance { @Test - @WithMockCustomUser - @DisplayName("지난 한달 출석 조회") + @DisplayName("최근 30일 출석 조회") void attendanceSearch() throws Exception { - // TODO : need refactoring // given - User user = userRepository.findAll().get(0); - Location location = new Location(37.539927, 127.073006); - LocalDateTime todayLocalDate = LocalDateTime.of(2024, 7, 1, 0, 0); - List dateList = new ArrayList<>(); - for (int i = 29; i > 0; i -= 2) { - LocalDateTime thatLocalDateTime = todayLocalDate.minusDays(i); - String formatDate = thatLocalDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); - dateList.add(formatDate); - - attendanceRepository.save(Attendance.of(user, location, thatLocalDateTime)); - } - when(dateTimeService.getLocalDateNow()) .thenReturn(todayLocalDate.toLocalDate()); + User user = userRepository.findAll().get(0); + List attendances = List.of( + Attendance.of(user, locationInKU, todayLocalDate), + Attendance.of(user, locationInKU, todayLocalDate.minusDays(1)), + Attendance.of(user, locationInKU, todayLocalDate.minusDays(2)), + Attendance.of(user, locationInKU, todayLocalDate.minusDays(29)), + Attendance.of(user, locationInKU, todayLocalDate.minusDays(30)), + Attendance.of(user, locationInKU, todayLocalDate.minusDays(31)) + ); + attendanceRepository.saveAll(attendances); + // expected - MvcResult mvcResult = mockMvc.perform(get("/api/attendances")) + mockMvc.perform(get("/api/attendances")) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess").value(true)) - .andDo(print()) - .andReturn(); - String json = mvcResult.getResponse().getContentAsString(); - List target = JsonPath.parse(json).read("$.response.attendances"); - assertThat(target).isEqualTo(dateList); + .andExpect(jsonPath("$.response.attendances.size()").value(5)) + .andExpect(jsonPath("$.response.attendances[0]").value("2024-06-01")) + .andExpect(jsonPath("$.response.attendances[1]").value("2024-06-02")) + .andExpect(jsonPath("$.response.attendances[2]").value("2024-06-29")) + .andExpect(jsonPath("$.response.attendances[3]").value("2024-06-30")) + .andExpect(jsonPath("$.response.attendances[4]").value("2024-07-01")) + .andDo(print()); } } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java index 3f0ea99..de94a75 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceRegisterServiceTest.java @@ -7,7 +7,6 @@ import com.playkuround.playkuroundserver.domain.attendance.exception.InvalidAttendanceLocationException; import com.playkuround.playkuroundserver.domain.badge.application.BadgeService; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.score.application.TotalScoreService; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; @@ -22,11 +21,10 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.time.LocalDate; -import java.time.LocalDateTime; +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) @@ -54,27 +52,25 @@ class AttendanceRegisterServiceTest { @DisplayName("출석 시 배지와 출석정보가 저장되고 유저의 출석횟수가 증가한다") void registerAttendance_1() { // given - when(attendanceRepository.existsByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) - .thenReturn(false); - when(dateTimeService.getLocalDateNow()) - .thenReturn(LocalDate.of(2024, 6, 30)); + User user = TestUtil.createUser(); + LocalDate localDate = LocalDate.of(2024, 6, 30); - NewlyRegisteredBadge newlyRegisteredBadge = new NewlyRegisteredBadge(); - newlyRegisteredBadge.addBadge(BadgeType.ATTENDANCE_1); - newlyRegisteredBadge.addBadge(BadgeType.ATTENDANCE_ARBOR_DAY); - when(badgeService.updateNewlyAttendanceBadges(any(User.class))) - .thenReturn(newlyRegisteredBadge); + when(dateTimeService.getLocalDateNow()) + .thenReturn(localDate); + when(attendanceRepository.existsByUserAndAttendanceDateTimeGreaterThanEqual(user, localDate.atStartOfDay())) + .thenReturn(false); + when(badgeService.updateNewlyAttendanceBadges(user)) + .thenReturn(List.of(BadgeType.ATTENDANCE_1, BadgeType.ATTENDANCE_ARBOR_DAY)); - User user = TestUtil.createUser(); Location location = new Location(37.539927, 127.073006); // when - NewlyRegisteredBadge result = attendanceRegisterService.registerAttendance(user, location); + List result = attendanceRegisterService.registerAttendance(user, location); // then assertThat(user.getAttendanceDays()).isEqualTo(1); - assertThat(result.getNewlyBadges()).extracting("name") - .containsExactlyInAnyOrder(BadgeType.ATTENDANCE_1.name(), BadgeType.ATTENDANCE_ARBOR_DAY.name()); + assertThat(result).hasSize(2) + .containsExactlyInAnyOrder(BadgeType.ATTENDANCE_1, BadgeType.ATTENDANCE_ARBOR_DAY); ArgumentCaptor attendanceArgument = ArgumentCaptor.forClass(Attendance.class); verify(attendanceRepository, times(1)).save(attendanceArgument.capture()); @@ -100,11 +96,14 @@ void registerAttendance_2() { @DisplayName("출석은 하루에 한번만 가능하다") void registerAttendance_3() { // given - when(attendanceRepository.existsByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) - .thenReturn(true); - when(dateTimeService.getLocalDateNow()) - .thenReturn(LocalDate.of(2024, 6, 30)); User user = TestUtil.createUser(); + LocalDate localDate = LocalDate.of(2024, 6, 30); + + when(dateTimeService.getLocalDateNow()) + .thenReturn(localDate); + when(attendanceRepository.existsByUserAndAttendanceDateTimeGreaterThanEqual(user, localDate.atStartOfDay())) + .thenReturn(true); + Location location = new Location(37.539927, 127.073006); // expect diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java index 79cf361..af5342d 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/attendance/application/AttendanceSearchServiceTest.java @@ -17,11 +17,8 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; -import java.util.Random; -import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.any; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -37,38 +34,37 @@ class AttendanceSearchServiceTest { private DateTimeService dateTimeService; @Test - @DisplayName("한달동안의 출석정보가 정렬되어 반환된다") + @DisplayName("30일 동안의 출석정보가 정렬되어 반환된다") void findAttendanceForMonth_1() { // given + LocalDate localDate = LocalDate.of(2024, 7, 1); when(dateTimeService.getLocalDateNow()) - .thenReturn(LocalDate.of(2024, 7, 1)); + .thenReturn(localDate); - Random random = new Random(); - LocalDateTime now = LocalDateTime.of(2024, 7, 1, 0, 0); User user = TestUtil.createUser(); + LocalDateTime localDateTime = localDate.atStartOfDay(); Location location = new Location(37.539927, 127.073006); - - List attendances = new ArrayList<>(); - List expected = new ArrayList<>(); - IntStream.iterate(1, x -> x + 1) - .limit(30) - .map(x -> random.nextInt(30)) - .distinct() - .sorted() - .forEach(x -> { - Attendance attendance = Attendance.of(user, location, now.plusDays(x)); - - attendances.add(attendance); - expected.add(attendance.getAttendanceDateTime()); - }); - when(attendanceRepository.findByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) + List attendances = List.of( + Attendance.of(user, location, localDateTime.minusDays(1)), + Attendance.of(user, location, localDateTime.minusDays(2)), + Attendance.of(user, location, localDateTime.minusDays(15)), + Attendance.of(user, location, localDateTime.minusDays(29)), + Attendance.of(user, location, localDateTime.minusDays(30)) + ); + + int agoDays = 30; + LocalDateTime agoDateTime = localDate.minusDays(agoDays).atStartOfDay(); + when(attendanceRepository.findByUserAndAttendanceDateTimeGreaterThanEqual(user, agoDateTime)) .thenReturn(attendances); - // when - List result = attendanceSearchService.findAttendance(user, 30); + List result = attendanceSearchService.findAttendance(user, agoDays); // then + List expected = attendances.stream() + .map(Attendance::getAttendanceDateTime) + .sorted() + .toList(); assertThat(result).isEqualTo(expected); } @@ -76,16 +72,21 @@ void findAttendanceForMonth_1() { @DisplayName("출석정보가 없으면 빈리스트가 반환된다") void findAttendanceForMonth_2() { // given + LocalDate localDate = LocalDate.of(2024, 7, 1); when(dateTimeService.getLocalDateNow()) - .thenReturn(LocalDate.of(2024, 7, 1)); - when(attendanceRepository.findByUserAndAttendanceDateTimeAfter(any(User.class), any(LocalDateTime.class))) + .thenReturn(localDate); + + User user = TestUtil.createUser(); + int agoDays = 30; + LocalDateTime agoDateTime = localDate.minusDays(agoDays).atStartOfDay(); + when(attendanceRepository.findByUserAndAttendanceDateTimeGreaterThanEqual(user, agoDateTime)) .thenReturn(new ArrayList<>()); // when - User user = TestUtil.createUser(); - List result = attendanceSearchService.findAttendance(user, 30); + List result = attendanceSearchService.findAttendance(user, agoDays); // then assertThat(result).isEmpty(); } + } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java index 8ec5dcc..c06fe4f 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java @@ -5,7 +5,6 @@ import com.playkuround.playkuroundserver.domain.badge.dao.BadgeRepository; import com.playkuround.playkuroundserver.domain.badge.domain.Badge; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; -import com.playkuround.playkuroundserver.domain.badge.dto.NewlyRegisteredBadge; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; @@ -109,26 +108,26 @@ class updateNewlyAttendanceBadges { static Stream generateAttendanceBadgeTestData() { return Stream.of( Arguments.of(1, - List.of(BadgeType.ATTENDANCE_1.name())), + List.of(BadgeType.ATTENDANCE_1)), Arguments.of(5, - List.of(BadgeType.ATTENDANCE_1.name(), - BadgeType.ATTENDANCE_5.name())), + List.of(BadgeType.ATTENDANCE_1, + BadgeType.ATTENDANCE_5)), Arguments.of(10, - List.of(BadgeType.ATTENDANCE_1.name(), - BadgeType.ATTENDANCE_5.name(), - BadgeType.ATTENDANCE_10.name())), + List.of(BadgeType.ATTENDANCE_1, + BadgeType.ATTENDANCE_5, + BadgeType.ATTENDANCE_10)), Arguments.of(30, - List.of(BadgeType.ATTENDANCE_1.name(), - BadgeType.ATTENDANCE_5.name(), - BadgeType.ATTENDANCE_10.name(), - BadgeType.ATTENDANCE_30.name())) + List.of(BadgeType.ATTENDANCE_1, + BadgeType.ATTENDANCE_5, + BadgeType.ATTENDANCE_10, + BadgeType.ATTENDANCE_30)) ); } @ParameterizedTest @MethodSource("generateAttendanceBadgeTestData") @DisplayName("출석 횟수에 따른 배지 획득") - void success_1(int attendanceDay, List expected) { + void success_1(int attendanceDay, List expected) { // given User user = TestUtil.createUser(); for (int i = 0; i < attendanceDay; i++) { @@ -139,7 +138,7 @@ void success_1(int attendanceDay, List expected) { when(dateTimeService.getLocalDateNow()) .thenReturn(LocalDate.of(2024, 7, 1)); - List result; + List result; try (MockedStatic mockedStatic = Mockito.mockStatic(DateTimeUtils.class)) { mockedStatic.when(() -> DateTimeUtils.isDuckDay(any())).thenReturn(false); mockedStatic.when(() -> DateTimeUtils.isArborDay(any())).thenReturn(false); @@ -148,15 +147,11 @@ void success_1(int attendanceDay, List expected) { mockedStatic.when(() -> DateTimeUtils.isFoundationDay(any())).thenReturn(false); // when - NewlyRegisteredBadge newlyRegisteredBadge = badgeService.updateNewlyAttendanceBadges(user); - result = newlyRegisteredBadge.getNewlyBadges(); + result = badgeService.updateNewlyAttendanceBadges(user); } // then - List target = result.stream() - .map(NewlyRegisteredBadge.BadgeInfo::name) - .toList(); - assertThat(target).isEqualTo(expected); + assertThat(result).isEqualTo(expected); } @Test @@ -169,7 +164,7 @@ void success_2() { when(dateTimeService.getLocalDateNow()) .thenReturn(LocalDate.of(2024, 7, 1)); - List result; + List result; try (MockedStatic mockedStatic = Mockito.mockStatic(DateTimeUtils.class)) { mockedStatic.when(() -> DateTimeUtils.isDuckDay(any())).thenReturn(false); mockedStatic.when(() -> DateTimeUtils.isArborDay(any())).thenReturn(false); @@ -178,13 +173,12 @@ void success_2() { mockedStatic.when(() -> DateTimeUtils.isFoundationDay(any())).thenReturn(false); // when - NewlyRegisteredBadge newlyRegisteredBadge = badgeService.updateNewlyAttendanceBadges(user); - result = newlyRegisteredBadge.getNewlyBadges(); + result = badgeService.updateNewlyAttendanceBadges(user); } // then - assertThat(result).hasSize(1); - assertThat(result.get(0).name()).isEqualTo(BadgeType.ATTENDANCE_CHILDREN_DAY.name()); + assertThat(result).hasSize(1) + .containsExactly(BadgeType.ATTENDANCE_CHILDREN_DAY); } @Test @@ -204,7 +198,7 @@ void success_3() { when(dateTimeService.getLocalDateNow()) .thenReturn(LocalDate.of(2024, 7, 1)); - List result; + List result; try (MockedStatic mockedStatic = Mockito.mockStatic(DateTimeUtils.class)) { mockedStatic.when(() -> DateTimeUtils.isDuckDay(any())).thenReturn(false); mockedStatic.when(() -> DateTimeUtils.isArborDay(any())).thenReturn(false); @@ -213,20 +207,12 @@ void success_3() { mockedStatic.when(() -> DateTimeUtils.isFoundationDay(any())).thenReturn(false); // when - NewlyRegisteredBadge newlyRegisteredBadge = badgeService.updateNewlyAttendanceBadges(user); - result = newlyRegisteredBadge.getNewlyBadges(); + result = badgeService.updateNewlyAttendanceBadges(user); } // then - assertThat(result).hasSize(2); - - List target = result.stream() - .map(NewlyRegisteredBadge.BadgeInfo::name) - .toList(); - assertThat(target).containsOnly( - BadgeType.ATTENDANCE_5.name(), - BadgeType.ATTENDANCE_30.name() - ); + assertThat(result).hasSize(2) + .containsExactlyInAnyOrder(BadgeType.ATTENDANCE_5, BadgeType.ATTENDANCE_30); } } @@ -237,47 +223,47 @@ class updateNewlyAdventureBadges { static Stream generateAdventureBadgeTestData() { return Stream.of( Arguments.of(LandmarkType.인문학관, - List.of(BadgeType.COLLEGE_OF_LIBERAL_ARTS.name())), + List.of(BadgeType.COLLEGE_OF_LIBERAL_ARTS)), Arguments.of(LandmarkType.과학관, - List.of(BadgeType.COLLEGE_OF_SCIENCES.name())), + List.of(BadgeType.COLLEGE_OF_SCIENCES)), Arguments.of(LandmarkType.건축관, - List.of(BadgeType.COLLEGE_OF_ARCHITECTURE.name())), + List.of(BadgeType.COLLEGE_OF_ARCHITECTURE)), Arguments.of(LandmarkType.공학관A, - List.of(BadgeType.COLLEGE_OF_ENGINEERING.name(), - BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY.name())), + List.of(BadgeType.COLLEGE_OF_ENGINEERING, + BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY)), Arguments.of(LandmarkType.공학관B, - List.of(BadgeType.COLLEGE_OF_ENGINEERING.name(), - BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY.name())), + List.of(BadgeType.COLLEGE_OF_ENGINEERING, + BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY)), Arguments.of(LandmarkType.공학관C, - List.of(BadgeType.COLLEGE_OF_ENGINEERING.name(), - BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY.name())), + List.of(BadgeType.COLLEGE_OF_ENGINEERING, + BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY)), Arguments.of(LandmarkType.신공학관, - List.of(BadgeType.COLLEGE_OF_ENGINEERING.name())), + List.of(BadgeType.COLLEGE_OF_ENGINEERING)), Arguments.of(LandmarkType.상허연구관, - List.of(BadgeType.COLLEGE_OF_SOCIAL_SCIENCES.name())), + List.of(BadgeType.COLLEGE_OF_SOCIAL_SCIENCES)), Arguments.of(LandmarkType.경영관, - List.of(BadgeType.COLLEGE_OF_BUSINESS_ADMINISTRATION.name())), + List.of(BadgeType.COLLEGE_OF_BUSINESS_ADMINISTRATION)), Arguments.of(LandmarkType.부동산학관, - List.of(BadgeType.COLLEGE_OF_REAL_ESTATE.name())), + List.of(BadgeType.COLLEGE_OF_REAL_ESTATE)), Arguments.of(LandmarkType.생명과학관, - List.of(BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY.name())), + List.of(BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY)), Arguments.of(LandmarkType.동물생명과학관, - List.of(BadgeType.COLLEGE_OF_BIOLOGICAL_SCIENCES.name())), + List.of(BadgeType.COLLEGE_OF_BIOLOGICAL_SCIENCES)), Arguments.of(LandmarkType.수의학관, - List.of(BadgeType.COLLEGE_OF_VETERINARY_MEDICINE.name())), + List.of(BadgeType.COLLEGE_OF_VETERINARY_MEDICINE)), Arguments.of(LandmarkType.예디대, - List.of(BadgeType.COLLEGE_OF_ART_AND_DESIGN.name())), + List.of(BadgeType.COLLEGE_OF_ART_AND_DESIGN)), Arguments.of(LandmarkType.공예관, - List.of(BadgeType.COLLEGE_OF_ART_AND_DESIGN.name())), + List.of(BadgeType.COLLEGE_OF_ART_AND_DESIGN)), Arguments.of(LandmarkType.교육과학관, - List.of(BadgeType.COLLEGE_OF_EDUCATION.name())) + List.of(BadgeType.COLLEGE_OF_EDUCATION)) ); } @ParameterizedTest @MethodSource("generateAdventureBadgeTestData") @DisplayName("대학별 배지") - void success_1(LandmarkType landmarkType, List badgeTypeList) throws Exception { + void success_1(LandmarkType landmarkType, List badgeTypeList) throws Exception { // given User user = TestUtil.createUser(); when(badgeRepository.findByUser(user)) @@ -288,14 +274,10 @@ void success_1(LandmarkType landmarkType, List badgeTypeList) throws Exc Landmark landmark = createLandmark(landmarkType); // when - NewlyRegisteredBadge newlyRegisteredBadge = badgeService.updateNewlyAdventureBadges(user, landmark); + List newlyRegisteredBadge = badgeService.updateNewlyAdventureBadges(user, landmark); // then - List result = newlyRegisteredBadge.getNewlyBadges(); - List target = result.stream() - .map(NewlyRegisteredBadge.BadgeInfo::name) - .toList(); - assertThat(target).isEqualTo(badgeTypeList); + assertThat(newlyRegisteredBadge).containsExactlyInAnyOrderElementsOf(badgeTypeList); } @Test @@ -311,17 +293,13 @@ void success_2() throws Exception { Landmark landmark = createLandmark(LandmarkType.공학관A); // when - NewlyRegisteredBadge newlyRegisteredBadge = badgeService.updateNewlyAdventureBadges(user, landmark); + List result = badgeService.updateNewlyAdventureBadges(user, landmark); // then - List result = newlyRegisteredBadge.getNewlyBadges(); - List target = result.stream() - .map(NewlyRegisteredBadge.BadgeInfo::name) - .toList(); - assertThat(target).containsOnly( - BadgeType.COLLEGE_OF_ENGINEERING.name(), - BadgeType.COLLEGE_OF_ENGINEERING_A.name(), - BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY.name() + assertThat(result).containsExactlyInAnyOrder( + BadgeType.COLLEGE_OF_ENGINEERING, + BadgeType.COLLEGE_OF_ENGINEERING_A, + BadgeType.COLLEGE_OF_INSTITUTE_TECHNOLOGY ); } From 2b52963f94eae83ab69b394423b255f228d01ce5 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Tue, 3 Sep 2024 14:07:16 +0900 Subject: [PATCH 68/79] refactor: authEmail, token --- .../domain/auth/email/api/AuthEmailApi.java | 2 +- .../application/AuthEmailSendServiceImpl.java | 11 +++- .../AuthEmailVerifyServiceImpl.java | 11 ++-- .../auth/email/application/CodeGenerator.java | 11 ++-- .../auth/email/dao/AuthEmailRepository.java | 2 +- .../auth/token/application/TokenManager.java | 7 +- .../application/TokenReissueService.java | 10 +-- .../auth/token/application/TokenService.java | 12 ++-- .../auth/token/domain/RefreshToken.java | 1 + .../domain/auth/token/domain/TokenType.java | 8 +-- .../user/application/UserLoginService.java | 2 +- .../application/AuthEmailSendServiceTest.java | 58 +++++++++++------ .../AuthEmailVerifyServiceTest.java | 64 +++++++++---------- .../domain/auth/token/api/TokenApiTest.java | 35 +++++----- .../user/api/UserManagementApiTest.java | 10 +-- 15 files changed, 125 insertions(+), 119 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java index 6c60564..9fd5f0f 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/api/AuthEmailApi.java @@ -26,7 +26,7 @@ public class AuthEmailApi { @PostMapping @Operation(summary = "인증메일 전송", description = "해당 메일로 숫자 6자리의 인증 코드를 전송합니다. " + - "인증 메일 전송은 자정을 기준으로 최대 5번까지 가능합니다. 또한 인증 유효시간은 5분입니다.") + "인증 메일 전송은 자정을 기준으로 이메일당 최대 5번까지 가능합니다. 또한 인증 유효시간은 5분입니다.") public ApiResponse authEmailSend(@RequestBody @Valid AuthEmailSendRequest requestDto) { AuthEmailInfo authEmailInfo = authEmailSendService.sendAuthEmail(requestDto.getTarget().toLowerCase()); return ApiUtils.success(AuthEmailSendResponse.from(authEmailInfo)); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java index 582a4d1..7038860 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java @@ -5,6 +5,7 @@ import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthEmailInfo; import com.playkuround.playkuroundserver.domain.auth.email.exception.NotKUEmailException; import com.playkuround.playkuroundserver.domain.auth.email.exception.SendingLimitExceededException; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.infra.email.EmailService; import com.playkuround.playkuroundserver.infra.email.Mail; import lombok.RequiredArgsConstructor; @@ -26,6 +27,7 @@ public class AuthEmailSendServiceImpl implements AuthEmailSendService { private final EmailService emailService; private final AuthEmailRepository authEmailRepository; + private final DateTimeService dateTimeService; private final TemplateEngine templateEngine; @Value("${authentication.email.domain}") @@ -62,8 +64,9 @@ private void validateEmailDomain(String target) { } private long validateSendingCount(String target) { - LocalDateTime today = LocalDate.now().atStartOfDay(); - long sendingCount = authEmailRepository.countByTargetAndCreatedAtAfter(target, today); + LocalDate today = dateTimeService.getLocalDateNow(); + LocalDateTime startOfToday = today.atStartOfDay(); + long sendingCount = authEmailRepository.countByTargetAndCreatedAtGreaterThanEqual(target, startOfToday); if (sendingCount >= maxSendingCount) { throw new SendingLimitExceededException(); } @@ -71,7 +74,9 @@ private long validateSendingCount(String target) { } private LocalDateTime saveAuthEmail(String target, String authenticationCode) { - LocalDateTime expiredAt = LocalDateTime.now().plusSeconds(codeExpirationSeconds); + LocalDateTime now = dateTimeService.getLocalDateTimeNow(); + LocalDateTime expiredAt = now.plusSeconds(codeExpirationSeconds); + AuthEmail authEmail = AuthEmail.createAuthEmail(target, authenticationCode, expiredAt); authEmailRepository.save(authEmail); return expiredAt; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceImpl.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceImpl.java index d9420e9..a9648b2 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceImpl.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceImpl.java @@ -13,7 +13,7 @@ import com.playkuround.playkuroundserver.domain.auth.token.dto.TokenDto; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.user.application.UserLoginService; -import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; +import com.playkuround.playkuroundserver.domain.user.exception.UserNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; @@ -25,7 +25,6 @@ public class AuthEmailVerifyServiceImpl implements AuthEmailVerifyService { private final TokenService tokenService; - private final UserRepository userRepository; private final UserLoginService userLoginService; private final AuthEmailRepository authEmailRepository; private final DateTimeService dateTimeService; @@ -38,13 +37,11 @@ public AuthVerifyEmailResult verifyAuthEmail(String code, String email) { validateEmailAndCode(authEmail, code); authEmail.changeInvalidate(); - boolean existsUser = userRepository.existsByEmail(email); - if (existsUser) { + try { TokenDto tokenDto = userLoginService.login(email); return new TokenDtoResult(tokenDto); - } - else { - AuthVerifyToken authVerifyToken = tokenService.registerAuthVerifyToken(); + } catch (UserNotFoundException e) { + AuthVerifyToken authVerifyToken = tokenService.saveAuthVerifyToken(); return new AuthVerifyTokenResult(authVerifyToken.getAuthVerifyToken()); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/CodeGenerator.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/CodeGenerator.java index 5f124e5..6617215 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/CodeGenerator.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/CodeGenerator.java @@ -11,14 +11,11 @@ public String generateCode(Set codeTypeSet, long codeLength) { String characters = createCharacters(codeTypeSet); - StringBuilder codeBuilder = new StringBuilder(); Random random = new Random(); - for (int i = 0; i < codeLength; i++) { - int index = random.nextInt(characters.length()); - char randomChar = characters.charAt(index); - codeBuilder.append(randomChar); - } - return codeBuilder.toString(); + return random.ints(codeLength, 0, characters.length()) + .mapToObj(characters::charAt) + .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) + .toString(); } private void validateParameters(Set codeTypeSet, long codeLength) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/dao/AuthEmailRepository.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/dao/AuthEmailRepository.java index e7e121f..f540e77 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/dao/AuthEmailRepository.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/dao/AuthEmailRepository.java @@ -10,6 +10,6 @@ public interface AuthEmailRepository extends JpaRepository { Optional findFirstByTargetOrderByCreatedAtDesc(String target); - long countByTargetAndCreatedAtAfter(String target, LocalDateTime localDateTime); + long countByTargetAndCreatedAtGreaterThanEqual(String target, LocalDateTime localDateTime); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenManager.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenManager.java index 81fe6b0..299b2ab 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenManager.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenManager.java @@ -23,6 +23,7 @@ import java.security.Key; import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.UUID; @@ -152,9 +153,9 @@ public String getTokenType(String token) { } public AuthVerifyToken createAuthVerifyTokenEntity() { - String key = UUID.randomUUID().toString(); + String token = UUID.randomUUID().toString(); LocalDateTime now = dateTimeService.getLocalDateTimeNow(); - return new AuthVerifyToken(key, now.plusSeconds(authVerifyTokenValidityInSeconds)); + return new AuthVerifyToken(token, now.plusSeconds(authVerifyTokenValidityInSeconds)); } public RefreshToken createRefreshTokenEntity(String username, String refreshToken) { @@ -162,7 +163,7 @@ public RefreshToken createRefreshTokenEntity(String username, String refreshToke return RefreshToken.builder() .userEmail(username) .refreshToken(refreshToken) - .expiredAt(now.plusSeconds(refreshTokenValidityInMilliseconds / 1000)) + .expiredAt(now.plus(refreshTokenValidityInMilliseconds, ChronoUnit.MILLIS)) .build(); } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenReissueService.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenReissueService.java index 5c73c26..77bd223 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenReissueService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenReissueService.java @@ -17,14 +17,14 @@ public class TokenReissueService { @Transactional public TokenDto reissue(String refreshToken) { - String username = tokenManager.getUsernameFromToken(refreshToken); - - if (!refreshTokenRepository.existsByUserEmail(username)) { + String userEmail = tokenManager.getUsernameFromToken(refreshToken); + if (!refreshTokenRepository.existsByUserEmail(userEmail)) { throw new InvalidRefreshTokenException(); } - TokenDto tokenDto = tokenManager.createTokenDto(username); - tokenService.registerRefreshToken(username, tokenDto.getRefreshToken()); + TokenDto tokenDto = tokenManager.createTokenDto(userEmail); + tokenService.saveRefreshToken(userEmail, tokenDto.getRefreshToken()); + return tokenDto; } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenService.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenService.java index 0ccc212..bf32c49 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/application/TokenService.java @@ -19,22 +19,22 @@ public class TokenService { private final RefreshTokenRepository refreshTokenRepository; private final AuthVerifyTokenRepository authVerifyTokenRepository; - public void registerRefreshToken(String username, String sRefreshToken) { + public void saveRefreshToken(String username, String sRefreshToken) { refreshTokenRepository.deleteByUserEmail(username); RefreshToken refreshToken = tokenManager.createRefreshTokenEntity(username, sRefreshToken); refreshTokenRepository.save(refreshToken); } - public void deleteRefreshTokenByUser(User user) { - refreshTokenRepository.deleteByUserEmail(user.getEmail()); - } - - public AuthVerifyToken registerAuthVerifyToken() { + public AuthVerifyToken saveAuthVerifyToken() { AuthVerifyToken authVerifyToken = tokenManager.createAuthVerifyTokenEntity(); return authVerifyTokenRepository.save(authVerifyToken); } + public void deleteRefreshTokenByUser(User user) { + refreshTokenRepository.deleteByUserEmail(user.getEmail()); + } + @Transactional(readOnly = true) public void validateAuthVerifyToken(String authVerifyToken) { if (!authVerifyTokenRepository.existsByAuthVerifyToken(authVerifyToken)) { diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/domain/RefreshToken.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/domain/RefreshToken.java index 74f69ae..6d84d2a 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/domain/RefreshToken.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/domain/RefreshToken.java @@ -12,6 +12,7 @@ @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(indexes = @Index(name = "idx_user_email", columnList = "userEmail")) public class RefreshToken { @Id diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/domain/TokenType.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/domain/TokenType.java index b206246..32482b7 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/domain/TokenType.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/token/domain/TokenType.java @@ -1,11 +1,5 @@ package com.playkuround.playkuroundserver.domain.auth.token.domain; public enum TokenType { - - ACCESS, REFRESH; - - public static boolean isAccessToken(String tokenType) { - return TokenType.ACCESS.name().equals(tokenType); - } - + ACCESS, REFRESH } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserLoginService.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserLoginService.java index 450ff82..1279652 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserLoginService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/application/UserLoginService.java @@ -22,7 +22,7 @@ public TokenDto login(String userEmail) { throw new UserNotFoundException(); } TokenDto tokenDto = tokenManager.createTokenDto(userEmail); - tokenService.registerRefreshToken(userEmail, tokenDto.getRefreshToken()); + tokenService.saveRefreshToken(userEmail, tokenDto.getRefreshToken()); return tokenDto; } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java index 33e8ed6..d062f6d 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java @@ -5,6 +5,7 @@ import com.playkuround.playkuroundserver.domain.auth.email.dto.AuthEmailInfo; import com.playkuround.playkuroundserver.domain.auth.email.exception.NotKUEmailException; import com.playkuround.playkuroundserver.domain.auth.email.exception.SendingLimitExceededException; +import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.infra.email.EmailService; import com.playkuround.playkuroundserver.infra.email.Mail; import org.junit.jupiter.api.BeforeEach; @@ -21,6 +22,7 @@ import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; +import java.time.LocalDate; import java.time.LocalDateTime; import static org.assertj.core.api.Assertions.assertThat; @@ -43,43 +45,53 @@ class AuthEmailSendServiceTest { @Mock private TemplateEngine templateEngine; + @Mock + private DateTimeService dateTimeService; + + private final long codeLength = 6L; + private final long maxSendingCount = 3L; + private final String emailDomain = "test.com"; + private final long codeExpirationSeconds = 300L; + @BeforeEach void setUp() { - ReflectionTestUtils.setField(authEmailSendService, "codeLength", 6L); - ReflectionTestUtils.setField(authEmailSendService, "maxSendingCount", 3L); - ReflectionTestUtils.setField(authEmailSendService, "emailDomain", "test.com"); - ReflectionTestUtils.setField(authEmailSendService, "codeExpirationSeconds", 300L); + ReflectionTestUtils.setField(authEmailSendService, "codeLength", codeLength); + ReflectionTestUtils.setField(authEmailSendService, "maxSendingCount", maxSendingCount); + ReflectionTestUtils.setField(authEmailSendService, "emailDomain", emailDomain); + ReflectionTestUtils.setField(authEmailSendService, "codeExpirationSeconds", codeExpirationSeconds); } @Test - @DisplayName("이메일 정상 정송") + @DisplayName("숫자로 이루어진 인증 번호가 저장되고, 이메일로 전송된다.") void sendAuthEmail_1() { // given + LocalDateTime now = LocalDateTime.of(2024, 9, 3, 13, 0, 0); + when(dateTimeService.getLocalDateTimeNow()).thenReturn(now); + when(dateTimeService.getLocalDateNow()).thenReturn(now.toLocalDate()); + + String target = "test@" + emailDomain; + long sendingCount = 0; + when(authEmailRepository.countByTargetAndCreatedAtGreaterThanEqual(target, now.toLocalDate().atStartOfDay())) + .thenReturn(sendingCount); + String content = "email content"; - when(authEmailRepository.countByTargetAndCreatedAtAfter(any(String.class), any(LocalDateTime.class))) - .thenReturn(0L); when(templateEngine.process(any(String.class), any(Context.class))) .thenReturn(content); // when - String target = "test@test.com"; AuthEmailInfo result = authEmailSendService.sendAuthEmail(target); // then - assertThat(result.sendingCount()).isEqualTo(1L); + assertThat(result.sendingCount()).isEqualTo(sendingCount + 1); + assertThat(result.expiredAt()).isEqualTo(now.plusSeconds(codeExpirationSeconds)); ArgumentCaptor authEmailArgument = ArgumentCaptor.forClass(AuthEmail.class); verify(authEmailRepository, times(1)).save(authEmailArgument.capture()); AuthEmail authEmail = authEmailArgument.getValue(); assertThat(authEmail.getTarget()).isEqualTo(target); - assertThat(authEmail.getCode()).containsPattern("[0-9]{6}"); - - ArgumentCaptor mailArgument = ArgumentCaptor.forClass(Mail.class); - verify(emailService, times(1)).sendMail(mailArgument.capture()); - Mail mail = mailArgument.getValue(); - assertThat(mail.target()).isEqualTo(target); - assertThat(mail.content()).contains(content); - assertThat(mail.title()).isEqualTo("[플레이쿠라운드] 회원가입 인증코드입니다."); + assertThat(authEmail.getCode()).containsPattern("[0-9]{" + codeLength + "}"); + + verify(emailService, times(1)).sendMail(new Mail(target, "[플레이쿠라운드] 회원가입 인증코드입니다.", content)); } @ParameterizedTest @@ -94,11 +106,15 @@ void sendAuthEmail_2(String target) { @DisplayName("하루 최대 전송횟수 이상은 메일을 보낼 수 없다.") void sendAuthEmail_3() { // given - when(authEmailRepository.countByTargetAndCreatedAtAfter(any(String.class), any(LocalDateTime.class))) - .thenReturn(3L); + LocalDate today = LocalDate.of(2024, 9, 3); + when(dateTimeService.getLocalDateNow()).thenReturn(today); - // when - assertThatThrownBy(() -> authEmailSendService.sendAuthEmail("email@test.com")) + String target = "email@test.com"; + when(authEmailRepository.countByTargetAndCreatedAtGreaterThanEqual(target, today.atStartOfDay())) + .thenReturn(maxSendingCount); + + // when & then + assertThatThrownBy(() -> authEmailSendService.sendAuthEmail(target)) .isInstanceOf(SendingLimitExceededException.class); } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java index e336278..2399aa3 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailVerifyServiceTest.java @@ -14,8 +14,8 @@ import com.playkuround.playkuroundserver.domain.auth.token.dto.TokenDto; import com.playkuround.playkuroundserver.domain.common.DateTimeService; import com.playkuround.playkuroundserver.domain.user.application.UserLoginService; -import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.User; +import com.playkuround.playkuroundserver.domain.user.exception.UserNotFoundException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -28,7 +28,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -40,9 +39,6 @@ class AuthEmailVerifyServiceTest { @Mock private TokenService tokenService; - @Mock - private UserRepository userRepository; - @Mock private UserLoginService userLoginService; @@ -53,7 +49,7 @@ class AuthEmailVerifyServiceTest { private DateTimeService dateTimeService; @Test - @DisplayName("이메일 인증 정상 처리 : 기존회원") + @DisplayName("이메일 인증 정상 처리 : 기존회원인 경우 TokenDto 반환") void authEmailSuccessExists() { // given User user = TestUtil.createUser(); @@ -63,11 +59,8 @@ void authEmailSuccessExists() { AuthEmail authEmail = AuthEmail.createAuthEmail(target, code, expiredAt); when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(target)) .thenReturn(Optional.of(authEmail)); - when(userRepository.existsByEmail(target)) - .thenReturn(true); when(dateTimeService.getLocalDateTimeNow()) - .thenReturn(expiredAt.minusMinutes(2)); - + .thenReturn(expiredAt.minusHours(1)); TokenDto tokenDto = new TokenDto("Bearer", "accessToken", "refreshToken", null, null); when(userLoginService.login(target)).thenReturn(tokenDto); @@ -84,7 +77,7 @@ void authEmailSuccessExists() { } @Test - @DisplayName("이메일 인증 정상 처리 : 신규회원") + @DisplayName("이메일 인증 정상 처리 : 신규회원인 경우 authVerifyToken 반환") void authEmailSuccessNewUser() { // given User user = TestUtil.createUser(); @@ -95,13 +88,13 @@ void authEmailSuccessNewUser() { AuthEmail authEmail = AuthEmail.createAuthEmail(target, code, expiredAt); when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(target)) .thenReturn(Optional.of(authEmail)); - when(userRepository.existsByEmail(target)) - .thenReturn(false); when(dateTimeService.getLocalDateTimeNow()) - .thenReturn(expiredAt.minusMinutes(2)); + .thenReturn(expiredAt.minusHours(1)); + when(userLoginService.login(target)) + .thenThrow(UserNotFoundException.class); AuthVerifyToken authVerifyToken = new AuthVerifyToken(authVerify, null); - when(tokenService.registerAuthVerifyToken()).thenReturn(authVerifyToken); + when(tokenService.saveAuthVerifyToken()).thenReturn(authVerifyToken); // when AuthVerifyEmailResult result = authEmailVerifyService.verifyAuthEmail(code, target); @@ -113,60 +106,63 @@ void authEmailSuccessNewUser() { } @Test - @DisplayName("AuthEmail entity가 없으면 AuthEmailNotFoundException 발생") + @DisplayName("AuthEmail entity가 없으면 AuthEmailNotFoundException 발생한다.") void emptyAuthEmailEntity() { // given - when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(any(String.class))) + String target = "test@konkuk.ac.kr"; + when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(target)) .thenReturn(Optional.empty()); // expected - assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail("code", "target")) + assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail("code", target)) .isInstanceOf(AuthEmailNotFoundException.class); } @Test - @DisplayName("authEmail이 유효하지 않으면 AuthEmailNotFoundException 발생") + @DisplayName("authEmail이 유효하지 않으면 AuthEmailNotFoundException 발생한다.") void authEmailInvalidate() { // given - AuthEmail authEmail = AuthEmail.createAuthEmail("target", "code", LocalDateTime.now()); + AuthEmail authEmail = AuthEmail.createAuthEmail("test@konkuk.ac.kr", "code", LocalDateTime.now()); authEmail.changeInvalidate(); - when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(any(String.class))) + when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(authEmail.getTarget())) .thenReturn(Optional.of(authEmail)); // expected - assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail("code", "target")) + assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail(authEmail.getCode(), authEmail.getTarget())) .isInstanceOf(AuthEmailNotFoundException.class); } @Test - @DisplayName("authEmail이 만료되면 AuthCodeExpiredException 발생") + @DisplayName("authEmail이 만료되면 AuthCodeExpiredException 발생한다.") void authEmailExpired() { // given LocalDateTime now = LocalDateTime.of(2024, 7, 1, 0, 0); - AuthEmail authEmail = AuthEmail.createAuthEmail("target", "code", now.minusDays(1)); - when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(any(String.class))) - .thenReturn(Optional.of(authEmail)); when(dateTimeService.getLocalDateTimeNow()) .thenReturn(now); + AuthEmail authEmail = AuthEmail.createAuthEmail("test@konkuk.ac.kr", "code", now.minusDays(1)); + when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(authEmail.getTarget())) + .thenReturn(Optional.of(authEmail)); + // expected - assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail("code", "target")) + assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail(authEmail.getCode(), authEmail.getTarget())) .isInstanceOf(AuthCodeExpiredException.class); } @Test - @DisplayName("authEmail의 code가 일치하지 않으면 NotMatchAuthCodeException 발생") + @DisplayName("authEmail의 code가 일치하지 않으면 NotMatchAuthCodeException 발생한다.") void authEmailCodeNotEquals() { // given - String code = "code"; - AuthEmail authEmail = AuthEmail.createAuthEmail("target", code, LocalDateTime.now().plusMinutes(1)); - when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(any(String.class))) - .thenReturn(Optional.of(authEmail)); + LocalDateTime now = LocalDateTime.now(); when(dateTimeService.getLocalDateTimeNow()) - .thenReturn(LocalDateTime.of(2024, 7, 1, 0, 0)); + .thenReturn(now); + + AuthEmail authEmail = AuthEmail.createAuthEmail("test@konkuk.ac.kr", "code", now.plusMinutes(1)); + when(authEmailRepository.findFirstByTargetOrderByCreatedAtDesc(authEmail.getTarget())) + .thenReturn(Optional.of(authEmail)); // expected - assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail(code + "NotEqual", "target")) + assertThatThrownBy(() -> authEmailVerifyService.verifyAuthEmail(authEmail.getCode() + "NotEqual", authEmail.getTarget())) .isInstanceOf(NotMatchAuthCodeException.class); } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/token/api/TokenApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/token/api/TokenApiTest.java index 3fc296b..c273ab8 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/token/api/TokenApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/token/api/TokenApiTest.java @@ -1,6 +1,7 @@ package com.playkuround.playkuroundserver.domain.auth.token.api; import com.fasterxml.jackson.databind.ObjectMapper; +import com.playkuround.playkuroundserver.IntegrationControllerTest; import com.playkuround.playkuroundserver.TestUtil; import com.playkuround.playkuroundserver.domain.auth.token.api.request.TokenReissueRequest; import com.playkuround.playkuroundserver.domain.auth.token.dao.RefreshTokenRepository; @@ -15,8 +16,6 @@ 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.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; @@ -28,8 +27,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@AutoConfigureMockMvc -@SpringBootTest(properties = "spring.profiles.active=test") +@IntegrationControllerTest class TokenApiTest { @Autowired @@ -49,16 +47,15 @@ class TokenApiTest { @AfterEach void clean() { - refreshTokenRepository.deleteAll(); - userRepository.deleteAll(); + refreshTokenRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); } @Test - @DisplayName("토큰 재발급 성공") + @DisplayName("refreshToken이 유효한 상태라면, accessToken과 refreshToken이 모두 재발급된다.") void reissueSuccess() throws Exception { // given - User user = TestUtil.createUser(); - userRepository.save(user); + User user = userRepository.save(TestUtil.createUser()); TokenDto tokenDto = userLoginService.login(user.getEmail()); TokenReissueRequest tokenReissueRequest = new TokenReissueRequest(tokenDto.getRefreshToken()); @@ -67,8 +64,7 @@ void reissueSuccess() throws Exception { // expected mockMvc.perform(post("/api/auth/reissue") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isOk()) .andExpect(jsonPath("$.isSuccess").value(true)) .andExpect(jsonPath("$.response.grantType").value(GrantType.BEARER.getType())) @@ -77,7 +73,9 @@ void reissueSuccess() throws Exception { .andDo(print()); List refreshTokens = refreshTokenRepository.findAll(); - assertThat(refreshTokens.size()).isEqualTo(1); + assertThat(refreshTokens).hasSize(1) + .extracting("userEmail") + .containsExactly(user.getEmail()); } @Test @@ -90,22 +88,22 @@ void reissueFailByInvalidateRefreshToken() throws Exception { // expected mockMvc.perform(post("/api/auth/reissue") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isUnauthorized()) .andExpect(jsonPath("$.isSuccess").value(false)) .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.INVALID_TOKEN.getCode())) .andExpect(jsonPath("$.errorResponse.message").value(ErrorCode.INVALID_TOKEN.getMessage())) .andExpect(jsonPath("$.errorResponse.status").value(ErrorCode.INVALID_TOKEN.getStatus().value())) .andDo(print()); + + assertThat(refreshTokenRepository.count()).isZero(); } @Test @DisplayName("토큰 재발급 실패 : 존재하지 않는 refreshToken") void reissueFailByNotFoundRefreshToken() throws Exception { // given - User user = TestUtil.createUser(); - userRepository.save(user); + User user = userRepository.save(TestUtil.createUser()); TokenDto tokenDto = userLoginService.login(user.getEmail()); refreshTokenRepository.deleteAll(); @@ -115,13 +113,14 @@ void reissueFailByNotFoundRefreshToken() throws Exception { // expected mockMvc.perform(post("/api/auth/reissue") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isUnauthorized()) .andExpect(jsonPath("$.isSuccess").value(false)) .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.INVALID_TOKEN.getCode())) .andExpect(jsonPath("$.errorResponse.message").value(ErrorCode.INVALID_TOKEN.getMessage())) .andExpect(jsonPath("$.errorResponse.status").value(ErrorCode.INVALID_TOKEN.getStatus().value())) .andDo(print()); + + assertThat(refreshTokenRepository.count()).isZero(); } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApiTest.java index b61fdad..2b5b5ea 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApiTest.java @@ -69,7 +69,7 @@ void afterEach() { @DisplayName("회원 등록 성공") void userRegisterSuccess() throws Exception { // given - AuthVerifyToken authVerifyToken = tokenService.registerAuthVerifyToken(); + AuthVerifyToken authVerifyToken = tokenService.saveAuthVerifyToken(); // when UserRegisterRequest registerRequest @@ -105,7 +105,7 @@ void userRegisterSuccess() throws Exception { assertThat(user.getMajor()).isEqualTo(major); assertThat(user.getNickname()).isEqualTo(nickname); assertThat(user.getRole()).isEqualTo(Role.ROLE_USER); - assertThat(user.getAttendanceDays()).isEqualTo(0); + assertThat(user.getAttendanceDays()).isZero(); } @Test @@ -128,7 +128,7 @@ void userRegisterFailByNotExitsAuthVerifyToken() throws Exception { .andExpect(jsonPath("$.errorResponse.status").value(ErrorCode.INVALID_TOKEN.getStatus().value())) .andDo(print()); List users = userRepository.findAll(); - assertThat(users).hasSize(0); + assertThat(users).isEmpty(); } @Test @@ -137,7 +137,7 @@ void userRegisterFailByDuplicateEmail() throws Exception { // given User user = User.create(email, nickname, major, Role.ROLE_USER); userRepository.save(user); - AuthVerifyToken authVerifyToken = tokenService.registerAuthVerifyToken(); + AuthVerifyToken authVerifyToken = tokenService.saveAuthVerifyToken(); // when UserRegisterRequest registerRequest @@ -165,7 +165,7 @@ void userRegisterFailByDuplicateNickname() throws Exception { // given User user = User.create(email, nickname, major, Role.ROLE_USER); userRepository.save(user); - AuthVerifyToken authVerifyToken = tokenService.registerAuthVerifyToken(); + AuthVerifyToken authVerifyToken = tokenService.saveAuthVerifyToken(); // when UserRegisterRequest registerRequest From 986a8e197b375f59c7cb33d74da8bc0f22d489b2 Mon Sep 17 00:00:00 2001 From: Seungtaek Hong Date: Wed, 4 Sep 2024 00:47:01 +0900 Subject: [PATCH 69/79] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a766ba2..5ff757b 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,12 @@ Android - + + appstore + Instagram - Linktree @@ -32,9 +33,9 @@ | ## Server Stack -- Java 17 +- JDK 17 - Spring Boot 3.1.3 -- AWS EC2 +- AWS EC2, ELB - AWS RDS - AWS ElastiCache for Redis - Prometheus, Grafana From d4e7195317fd8acb7b259795d43ff72495c91a23 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Wed, 4 Sep 2024 11:39:40 +0900 Subject: [PATCH 70/79] refactor: landmark, score --- .../api/response/NearestLandmarkResponse.java | 2 +- .../domain/landmark/dto/NearestLandmark.java | 4 +- .../api/response/ScoreRankingResponse.java | 8 +- .../application/LandmarkRankService.java | 8 +- .../LandmarkFindNearServiceTest.java | 40 +++-- .../application/LandmarkRankServiceTest.java | 148 +++++++++++------- 6 files changed, 118 insertions(+), 92 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/NearestLandmarkResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/NearestLandmarkResponse.java index e7c365a..aa3ea74 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/NearestLandmarkResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/api/response/NearestLandmarkResponse.java @@ -27,7 +27,7 @@ private NearestLandmarkResponse(String name, Double distance, Long landmarkId) { } public static NearestLandmarkResponse from(NearestLandmark nearestLandmark) { - if (nearestLandmark.isHasResult()) { + if (nearestLandmark.getLandmarkId() != null) { return new NearestLandmarkResponse(nearestLandmark.getName(), nearestLandmark.getDistance(), nearestLandmark.getLandmarkId()); } return new NearestLandmarkResponse(); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/dto/NearestLandmark.java b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/dto/NearestLandmark.java index cbf94a5..812629c 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/landmark/dto/NearestLandmark.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/landmark/dto/NearestLandmark.java @@ -9,11 +9,9 @@ public class NearestLandmark { private String name; private Long landmarkId; private double distance; - private boolean hasResult = false; public void update(Landmark landmark, double distance) { - this.hasResult = true; - if (landmarkId == null || this.distance > distance) { + if (this.landmarkId == null || this.distance > distance) { this.distance = distance; this.landmarkId = landmark.getId(); this.name = landmark.getName().name(); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java index e39e175..d487c93 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/api/response/ScoreRankingResponse.java @@ -20,13 +20,13 @@ public static ScoreRankingResponse createEmptyResponse() { return new ScoreRankingResponse(); } - public void addRank(String nickname, int score, BadgeType badgeType) { - String badgeTypeName = badgeType != null ? badgeType.name() : null; + public void addRank(String nickname, int score, BadgeType profileBadgeType) { + String badgeTypeName = profileBadgeType != null ? profileBadgeType.name() : null; this.rank.add(new RankList(nickname, badgeTypeName, score)); } - public void setMyRank(int ranking, int score, BadgeType badgeType) { - String badgeTypeName = badgeType != null ? badgeType.name() : null; + public void setMyRank(int ranking, int score, BadgeType profileBadgeType) { + String badgeTypeName = profileBadgeType != null ? profileBadgeType.name() : null; this.myRank = new MyRank(ranking, score, badgeTypeName); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java index f157820..59e71d6 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankService.java @@ -24,15 +24,17 @@ public class LandmarkRankService { @Transactional(readOnly = true) public ScoreRankingResponse getRankTop100ByLandmark(User user, Long landmarkId) { ScoreRankingResponse response = ScoreRankingResponse.createEmptyResponse(); - LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.getLocalDateNow()); + LocalDateTime monthStartDateTime = DateTimeUtils.getMonthStartDateTime(dateTimeService.getLocalDateNow()); List nicknameAndScores = adventureRepository.findRankTop100DescByLandmarkId(landmarkId, monthStartDateTime); - nicknameAndScores.forEach(nicknameAndScore -> - response.addRank(nicknameAndScore.nickname(), nicknameAndScore.score(), nicknameAndScore.badgeType())); + for (NicknameAndScoreAndBadgeType nicknameAndScore : nicknameAndScores) { + response.addRank(nicknameAndScore.nickname(), nicknameAndScore.score(), nicknameAndScore.badgeType()); + } RankAndScore rankAndScore = adventureRepository.findMyRankByLandmarkId(user, landmarkId, monthStartDateTime) .orElseGet(() -> new RankAndScore(0, 0)); response.setMyRank(rankAndScore.ranking(), rankAndScore.score(), user.getProfileBadge()); + return response; } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkFindNearServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkFindNearServiceTest.java index a5d2066..f409350 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkFindNearServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/landmark/application/LandmarkFindNearServiceTest.java @@ -28,57 +28,53 @@ class LandmarkFindNearServiceTest { private LandmarkRepository landmarkRepository; @Test - @DisplayName("가장 가까운 랜드마크 조회") + @DisplayName("인식 반경 내에 여러 랜드마크가 있다면, 중심 좌표와 더 가까운 랜드마크가 반환된다.") void findNearestLandmark() { // given Landmark mockLandmark1 = mock(Landmark.class); when(mockLandmark1.getId()).thenReturn(1L); - when(mockLandmark1.getLatitude()).thenReturn(37.539927); when(mockLandmark1.getName()).thenReturn(LandmarkType.중문); + when(mockLandmark1.getLatitude()).thenReturn(37.539927); when(mockLandmark1.getLongitude()).thenReturn(127.073006); when(mockLandmark1.getRecognitionRadius()).thenReturn(20); Landmark mockLandmark2 = mock(Landmark.class); - when(mockLandmark2.getLatitude()).thenReturn(37.0); - when(mockLandmark2.getLongitude()).thenReturn(127.0); - when(mockLandmark2.getRecognitionRadius()).thenReturn(20); + when(mockLandmark2.getLatitude()).thenReturn(37.53992); + when(mockLandmark2.getLongitude()).thenReturn(127.07300); + when(mockLandmark2.getRecognitionRadius()).thenReturn(100); List landmarks = List.of(mockLandmark1, mockLandmark2); when(landmarkRepository.findAll()).thenReturn(landmarks); + Location location = new Location(mockLandmark1.getLatitude(), mockLandmark1.getLongitude()); + // when - Location location = new Location(37.539927, 127.073006); NearestLandmark nearestLandmark = landmarkFindNearService.findNearestLandmark(location); // then - assertThat(nearestLandmark.isHasResult()).isTrue(); - assertThat(nearestLandmark.getLandmarkId()).isEqualTo(1L); - assertThat(nearestLandmark.getName()).isEqualTo(LandmarkType.중문.name()); + assertThat(nearestLandmark.getLandmarkId()).isEqualTo(mockLandmark1.getId()); + assertThat(nearestLandmark.getName()).isEqualTo(mockLandmark1.getName().name()); } @Test - @DisplayName("인식 반경에 랜드마크가 없다면 결과 데이터가 없다.") + @DisplayName("인식 반경 내에 랜드마크가 없다면 결과 데이터가 없다.") void findNearestLandmarkEmpty() { // given - Landmark mockLandmark1 = mock(Landmark.class); - when(mockLandmark1.getLatitude()).thenReturn(37.539927); - when(mockLandmark1.getLongitude()).thenReturn(127.073006); - when(mockLandmark1.getRecognitionRadius()).thenReturn(5); - - Landmark mockLandmark2 = mock(Landmark.class); - when(mockLandmark2.getLatitude()).thenReturn(37.0); - when(mockLandmark2.getLongitude()).thenReturn(127.0); - when(mockLandmark2.getRecognitionRadius()).thenReturn(3); + Landmark mockLandmark = mock(Landmark.class); + when(mockLandmark.getLatitude()).thenReturn(37.539927); + when(mockLandmark.getLongitude()).thenReturn(127.073006); + when(mockLandmark.getRecognitionRadius()).thenReturn(5); - List landmarks = List.of(mockLandmark1, mockLandmark2); + List landmarks = List.of(mockLandmark); when(landmarkRepository.findAll()).thenReturn(landmarks); + Location location = new Location(0, 0); + // when - Location location = new Location(37.539, 127.0736); NearestLandmark nearestLandmark = landmarkFindNearService.findNearestLandmark(location); // then - assertThat(nearestLandmark.isHasResult()).isFalse(); + assertThat(nearestLandmark.getLandmarkId()).isNull(); } } \ No newline at end of file diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java index 504a291..cc5d7d0 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/score/application/LandmarkRankServiceTest.java @@ -8,6 +8,7 @@ import com.playkuround.playkuroundserver.domain.score.dto.NicknameAndScoreAndBadgeType; import com.playkuround.playkuroundserver.domain.score.dto.RankAndScore; import com.playkuround.playkuroundserver.domain.user.domain.User; +import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -17,13 +18,13 @@ import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -39,19 +40,24 @@ class LandmarkRankServiceTest { private DateTimeService dateTimeService; @Test - @DisplayName("랭킹 유저가 한명도 없을 때") + @DisplayName("랭킹 유저가 한명도 없으면 빈 응답을 반환한다.") void getRankTop100ByLandmark_1() { // given - when(adventureRepository.findRankTop100DescByLandmarkId(any(Long.class), any(LocalDateTime.class))) - .thenReturn(List.of()); - when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) - .thenReturn(Optional.empty()); + LocalDate localDate = LocalDate.of(2024, 7, 1); when(dateTimeService.getLocalDateNow()) - .thenReturn(LocalDate.of(2024, 7, 1)); + .thenReturn(localDate); + + Long landmarkId = 1L; + LocalDateTime startDateTime = DateTimeUtils.getMonthStartDateTime(localDate); + when(adventureRepository.findRankTop100DescByLandmarkId(landmarkId, startDateTime)) + .thenReturn(new ArrayList<>()); - // when User user = TestUtil.createUser(); - ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + when(adventureRepository.findMyRankByLandmarkId(user, landmarkId, startDateTime)) + .thenReturn(Optional.empty()); + + // when + ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, landmarkId); // then assertThat(result.getRank()).isEmpty(); @@ -63,28 +69,36 @@ void getRankTop100ByLandmark_1() { @DisplayName("전체 유저 100명 미만 + 내 랭킹은 없음") void getRankTop100ByLandmark_2() { // given - List nicknameAndScores = IntStream.rangeClosed(1, 50) - .mapToObj(i -> new NicknameAndScoreAndBadgeType("nickname" + (51 - i), 51 - i, null)) - .toList(); - when(adventureRepository.findRankTop100DescByLandmarkId(any(Long.class), any(LocalDateTime.class))) - .thenReturn(nicknameAndScores); - when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) - .thenReturn(Optional.empty()); + LocalDate localDate = LocalDate.of(2024, 7, 1); when(dateTimeService.getLocalDateNow()) - .thenReturn(LocalDate.of(2024, 7, 1)); + .thenReturn(localDate); + + Long landmarkId = 1L; + LocalDateTime startDateTime = DateTimeUtils.getMonthStartDateTime(localDate); + List rankData = List.of( + new NicknameAndScoreAndBadgeType("user1", 100, BadgeType.ATTENDANCE_1), + new NicknameAndScoreAndBadgeType("user2", 50, BadgeType.ATTENDANCE_10), + new NicknameAndScoreAndBadgeType("user3", 1, BadgeType.ATTENDANCE_100) + ); + when(adventureRepository.findRankTop100DescByLandmarkId(landmarkId, startDateTime)) + .thenReturn(rankData); - // when User user = TestUtil.createUser(); - ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + when(adventureRepository.findMyRankByLandmarkId(user, landmarkId, startDateTime)) + .thenReturn(Optional.empty()); + + // when + ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, landmarkId); // then List rankList = result.getRank(); - assertThat(rankList).hasSize(50); - for (int i = 50; i > 0; i--) { - assertThat(rankList.get(50 - i).getNickname()).isEqualTo("nickname" + i); - assertThat(rankList.get(50 - i).getScore()).isEqualTo(i); - } - + assertThat(rankList).hasSize(3) + .extracting("nickname", "score", "profileBadge") + .containsExactly( + tuple("user1", 100, BadgeType.ATTENDANCE_1.name()), + tuple("user2", 50, BadgeType.ATTENDANCE_10.name()), + tuple("user3", 1, BadgeType.ATTENDANCE_100.name()) + ); assertThat(result.getMyRank().getRanking()).isZero(); assertThat(result.getMyRank().getScore()).isZero(); } @@ -93,47 +107,63 @@ void getRankTop100ByLandmark_2() { @DisplayName("전체 유저 100명 미만 + 내 랭킹 존재") void getRankTop100ByLandmark_3() { // given - List nicknameAndScores = IntStream.rangeClosed(1, 50) - .mapToObj(i -> new NicknameAndScoreAndBadgeType("nickname" + (51 - i), 51 - i, null)) - .toList(); - when(adventureRepository.findRankTop100DescByLandmarkId(any(Long.class), any(LocalDateTime.class))) - .thenReturn(nicknameAndScores); - when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) - .thenReturn(Optional.of(new RankAndScore(14, 37))); + LocalDate localDate = LocalDate.of(2024, 7, 1); when(dateTimeService.getLocalDateNow()) - .thenReturn(LocalDate.of(2024, 7, 1)); + .thenReturn(localDate); + + Long landmarkId = 1L; + LocalDateTime startDateTime = DateTimeUtils.getMonthStartDateTime(localDate); + List rankData = List.of( + new NicknameAndScoreAndBadgeType("user1", 100, BadgeType.ATTENDANCE_1), + new NicknameAndScoreAndBadgeType("user2", 50, BadgeType.ATTENDANCE_10), + new NicknameAndScoreAndBadgeType("user3", 1, BadgeType.ATTENDANCE_100) + ); + when(adventureRepository.findRankTop100DescByLandmarkId(landmarkId, startDateTime)) + .thenReturn(rankData); - // when User user = TestUtil.createUser(); - ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); + RankAndScore myRank = new RankAndScore(14, 37); + when(adventureRepository.findMyRankByLandmarkId(user, landmarkId, startDateTime)) + .thenReturn(Optional.of(myRank)); + + // when + ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, landmarkId); // then List rankList = result.getRank(); - assertThat(rankList).hasSize(50); - for (int i = 50; i > 0; i--) { - assertThat(rankList.get(50 - i).getNickname()).isEqualTo("nickname" + i); - assertThat(rankList.get(50 - i).getScore()).isEqualTo(i); - } - assertThat(result.getMyRank().getScore()).isEqualTo(37); - assertThat(result.getMyRank().getRanking()).isEqualTo(14); + assertThat(rankList).hasSize(3) + .extracting("nickname", "score", "profileBadge") + .containsExactly( + tuple("user1", 100, BadgeType.ATTENDANCE_1.name()), + tuple("user2", 50, BadgeType.ATTENDANCE_10.name()), + tuple("user3", 1, BadgeType.ATTENDANCE_100.name()) + ); + assertThat(result.getMyRank().getScore()).isEqualTo(myRank.score()); + assertThat(result.getMyRank().getRanking()).isEqualTo(myRank.ranking()); } @Test @DisplayName("전체 유저 100명 초과 + 내 랭킹 중간에 존재") void getRankTop100ByLandmark_4() { // given + LocalDate localDate = LocalDate.of(2024, 7, 1); + when(dateTimeService.getLocalDateNow()) + .thenReturn(localDate); + + Long landmarkId = 1L; + LocalDateTime startDateTime = DateTimeUtils.getMonthStartDateTime(localDate); List nicknameAndScores = IntStream.rangeClosed(1, 101) .mapToObj(i -> new NicknameAndScoreAndBadgeType("nickname" + (102 - i), 102 - i, null)) .toList(); - when(adventureRepository.findRankTop100DescByLandmarkId(any(Long.class), any(LocalDateTime.class))) + when(adventureRepository.findRankTop100DescByLandmarkId(landmarkId, startDateTime)) .thenReturn(nicknameAndScores); - when(adventureRepository.findMyRankByLandmarkId(any(User.class), any(Long.class), any(LocalDateTime.class))) - .thenReturn(Optional.of(new RankAndScore(40, 62))); - when(dateTimeService.getLocalDateNow()) - .thenReturn(LocalDate.of(2024, 7, 1)); - // when User user = TestUtil.createUser(); + RankAndScore myRank = new RankAndScore(40, 62); + when(adventureRepository.findMyRankByLandmarkId(user, landmarkId, startDateTime)) + .thenReturn(Optional.of(myRank)); + + // when ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, 1L); // then @@ -151,24 +181,24 @@ void getRankTop100ByLandmark_4() { @DisplayName("랜드마크 랭킹 조회 결과에는 사용자 프로필 배지 데이터가 포함되어 있다.") void getRankTop100ByLandmark_5() { // given - LocalDate now = LocalDate.of(2024, 7, 1); + LocalDate localDate = LocalDate.of(2024, 7, 1); when(dateTimeService.getLocalDateNow()) - .thenReturn(now); + .thenReturn(localDate); + Long landmarkId = 1L; + LocalDateTime startDateTime = DateTimeUtils.getMonthStartDateTime(localDate); List rankData = List.of( new NicknameAndScoreAndBadgeType("user1", 10, BadgeType.ATTENDANCE_1), new NicknameAndScoreAndBadgeType("user2", 5, BadgeType.MONTHLY_RANKING_1) ); - - Long landmarkId = 1L; - when(adventureRepository.findRankTop100DescByLandmarkId(landmarkId, now.atStartOfDay())) + when(adventureRepository.findRankTop100DescByLandmarkId(landmarkId, startDateTime)) .thenReturn(rankData); User user = TestUtil.createUser(); user.updateProfileBadge(BadgeType.ATTENDANCE_CHRISTMAS_DAY); - when(adventureRepository.findMyRankByLandmarkId(user, landmarkId, now.atStartOfDay())) - .thenReturn(Optional.of(new RankAndScore(2, 7))); - + RankAndScore myRank = new RankAndScore(2, 7); + when(adventureRepository.findMyRankByLandmarkId(user, landmarkId, startDateTime)) + .thenReturn(Optional.of(myRank)); // when ScoreRankingResponse result = landmarkRankService.getRankTop100ByLandmark(user, landmarkId); @@ -180,8 +210,8 @@ void getRankTop100ByLandmark_5() { tuple("user1", BadgeType.ATTENDANCE_1.name(), 10), tuple("user2", BadgeType.MONTHLY_RANKING_1.name(), 5) ); - assertThat(result.getMyRank().getScore()).isEqualTo(7); - assertThat(result.getMyRank().getRanking()).isEqualTo(2); - assertThat(result.getMyRank().getProfileBadge()).isEqualTo(BadgeType.ATTENDANCE_CHRISTMAS_DAY.name()); + assertThat(result.getMyRank().getScore()).isEqualTo(myRank.score()); + assertThat(result.getMyRank().getRanking()).isEqualTo(myRank.ranking()); + assertThat(result.getMyRank().getProfileBadge()).isEqualTo(user.getProfileBadge().name()); } } \ No newline at end of file From c649ce2db378694aff935c2871baee3388e5efd5 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Wed, 4 Sep 2024 11:50:21 +0900 Subject: [PATCH 71/79] refactor: systemCheck --- .../application/SystemCheckService.java | 4 ++- .../systemcheck/domain/SystemCheck.java | 3 --- .../systemcheck/dto/HealthCheckDto.java | 3 +-- .../application/SystemCheckServiceTest.java | 26 +++++++++---------- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/application/SystemCheckService.java b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/application/SystemCheckService.java index d0ec393..cddd6c7 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/application/SystemCheckService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/application/SystemCheckService.java @@ -20,6 +20,7 @@ public class SystemCheckService { private final AppVersionRepository appVersionRepository; private final SystemCheckRepository systemCheckRepository; + @Transactional(readOnly = true) public boolean isSystemAvailable() { Optional optionalSystemCheck = systemCheckRepository.findTopByOrderByUpdatedAtDesc(); return optionalSystemCheck.map(SystemCheck::isAvailable) @@ -33,10 +34,11 @@ public void changeSystemAvailable(boolean available) { systemCheckRepository.save(systemCheck); } + @Transactional(readOnly = true) public HealthCheckDto healthCheck() { boolean systemAvailable = isSystemAvailable(); - List supportAppVersionList = appVersionRepository.findAll(); + List supportAppVersionList = appVersionRepository.findAll(); List list = supportAppVersionList.stream() .map(appVersion -> new OSAndVersion(appVersion.getOs(), appVersion.getVersion())) .distinct() diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/domain/SystemCheck.java b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/domain/SystemCheck.java index d0f528e..b014d77 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/domain/SystemCheck.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/domain/SystemCheck.java @@ -24,7 +24,4 @@ public SystemCheck(boolean available) { this.available = available; } - public void updateAvailable(boolean available) { - this.available = available; - } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/dto/HealthCheckDto.java b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/dto/HealthCheckDto.java index ba5bdc9..f0c86bb 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/dto/HealthCheckDto.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/systemcheck/dto/HealthCheckDto.java @@ -4,6 +4,5 @@ import java.util.List; -public record HealthCheckDto(boolean systemAvailable, - List supportAppVersionList) { +public record HealthCheckDto(boolean systemAvailable, List supportAppVersionList) { } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/application/SystemCheckServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/application/SystemCheckServiceTest.java index ab37e2c..40a28e8 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/application/SystemCheckServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/systemcheck/application/SystemCheckServiceTest.java @@ -100,26 +100,26 @@ void success_1() { // given when(systemCheckRepository.findTopByOrderByUpdatedAtDesc()) .thenReturn(Optional.of(new SystemCheck(true))); + + List supportedAppVersion = List.of( + new AppVersion(OperationSystem.ANDROID, "1.0.0"), + new AppVersion(OperationSystem.ANDROID, "1.0.1"), + new AppVersion(OperationSystem.IOS, "1.0.3") + ); when(appVersionRepository.findAll()) - .thenReturn( - List.of( - new AppVersion(OperationSystem.ANDROID, "1.0.0"), - new AppVersion(OperationSystem.ANDROID, "1.0.1"), - new AppVersion(OperationSystem.IOS, "1.0.3") - ) - ); + .thenReturn(supportedAppVersion); // when HealthCheckDto healthCheckDto = systemCheckService.healthCheck(); // then assertThat(healthCheckDto.systemAvailable()).isTrue(); - assertThat(healthCheckDto.supportAppVersionList()) - .containsExactlyInAnyOrder( - new OSAndVersion(OperationSystem.ANDROID, "1.0.0"), - new OSAndVersion(OperationSystem.ANDROID, "1.0.1"), - new OSAndVersion(OperationSystem.IOS, "1.0.3") - ); + + List expected = supportedAppVersion.stream() + .map(appVersion -> new OSAndVersion(appVersion.getOs(), appVersion.getVersion())) + .toList(); + assertThat(healthCheckDto.supportAppVersionList()).hasSize(3) + .containsExactlyInAnyOrderElementsOf(expected); } } From 3cc40c7b0c1fae12f9429e5a260bf7e61b411eec Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Wed, 4 Sep 2024 22:24:12 +0900 Subject: [PATCH 72/79] update security config, landmark data --- .../global/config/WebSecurityConfig.java | 34 +++++++++---------- src/main/resources/data-h2.sql | 2 +- src/main/resources/data-mysql.sql | 2 +- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java b/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java index f7dff95..bd2bd6c 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/config/WebSecurityConfig.java @@ -16,6 +16,7 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @Configuration @EnableWebSecurity @@ -36,26 +37,23 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .authorizeHttpRequests(request -> request .requestMatchers( //PathRequest.toH2Console(), - PathRequest.toStaticResources().atCommonLocations() + PathRequest.toStaticResources().atCommonLocations(), + AntPathRequestMatcher.antMatcher("/"), + AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/users/register"), + AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/users/login"), + AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api/users/availability"), + AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/auth/tokens"), + AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api/auth/emails"), + AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/auth/emails"), + AntPathRequestMatcher.antMatcher(HttpMethod.POST, "/api/auth/reissue"), + AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/swagger-ui/**"), + AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/swagger-ui.html"), + AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api-docs/**"), + AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/api/system-available"), + AntPathRequestMatcher.antMatcher("/actu/**") ).permitAll() .requestMatchers( - HttpMethod.GET, - "/", "/swagger-ui/**", "/api-docs/**", "/actu/**", - "/api/users/availability", - "/api/auth/emails", - "/api/system-available" - ).permitAll() - .requestMatchers( - HttpMethod.POST, - "/", "/actu/**", - "/api/users/register", - "/api/users/login", - "/api/auth/tokens", - "/api/auth/emails", - "/api/auth/reissue" - ).permitAll() - .requestMatchers( - "/api/admin/**" + AntPathRequestMatcher.antMatcher("/api/admin/**") ).hasRole("ADMIN") .anyRequest().authenticated() ) diff --git a/src/main/resources/data-h2.sql b/src/main/resources/data-h2.sql index 03b6e7d..a74c520 100644 --- a/src/main/resources/data-h2.sql +++ b/src/main/resources/data-h2.sql @@ -32,7 +32,7 @@ values (15, 37.544319, 127.076184, 40, '경영관', NULL, 0); insert into "landmark" ("id", "latitude", "longitude", "recognition_radius", "name", "user_id", "highest_score") values (16, 37.543374, 127.077314, 40, '새천년관', NULL, 0); insert into "landmark" ("id", "latitude", "longitude", "recognition_radius", "name", "user_id", "highest_score") -values (17, 37.543732, 127.078482, 25, '건축관', NULL, 0); +values (17, 37.5438662, 127.0787897, 60, '건축관', NULL, 0); insert into "landmark" ("id", "latitude", "longitude", "recognition_radius", "name", "user_id", "highest_score") values (18, 37.543283, 127.078093, 25, '부동산학관', NULL, 0); insert into "landmark" ("id", "latitude", "longitude", "recognition_radius", "name", "user_id", "highest_score") diff --git a/src/main/resources/data-mysql.sql b/src/main/resources/data-mysql.sql index d2d818f..1bd2f12 100644 --- a/src/main/resources/data-mysql.sql +++ b/src/main/resources/data-mysql.sql @@ -33,7 +33,7 @@ values (15, 37.544319, 127.076184, 40, '경영관', NULL, 0); insert into landmark (id, latitude, longitude, recognition_radius, name, user_id, highest_score) values (16, 37.543374, 127.077314, 40, '새천년관', NULL, 0); insert into landmark (id, latitude, longitude, recognition_radius, name, user_id, highest_score) -values (17, 37.543732, 127.078482, 25, '건축관', NULL, 0); +values (17, 37.5438662, 127.0787897, 60, '건축관', NULL, 0); insert into landmark (id, latitude, longitude, recognition_radius, name, user_id, highest_score) values (18, 37.543283, 127.078093, 25, '부동산학관', NULL, 0); insert into landmark (id, latitude, longitude, recognition_radius, name, user_id, highest_score) From c81d7e5d8ca0ff0a267b8e6eda8e3beb92efe629 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Sat, 7 Sep 2024 11:22:07 +0900 Subject: [PATCH 73/79] update log content on loggingFilter --- .../global/security/LoggingFilter.java | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java b/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java index 9722ec4..87850d2 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java @@ -13,28 +13,37 @@ @Slf4j public class LoggingFilter extends OncePerRequestFilter { - private static void logRequest(HttpServletRequest request) { - if (request.getRequestURI() != null && - (request.getRequestURI().contains("/prometheus") || request.getRequestURI().equals("/api/system-available"))) { + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + if (!isAsyncDispatch(request)) { + logRequest(request); + } + filterChain.doFilter(request, response); + } + + private void logRequest(HttpServletRequest request) { + if (isNotLogFilterTarget(request)) { return; } + String queryString = request.getQueryString(); String bearerToken = request.getHeader(HttpHeaders.AUTHORIZATION); log.info("Request : {} uri=[{}] content-type=[{}] token=[{}]", request.getMethod(), - queryString == null ? request.getRequestURI() : request.getRequestURI() + queryString, + queryString == null ? request.getRequestURI() : request.getRequestURI() + "?" + queryString, request.getContentType(), bearerToken); } - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - if (!isAsyncDispatch(request)) { - logRequest(request); + private boolean isNotLogFilterTarget(HttpServletRequest request) { + if (request.getRequestURI() == null) { + return false; } - filterChain.doFilter(request, response); + String requestURI = request.getRequestURI(); + return requestURI.contains("/prometheus") || requestURI.equals("/api/system-available"); } + } From a96fcd53abaa933189a708afe11926a92debb287 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 9 Sep 2024 14:01:01 +0900 Subject: [PATCH 74/79] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=8B=9C=20=EC=82=B0=EC=97=85=EA=B2=BD=EC=98=81?= =?UTF-8?q?=EA=B3=B5=ED=95=99=EB=B6=80=20=EC=A0=84=EA=B3=B5=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/api/UserManagementApi.java | 4 ++- .../user/api/request/UserRegisterRequest.java | 5 ++-- .../domain/user/domain/Major.java | 26 +++++++++++++++---- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java index 4f6bd4b..1180aa9 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/UserManagementApi.java @@ -37,8 +37,10 @@ public class UserManagementApi { public ApiResponse registerUser(@RequestBody @Valid UserRegisterRequest request) { tokenService.validateAuthVerifyToken(request.getAuthVerifyToken()); + Major major = Major.fromString(request.getMajor()) + .orElseThrow(() -> new IllegalArgumentException("잘못된 학과명입니다.")); UserRegisterDto userRegisterDto - = new UserRegisterDto(request.getEmail(), request.getNickname(), Major.valueOf(request.getMajor())); + = new UserRegisterDto(request.getEmail(), request.getNickname(), major); TokenDto tokenDto = userRegisterService.registerUser(userRegisterDto); tokenService.deleteAuthVerifyToken(request.getAuthVerifyToken()); diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/UserRegisterRequest.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/UserRegisterRequest.java index 26bb056..cf373a9 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/UserRegisterRequest.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/UserRegisterRequest.java @@ -1,7 +1,5 @@ package com.playkuround.playkuroundserver.domain.user.api.request; -import com.playkuround.playkuroundserver.domain.user.domain.Major; -import com.playkuround.playkuroundserver.global.validation.ValidEnum; import io.swagger.v3.oas.annotations.ExternalDocumentation; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; @@ -30,7 +28,8 @@ public class UserRegisterRequest { @Schema(description = "사용할 닉네임(한글, 영어, 숫자만 허용)", example = "tester", minLength = 2, maxLength = 8) private String nickname; - @ValidEnum(enumClass = Major.class, message = "잘못된 학과명입니다.") + //@ValidEnum(enumClass = Major.class, message = "잘못된 학과명입니다.") + @NotBlank(message = "학과는 필수값입니다.") @Schema(description = "학과. 학과 리스트는 외부 문서 참고", example = "컴퓨터공학부", requiredMode = RequiredMode.REQUIRED) private String major; diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java index 92fc5f2..45b4e2d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/Major.java @@ -1,8 +1,16 @@ package com.playkuround.playkuroundserver.domain.user.domain; import com.playkuround.playkuroundserver.domain.badge.domain.BadgeType; +import lombok.RequiredArgsConstructor; + +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.toMap; @SuppressWarnings("NonAsciiCharacters") +@RequiredArgsConstructor public enum Major { // 문과대학 @@ -99,14 +107,25 @@ public enum Major { private final Collage collage; - Major(Collage collage) { - this.collage = collage; + private static final Map stringToEnum = + Stream.of(values()) + .collect(toMap(Object::toString, e -> e)); + + public static Optional fromString(String source) { + if ("산업경영공학부 산업공학과".equals(source)) { + return Optional.of(Major.산업경영공학부_산업공학과); + } + if ("산업경영공학부 신산업융합학과".equals(source)) { + return Optional.of(Major.산업경영공학부_신산업융합학과); + } + return Optional.ofNullable(stringToEnum.get(source)); } public BadgeType getCollageBadgeType() { return collage.collageBadgeType; } + @RequiredArgsConstructor enum Collage { 문과대학(BadgeType.COLLEGE_OF_LIBERAL_ARTS), 이과대학(BadgeType.COLLEGE_OF_SCIENCES), @@ -125,9 +144,6 @@ enum Collage { private final BadgeType collageBadgeType; - Collage(BadgeType collageBadgeType) { - this.collageBadgeType = collageBadgeType; - } } } From 671e6dade44bf57c5b537942128fc36474837523 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Mon, 9 Sep 2024 14:04:14 +0900 Subject: [PATCH 75/79] =?UTF-8?q?feat:=20log=20content=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 --- .../playkuroundserver/global/security/LoggingFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java b/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java index 87850d2..1c076e6 100644 --- a/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java +++ b/src/main/java/com/playkuround/playkuroundserver/global/security/LoggingFilter.java @@ -30,7 +30,7 @@ private void logRequest(HttpServletRequest request) { String bearerToken = request.getHeader(HttpHeaders.AUTHORIZATION); log.info("Request : {} uri=[{}] content-type=[{}] token=[{}]", request.getMethod(), - queryString == null ? request.getRequestURI() : request.getRequestURI() + "?" + queryString, + queryString == null || queryString.isEmpty() ? request.getRequestURI() : request.getRequestURI() + "?" + queryString, request.getContentType(), bearerToken); } From 4937324470e80c8758fb1d920ecefad4e9f4e64c Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Thu, 12 Sep 2024 11:12:46 +0900 Subject: [PATCH 76/79] =?UTF-8?q?feat:=20User=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=8B=9C=20Set=EC=9D=B4=20null=EC=9D=B4=20=EC=95=84=EB=8B=88?= =?UTF-8?q?=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../playkuround/playkuroundserver/domain/user/domain/User.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java index 593d575..baffbce 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/domain/User.java @@ -50,6 +50,7 @@ private User(String email, String nickname, Major major, Role role) { this.nickname = nickname; this.major = major; this.role = role; + this.notification = new HashSet<>(); } public static User create(String email, String nickname, Major major, Role role) { From be590a7eafdb9eb0365ea1b108d2bd829840a4ab Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Thu, 12 Sep 2024 11:13:30 +0900 Subject: [PATCH 77/79] =?UTF-8?q?feat:=20=EC=88=98=EB=8F=99=20=EB=B0=B0?= =?UTF-8?q?=EC=A7=80=20=EC=A0=80=EC=9E=A5=20API=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=EC=9D=B4=EB=A9=94=EC=9D=BC=EC=9D=84=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=EB=B0=9B=EC=9D=84=20?= =?UTF-8?q?=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../badge/application/BadgeService.java | 41 ++++++++++++++----- .../domain/user/api/AdminApi.java | 6 +-- .../api/request/ManualBadgeSaveRequest.java | 8 ++-- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java index 9b382a0..0cfc167 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeService.java @@ -144,19 +144,40 @@ public boolean saveTheDreamOfDuckBadge(User user) { return true; } - public boolean saveManualBadge(String userEmail, BadgeType badgeType, boolean registerMessage) { - User user = userRepository.findByEmail(userEmail) - .orElseThrow(UserNotFoundException::new); - if (badgeRepository.existsByUserAndBadgeType(user, badgeType)) { - return false; + public int saveManualBadge(List userEmails, BadgeType badgeType, boolean registerMessage) { + validateEmailsSize(userEmails); + + List users = findUsersExactlyIn(userEmails); + int successCount = 0; + for (User user : users) { + if (badgeRepository.existsByUserAndBadgeType(user, badgeType)) { + continue; + } + + Badge badge = Badge.createBadge(user, badgeType); + badgeRepository.save(badge); + successCount++; + if (registerMessage) { + user.addNewBadgeNotification(badgeType); + } } - Badge badge = Badge.createBadge(user, badgeType); - badgeRepository.save(badge); - if (registerMessage) { - user.addNewBadgeNotification(badgeType); + return successCount; + } + + private void validateEmailsSize(List userEmails) { + if (userEmails.size() == Integer.MAX_VALUE) { + throw new IllegalArgumentException("The number of emails is too large."); } - return true; + } + + private List findUsersExactlyIn(List userEmails) { + List users = userRepository.findByEmailIn(userEmails); + if (users.size() != userEmails.size()) { + throw new UserNotFoundException(); + } + + return users; } } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java index e22a5d6..285bd25 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/AdminApi.java @@ -25,10 +25,10 @@ public class AdminApi { @PostMapping("badges/manual") @ResponseStatus(HttpStatus.CREATED) @Operation(summary = "수동 배지 등록", - description = "수동으로 배지를 등록합니다. 이미 획득한 배지였다면 false를 반환합니다. 설정에 따라 개인 메시지로 등록할 수 있습니다.") - public ApiResponse saveManualBadge(@RequestBody @Valid ManualBadgeSaveRequest request) { + description = "수동으로 배지를 등록합니다. 성공적으로 배지 저장에 성공한 개수를 반환합니다. 설정에 따라 개인 메시지로 등록할 수 있습니다.") + public ApiResponse saveManualBadge(@RequestBody @Valid ManualBadgeSaveRequest request) { BadgeType badgeType = BadgeType.valueOf(request.getBadge()); - boolean response = badgeService.saveManualBadge(request.getUserEmail(), badgeType, request.isRegisterMessage()); + int response = badgeService.saveManualBadge(request.getUserEmail(), badgeType, request.isRegisterMessage()); return ApiUtils.success(response); } diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/ManualBadgeSaveRequest.java b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/ManualBadgeSaveRequest.java index d45542b..844fff1 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/ManualBadgeSaveRequest.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/user/api/request/ManualBadgeSaveRequest.java @@ -10,15 +10,15 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.List; + @Getter @AllArgsConstructor @NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) public class ManualBadgeSaveRequest { - @NotBlank(message = "이메일은 필수값입니다.") - @Email(message = "올바른 이메일 형식이 아닙니다.") - @Schema(description = "배지를 부여할 유저 이메일", example = "tester@konkuk.ac.kr", requiredMode = RequiredMode.REQUIRED) - private String userEmail; + @Schema(description = "배지를 부여할 유저 이메일 리스트", example = "[user2@konkuk.ac.kr, user2@konkuk.ac.kr]", requiredMode = RequiredMode.REQUIRED) + private List<@NotBlank(message = "이메일은 필수값입니다.") @Email(message = "올바른 이메일 형식이 아닙니다.") String> userEmail; @ValidEnum(enumClass = BadgeType.class, message = "잘못된 배지타입입니다.") @Schema(description = "배지타입. 배지타입명은 외부 문서 참고", example = "ATTENDANCE_FOUNDATION_DAY", requiredMode = RequiredMode.REQUIRED) From dde69e01c2d402c4fbcea920a199934328c0e3c4 Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Thu, 12 Sep 2024 11:13:46 +0900 Subject: [PATCH 78/79] =?UTF-8?q?test:=20=EC=88=98=EB=8F=99=20=EB=B0=B0?= =?UTF-8?q?=EC=A7=80=20=EC=A0=80=EC=9E=A5=20API,=20unit=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../badge/application/BadgeServiceTest.java | 97 ++++++++--- .../domain/user/api/AdminApiTest.java | 150 ++++++++++-------- 2 files changed, 162 insertions(+), 85 deletions(-) diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java index c06fe4f..0f2aece 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/badge/application/BadgeServiceTest.java @@ -9,9 +9,11 @@ import com.playkuround.playkuroundserver.domain.landmark.domain.Landmark; import com.playkuround.playkuroundserver.domain.landmark.domain.LandmarkType; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; +import com.playkuround.playkuroundserver.domain.user.domain.Major; import com.playkuround.playkuroundserver.domain.user.domain.Notification; import com.playkuround.playkuroundserver.domain.user.domain.NotificationEnum; import com.playkuround.playkuroundserver.domain.user.domain.User; +import com.playkuround.playkuroundserver.domain.user.exception.UserNotFoundException; import com.playkuround.playkuroundserver.global.util.DateTimeUtils; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -32,12 +34,12 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class BadgeServiceTest { @@ -343,44 +345,95 @@ void success_1(boolean hasBadge) { @DisplayName("배지 수동 등록") class saveManualBadge { - @ParameterizedTest - @ValueSource(booleans = {true, false}) - @DisplayName("정상 저장되었다면 true, 이미 저장된 배지였으면 false를 반환한다.") - void success_1(boolean hasBadge) { + @Test + @DisplayName("새롭게 정상 저장된 배지 개수를 반환한다.") + void success_1() { // given - User user = TestUtil.createUser(); + List users = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부), + TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.국제무역학과) + ); + List emails = users.stream() + .map(User::getEmail) + .toList(); + when(userRepository.findByEmailIn(emails)) + .thenReturn(users); + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; - when(userRepository.findByEmail(user.getEmail())) - .thenReturn(Optional.of(user)); - when(badgeRepository.existsByUserAndBadgeType(user, badgeType)) - .thenReturn(hasBadge); + when(badgeRepository.existsByUserAndBadgeType(users.get(0), badgeType)) + .thenReturn(true); + when(badgeRepository.existsByUserAndBadgeType(users.get(1), badgeType)) + .thenReturn(false); + when(badgeRepository.existsByUserAndBadgeType(users.get(2), badgeType)) + .thenReturn(false); // when - boolean result = badgeService.saveManualBadge(user.getEmail(), badgeType, false); + int result = badgeService.saveManualBadge(emails, badgeType, false); // then - assertThat(result).isEqualTo(!hasBadge); - assertThat(user.getNotification()).isNull(); + assertThat(result).isEqualTo(2); + verify(badgeRepository, times(2)).save(any(Badge.class)); } @Test - @DisplayName("개인 메시지로 저장") + @DisplayName("registerMessage 값을 true로 설정하면 user.notification에 원소가 추가된다.") void success_2() { // given - User user = TestUtil.createUser(); + List users = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부), + TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.국제무역학과) + ); + List emails = users.stream() + .map(User::getEmail) + .toList(); + when(userRepository.findByEmailIn(emails)) + .thenReturn(users); + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; - when(userRepository.findByEmail(user.getEmail())) - .thenReturn(Optional.of(user)); - when(badgeRepository.existsByUserAndBadgeType(user, badgeType)) + when(badgeRepository.existsByUserAndBadgeType(users.get(0), badgeType)) + .thenReturn(true); + when(badgeRepository.existsByUserAndBadgeType(users.get(1), badgeType)) + .thenReturn(false); + when(badgeRepository.existsByUserAndBadgeType(users.get(2), badgeType)) .thenReturn(false); // when - boolean result = badgeService.saveManualBadge(user.getEmail(), badgeType, true); + int result = badgeService.saveManualBadge(emails, badgeType, true); // then - assertThat(result).isTrue(); - assertThat(user.getNotification()) + assertThat(result).isEqualTo(2); + verify(badgeRepository, times(2)).save(any(Badge.class)); + + assertThat(users.get(0).getNotification()).isEmpty(); + assertThat(users.get(1).getNotification()) .containsOnly(new Notification(NotificationEnum.NEW_BADGE, badgeType.name())); + assertThat(users.get(2).getNotification()) + .containsOnly(new Notification(NotificationEnum.NEW_BADGE, badgeType.name())); + } + + @Test + @DisplayName("존재하지 않는 이메일이 하나라도 존재하면 예외를 던진다.") + void fail_1() { + // given + List users = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부), + TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.국제무역학과) + ); + List emails = users.subList(1, users.size()).stream() + .map(User::getEmail) + .toList(); + when(userRepository.findByEmailIn(emails)) + .thenReturn(users); + + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; + + // expected + assertThatThrownBy(() -> badgeService.saveManualBadge(emails, badgeType, false)) + .isInstanceOf(UserNotFoundException.class); + verify(badgeRepository, times(0)).save(any(Badge.class)); } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java index aa07143..221c944 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/user/api/AdminApiTest.java @@ -9,6 +9,7 @@ import com.playkuround.playkuroundserver.domain.user.api.request.ManualBadgeSaveRequest; import com.playkuround.playkuroundserver.domain.user.dao.UserRepository; import com.playkuround.playkuroundserver.domain.user.domain.*; +import com.playkuround.playkuroundserver.global.error.ErrorCode; import com.playkuround.playkuroundserver.securityConfig.WithMockCustomUser; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; @@ -18,11 +19,13 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; +import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.Set; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -50,110 +53,131 @@ void clean() { } @Nested + @WithMockCustomUser(role = Role.ROLE_ADMIN) @DisplayName("배지 수동 등록") class saveManualBadge { @Test - @WithMockCustomUser(role = Role.ROLE_ADMIN) - @DisplayName("정상 배지 수동 등록 : 개인 메시지 저장 안함") + @DisplayName("기존에 가지고 있지 않는 배지인 경우만 저장된다.") void success_1() throws Exception { // given - User user = TestUtil.createUser("aa@konkuk.ac.kr", "newNickname", Major.건축학부); - userRepository.save(user); - + List users = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부), + TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.국제무역학과) + ); + userRepository.saveAll(users); + + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; + badgeRepository.save(new Badge(users.get(0), BadgeType.MONTHLY_RANKING_1)); + + List emails = users.stream() + .map(User::getEmail) + .toList(); ManualBadgeSaveRequest manualBadgeSaveRequest - = new ManualBadgeSaveRequest(user.getEmail(), BadgeType.MONTHLY_RANKING_1.name(), false); + = new ManualBadgeSaveRequest(emails, badgeType.name(), false); String request = objectMapper.writeValueAsString(manualBadgeSaveRequest); // expect mockMvc.perform(post("/api/admin/badges/manual") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.response").value(true)) + .andExpect(jsonPath("$.response").value(2)) .andDo(print()); - List badges = badgeRepository.findByUser(user); - assertThat(badges).hasSize(1); - assertThat(badges.get(0).getBadgeType()).isEqualTo(BadgeType.MONTHLY_RANKING_1); - assertThat(user.getNotification()).isNull(); + List badges = badgeRepository.findAll(); + assertThat(badges).hasSize(3) + .extracting("user.id", "badgeType") + .containsExactlyInAnyOrder( + tuple(users.get(0).getId(), badgeType), + tuple(users.get(1).getId(), badgeType), + tuple(users.get(2).getId(), badgeType) + ); } @Test - @WithMockCustomUser(role = Role.ROLE_ADMIN) - @DisplayName("정상 배지 수동 등록 : 개인 메시지 저장") + @DisplayName("개인 메시지 저장 설정이 true인 경우, 새롭게 배지가 저장된 유저에게 메시지가 저장된다") void success_2() throws Exception { // given - User user = TestUtil.createUser("aa@konkuk.ac.kr", "test", Major.건축학부); - userRepository.save(user); - + List existUsers = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.컴퓨터공학부), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.국제무역학과) + ); + List notExistUsers = List.of( + TestUtil.createUser("user3@konkuk.ac.kr", "user3", Major.건축학부), + TestUtil.createUser("user4@konkuk.ac.kr", "user4", Major.국어국문학과) + ); + + List allUsers = Stream.concat(existUsers.stream(), notExistUsers.stream()).toList(); + userRepository.saveAll(allUsers); + + BadgeType badgeType = BadgeType.MONTHLY_RANKING_1; + List badges = existUsers.stream() + .map(user -> new Badge(user, badgeType)) + .toList(); + badgeRepository.saveAll(badges); + + List emails = allUsers.stream() + .map(User::getEmail) + .toList(); ManualBadgeSaveRequest manualBadgeSaveRequest - = new ManualBadgeSaveRequest(user.getEmail(), BadgeType.MONTHLY_RANKING_1.name(), true); + = new ManualBadgeSaveRequest(emails, badgeType.name(), true); String request = objectMapper.writeValueAsString(manualBadgeSaveRequest); // expect mockMvc.perform(post("/api/admin/badges/manual") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) + .content(request)) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.response").value(true)) + .andExpect(jsonPath("$.response").value(notExistUsers.size())) .andDo(print()); - List badges = badgeRepository.findByUser(user); - assertThat(badges).hasSize(1); - assertThat(badges.get(0).getBadgeType()).isEqualTo(BadgeType.MONTHLY_RANKING_1); - - Optional optionalUser = userRepository.findByEmail(user.getEmail()); - Set notification = optionalUser.get().getNotification(); - assertThat(notification) - .containsOnly(new Notification(NotificationEnum.NEW_BADGE, BadgeType.MONTHLY_RANKING_1.name())); + List notExistUserEmails = notExistUsers.stream() + .map(User::getEmail) + .toList(); + notExistUsers = userRepository.findByEmailIn(notExistUserEmails); + assertThat(notExistUsers).hasSize(notExistUsers.size()) + .extracting("notification", Set.class) + .allMatch(notifications -> notifications.contains(new Notification(NotificationEnum.NEW_BADGE, badgeType.name()))); + + List existUserEmails = existUsers.stream() + .map(User::getEmail) + .toList(); + existUsers = userRepository.findByEmailIn(existUserEmails); + assertThat(existUsers).hasSize(existUsers.size()) + .extracting("notification", Set.class) + .allMatch(Set::isEmpty); } @Test - @WithMockCustomUser(role = Role.ROLE_ADMIN) - @DisplayName("이미 가지고 있는 배지면 false를 반환한다") + @DisplayName("존재하지 않는 이메일이 하나라도 존재하면 예외를 던진다.") void fail_1() throws Exception { // given - User user = TestUtil.createUser("aa@konkuk.ac.kr", "test", Major.건축학부); - userRepository.save(user); - badgeRepository.save(new Badge(user, BadgeType.MONTHLY_RANKING_1)); - + List users = List.of( + TestUtil.createUser("user1@konkuk.ac.kr", "user1", Major.경영학과), + TestUtil.createUser("user2@konkuk.ac.kr", "user2", Major.컴퓨터공학부) + ); + userRepository.saveAll(users); + + List emails = new ArrayList<>(); + users.stream() + .map(User::getEmail) + .forEach(emails::add); + emails.add("notFoundUser@konkuk.ac.kr"); ManualBadgeSaveRequest manualBadgeSaveRequest - = new ManualBadgeSaveRequest(user.getEmail(), BadgeType.MONTHLY_RANKING_1.name(), true); + = new ManualBadgeSaveRequest(emails, BadgeType.MONTHLY_RANKING_1.name(), false); String request = objectMapper.writeValueAsString(manualBadgeSaveRequest); // expect mockMvc.perform(post("/api/admin/badges/manual") .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) - .andExpect(status().isCreated()) - .andExpect(jsonPath("$.response").value(false)) + .content(request)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.errorResponse.code").value(ErrorCode.USER_NOT_FOUND.getCode())) + .andExpect(jsonPath("$.errorResponse.message").value(ErrorCode.USER_NOT_FOUND.getMessage())) .andDo(print()); - - List badges = badgeRepository.findByUser(user); - assertThat(badges).hasSize(1); - assertThat(user.getNotification()).isNull(); } - @Test - @WithMockCustomUser(role = Role.ROLE_USER) - @DisplayName("admin 권한이 없으면 권한 에러가 발생한다") - void fail_2() throws Exception { - // given - ManualBadgeSaveRequest manualBadgeSaveRequest - = new ManualBadgeSaveRequest("test@konkuk.ac.kr", BadgeType.MONTHLY_RANKING_1.name(), true); - String request = objectMapper.writeValueAsString(manualBadgeSaveRequest); - - // expect - mockMvc.perform(post("/api/admin/badges/manual") - .contentType(MediaType.APPLICATION_JSON) - .content(request) - ) - .andExpect(status().isForbidden()) - .andDo(print()); - } } } \ No newline at end of file From 87e605b491ae6253603f84acc5b73122352daa9d Mon Sep 17 00:00:00 2001 From: seungtaekhong Date: Thu, 12 Sep 2024 14:20:07 +0900 Subject: [PATCH 79/79] feat: extract email title to yaml --- .../auth/email/application/AuthEmailSendServiceImpl.java | 6 ++++-- .../auth/email/application/AuthEmailSendServiceTest.java | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java index 7038860..65c045d 100644 --- a/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java +++ b/src/main/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceImpl.java @@ -33,6 +33,9 @@ public class AuthEmailSendServiceImpl implements AuthEmailSendService { @Value("${authentication.email.domain}") private String emailDomain; + @Value("${authentication.email.title}") + private String emailTitle; + @Value("${authentication.email.max-send-count}") private Long maxSendingCount; @@ -83,12 +86,11 @@ private LocalDateTime saveAuthEmail(String target, String authenticationCode) { } private void sendEmail(String target, String authenticationCode) { - String title = "[플레이쿠라운드] 회원가입 인증코드입니다."; Context context = new Context(); context.setVariable("code", authenticationCode); String content = templateEngine.process("mail-template", context); - Mail mail = new Mail(target, title, content); + Mail mail = new Mail(target, emailTitle, content); emailService.sendMail(mail); } } diff --git a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java index d062f6d..80fd509 100644 --- a/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java +++ b/src/test/java/com/playkuround/playkuroundserver/domain/auth/email/application/AuthEmailSendServiceTest.java @@ -48,9 +48,10 @@ class AuthEmailSendServiceTest { @Mock private DateTimeService dateTimeService; + private final String emailDomain = "test.com"; + private final String emailTitle = "[플레이쿠라운드] 회원가입 인증코드입니다."; private final long codeLength = 6L; private final long maxSendingCount = 3L; - private final String emailDomain = "test.com"; private final long codeExpirationSeconds = 300L; @BeforeEach @@ -59,6 +60,7 @@ void setUp() { ReflectionTestUtils.setField(authEmailSendService, "maxSendingCount", maxSendingCount); ReflectionTestUtils.setField(authEmailSendService, "emailDomain", emailDomain); ReflectionTestUtils.setField(authEmailSendService, "codeExpirationSeconds", codeExpirationSeconds); + ReflectionTestUtils.setField(authEmailSendService, "emailTitle", emailTitle); } @Test @@ -91,7 +93,7 @@ void sendAuthEmail_1() { assertThat(authEmail.getTarget()).isEqualTo(target); assertThat(authEmail.getCode()).containsPattern("[0-9]{" + codeLength + "}"); - verify(emailService, times(1)).sendMail(new Mail(target, "[플레이쿠라운드] 회원가입 인증코드입니다.", content)); + verify(emailService, times(1)).sendMail(new Mail(target, emailTitle, content)); } @ParameterizedTest