diff --git a/.github/workflows/checkstyle-validation.yml b/.github/workflows/checkstyle-validation.yml index 86277c01f..8b8fc328c 100644 --- a/.github/workflows/checkstyle-validation.yml +++ b/.github/workflows/checkstyle-validation.yml @@ -2,7 +2,7 @@ name: ๐Ÿ‘ฎCheckstyle validation on: pull_request: - branches: [ main, dev ] + branches: [ main, dev , recruit-dev] jobs: checkstyle: diff --git a/.github/workflows/test-code-validation.yml b/.github/workflows/test-code-validation.yml index 2d4b0468d..958027d64 100644 --- a/.github/workflows/test-code-validation.yml +++ b/.github/workflows/test-code-validation.yml @@ -2,7 +2,7 @@ name: ๐Ÿ’ป Test code validation on: pull_request: - branches: [ main, dev ] + branches: [ main, dev, recruit-dev] jobs: test: diff --git a/.gitignore b/.gitignore index 443c346ca..90e6c5ba4 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,8 @@ build/ gg-pingpong-api/src/main/resources/application.yml .DS_Store python -/logs +**/logs +**/src/main/generated/ ### STS ### @@ -27,9 +28,11 @@ bin/ *.iws *.iml *.ipr +*.log out/ !**/src/main/**/out/ !**/src/test/**/out/ +**/generated ### NetBeans ### /nbproject/private/ @@ -46,7 +49,9 @@ out/ pingping.pem ### logs ### -./logs/* +**/logs/* ### git commit message convention file ### .gitmessage.txt + +**/generated diff --git a/README.md b/README.md index d25b712c7..492e93961 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,18 @@ https://42gg.kr/ - 4๊ธฐ: 2023.08.01 ~ 2023.09.21 +- 5๊ธฐ : 2023.11.01 ~ 2024.01.31 + ## โšก๏ธ ํ”„๋กœ์ ํŠธ ์•„ํ‚คํ…์ฒ˜ -systemArchitecture     +![gg-5th-architecture](https://github.com/42organization/42gg.server.dev.v2/assets/33301153/f801e7b5-d579-467b-9ad0-2bfec506dcaa) + + -## โšก๏ธ 3๊ธฐ ์ง„ํ–‰ ์‚ฌํ•ญ +## โšก๏ธ ํŒ€์†Œ๊ฐœ +### 3๊ธฐ +
+ 3๊ธฐ ์ง„ํ–‰ ์‚ฌํ•ญ +
### โšก๏ธโšก ๋กœ๊ทธ์ธ ์—ฐ๋™ ์ถ”๊ฐ€ - v1์—์„œ ์ง€์›ํ•˜์ง€ ์•Š๋˜ ์นด์นด์˜ค๊ณ„์ • ์—ฐ๋™ ๊ธฐ๋Šฅ ์ถ”๊ฐ€(์ขŒ : v1, ์šฐ: v2)

@@ -77,30 +85,9 @@ https://42gg.kr/ dockerPs    
-## โšก๏ธ 4๊ธฐ ์ง„ํ–‰ ์‚ฌํ•ญ -### โšก๏ธโšก DB table ๊ตฌ์กฐ ๋ณ€๊ฒฝ -- ์ƒ์ , ํ‹ฐ์–ด ๋“ฑ ์„œ๋น„์Šค ํ™•์žฅ์„ ์œ„ํ•œ DB ์žฌ์„ค๊ณ„ -ERD V3 - -### โšก๏ธโšก ์žฌํ™” ์‹œ์Šคํ…œ ์ถ”๊ฐ€ -- ์ถœ์„, ๊ฒŒ์ž„ ์ŠนํŒจ์— ์—ฐ๊ด€ํ•ด ์žฌํ™” ์‹œ์Šคํ…œ ์ถ”๊ฐ€ -attendance - -### โšก๏ธโšก ์ƒ์ , ์•„์ดํ…œ ์„œ๋น„์Šค ์ถ”๊ฐ€ -- ์œ ์ € ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ฐ˜์˜ํ•œ ๊ธฐ๋Šฅ ํ™•์žฅ -แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-23 แ„‹แ…ฉแ„’แ…ฎ 11 48 01 -แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-23 แ„‹แ…ฉแ„’แ…ฎ 11 48 18 - -### โšก๏ธโšก ํ‹ฐ์–ด ์‹œ์Šคํ…œ ์ถ”๊ฐ€ -- ๋žญํ‚น์ „ ํ™œ์„ฑํ™”๋ฅผ ์œ„ํ•œ ํ‹ฐ์–ด ์‹œ์Šคํ…œ ์ถ”๊ฐ€ -tier - -### โšก๏ธโšก ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€ ๊ตฌํ˜„ -- ์›ํ™œํ•œ ์šด์˜์„ ์œ„ํ•œ ๊ด€๋ฆฌ์ž ๊ธฐ๋Šฅ ์ถ”๊ฐ€ -admin + +
-## โšก๏ธ ํŒ€์†Œ๊ฐœ -### 3๊ธฐ @@ -129,7 +116,37 @@ https://42gg.kr/
+ + ### 4๊ธฐ +
+ 4๊ธฐ ์ง„ํ–‰ ์‚ฌํ•ญ +
+ +### โšก๏ธโšก DB table ๊ตฌ์กฐ ๋ณ€๊ฒฝ +- ์ƒ์ , ํ‹ฐ์–ด ๋“ฑ ์„œ๋น„์Šค ํ™•์žฅ์„ ์œ„ํ•œ DB ์žฌ์„ค๊ณ„ +ERD V3 + +### โšก๏ธโšก ์žฌํ™” ์‹œ์Šคํ…œ ์ถ”๊ฐ€ +- ์ถœ์„, ๊ฒŒ์ž„ ์ŠนํŒจ์— ์—ฐ๊ด€ํ•ด ์žฌํ™” ์‹œ์Šคํ…œ ์ถ”๊ฐ€ +attendance + +### โšก๏ธโšก ์ƒ์ , ์•„์ดํ…œ ์„œ๋น„์Šค ์ถ”๊ฐ€ +- ์œ ์ € ์š”๊ตฌ์‚ฌํ•ญ์„ ๋ฐ˜์˜ํ•œ ๊ธฐ๋Šฅ ํ™•์žฅ +แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-23 แ„‹แ…ฉแ„’แ…ฎ 11 48 01 +แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2023-09-23 แ„‹แ…ฉแ„’แ…ฎ 11 48 18 + +### โšก๏ธโšก ํ‹ฐ์–ด ์‹œ์Šคํ…œ ์ถ”๊ฐ€ +- ๋žญํ‚น์ „ ํ™œ์„ฑํ™”๋ฅผ ์œ„ํ•œ ํ‹ฐ์–ด ์‹œ์Šคํ…œ ์ถ”๊ฐ€ +tier + +### โšก๏ธโšก ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€ ๊ตฌํ˜„ +- ์›ํ™œํ•œ ์šด์˜์„ ์œ„ํ•œ ๊ด€๋ฆฌ์ž ๊ธฐ๋Šฅ ์ถ”๊ฐ€ +admin + +
+
+ @@ -157,8 +174,66 @@ https://42gg.kr/
+### 5๊ธฐ +
+ 5๊ธฐ ์ง„ํ–‰ ์‚ฌํ•ญ +
+ +### โšก๏ธโšก ํ† ๋„ˆ๋จผํŠธ ๊ฐœ๋ฐœ +5th-tournament + +### โšก๏ธโšก ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ๊ฐœ์„  (2024-03-19 ๊ธฐ์ค€) +### ์ „์ฒด 68% -> 74% +5th-test-coverage-total + +### ๋‹จ์œ„ ํ…Œ์ŠคํŠธ 0% -> 30% +5th-test-coverage-unit + + +### โšก๏ธโšก ์•„ํ‚คํ…์ฒ˜ ๋ณ€๊ฒฝ +### BEFORE + systemArchitecture     +### AFTER + ![gg-5th-architecture](https://github.com/42organization/42gg.server.dev.v2/assets/33301153/f801e7b5-d579-467b-9ad0-2bfec506dcaa) + +### โšก๏ธโšก DB table ๊ตฌ์กฐ ๋ณ€๊ฒฝ +![image](https://github.com/42organization/42gg.server.dev.v2/assets/33301153/d4c68d74-590c-41db-9c47-0bdd4f249bc3) + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
๐Ÿ“๐Ÿ“๐Ÿ“๐Ÿ“๐Ÿ“
๊ณ ์Šน์ค€ @kokomong2๊น€ํ•œ๋‚˜ @Kimhan-nah๋ฐ•์ˆ˜์ง„ @Newsujin ์ด์žํ›ˆ @SONGS4RI์ •์Šน์ฒ  @middlefitting
ํ† ๋„ˆ๋จผํŠธ ๊ฐœ๋ฐœ,
ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ๊ฐœ์„ 
ํŒ€์žฅ, ํ† ๋„ˆ๋จผํŠธ ๊ฐœ๋ฐœ,
ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ๊ฐœ์„ 
ํ† ๋„ˆ๋จผํŠธ ๊ฐœ๋ฐœ,
ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ๊ฐœ์„ 
ํ† ๋„ˆ๋จผํŠธ ๊ฐœ๋ฐœ,
ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ๊ฐœ์„ 
์ธํ”„๋ผ ๋‹ด๋‹น,
ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ๊ฐœ์„ 
## โšก๏ธ ํ•„์š” ํŒŒ์ผ +
+ application.yml +
+ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์–‘์‹์˜ "application.yml"ํŒŒ์ผ์ด "src/main/resources/"๊ฒฝ๋กœ์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ``` spring: @@ -319,3 +394,6 @@ app: refreshTokenExpiry: "" ``` + +
+
diff --git a/build.gradle b/build.gradle index fdb0fa7f7..7233d1bff 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ editorconfig { } springBoot { - mainClass = "gg.pingpong.api.PingPongApiApplication" + mainClass = "gg.PingPongApiApplication" } group = 'io.42pp' @@ -56,6 +56,9 @@ subprojects { implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'org.redisson:redisson:3.17.3' + //devtools + implementation 'org.springframework.boot:spring-boot-devtools' + /* spring doc */ implementation 'org.springdoc:springdoc-openapi-ui:1.6.6' @@ -88,6 +91,10 @@ subprojects { testImplementation "org.junit.jupiter:junit-jupiter:5.8.1" testImplementation "org.testcontainers:testcontainers:1.19.3" testImplementation "org.testcontainers:junit-jupiter:1.19.3" + + // mapstruct ์ถ”๊ฐ€ + implementation 'org.mapstruct:mapstruct:1.5.5.Final' + annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final' } //ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ •๋„๊ตฌ @@ -243,6 +250,30 @@ project(':gg-pingpong-api') { implementation project(':gg-repo') implementation project(':gg-admin-repo') implementation project(':gg-utils') + implementation project(':gg-auth') + implementation project(':gg-recruit-api') + } +} + +project(':gg-recruit-api') { + bootJar { enabled = false } + jar { enabled = true } + dependencies { + implementation project(':gg-data') + implementation project(':gg-repo') + implementation project(':gg-admin-repo') + implementation project(':gg-utils') + implementation project(':gg-auth') + } +} + +project(':gg-auth') { + bootJar { enabled = false } + jar { enabled = true } + dependencies { + implementation project(':gg-data') + implementation project(':gg-repo') + implementation project(':gg-utils') } } diff --git a/codecov.yml b/codecov.yml index 1c5086536..3cb47c47c 100644 --- a/codecov.yml +++ b/codecov.yml @@ -13,12 +13,18 @@ flags: unitTest: paths: - gg-pingpong-api/src/main/java/gg/pingpong/api - - gg-pingpong-repo/src/main/java/gg/pingpong/repo - - gg-pingpong-admin-repo/src/main/java/gg/pingpong/admin/repo - - gg-pingpong-data/src/main/java/gg/pingpong/data + - gg-repo/src/main/java/gg/repo + - gg-admin-repo/src/main/java/gg/admin/repo + - gg-data/src/main/java/gg/data + - gg-auth/src/main/java/gg/auth + - gg-utils/src/main/java/gg/utils + - gg-recruit-api/src/main/java/gg/recruit/api integrationTest: paths: - gg-pingpong-api/src/main/java/gg/pingpong/api - - gg-pingpong-repo/src/main/java/gg/pingpong/repo - - gg-pingpong-admin-repo/src/main/java/gg/pingpong/admin/repo - - gg-pingpong-data/src/main/java/gg/pingpong/data + - gg-repo/src/main/java/gg/repo + - gg-admin-repo/src/main/java/gg/admin/repo + - gg-data/src/main/java/gg/data + - gg-auth/src/main/java/gg/auth + - gg-utils/src/main/java/gg/utils + - gg-recruit-api/src/main/java/gg/recruit/api diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/category/CategoryAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/category/CategoryAdminRepository.java new file mode 100644 index 000000000..26c8ae8e8 --- /dev/null +++ b/gg-admin-repo/src/main/java/gg/admin/repo/category/CategoryAdminRepository.java @@ -0,0 +1,13 @@ +package gg.admin.repo.category; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +import gg.data.party.Category; + +public interface CategoryAdminRepository extends JpaRepository { + boolean existsByName(String categoryName); + + Optional findByName(String categoryName); +} diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/comment/CommentAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/comment/CommentAdminRepository.java new file mode 100644 index 000000000..4d0ebe1f6 --- /dev/null +++ b/gg-admin-repo/src/main/java/gg/admin/repo/comment/CommentAdminRepository.java @@ -0,0 +1,8 @@ +package gg.admin.repo.comment; + +import org.springframework.data.jpa.repository.JpaRepository; + +import gg.data.party.Comment; + +public interface CommentAdminRepository extends JpaRepository { +} diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/game/GameAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/game/GameAdminRepository.java index 18efb7a17..fdfe0bdb8 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/game/GameAdminRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/game/GameAdminRepository.java @@ -10,10 +10,10 @@ import org.springframework.data.repository.query.Param; import gg.admin.repo.game.out.GameTeamUser; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.season.Season; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.season.Season; public interface GameAdminRepository extends JpaRepository { @@ -33,8 +33,10 @@ public interface GameAdminRepository extends JpaRepository { + "order by t1.startTime desc;", nativeQuery = true) List findTeamsByGameIsIn(@Param("games") List games); - @Query(value = "SELECT g FROM Game g, Team t, TeamUser tu WHERE g.status = :status AND g.id = t.game.id" - + " AND t.id = tu.team.id AND tu.user.id = :userId") + @Query(value = "SELECT g FROM Game g " + + "INNER JOIN Team t ON g.id = t.game.id " + + "INNER JOIN TeamUser tu ON tu.team.id = t.id " + + "WHERE g.status = :status AND tu.user.id = :userId") Optional findByStatusTypeAndUserId(@Param("status") StatusType status, @Param("userId") Long userId); @Query(value = "SELECT g FROM Game g JOIN FETCH g.season WHERE g.id = :gameId") diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepository.java index fb7e4b362..e2cac85e4 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepository.java @@ -2,7 +2,7 @@ import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.game.PChange; +import gg.data.pingpong.game.PChange; public interface PChangeAdminRepository extends JpaRepository, PChangeAdminRepositoryCustom { } diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepositoryCustom.java b/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepositoryCustom.java index afaed7f3b..f1367a479 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepositoryCustom.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepositoryCustom.java @@ -2,7 +2,7 @@ import java.util.List; -import gg.data.game.PChange; +import gg.data.pingpong.game.PChange; public interface PChangeAdminRepositoryCustom { List findByTeamUser(Long userId); diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepositoryCustomImpl.java b/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepositoryCustomImpl.java index a9702a353..eb5fb8dff 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepositoryCustomImpl.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/game/PChangeAdminRepositoryCustomImpl.java @@ -5,7 +5,7 @@ import javax.persistence.EntityManager; import javax.persistence.LockModeType; -import gg.data.game.PChange; +import gg.data.pingpong.game.PChange; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/game/TeamAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/game/TeamAdminRepository.java index da465572f..9407a7d35 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/game/TeamAdminRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/game/TeamAdminRepository.java @@ -4,8 +4,8 @@ import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.game.Game; -import gg.data.game.Team; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; public interface TeamAdminRepository extends JpaRepository { List findAllByGame(Game game); diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/game/TeamUserAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/game/TeamUserAdminRepository.java index 7b4750dda..6c1c7e7f5 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/game/TeamUserAdminRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/game/TeamUserAdminRepository.java @@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.game.TeamUser; +import gg.data.pingpong.game.TeamUser; import gg.data.user.User; public interface TeamUserAdminRepository extends JpaRepository { diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/game/out/GameTeamUser.java b/gg-admin-repo/src/main/java/gg/admin/repo/game/out/GameTeamUser.java index 60cb599f2..8246eac27 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/game/out/GameTeamUser.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/game/out/GameTeamUser.java @@ -2,8 +2,8 @@ import java.time.LocalDateTime; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; public interface GameTeamUser { Long getGameId(); diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/manage/AdminSlotManagementsRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/manage/AdminSlotManagementsRepository.java index ebcf52842..afb3d4b98 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/manage/AdminSlotManagementsRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/manage/AdminSlotManagementsRepository.java @@ -8,7 +8,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.manage.SlotManagement; +import gg.data.pingpong.manage.SlotManagement; public interface AdminSlotManagementsRepository extends JpaRepository { @Query("select slot from SlotManagement slot " @@ -20,4 +20,8 @@ public interface AdminSlotManagementsRepository extends JpaRepository findFirstByOrderByIdDesc(); + @Query("select sm from SlotManagement sm where (sm.endTime is null" + + " or sm.endTime > :now) and sm.startTime <=:now") + Optional findCurrent(@Param("now") LocalDateTime now); + } diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/match/RedisMatchTimeAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/match/RedisMatchTimeAdminRepository.java new file mode 100644 index 000000000..632ce95f3 --- /dev/null +++ b/gg-admin-repo/src/main/java/gg/admin/repo/match/RedisMatchTimeAdminRepository.java @@ -0,0 +1,29 @@ +package gg.admin.repo.match; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Repository; + +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.MatchKey; +import lombok.RequiredArgsConstructor; + +@Repository +@RequiredArgsConstructor +public class RedisMatchTimeAdminRepository { + private final RedisTemplate redisTemplate; + + public Map> getAllEnrolledSlots() { + Set keys = redisTemplate.keys(MatchKey.getAllTime() + "*"); + int prefixIdx = MatchKey.getAllTime().length(); + + return keys.stream().collect(Collectors.toMap( + key -> LocalDateTime.parse(key.substring(prefixIdx)), + key -> redisTemplate.opsForList().range(key, 0, -1))); + } +} diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/recruit/ApplicationAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/recruit/ApplicationAdminRepository.java new file mode 100644 index 000000000..3645e8aec --- /dev/null +++ b/gg-admin-repo/src/main/java/gg/admin/repo/recruit/ApplicationAdminRepository.java @@ -0,0 +1,70 @@ +package gg.admin.repo.recruit; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.recruit.application.Application; + +public interface ApplicationAdminRepository extends JpaRepository { + Optional findByIdAndRecruitId(Long applicationId, Long recruitId); + + /** + * id ์กฐ๊ฑด์— ์ผ์น˜ํ•˜๋Š” ์ง€์›์„œ ๋ชฉ๋ก ๋ฐ˜ํ™˜ + * @param recruitId + * @param pageable + * @return + */ + @EntityGraph(attributePaths = {"user", "applicationAnswers", "applicationAnswers.question", + "applicationAnswers.question.checkLists"}) + Page findByRecruitIdAndIsDeletedFalseOrderByIdDesc(Long recruitId, Pageable pageable); + + /** + * id ์กฐ๊ฑด ๋ฐ ์ฒดํฌ๋ฆฌ์ŠคํŠธ ์กฐ๊ฑด์— ์ผ์น˜ํ•˜๋Š” ์ง€์›์„œ ๋ชฉ๋ก ๋ฐ˜ํ™˜ + * @param recruitId + * @param questionId + * @param checkListIds + * @param pageable + */ + @EntityGraph(attributePaths = {"user", "applicationAnswers", "applicationAnswers.question", + "applicationAnswers.question.checkLists"}) + @Query("SELECT a FROM Application a WHERE a.isDeleted = false AND a.id IN " + + "(SELECT aa.application.id FROM ApplicationAnswerCheckList aa " + + "JOIN aa.checkList cl " + + "JOIN aa.application.recruit r " + + "WHERE r.id =:recruitId AND aa.question.id = :questionId AND cl.id IN :checkListIds) " + + "ORDER BY a.id DESC") + Page findAllByCheckList( + @Param("recruitId") Long recruitId, + @Param("questionId") Long questionId, + @Param("checkListIds") List checkListIds, + Pageable pageable); + + @EntityGraph(attributePaths = {"user", "applicationAnswers", "applicationAnswers.question", + "applicationAnswers.question.checkLists"}) + @Query("SELECT a FROM Application a WHERE a.isDeleted = false AND a.id IN " + + "(SELECT aa.application.id FROM ApplicationAnswerText aa " + + "JOIN aa.application.recruit r " + + "WHERE r.id =:recruitId AND aa.question.id = :questionId AND aa.answer LIKE CONCAT('%', :search, '%')) " + + "ORDER BY a.id DESC") + Page findAllByContainSearch( + @Param("recruitId") Long recruitId, + @Param("questionId") Long questionId, + @Param("search") String search, + Pageable pageable); + + @Query("SELECT a FROM Application a " + + "JOIN FETCH a.user " + + "LEFT JOIN FETCH a.recruitStatus " + + "WHERE a.recruit.id = :recruitmentId " + + "ORDER BY a.id DESC") + List findAllByRecruitmentIdWithUserAndRecruitStatusFetchJoinOrderByIdDesc( + @Param("recruitmentId") Long recruitId); +} + diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/recruit/RecruitmentAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/recruit/RecruitmentAdminRepository.java new file mode 100644 index 000000000..58a43a8c4 --- /dev/null +++ b/gg-admin-repo/src/main/java/gg/admin/repo/recruit/RecruitmentAdminRepository.java @@ -0,0 +1,19 @@ +package gg.admin.repo.recruit; + +import java.util.Optional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import gg.data.recruit.recruitment.Recruitment; + +public interface RecruitmentAdminRepository extends JpaRepository { + Page findAllByOrderByEndTimeDesc(Pageable pageable); + + Page findAllByIsDeletedOrderByEndTimeDesc(boolean isDeleted, Pageable pageable); + + @Query("SELECT r FROM Recruitment r WHERE r.id = :recruitId AND r.isDeleted = false") + Optional findNotDeletedRecruit(Long recruitId); +} diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/recruit/manage/RecruitResultMessageRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/recruit/manage/RecruitResultMessageRepository.java new file mode 100644 index 000000000..ab38f3739 --- /dev/null +++ b/gg-admin-repo/src/main/java/gg/admin/repo/recruit/manage/RecruitResultMessageRepository.java @@ -0,0 +1,27 @@ +package gg.admin.repo.recruit.manage; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Transactional; + +import gg.data.recruit.manage.ResultMessage; +import gg.data.recruit.manage.enums.MessageType; + +public interface RecruitResultMessageRepository extends JpaRepository { + @Transactional + @Modifying + @Query("UPDATE ResultMessage rm SET rm.isUse = false WHERE rm.messageType = :messageType") + void disablePreviousResultMessages(@Param("messageType") MessageType messageType); + + @Query("SELECT r FROM ResultMessage r ORDER BY r.id DESC") + List findAllOrderByIdDesc(); + + @Query("SELECT r FROM ResultMessage r " + + "WHERE r.messageType = :messageType and r.isUse = true ") + Optional findActiveResultMessageByMessageType(@Param("messageType") MessageType messageType); +} diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/recruit/recruitment/QuestionAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/recruit/recruitment/QuestionAdminRepository.java new file mode 100644 index 000000000..6dc2d08ab --- /dev/null +++ b/gg-admin-repo/src/main/java/gg/admin/repo/recruit/recruitment/QuestionAdminRepository.java @@ -0,0 +1,8 @@ +package gg.admin.repo.recruit.recruitment; + +import org.springframework.data.jpa.repository.JpaRepository; + +import gg.data.recruit.recruitment.Question; + +public interface QuestionAdminRepository extends JpaRepository { +} diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/recruit/recruitment/RecruitStatusAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/recruit/recruitment/RecruitStatusAdminRepository.java new file mode 100644 index 000000000..7aa448d0b --- /dev/null +++ b/gg-admin-repo/src/main/java/gg/admin/repo/recruit/recruitment/RecruitStatusAdminRepository.java @@ -0,0 +1,25 @@ +package gg.admin.repo.recruit.recruitment; + +import java.time.LocalDateTime; +import java.util.List; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.recruit.application.RecruitStatus; + +public interface RecruitStatusAdminRepository extends JpaRepository { + @Query("SELECT rs FROM RecruitStatus rs WHERE rs.application.recruit.id = :recruitmentId AND " + + "rs.interviewDate BETWEEN :startDate AND :endDate") + List findFirstByRecruitmentIdAndInterviewDateBetween(@Param("recruitmentId") Long recruitmentId, + @Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate, Pageable pageable); + + default boolean existsByRecruitmentIdAndInterviewDateBetween(Long recruitmentId, LocalDateTime startDate, + LocalDateTime endDate) { + return findFirstByRecruitmentIdAndInterviewDateBetween(recruitmentId, startDate, endDate, + PageRequest.of(0, 1)).size() == 1; + } +} diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/room/RoomAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/room/RoomAdminRepository.java new file mode 100644 index 000000000..af9fea20f --- /dev/null +++ b/gg-admin-repo/src/main/java/gg/admin/repo/room/RoomAdminRepository.java @@ -0,0 +1,13 @@ +package gg.admin.repo.room; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; + +import gg.data.party.Category; +import gg.data.party.Room; + +public interface RoomAdminRepository extends JpaRepository { + List findByCategory(Category category); + +} diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/season/SeasonAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/season/SeasonAdminRepository.java index 7c7a61365..a43dd399a 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/season/SeasonAdminRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/season/SeasonAdminRepository.java @@ -9,7 +9,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.season.Season; +import gg.data.pingpong.season.Season; public interface SeasonAdminRepository extends JpaRepository { /* ์ž…๋ ฅ์‹œ๊ฐ„๊ณผ ๋ชจ๋“œ๋กœ ์ž…๋ ฅ์‹œ๊ฐ„ ์ดํ›„ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์‹œ์ฆŒ ๊ฐ€์ ธ์˜ค๊ธฐ */ diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/store/CoinPolicyAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/store/CoinPolicyAdminRepository.java index 72fd33f20..a7e04149b 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/store/CoinPolicyAdminRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/store/CoinPolicyAdminRepository.java @@ -4,7 +4,7 @@ import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.store.CoinPolicy; +import gg.data.pingpong.store.CoinPolicy; public interface CoinPolicyAdminRepository extends JpaRepository { Optional findFirstByOrderByIdDesc(); diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/store/ItemAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/store/ItemAdminRepository.java index 007cf8f02..1263179aa 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/store/ItemAdminRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/store/ItemAdminRepository.java @@ -4,7 +4,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.store.Item; +import gg.data.pingpong.store.Item; public interface ItemAdminRepository extends JpaRepository { Page findAll(Pageable pageable); diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/store/MegaphoneAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/store/MegaphoneAdminRepository.java index 133b024b0..f000494cd 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/store/MegaphoneAdminRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/store/MegaphoneAdminRepository.java @@ -4,7 +4,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.store.Megaphone; +import gg.data.pingpong.store.Megaphone; public interface MegaphoneAdminRepository extends JpaRepository { Page findMegaphonesByUserIntraId(String intraId, Pageable pageable); diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/store/ReceiptAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/store/ReceiptAdminRepository.java index d121c17ae..13fd25551 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/store/ReceiptAdminRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/store/ReceiptAdminRepository.java @@ -4,7 +4,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.store.Receipt; +import gg.data.pingpong.store.Receipt; public interface ReceiptAdminRepository extends JpaRepository, ReceiptAdminRepositorySearch { Page findAll(Pageable pageable); diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/store/ReceiptAdminRepositorySearch.java b/gg-admin-repo/src/main/java/gg/admin/repo/store/ReceiptAdminRepositorySearch.java index 7d24f901e..59f4eec7b 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/store/ReceiptAdminRepositorySearch.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/store/ReceiptAdminRepositorySearch.java @@ -5,7 +5,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.store.Receipt; +import gg.data.pingpong.store.Receipt; public interface ReceiptAdminRepositorySearch { @Query(value = "select re from Receipt re where re.purchaserIntraId = :intraId or re.ownerIntraId = :intraId") diff --git a/gg-admin-repo/src/test/java/gg/admin/repo/TestSpringBootApplication.java b/gg-admin-repo/src/test/java/gg/admin/repo/TestSpringBootApplication.java new file mode 100644 index 000000000..cb0a5c276 --- /dev/null +++ b/gg-admin-repo/src/test/java/gg/admin/repo/TestSpringBootApplication.java @@ -0,0 +1,8 @@ +package gg.admin.repo; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = {"gg.recruit.api", "gg.utils", "gg.data", "gg.repo", + "gg.admin.repo", "gg.auth", "gg.pingpong.api"}) +public class TestSpringBootApplication { +} diff --git a/gg-admin-repo/src/test/java/gg/admin/repo/recruit/ApplicationAdminRepositoryTest.java b/gg-admin-repo/src/test/java/gg/admin/repo/recruit/ApplicationAdminRepositoryTest.java new file mode 100644 index 000000000..30c5a1a29 --- /dev/null +++ b/gg-admin-repo/src/test/java/gg/admin/repo/recruit/ApplicationAdminRepositoryTest.java @@ -0,0 +1,231 @@ +package gg.admin.repo.recruit; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import javax.persistence.EntityManager; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +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.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.transaction.annotation.Transactional; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.ApplicationAnswerCheckList; +import gg.data.recruit.application.ApplicationAnswerText; +import gg.data.recruit.application.RecruitStatus; +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.recruit.recruitment.enums.InputType; +import gg.data.user.User; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; +import gg.utils.annotation.UnitTest; + +@IntegrationTest +@UnitTest +@Transactional +class ApplicationAdminRepositoryTest { + @Autowired + EntityManager entityManager; + + @Autowired + ApplicationAdminRepository applicationAdminRepository; + + @Autowired + TestDataUtils testDataUtils; + + @Nested + @DisplayName("findByIdAndRecruitId") + class FindByIdAndRecruitId { + @Test + @DisplayName("์กฐํšŒ ์„ฑ๊ณต") + void findSuccess() { + //Arrange + User user = testDataUtils.createNewUser(); + Recruitment recruitment = testDataUtils.createNewRecruitment(); + Application application = testDataUtils.createApplication(user, recruitment); + entityManager.flush(); + Long recruitmentId = recruitment.getId(); + Long applicationId = application.getId(); + entityManager.clear(); + + //Act + Optional res = applicationAdminRepository.findByIdAndRecruitId(applicationId, recruitmentId); + + //Assert + Assertions.assertThat(res.get()).isNotNull(); + } + } + + @Nested + @DisplayName("findAllByRecruitmentIdWithUserAndRecruitStatusFetchJoin") + class FindAllByRecruitmentIdWithUserAndRecruitStatusFetchJoin { + @Test + @DisplayName("์กฐํšŒ ์„ฑ๊ณต") + void findSuccess() { + //Arrange + User user = testDataUtils.createNewUser(); + Recruitment recruitment = testDataUtils.createNewRecruitment(); + Application application1 = testDataUtils.createApplication(user, recruitment); + entityManager.flush(); + Application application2 = testDataUtils.createApplication(user, recruitment); + RecruitStatus recruitStatus = testDataUtils.createRecruitStatus(application2); + entityManager.flush(); + + Long recruitmentId = recruitment.getId(); + Long application1Id = application1.getId(); + Long application2Id = application2.getId(); + Long userId = user.getId(); + Long recruitStatusId = recruitStatus.getId(); + entityManager.clear(); + + //Act + List res; + res = applicationAdminRepository + .findAllByRecruitmentIdWithUserAndRecruitStatusFetchJoinOrderByIdDesc(recruitmentId); + + //Assert + Assertions.assertThat(res.get(0).getId()).isEqualTo(application2Id); + Assertions.assertThat(res.get(0).getUser().getId()).isEqualTo(userId); + Assertions.assertThat(res.get(0).getRecruitStatus().getId()).isEqualTo(recruitStatusId); + + Assertions.assertThat(res.get(1).getId()).isEqualTo(application1Id); + Assertions.assertThat(res.get(1).getUser().getId()).isEqualTo(userId); + Assertions.assertThat(res.get(1).getRecruitStatus()).isNull(); + } + } + + @Nested + @DisplayName("application by getRecruitmentApplications condition success test") + class ApplicationByGetRecruitmentApplicationsCondition { + Long wrongApplicationId; + Long userId; + Long recruitmentId; + Long applicationId; + Long questionId; + Long checkListId1; + Long checkListId2; + Long applicationAnswerCheckListId; + String search = "hello world"; + + @BeforeEach + public void init() { + Recruitment recruitment = testDataUtils.createNewRecruitment(); + User user = testDataUtils.createNewUser(); + + //target 1 + Application application = testDataUtils.createApplication(user, recruitment); + Question question = testDataUtils.createNewQuestion(recruitment, InputType.SINGLE_CHECK, "dubby", 2); + CheckList checkList = testDataUtils.createNewCheckList(question, "dd"); + ApplicationAnswerCheckList applicationAnswerCheckList = testDataUtils.createNewApplicationAnswerCheckList( + application, question, checkList); + + //target 2 + Application application2 = testDataUtils.createApplication(user, recruitment); + CheckList checkList2 = testDataUtils.createNewCheckList(question, "dd"); + ApplicationAnswerCheckList applicationAnswerCheckList2 = testDataUtils.createNewApplicationAnswerCheckList( + application2, question, checkList2); + + //must not contain + Application application3 = testDataUtils.createApplication(user, recruitment); + CheckList checkList3 = testDataUtils.createNewCheckList(question, "dd"); + ApplicationAnswerCheckList applicationAnswerCheckList3 = testDataUtils.createNewApplicationAnswerCheckList( + application, question, checkList3); + + // search target + ApplicationAnswerText answerText = testDataUtils.createNewApplicationAnswerText(application, question, + search); + ApplicationAnswerText answerText2 = testDataUtils.createNewApplicationAnswerText(application2, question, + "pp" + search + "pp"); + ApplicationAnswerText answerText3 = testDataUtils.createNewApplicationAnswerText(application3, question, + "pp" + search); + + wrongApplicationId = application3.getId(); + userId = user.getId(); + recruitmentId = recruitment.getId(); + applicationId = application.getId(); + questionId = question.getId(); + checkListId1 = checkList.getId(); + checkListId2 = checkList2.getId(); + applicationAnswerCheckListId = applicationAnswerCheckList.getId(); + + entityManager.flush(); + entityManager.clear(); + } + + @Nested + @DisplayName("findByRecruitIdAndIsDeletedFalse") + class FindByRecruitIdAndIsDeletedFalse { + + @Test + @DisplayName("์กฐํšŒ ์„ฑ๊ณต") + void success() { + //Arrange + Pageable pageable = PageRequest.of(0, 10); + + // Act + Page result = applicationAdminRepository.findByRecruitIdAndIsDeletedFalseOrderByIdDesc( + recruitmentId, + pageable); + + // Assert + Assertions.assertThat(result.getContent().size()).isEqualTo(3); + } + } + + @Nested + @DisplayName("FindAllByCheckList") + class FindAllByCheckList { + + @Test + @DisplayName("์—ฌ๋Ÿฌ๊ฐœ์˜ ์กฐ๊ฑด ์ค‘ ํ•˜๋‚˜๋งŒ ๋งŒ์กฑํ•ด๋„ ์กฐํšŒ๊ฐ€ ์„ฑ๊ณต") + void success() { + //Arrange + List checkListTargetId = new ArrayList<>(); + checkListTargetId.add(checkListId1); + checkListTargetId.add(checkListId2); + Pageable pageable = PageRequest.of(0, 10); + + // Act + Page result = applicationAdminRepository.findAllByCheckList(recruitmentId, + questionId, checkListTargetId, pageable); + + // Assert + Assertions.assertThat(result.getContent().size()).isEqualTo(2); + for (Application entity : result.getContent()) { + Assertions.assertThat(entity.getId()).isNotEqualTo(wrongApplicationId); + } + } + } + + @Nested + @DisplayName("findAllByContainSearch") + class FindAllByContainSearch { + + @Test + @DisplayName("search๋ฅผ ํฌํ•จํ•˜๋ฉด ์กฐํšŒ ์„ฑ๊ณต") + void success() { + //Arrange + Pageable pageable = PageRequest.of(0, 10); + + // Act + Page result = applicationAdminRepository.findAllByContainSearch(recruitmentId, + questionId, search, pageable); + + // Assert + Assertions.assertThat(result.getContent().size()).isEqualTo(3); + } + } + + } + +} diff --git a/gg-admin-repo/src/test/java/gg/admin/repo/recruit/recruitment/RecruitStatusAdminRepositoryTest.java b/gg-admin-repo/src/test/java/gg/admin/repo/recruit/recruitment/RecruitStatusAdminRepositoryTest.java new file mode 100644 index 000000000..094201ea9 --- /dev/null +++ b/gg-admin-repo/src/test/java/gg/admin/repo/recruit/recruitment/RecruitStatusAdminRepositoryTest.java @@ -0,0 +1,87 @@ +package gg.admin.repo.recruit.recruitment; + +import static org.assertj.core.api.AssertionsForClassTypes.*; + +import java.time.LocalDateTime; + +import javax.persistence.EntityManager; + +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.transaction.annotation.Transactional; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.RecruitStatus; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.user.User; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; +import gg.utils.annotation.UnitTest; + +@IntegrationTest +@Transactional +@UnitTest +class RecruitStatusAdminRepositoryTest { + @Autowired + RecruitStatusAdminRepository recruitStatusAdminRepository; + + @Autowired + EntityManager entityManager; + + @Autowired + TestDataUtils testDataUtils; + + @Nested + @DisplayName("findFirstByRecruitmentIdAndInterviewDateBetween") + class FindFirstByRecruitmentIdAndInterviewDateBetween { + @Test + @DisplayName("์‹œ๊ฐ„RecruitStatus ์กฐํšŒ ์„ฑ๊ณต") + void findSuccess() { + // Arrange + int minutes = 30; + LocalDateTime startTime = LocalDateTime.of(2021, 1, 1, 0, 0); + LocalDateTime endTime = startTime.plusMinutes(minutes); + + User user = testDataUtils.createNewUser(); + Recruitment recruitment = testDataUtils.createNewRecruitment(); + Application application = testDataUtils.createApplication(user, recruitment); + RecruitStatus recruitStatus = testDataUtils.createRecruitStatus(application, startTime); + entityManager.flush(); + Long recruitmentId = recruitment.getId(); + + // Act + boolean exist = recruitStatusAdminRepository.existsByRecruitmentIdAndInterviewDateBetween( + recruitmentId, startTime, endTime); + + // Assert + assertThat(exist).isTrue(); + } + + @Test + @DisplayName("์—ฌ๋Ÿฌ๊ฐœ RecruitStatus์—์„œ๋„ 1๊ฐœ๋งŒ ์ฐพ๋Š”๋‹ค.") + void findFirst() { + // Arrange + int minutes = 30; + LocalDateTime startTime = LocalDateTime.of(2021, 1, 1, 0, 0); + LocalDateTime endTime = startTime.plusMinutes(minutes); + + User user = testDataUtils.createNewUser(); + Recruitment recruitment = testDataUtils.createNewRecruitment(); + Application application1 = testDataUtils.createApplication(user, recruitment); + Application application2 = testDataUtils.createApplication(user, recruitment); + RecruitStatus recruitStatus1 = testDataUtils.createRecruitStatus(application1, startTime); + RecruitStatus recruitStatus2 = testDataUtils.createRecruitStatus(application2, startTime.plusMinutes(10)); + entityManager.flush(); + Long recruitmentId = recruitment.getId(); + + // Act + boolean exist = recruitStatusAdminRepository.existsByRecruitmentIdAndInterviewDateBetween( + recruitmentId, startTime, endTime); + + // Assert + assertThat(exist).isTrue(); + } + } +} diff --git a/gg-admin-repo/src/test/java/gg/admin/repo/recurit/maage/RecruitResultMessageRepositoryTest.java b/gg-admin-repo/src/test/java/gg/admin/repo/recurit/maage/RecruitResultMessageRepositoryTest.java new file mode 100644 index 000000000..be6b1f403 --- /dev/null +++ b/gg-admin-repo/src/test/java/gg/admin/repo/recurit/maage/RecruitResultMessageRepositoryTest.java @@ -0,0 +1,104 @@ +package gg.admin.repo.recurit.maage; + +import java.util.List; + +import javax.persistence.EntityManager; + +import org.assertj.core.api.Assertions; +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.transaction.annotation.Transactional; + +import gg.admin.repo.recruit.manage.RecruitResultMessageRepository; +import gg.data.recruit.manage.ResultMessage; +import gg.data.recruit.manage.enums.MessageType; +import gg.utils.annotation.IntegrationTest; +import gg.utils.annotation.UnitTest; + +@IntegrationTest +@UnitTest +@Transactional +public class RecruitResultMessageRepositoryTest { + + @Autowired + EntityManager entityManager; + + @Autowired + RecruitResultMessageRepository recruitResultMessageRepository; + + @Nested + @DisplayName("disablePreviousResultMessages") + class DisablePreviousResultMessages { + @Test + @DisplayName("MessageType์— ํ•ด๋‹นํ•˜๋Š” ๋ชจ๋“  ์ปฌ๋Ÿผ์ด ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•œ๋‹ค") + void test() { + MessageType targetType = MessageType.FAIL; + MessageType notTargetType = MessageType.PASS; + //Arrange + ResultMessage resultMessage1 = ResultMessage.builder() + .messageType(targetType) + .content("good bye") + .build(); + + ResultMessage resultMessage2 = ResultMessage.builder() + .messageType(notTargetType) + .content("good bye") + .build(); + + ResultMessage resultMessage3 = ResultMessage.builder() + .messageType(targetType) + .content("good bye") + .build(); + + entityManager.persist(resultMessage1); + entityManager.persist(resultMessage2); + entityManager.persist(resultMessage3); + entityManager.flush(); + entityManager.clear(); + + //Act + recruitResultMessageRepository.disablePreviousResultMessages(MessageType.FAIL); + + //Assert + List entities = recruitResultMessageRepository.findAll(); + for (ResultMessage entity : entities) { + if (entity.getMessageType() == targetType) { + Assertions.assertThat(entity.getIsUse()).isFalse(); + } else { + Assertions.assertThat(entity.getIsUse()).isTrue(); + } + } + } + } + + @Nested + @DisplayName("findAllOrderByIdDesc") + class FindAllOrderByIdDesc { + @Test + @DisplayName("๊ฒฐ๊ณผ ๋ฉ”์‹œ์ง€ ์กฐํšŒ") + void success() { + //Arrange + createResultMessage(MessageType.FAIL); + createResultMessage(MessageType.INTERVIEW); + createResultMessage(MessageType.PASS); + entityManager.flush(); + entityManager.clear(); + + //Act + List results = recruitResultMessageRepository.findAllOrderByIdDesc(); + + //Assert + Assertions.assertThat(results.size()).isEqualTo(3); + } + } + + void createResultMessage(MessageType messageType) { + ResultMessage resultMessage1 = ResultMessage.builder() + .messageType(messageType) + .content("hello") + .build(); + entityManager.persist(resultMessage1); + } +} diff --git a/gg-admin-repo/src/test/resources/application.yml b/gg-admin-repo/src/test/resources/application.yml new file mode 100644 index 000000000..f28374ce9 --- /dev/null +++ b/gg-admin-repo/src/test/resources/application.yml @@ -0,0 +1,184 @@ +spring: + application: + name: 42gg + + profiles: + active: testCode + + security: + oauth2.client: + authenticationScheme: header + registration: + 42: + redirect-uri: "{baseUrl}/{action}/oauth2/code/{registrationId}" + authorization-grant-type: authorization_code + scope: public + kakao: + redirect-uri: "{baseUrl}/{action}/oauth2/code/{registrationId}" + authorization-grant-type: authorization_code + scope: profile_nickname, profile_image, account_email + provider: + 42: + authorization-uri: "https://api.intra.42.fr/oauth/authorize" + token-uri: "https://api.intra.42.fr/oauth/token" + user-info-uri: "https://api.intra.42.fr/v2/me" + user-name-attribute: id + kakao: + authorization-uri: "https://kauth.kakao.com/oauth/authorize" + token-uri: "https://kauth.kakao.com/oauth/token" + user-info-uri: "https://kapi.kakao.com/v2/user/me" + user-name-attribute: id + + mvc: + hiddenmethod: + filter: + enabled: true + data: + web: + pageable: + default-page-size: 20 + one-indexed-parameters: false + + mail: + host: smtp.gmail.com + port: 587 + username: dummy + password: dummy + properties: + mail: + smtp: + starttls: + enable: true + required: true + auth: true + + # Message ์„ค์ • + messages: + basename: 'messages/validation' + encoding: UTF-8 + +springdoc: + swagger-ui: + path: /api-docs + default-consumes-media-type: application/json + default-produces-media-type: application/json + +app: + auth: + tokenSecret: authdummydummydummydummydummydummydummydummydummy + refreshTokenSecret: refreshdummydummydummydummydummydummydummydummydummy + +info: + image: + defaultUrl: 'https://42gg-public-test-image.s3.ap-northeast-2.amazonaws.com/images/small_default.jpeg' + itemNotFoundUrl: 'https://42gg-public-test-image.s3.ap-northeast-2.amazonaws.com/images/not_found.svg' + +constant: + allowedMinimalStartDays: 2 + tournamentSchedule: "0 0 0 * * *" + +# -- actuator + +management: + server: + port: 8081 + + info: + java: + enabled: true + os: + enabled: true + env: + enabled: true + + health: + show-details: always + + endpoints: + jmx: + exposure: + exclude: "*" + + web: + exposure: + include: "prometheus" + +server: + tomcat: + mbeanregistry: + enabled: true + +--- +spring.config.activate.on-profile: testCode + +# =========================== LOCAL =========================== +spring: + flyway: + enabled: true + baselineOnMigrate: true + locations: classpath:db/migration + user: root + password: 1234 + + jpa: + database-platform: org.hibernate.dialect.MySQL8Dialect + hibernate: + ddl-auto: validate + properties: + hibernate: + show_sql: true + format_sql: true + use_sql_comments: false + + security: + oauth2.client: + registration: + 42: + client-id: "dummy" + client-secret: "dummy" + kakao: + client-id: "dummy" + client-secret: "dummy" + client-authentication-method: POST + + # Redis ์„ค์ • + cache: + type: redis + +# cors ์„ค์ • +cors: + allowed-origins: 'http://localhost:8080,http://127.0.0.1:8081' + allowed-methods: GET,POST,PUT,DELETE,OPTIONS,PATCH + allowed-headers: '*' + allowed-Credentials: false + max-age: 3600 + +logging-level: + org.hibernate.SQL: debug + org.hibernate.type: trace + +slack: + xoxbToken: "dummy" + +info: + web: + frontUrl: 'http://localhost:8080' + domain: "localhost" + +cloud: + aws: + credentials: + accessKey: dummy + secretKey: dummy + s3: + bucket: 42gg-public-test-image + dir: images/ + region: + static: ap-northeast-2 + stack: + auto: false + +app: + auth: + refreshTokenExpiry: 604800000 + tokenExpiry: 604800000 diff --git a/gg-auth/build.gradle b/gg-auth/build.gradle new file mode 100644 index 000000000..1a7f1307b --- /dev/null +++ b/gg-auth/build.gradle @@ -0,0 +1,22 @@ +plugins { + id 'java' +} + +group 'gg.auth' +version '42gg' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + + implementation 'io.jsonwebtoken:jjwt-api:0.11.2' + implementation 'io.jsonwebtoken:jjwt-impl:0.11.2' + implementation 'io.jsonwebtoken:jjwt-jackson:0.11.2' + + annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" + + testImplementation testFixtures(project(':gg-utils')) +} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/dto/UserDto.java b/gg-auth/src/main/java/gg/auth/UserDto.java similarity index 97% rename from gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/dto/UserDto.java rename to gg-auth/src/main/java/gg/auth/UserDto.java index 1d95daf26..37f3cef29 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/dto/UserDto.java +++ b/gg-auth/src/main/java/gg/auth/UserDto.java @@ -1,4 +1,4 @@ -package gg.pingpong.api.user.user.dto; +package gg.auth; import gg.data.user.User; import gg.data.user.type.RacketType; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/argumentresolver/Login.java b/gg-auth/src/main/java/gg/auth/argumentresolver/Login.java similarity index 82% rename from gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/argumentresolver/Login.java rename to gg-auth/src/main/java/gg/auth/argumentresolver/Login.java index a2721766f..3cc11774e 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/argumentresolver/Login.java +++ b/gg-auth/src/main/java/gg/auth/argumentresolver/Login.java @@ -1,4 +1,4 @@ -package gg.pingpong.api.global.utils.argumentresolver; +package gg.auth.argumentresolver; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/argumentresolver/LoginMemberArgumentResolver.java b/gg-auth/src/main/java/gg/auth/argumentresolver/LoginMemberArgumentResolver.java similarity index 87% rename from gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/argumentresolver/LoginMemberArgumentResolver.java rename to gg-auth/src/main/java/gg/auth/argumentresolver/LoginMemberArgumentResolver.java index 69a63945f..ffa51883c 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/argumentresolver/LoginMemberArgumentResolver.java +++ b/gg-auth/src/main/java/gg/auth/argumentresolver/LoginMemberArgumentResolver.java @@ -1,4 +1,4 @@ -package gg.pingpong.api.global.utils.argumentresolver; +package gg.auth.argumentresolver; import javax.servlet.http.HttpServletRequest; @@ -8,10 +8,10 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; +import gg.auth.UserDto; +import gg.auth.utils.AuthTokenProvider; +import gg.auth.utils.HeaderUtil; import gg.data.user.User; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; -import gg.pingpong.api.global.utils.HeaderUtil; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.user.UserRepository; import lombok.RequiredArgsConstructor; diff --git a/gg-auth/src/main/java/gg/auth/config/AuthWebConfig.java b/gg-auth/src/main/java/gg/auth/config/AuthWebConfig.java new file mode 100644 index 000000000..8ececc24a --- /dev/null +++ b/gg-auth/src/main/java/gg/auth/config/AuthWebConfig.java @@ -0,0 +1,24 @@ +package gg.auth.config; + +import java.util.List; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import gg.auth.argumentresolver.LoginMemberArgumentResolver; +import gg.auth.utils.AuthTokenProvider; +import gg.repo.user.UserRepository; +import lombok.RequiredArgsConstructor; + +@Configuration +@RequiredArgsConstructor +public class AuthWebConfig implements WebMvcConfigurer { + private final UserRepository userRepository; + private final AuthTokenProvider tokenProvider; + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(new LoginMemberArgumentResolver(userRepository, tokenProvider)); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/config/properties/AppProperties.java b/gg-auth/src/main/java/gg/auth/properties/AppProperties.java similarity index 94% rename from gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/config/properties/AppProperties.java rename to gg-auth/src/main/java/gg/auth/properties/AppProperties.java index 7d3a828ae..43713387a 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/config/properties/AppProperties.java +++ b/gg-auth/src/main/java/gg/auth/properties/AppProperties.java @@ -1,4 +1,4 @@ -package gg.pingpong.api.global.security.config.properties; +package gg.auth.properties; import java.util.ArrayList; import java.util.List; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/jwt/utils/AuthTokenProvider.java b/gg-auth/src/main/java/gg/auth/utils/AuthTokenProvider.java similarity index 94% rename from gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/jwt/utils/AuthTokenProvider.java rename to gg-auth/src/main/java/gg/auth/utils/AuthTokenProvider.java index afbfe1192..c3eb7d6e3 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/jwt/utils/AuthTokenProvider.java +++ b/gg-auth/src/main/java/gg/auth/utils/AuthTokenProvider.java @@ -1,11 +1,11 @@ -package gg.pingpong.api.global.security.jwt.utils; +package gg.auth.utils; import java.security.Key; import java.util.Date; import org.springframework.stereotype.Component; -import gg.pingpong.api.global.security.config.properties.AppProperties; +import gg.auth.properties.AppProperties; import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jwts; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/HeaderUtil.java b/gg-auth/src/main/java/gg/auth/utils/HeaderUtil.java similarity index 93% rename from gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/HeaderUtil.java rename to gg-auth/src/main/java/gg/auth/utils/HeaderUtil.java index 7bc680609..38fa93f62 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/HeaderUtil.java +++ b/gg-auth/src/main/java/gg/auth/utils/HeaderUtil.java @@ -1,4 +1,4 @@ -package gg.pingpong.api.global.utils; +package gg.auth.utils; import javax.servlet.http.HttpServletRequest; diff --git a/gg-data/src/main/java/gg/data/party/Category.java b/gg-data/src/main/java/gg/data/party/Category.java new file mode 100644 index 000000000..30c4610ce --- /dev/null +++ b/gg-data/src/main/java/gg/data/party/Category.java @@ -0,0 +1,28 @@ +package gg.data.party; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +import gg.data.BaseTimeEntity; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class Category extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", length = 10) + private String name; + + public Category(String name) { + this.name = name; + } +} diff --git a/gg-data/src/main/java/gg/data/party/Comment.java b/gg-data/src/main/java/gg/data/party/Comment.java new file mode 100644 index 000000000..ce4f559f0 --- /dev/null +++ b/gg-data/src/main/java/gg/data/party/Comment.java @@ -0,0 +1,57 @@ +package gg.data.party; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import gg.data.BaseTimeEntity; +import gg.data.user.User; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class Comment extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_room_id", nullable = false) + private UserRoom userRoom; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "room_id", nullable = false) + private Room room; + + @Column(name = "content", length = 100, nullable = false) + private String content; + + @Column(name = "is_hidden", nullable = false) + private boolean isHidden; + + public Comment(User user, UserRoom userRoom, Room room, String content) { + this.user = user; + this.userRoom = userRoom; + this.room = room; + this.content = content; + this.isHidden = false; + this.room.getComments().add(this); + } + + public void updateHidden(boolean isHidden) { + this.isHidden = isHidden; + } +} + diff --git a/gg-data/src/main/java/gg/data/party/CommentReport.java b/gg-data/src/main/java/gg/data/party/CommentReport.java new file mode 100644 index 000000000..c447c454b --- /dev/null +++ b/gg-data/src/main/java/gg/data/party/CommentReport.java @@ -0,0 +1,47 @@ +package gg.data.party; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import gg.data.BaseTimeEntity; +import gg.data.user.User; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class CommentReport extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "reporter_id") + private User reporter; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "comment_id") + private Comment comment; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "room_id") + private Room room; + + @Column(length = 100) + private String message; + + public CommentReport(User reporter, Comment comment, Room room, String message) { + this.reporter = reporter; + this.comment = comment; + this.room = room; + this.message = message; + } +} diff --git a/gg-data/src/main/java/gg/data/party/GameTemplate.java b/gg-data/src/main/java/gg/data/party/GameTemplate.java new file mode 100644 index 000000000..5a5f30860 --- /dev/null +++ b/gg-data/src/main/java/gg/data/party/GameTemplate.java @@ -0,0 +1,84 @@ +package gg.data.party; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import gg.data.BaseTimeEntity; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class GameTemplate extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "category_id") + private Category category; + + @Column(length = 20) + private String gameName; + + @Column + private int maxGamePeople; + + @Column + private int minGamePeople; + + @Column + private int maxGameTime; + + @Column + private int minGameTime; + + @Column(length = 10) + private String genre; + + @Column(length = 10) + private String difficulty; + + @Column(length = 100) + private String summary; + + @Builder + public GameTemplate(Category category, String gameName, Integer maxGamePeople, Integer minGamePeople, + Integer maxGameTime, Integer minGameTime, String genre, String difficulty, String summary) { + this.category = category; + this.gameName = gameName; + this.maxGamePeople = maxGamePeople; + this.minGamePeople = minGamePeople; + this.maxGameTime = maxGameTime; + this.minGameTime = minGameTime; + this.genre = genre; + this.difficulty = difficulty; + this.summary = summary; + } + + public void modifyTemplateDetails(String gameName, Integer maxGamePeople, Integer minGamePeople, + Integer maxGameTime, Integer minGameTime, String genre, + String difficulty, String summary) { + this.gameName = gameName; + this.maxGamePeople = maxGamePeople; + this.minGamePeople = minGamePeople; + this.maxGameTime = maxGameTime; + this.minGameTime = minGameTime; + this.genre = genre; + this.difficulty = difficulty; + this.summary = summary; + } + + public void modifyCategory(Category category) { + this.category = category; + } +} diff --git a/gg-data/src/main/java/gg/data/party/PartyPenalty.java b/gg-data/src/main/java/gg/data/party/PartyPenalty.java new file mode 100644 index 000000000..f0aaeb8d2 --- /dev/null +++ b/gg-data/src/main/java/gg/data/party/PartyPenalty.java @@ -0,0 +1,67 @@ +package gg.data.party; + +import java.time.LocalDateTime; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.validation.constraints.NotNull; + +import gg.data.BaseTimeEntity; +import gg.data.user.User; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class PartyPenalty extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @NotNull + @Column(name = "penalty_type", length = 20) + private String penaltyType; + + @Column(name = "message", length = 100) + private String message; + + @NotNull + @Column(name = "start_time") + private LocalDateTime startTime; + + @NotNull + @Column(name = "penalty_time") + private int penaltyTime; + + public PartyPenalty(User user, String penaltyType, String message, LocalDateTime startTime, Integer penaltyTime) { + this.user = user; + this.penaltyType = penaltyType; + this.message = message; + this.startTime = startTime; + this.penaltyTime = penaltyTime; + } + + public static boolean isFreeFromPenalty(PartyPenalty partyPenalty) { + return !LocalDateTime.now().isAfter(partyPenalty.getStartTime().plusMinutes(partyPenalty.getPenaltyTime())); + } + + public void update(String penaltyType, String message, Integer penaltyTime) { + this.penaltyType = penaltyType; + this.message = message; + this.penaltyTime = penaltyTime; + } + +} diff --git a/gg-data/src/main/java/gg/data/party/Room.java b/gg-data/src/main/java/gg/data/party/Room.java new file mode 100644 index 000000000..61c690f80 --- /dev/null +++ b/gg-data/src/main/java/gg/data/party/Room.java @@ -0,0 +1,124 @@ +package gg.data.party; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import gg.data.BaseTimeEntity; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class Room extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "host_id") + private User host; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "creator_id") + private User creator; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "category_id") + private Category category; + + @Column(name = "current_people") + private int currentPeople; + + @Column(name = "title", length = 15) + private String title; + + @Column(name = "content", length = 100) + private String content; + + @Column(name = "max_people") + private int maxPeople; + + @Column(name = "min_people") + private int minPeople; + + @Column(name = "due_date") + private LocalDateTime dueDate; + + @Column(name = "start_date") + private LocalDateTime startDate; + + @OneToMany(mappedBy = "room", cascade = CascadeType.ALL) + private List comments = new ArrayList<>(); + + @Enumerated(EnumType.STRING) + @Column(name = "status") + private RoomType status; + + @Builder + public Room(User host, User creator, Category category, String title, String content, Integer currentPeople, + Integer maxPeople, Integer minPeople, LocalDateTime dueDate, RoomType status) { + this.host = host; + this.creator = creator; + this.category = category; + this.title = title; + this.content = content; + this.currentPeople = currentPeople; + this.maxPeople = maxPeople; + this.minPeople = minPeople; + this.dueDate = dueDate; + this.startDate = null; + this.status = status; + } + + public void updateCurrentPeople(int currentPeople) { + this.currentPeople = currentPeople; + } + + public void updateCategory(Category category) { + this.category = category; + } + + public void changeRoomStatus(RoomType status) { + this.status = status; + } + + public void updateHost(User host) { + this.host = host; + } + + public void roomStart() { + this.startDate = LocalDateTime.now(); + this.status = RoomType.START; + } + + public void roomFinish() { + this.status = RoomType.FINISH; + } + + public void roomFail() { + this.status = RoomType.FAIL; + } + + public void roomHidden() { + this.status = RoomType.HIDDEN; + } +} diff --git a/gg-data/src/main/java/gg/data/party/RoomReport.java b/gg-data/src/main/java/gg/data/party/RoomReport.java new file mode 100644 index 000000000..1242a4223 --- /dev/null +++ b/gg-data/src/main/java/gg/data/party/RoomReport.java @@ -0,0 +1,47 @@ +package gg.data.party; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import gg.data.BaseTimeEntity; +import gg.data.user.User; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class RoomReport extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "reporter_id") + private User reporter; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "reportee_id") + private User reportee; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "room_id") + private Room room; + + @Column(length = 100) + private String message; + + public RoomReport(User reporter, User reportee, Room room, String message) { + this.reporter = reporter; + this.reportee = reportee; + this.room = room; + this.message = message; + } +} diff --git a/gg-data/src/main/java/gg/data/party/UserReport.java b/gg-data/src/main/java/gg/data/party/UserReport.java new file mode 100644 index 000000000..e33de0e54 --- /dev/null +++ b/gg-data/src/main/java/gg/data/party/UserReport.java @@ -0,0 +1,47 @@ +package gg.data.party; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import gg.data.BaseTimeEntity; +import gg.data.user.User; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class UserReport extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "reporter_id") + private User reporter; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "reportee_id") + private User reportee; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "room_id") + private Room room; + + @Column(length = 100) + private String message; + + public UserReport(User reporter, User reportee, Room room, String message) { + this.reporter = reporter; + this.reportee = reportee; + this.room = room; + this.message = message; + } +} diff --git a/gg-data/src/main/java/gg/data/party/UserRoom.java b/gg-data/src/main/java/gg/data/party/UserRoom.java new file mode 100644 index 000000000..dd79cd050 --- /dev/null +++ b/gg-data/src/main/java/gg/data/party/UserRoom.java @@ -0,0 +1,65 @@ +package gg.data.party; + +import static gg.utils.exception.BusinessChecker.*; +import static gg.utils.exception.ErrorCode.*; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import gg.data.BaseTimeEntity; +import gg.data.user.User; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Entity +public class UserRoom extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "room_id") + private Room room; + + @Column(name = "nickname", length = 20) + private String nickname; + + @Column(name = "is_exist") + private boolean isExist; + + public UserRoom(User user, Room room, String randomNickname) { + this.user = user; + this.room = room; + this.nickname = randomNickname; + this.isExist = true; + } + + public UserRoom(User user, Room room, String nickname, boolean isExist) { + this.user = user; + this.room = room; + this.nickname = nickname; + this.isExist = isExist; + } + + public void updateIsExist(boolean isExist) { + mustNotNull(isExist, NULL_POINT); + this.isExist = isExist; + } + + public boolean getIsExist() { + return this.isExist; + } +} diff --git a/gg-data/src/main/java/gg/data/party/type/RoomType.java b/gg-data/src/main/java/gg/data/party/type/RoomType.java new file mode 100644 index 000000000..96bbb9ea5 --- /dev/null +++ b/gg-data/src/main/java/gg/data/party/type/RoomType.java @@ -0,0 +1,17 @@ +package gg.data.party.type; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum RoomType { + OPEN("open", "๋ฐฉ ์‹œ์ž‘ ์ „"), + START("live", "๋ฐฉ ์ง„ํ–‰ ์ค‘"), + FINISH("end", "๋ฐฉ ์ข…๋ฃŒ"), + HIDDEN("end", "์‹ ๊ณ ๋กœ ์ธํ•œ ๊ฐ€๋ฆผ ์ƒํƒœ"), + FAIL("end", "๋งค์นญ ์‹คํŒจํ•œ ๋ฐฉ"); + + private final String code; + private final String desc; +} diff --git a/gg-data/src/main/java/gg/data/game/Game.java b/gg-data/src/main/java/gg/data/pingpong/game/Game.java similarity index 94% rename from gg-data/src/main/java/gg/data/game/Game.java rename to gg-data/src/main/java/gg/data/pingpong/game/Game.java index 2799d9d40..b72071b4e 100644 --- a/gg-data/src/main/java/gg/data/game/Game.java +++ b/gg-data/src/main/java/gg/data/pingpong/game/Game.java @@ -1,4 +1,4 @@ -package gg.data.game; +package gg.data.pingpong.game; import java.time.LocalDateTime; import java.util.ArrayList; @@ -20,9 +20,9 @@ import org.hibernate.annotations.DynamicUpdate; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.season.Season; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.season.Season; import gg.utils.exception.BusinessChecker; import gg.utils.exception.ErrorCode; import lombok.AllArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/game/PChange.java b/gg-data/src/main/java/gg/data/pingpong/game/PChange.java similarity index 98% rename from gg-data/src/main/java/gg/data/game/PChange.java rename to gg-data/src/main/java/gg/data/pingpong/game/PChange.java index e1de0dda3..8dfd650fd 100644 --- a/gg-data/src/main/java/gg/data/game/PChange.java +++ b/gg-data/src/main/java/gg/data/pingpong/game/PChange.java @@ -1,4 +1,4 @@ -package gg.data.game; +package gg.data.pingpong.game; import javax.persistence.Column; import javax.persistence.Entity; diff --git a/gg-data/src/main/java/gg/data/game/Team.java b/gg-data/src/main/java/gg/data/pingpong/game/Team.java similarity index 98% rename from gg-data/src/main/java/gg/data/game/Team.java rename to gg-data/src/main/java/gg/data/pingpong/game/Team.java index 454f0ade7..d3b1c90f1 100644 --- a/gg-data/src/main/java/gg/data/game/Team.java +++ b/gg-data/src/main/java/gg/data/pingpong/game/Team.java @@ -1,4 +1,4 @@ -package gg.data.game; +package gg.data.pingpong.game; import java.util.ArrayList; import java.util.List; diff --git a/gg-data/src/main/java/gg/data/game/TeamUser.java b/gg-data/src/main/java/gg/data/pingpong/game/TeamUser.java similarity index 97% rename from gg-data/src/main/java/gg/data/game/TeamUser.java rename to gg-data/src/main/java/gg/data/pingpong/game/TeamUser.java index 525e39351..4987b0e84 100644 --- a/gg-data/src/main/java/gg/data/game/TeamUser.java +++ b/gg-data/src/main/java/gg/data/pingpong/game/TeamUser.java @@ -1,4 +1,4 @@ -package gg.data.game; +package gg.data.pingpong.game; import javax.persistence.Entity; import javax.persistence.FetchType; diff --git a/gg-data/src/main/java/gg/data/game/type/Mode.java b/gg-data/src/main/java/gg/data/pingpong/game/type/Mode.java similarity index 94% rename from gg-data/src/main/java/gg/data/game/type/Mode.java rename to gg-data/src/main/java/gg/data/pingpong/game/type/Mode.java index bd0b05954..0e5138b36 100644 --- a/gg-data/src/main/java/gg/data/game/type/Mode.java +++ b/gg-data/src/main/java/gg/data/pingpong/game/type/Mode.java @@ -1,4 +1,4 @@ -package gg.data.game.type; +package gg.data.pingpong.game.type; import java.util.Locale; diff --git a/gg-data/src/main/java/gg/data/game/type/StatusType.java b/gg-data/src/main/java/gg/data/pingpong/game/type/StatusType.java similarity index 95% rename from gg-data/src/main/java/gg/data/game/type/StatusType.java rename to gg-data/src/main/java/gg/data/pingpong/game/type/StatusType.java index 78bef3fd9..266758ee9 100644 --- a/gg-data/src/main/java/gg/data/game/type/StatusType.java +++ b/gg-data/src/main/java/gg/data/pingpong/game/type/StatusType.java @@ -1,4 +1,4 @@ -package gg.data.game.type; +package gg.data.pingpong.game.type; import java.util.Locale; diff --git a/gg-data/src/main/java/gg/data/manage/SlotManagement.java b/gg-data/src/main/java/gg/data/pingpong/manage/SlotManagement.java similarity index 98% rename from gg-data/src/main/java/gg/data/manage/SlotManagement.java rename to gg-data/src/main/java/gg/data/pingpong/manage/SlotManagement.java index 2ac1382ff..79783706e 100644 --- a/gg-data/src/main/java/gg/data/manage/SlotManagement.java +++ b/gg-data/src/main/java/gg/data/pingpong/manage/SlotManagement.java @@ -1,4 +1,4 @@ -package gg.data.manage; +package gg.data.pingpong.manage; import java.time.LocalDateTime; diff --git a/gg-data/src/main/java/gg/data/match/RedisMatchTime.java b/gg-data/src/main/java/gg/data/pingpong/match/RedisMatchTime.java similarity index 92% rename from gg-data/src/main/java/gg/data/match/RedisMatchTime.java rename to gg-data/src/main/java/gg/data/pingpong/match/RedisMatchTime.java index 10e8a5a03..742656a3d 100644 --- a/gg-data/src/main/java/gg/data/match/RedisMatchTime.java +++ b/gg-data/src/main/java/gg/data/pingpong/match/RedisMatchTime.java @@ -1,4 +1,4 @@ -package gg.data.match; +package gg.data.pingpong.match; import java.io.Serializable; import java.time.LocalDateTime; @@ -12,7 +12,7 @@ import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; -import gg.data.match.type.Option; +import gg.data.pingpong.match.type.Option; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/match/RedisMatchUser.java b/gg-data/src/main/java/gg/data/pingpong/match/RedisMatchUser.java similarity index 87% rename from gg-data/src/main/java/gg/data/match/RedisMatchUser.java rename to gg-data/src/main/java/gg/data/pingpong/match/RedisMatchUser.java index b76350975..15cb8f676 100644 --- a/gg-data/src/main/java/gg/data/match/RedisMatchUser.java +++ b/gg-data/src/main/java/gg/data/pingpong/match/RedisMatchUser.java @@ -1,4 +1,4 @@ -package gg.data.match; +package gg.data.pingpong.match; import java.io.Serializable; @@ -6,7 +6,7 @@ import org.springframework.data.redis.core.RedisHash; -import gg.data.match.type.Option; +import gg.data.pingpong.match.type.Option; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/match/type/MatchKey.java b/gg-data/src/main/java/gg/data/pingpong/match/type/MatchKey.java similarity index 94% rename from gg-data/src/main/java/gg/data/match/type/MatchKey.java rename to gg-data/src/main/java/gg/data/pingpong/match/type/MatchKey.java index 78f3fbd0f..017f4f614 100644 --- a/gg-data/src/main/java/gg/data/match/type/MatchKey.java +++ b/gg-data/src/main/java/gg/data/pingpong/match/type/MatchKey.java @@ -1,4 +1,4 @@ -package gg.data.match.type; +package gg.data.pingpong.match.type; import java.time.LocalDateTime; diff --git a/gg-data/src/main/java/gg/data/match/type/Option.java b/gg-data/src/main/java/gg/data/pingpong/match/type/Option.java similarity index 95% rename from gg-data/src/main/java/gg/data/match/type/Option.java rename to gg-data/src/main/java/gg/data/pingpong/match/type/Option.java index a5f6225f0..3ef858ce7 100644 --- a/gg-data/src/main/java/gg/data/match/type/Option.java +++ b/gg-data/src/main/java/gg/data/pingpong/match/type/Option.java @@ -1,4 +1,4 @@ -package gg.data.match.type; +package gg.data.pingpong.match.type; import java.util.Locale; diff --git a/gg-data/src/main/java/gg/data/match/type/SlotStatus.java b/gg-data/src/main/java/gg/data/pingpong/match/type/SlotStatus.java similarity index 94% rename from gg-data/src/main/java/gg/data/match/type/SlotStatus.java rename to gg-data/src/main/java/gg/data/pingpong/match/type/SlotStatus.java index e2aca1604..7d3126668 100644 --- a/gg-data/src/main/java/gg/data/match/type/SlotStatus.java +++ b/gg-data/src/main/java/gg/data/pingpong/match/type/SlotStatus.java @@ -1,4 +1,4 @@ -package gg.data.match.type; +package gg.data.pingpong.match.type; import java.util.Locale; diff --git a/gg-data/src/main/java/gg/data/match/type/TournamentMatchStatus.java b/gg-data/src/main/java/gg/data/pingpong/match/type/TournamentMatchStatus.java similarity index 91% rename from gg-data/src/main/java/gg/data/match/type/TournamentMatchStatus.java rename to gg-data/src/main/java/gg/data/pingpong/match/type/TournamentMatchStatus.java index 24602a660..3e3f2651d 100644 --- a/gg-data/src/main/java/gg/data/match/type/TournamentMatchStatus.java +++ b/gg-data/src/main/java/gg/data/pingpong/match/type/TournamentMatchStatus.java @@ -1,4 +1,4 @@ -package gg.data.match.type; +package gg.data.pingpong.match.type; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/rank/Rank.java b/gg-data/src/main/java/gg/data/pingpong/rank/Rank.java similarity index 97% rename from gg-data/src/main/java/gg/data/rank/Rank.java rename to gg-data/src/main/java/gg/data/pingpong/rank/Rank.java index 6dc0ed4a4..19dbae8f2 100644 --- a/gg-data/src/main/java/gg/data/rank/Rank.java +++ b/gg-data/src/main/java/gg/data/pingpong/rank/Rank.java @@ -1,4 +1,4 @@ -package gg.data.rank; +package gg.data.pingpong.rank; import java.io.Serializable; @@ -16,7 +16,7 @@ import org.hibernate.annotations.DynamicUpdate; import gg.data.BaseTimeEntity; -import gg.data.season.Season; +import gg.data.pingpong.season.Season; import gg.data.user.User; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/gg-data/src/main/java/gg/data/rank/Tier.java b/gg-data/src/main/java/gg/data/pingpong/rank/Tier.java similarity index 95% rename from gg-data/src/main/java/gg/data/rank/Tier.java rename to gg-data/src/main/java/gg/data/pingpong/rank/Tier.java index ea26be3b9..49f93cfd5 100644 --- a/gg-data/src/main/java/gg/data/rank/Tier.java +++ b/gg-data/src/main/java/gg/data/pingpong/rank/Tier.java @@ -1,4 +1,4 @@ -package gg.data.rank; +package gg.data.pingpong.rank; import java.io.Serializable; diff --git a/gg-data/src/main/java/gg/data/rank/redis/RankRedis.java b/gg-data/src/main/java/gg/data/pingpong/rank/redis/RankRedis.java similarity index 96% rename from gg-data/src/main/java/gg/data/rank/redis/RankRedis.java rename to gg-data/src/main/java/gg/data/pingpong/rank/redis/RankRedis.java index 29fbfb5fa..117dcbe7c 100644 --- a/gg-data/src/main/java/gg/data/rank/redis/RankRedis.java +++ b/gg-data/src/main/java/gg/data/pingpong/rank/redis/RankRedis.java @@ -1,10 +1,10 @@ -package gg.data.rank.redis; +package gg.data.pingpong.rank.redis; import java.io.Serializable; import org.springframework.data.redis.core.RedisHash; -import gg.data.rank.Rank; +import gg.data.pingpong.rank.Rank; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/gg-data/src/main/java/gg/data/season/Season.java b/gg-data/src/main/java/gg/data/pingpong/season/Season.java similarity index 97% rename from gg-data/src/main/java/gg/data/season/Season.java rename to gg-data/src/main/java/gg/data/pingpong/season/Season.java index ceffb0d78..eab18fb89 100644 --- a/gg-data/src/main/java/gg/data/season/Season.java +++ b/gg-data/src/main/java/gg/data/pingpong/season/Season.java @@ -1,4 +1,4 @@ -package gg.data.season; +package gg.data.pingpong.season; import java.time.LocalDateTime; diff --git a/gg-data/src/main/java/gg/data/store/CoinHistory.java b/gg-data/src/main/java/gg/data/pingpong/store/CoinHistory.java similarity index 97% rename from gg-data/src/main/java/gg/data/store/CoinHistory.java rename to gg-data/src/main/java/gg/data/pingpong/store/CoinHistory.java index b1e3b731c..5c5f2317e 100644 --- a/gg-data/src/main/java/gg/data/store/CoinHistory.java +++ b/gg-data/src/main/java/gg/data/pingpong/store/CoinHistory.java @@ -1,4 +1,4 @@ -package gg.data.store; +package gg.data.pingpong.store; import java.time.LocalDateTime; diff --git a/gg-data/src/main/java/gg/data/store/CoinPolicy.java b/gg-data/src/main/java/gg/data/pingpong/store/CoinPolicy.java similarity index 98% rename from gg-data/src/main/java/gg/data/store/CoinPolicy.java rename to gg-data/src/main/java/gg/data/pingpong/store/CoinPolicy.java index 57bb6a20d..6f871bba0 100644 --- a/gg-data/src/main/java/gg/data/store/CoinPolicy.java +++ b/gg-data/src/main/java/gg/data/pingpong/store/CoinPolicy.java @@ -1,4 +1,4 @@ -package gg.data.store; +package gg.data.pingpong.store; import java.time.LocalDateTime; diff --git a/gg-data/src/main/java/gg/data/store/Item.java b/gg-data/src/main/java/gg/data/pingpong/store/Item.java similarity index 96% rename from gg-data/src/main/java/gg/data/store/Item.java rename to gg-data/src/main/java/gg/data/pingpong/store/Item.java index 4220eefa7..de159f830 100644 --- a/gg-data/src/main/java/gg/data/store/Item.java +++ b/gg-data/src/main/java/gg/data/pingpong/store/Item.java @@ -1,4 +1,4 @@ -package gg.data.store; +package gg.data.pingpong.store; import java.time.LocalDateTime; @@ -11,7 +11,7 @@ import javax.persistence.Id; import javax.validation.constraints.NotNull; -import gg.data.store.type.ItemType; +import gg.data.pingpong.store.type.ItemType; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/store/Megaphone.java b/gg-data/src/main/java/gg/data/pingpong/store/Megaphone.java similarity index 97% rename from gg-data/src/main/java/gg/data/store/Megaphone.java rename to gg-data/src/main/java/gg/data/pingpong/store/Megaphone.java index 6d2a82de3..251e13f2f 100644 --- a/gg-data/src/main/java/gg/data/store/Megaphone.java +++ b/gg-data/src/main/java/gg/data/pingpong/store/Megaphone.java @@ -1,4 +1,4 @@ -package gg.data.store; +package gg.data.pingpong.store; import java.time.LocalDate; diff --git a/gg-data/src/main/java/gg/data/store/Receipt.java b/gg-data/src/main/java/gg/data/pingpong/store/Receipt.java similarity index 95% rename from gg-data/src/main/java/gg/data/store/Receipt.java rename to gg-data/src/main/java/gg/data/pingpong/store/Receipt.java index d5d40cdad..7b6400758 100644 --- a/gg-data/src/main/java/gg/data/store/Receipt.java +++ b/gg-data/src/main/java/gg/data/pingpong/store/Receipt.java @@ -1,4 +1,4 @@ -package gg.data.store; +package gg.data.pingpong.store; import java.time.LocalDateTime; @@ -14,7 +14,7 @@ import javax.persistence.ManyToOne; import javax.validation.constraints.NotNull; -import gg.data.store.type.ItemStatus; +import gg.data.pingpong.store.type.ItemStatus; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/store/redis/MegaphoneRedis.java b/gg-data/src/main/java/gg/data/pingpong/store/redis/MegaphoneRedis.java similarity index 95% rename from gg-data/src/main/java/gg/data/store/redis/MegaphoneRedis.java rename to gg-data/src/main/java/gg/data/pingpong/store/redis/MegaphoneRedis.java index 36c922012..8a7f0e190 100644 --- a/gg-data/src/main/java/gg/data/store/redis/MegaphoneRedis.java +++ b/gg-data/src/main/java/gg/data/pingpong/store/redis/MegaphoneRedis.java @@ -1,4 +1,4 @@ -package gg.data.store.redis; +package gg.data.pingpong.store.redis; import java.time.LocalDateTime; diff --git a/gg-data/src/main/java/gg/data/store/type/HistoryType.java b/gg-data/src/main/java/gg/data/pingpong/store/type/HistoryType.java similarity index 88% rename from gg-data/src/main/java/gg/data/store/type/HistoryType.java rename to gg-data/src/main/java/gg/data/pingpong/store/type/HistoryType.java index 9a1ba6c83..206afe016 100644 --- a/gg-data/src/main/java/gg/data/store/type/HistoryType.java +++ b/gg-data/src/main/java/gg/data/pingpong/store/type/HistoryType.java @@ -1,4 +1,4 @@ -package gg.data.store.type; +package gg.data.pingpong.store.type; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/store/type/ItemStatus.java b/gg-data/src/main/java/gg/data/pingpong/store/type/ItemStatus.java similarity index 88% rename from gg-data/src/main/java/gg/data/store/type/ItemStatus.java rename to gg-data/src/main/java/gg/data/pingpong/store/type/ItemStatus.java index 31c47a1b7..1d7e00e4b 100644 --- a/gg-data/src/main/java/gg/data/store/type/ItemStatus.java +++ b/gg-data/src/main/java/gg/data/pingpong/store/type/ItemStatus.java @@ -1,4 +1,4 @@ -package gg.data.store.type; +package gg.data.pingpong.store.type; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/store/type/ItemType.java b/gg-data/src/main/java/gg/data/pingpong/store/type/ItemType.java similarity index 80% rename from gg-data/src/main/java/gg/data/store/type/ItemType.java rename to gg-data/src/main/java/gg/data/pingpong/store/type/ItemType.java index 920ab5d3a..ae156950f 100644 --- a/gg-data/src/main/java/gg/data/store/type/ItemType.java +++ b/gg-data/src/main/java/gg/data/pingpong/store/type/ItemType.java @@ -1,4 +1,4 @@ -package gg.data.store.type; +package gg.data.pingpong.store.type; import lombok.RequiredArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/tournament/Tournament.java b/gg-data/src/main/java/gg/data/pingpong/tournament/Tournament.java similarity index 96% rename from gg-data/src/main/java/gg/data/tournament/Tournament.java rename to gg-data/src/main/java/gg/data/pingpong/tournament/Tournament.java index 38b976fdb..80809bc92 100644 --- a/gg-data/src/main/java/gg/data/tournament/Tournament.java +++ b/gg-data/src/main/java/gg/data/pingpong/tournament/Tournament.java @@ -1,4 +1,4 @@ -package gg.data.tournament; +package gg.data.pingpong.tournament; import static gg.utils.exception.BusinessChecker.*; import static gg.utils.exception.ErrorCode.*; @@ -23,8 +23,8 @@ import javax.validation.constraints.NotNull; import gg.data.BaseTimeEntity; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; import gg.data.user.User; import lombok.AccessLevel; import lombok.Builder; diff --git a/gg-data/src/main/java/gg/data/tournament/TournamentGame.java b/gg-data/src/main/java/gg/data/pingpong/tournament/TournamentGame.java similarity index 92% rename from gg-data/src/main/java/gg/data/tournament/TournamentGame.java rename to gg-data/src/main/java/gg/data/pingpong/tournament/TournamentGame.java index c2d2166e5..4dd4ef495 100644 --- a/gg-data/src/main/java/gg/data/tournament/TournamentGame.java +++ b/gg-data/src/main/java/gg/data/pingpong/tournament/TournamentGame.java @@ -1,4 +1,4 @@ -package gg.data.tournament; +package gg.data.pingpong.tournament; import javax.persistence.Column; import javax.persistence.Entity; @@ -14,8 +14,8 @@ import javax.validation.constraints.NotNull; import gg.data.BaseTimeEntity; -import gg.data.game.Game; -import gg.data.tournament.type.TournamentRound; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.tournament.type.TournamentRound; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; diff --git a/gg-data/src/main/java/gg/data/tournament/TournamentUser.java b/gg-data/src/main/java/gg/data/pingpong/tournament/TournamentUser.java similarity index 97% rename from gg-data/src/main/java/gg/data/tournament/TournamentUser.java rename to gg-data/src/main/java/gg/data/pingpong/tournament/TournamentUser.java index 2e7a7ef27..93df607f5 100644 --- a/gg-data/src/main/java/gg/data/tournament/TournamentUser.java +++ b/gg-data/src/main/java/gg/data/pingpong/tournament/TournamentUser.java @@ -1,4 +1,4 @@ -package gg.data.tournament; +package gg.data.pingpong.tournament; import java.time.LocalDateTime; diff --git a/gg-data/src/main/java/gg/data/tournament/type/RoundNumber.java b/gg-data/src/main/java/gg/data/pingpong/tournament/type/RoundNumber.java similarity index 85% rename from gg-data/src/main/java/gg/data/tournament/type/RoundNumber.java rename to gg-data/src/main/java/gg/data/pingpong/tournament/type/RoundNumber.java index ecbd44897..0d638dbfc 100644 --- a/gg-data/src/main/java/gg/data/tournament/type/RoundNumber.java +++ b/gg-data/src/main/java/gg/data/pingpong/tournament/type/RoundNumber.java @@ -1,4 +1,4 @@ -package gg.data.tournament.type; +package gg.data.pingpong.tournament.type; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/tournament/type/TournamentRound.java b/gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentRound.java similarity index 93% rename from gg-data/src/main/java/gg/data/tournament/type/TournamentRound.java rename to gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentRound.java index 8b868cb00..4c367996a 100644 --- a/gg-data/src/main/java/gg/data/tournament/type/TournamentRound.java +++ b/gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentRound.java @@ -1,6 +1,6 @@ -package gg.data.tournament.type; +package gg.data.pingpong.tournament.type; -import static gg.data.tournament.type.RoundNumber.*; +import static gg.data.pingpong.tournament.type.RoundNumber.*; import java.util.ArrayList; import java.util.List; diff --git a/gg-data/src/main/java/gg/data/tournament/type/TournamentStatus.java b/gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentStatus.java similarity index 94% rename from gg-data/src/main/java/gg/data/tournament/type/TournamentStatus.java rename to gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentStatus.java index 02ba48893..6722984f0 100644 --- a/gg-data/src/main/java/gg/data/tournament/type/TournamentStatus.java +++ b/gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentStatus.java @@ -1,4 +1,4 @@ -package gg.data.tournament.type; +package gg.data.pingpong.tournament.type; import java.util.Locale; diff --git a/gg-data/src/main/java/gg/data/tournament/type/TournamentType.java b/gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentType.java similarity index 94% rename from gg-data/src/main/java/gg/data/tournament/type/TournamentType.java rename to gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentType.java index 276830c5d..650c6ba57 100644 --- a/gg-data/src/main/java/gg/data/tournament/type/TournamentType.java +++ b/gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentType.java @@ -1,4 +1,4 @@ -package gg.data.tournament.type; +package gg.data.pingpong.tournament.type; import java.util.Locale; diff --git a/gg-data/src/main/java/gg/data/tournament/type/TournamentUserStatus.java b/gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentUserStatus.java similarity index 88% rename from gg-data/src/main/java/gg/data/tournament/type/TournamentUserStatus.java rename to gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentUserStatus.java index 2ef930740..64fb9a1b7 100644 --- a/gg-data/src/main/java/gg/data/tournament/type/TournamentUserStatus.java +++ b/gg-data/src/main/java/gg/data/pingpong/tournament/type/TournamentUserStatus.java @@ -1,4 +1,4 @@ -package gg.data.tournament.type; +package gg.data.pingpong.tournament.type; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/gg-data/src/main/java/gg/data/recruit/application/Application.java b/gg-data/src/main/java/gg/data/recruit/application/Application.java new file mode 100644 index 000000000..8e8f4ad23 --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/application/Application.java @@ -0,0 +1,81 @@ +package gg.data.recruit.application; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; + +import gg.data.BaseTimeEntity; +import gg.data.recruit.application.enums.ApplicationStatus; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.user.User; +import gg.utils.exception.BusinessChecker; +import gg.utils.exception.ErrorCode; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class Application extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "recruit_id", nullable = false) + private Recruitment recruit; + + @OneToOne(mappedBy = "application", fetch = FetchType.LAZY) + private RecruitStatus recruitStatus; + + private Boolean isDeleted; + + @Enumerated(EnumType.STRING) + @Column(length = 15, nullable = false) + private ApplicationStatus status; + + @OneToMany(mappedBy = "application", fetch = FetchType.LAZY) + private Set applicationAnswers = new HashSet<>(); + + public Application(User user, Recruitment recruit) { + this.user = user; + this.recruit = recruit; + this.isDeleted = false; + this.status = ApplicationStatus.PROGRESS_DOCS; + } + + public String getRecruitTitle() { + return this.recruit.getTitle(); + } + + public void delete() { + this.isDeleted = Boolean.TRUE; + } + + public Boolean isUpdateAvailable() { + return !recruit.isEnd(); + } + + public void updateApplicationStatus(ApplicationStatus status) { + BusinessChecker.mustNotNull(status, ErrorCode.BAD_ARGU); + this.status = status; + } +} diff --git a/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswer.java b/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswer.java new file mode 100644 index 000000000..cec03b60b --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswer.java @@ -0,0 +1,56 @@ +package gg.data.recruit.application; + +import javax.persistence.DiscriminatorColumn; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import gg.data.BaseTimeEntity; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.enums.InputType; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Inheritance(strategy = InheritanceType.JOINED) +@DiscriminatorColumn(name = "answer_type") +@Getter +public abstract class ApplicationAnswer extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "question_id", nullable = false) + private Question question; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "application_id", nullable = false) + @Getter + private Application application; + + public InputType getInputType() { + return question.getInputType(); + } + + public Long getQuestionId() { + return question.getId(); + } + + public abstract String getAnswer(); + + public abstract ApplicationAnswerEntityDto toForm(); + + public ApplicationAnswer(Application application, Question question) { + this.question = question; + this.application = application; + } +} diff --git a/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswerCheckList.java b/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswerCheckList.java new file mode 100644 index 000000000..8048dde5e --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswerCheckList.java @@ -0,0 +1,39 @@ +package gg.data.recruit.application; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@DiscriminatorValue("CHECK_LIST") +@Getter +public class ApplicationAnswerCheckList extends ApplicationAnswer { + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "check_list_id", nullable = false) + private CheckList checkList; + + @Override + public String getAnswer() { + return checkList.getContent(); + } + + @Override + public ApplicationAnswerEntityDto toForm() { + return new ApplicationAnswerEntityDto(this.getQuestionId(), this.getInputType(), + new CheckListEntityDto(checkList.getId(), checkList.getContent())); + } + + public ApplicationAnswerCheckList(Application application, Question question, + CheckList checkList) { + super(application, question); + this.checkList = checkList; + } +} diff --git a/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswerEntityDto.java b/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswerEntityDto.java new file mode 100644 index 000000000..162dc03d4 --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswerEntityDto.java @@ -0,0 +1,24 @@ +package gg.data.recruit.application; +import gg.data.recruit.recruitment.enums.InputType; +import lombok.Getter; + +@Getter +public class ApplicationAnswerEntityDto { + private Long questionId; + private InputType inputType; + + private CheckListEntityDto checkedList; + private String answer; + + public ApplicationAnswerEntityDto(Long questionId, InputType inputType, CheckListEntityDto checkedList) { + this.questionId = questionId; + this.inputType = inputType; + this.checkedList = checkedList; + } + + public ApplicationAnswerEntityDto(Long questionId, InputType inputType, String answer) { + this.questionId = questionId; + this.inputType = inputType; + this.answer = answer; + } +} diff --git a/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswerText.java b/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswerText.java new file mode 100644 index 000000000..c20d4b396 --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/application/ApplicationAnswerText.java @@ -0,0 +1,31 @@ +package gg.data.recruit.application; + +import javax.persistence.Column; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +import gg.data.recruit.recruitment.Question; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@DiscriminatorValue("TEXT") +public class ApplicationAnswerText extends ApplicationAnswer { + @Column(length = 1000) + private String answer; + + @Override + public String getAnswer() { + return answer; + } + + @Override + public ApplicationAnswerEntityDto toForm() { + return new ApplicationAnswerEntityDto(this.getQuestionId(), this.getInputType(), answer); + } + + public ApplicationAnswerText(Application application, Question question, String answer) { + super(application, question); + this.answer = answer; + } +} diff --git a/gg-data/src/main/java/gg/data/recruit/application/CheckListEntityDto.java b/gg-data/src/main/java/gg/data/recruit/application/CheckListEntityDto.java new file mode 100644 index 000000000..87fea3d29 --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/application/CheckListEntityDto.java @@ -0,0 +1,11 @@ +package gg.data.recruit.application; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class CheckListEntityDto { + private Long checkListId; + private String content; +} diff --git a/gg-data/src/main/java/gg/data/recruit/application/RecruitStatus.java b/gg-data/src/main/java/gg/data/recruit/application/RecruitStatus.java new file mode 100644 index 000000000..599cf91fc --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/application/RecruitStatus.java @@ -0,0 +1,46 @@ +package gg.data.recruit.application; + +import java.time.LocalDateTime; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; + +import gg.data.BaseTimeEntity; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class RecruitStatus extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "application_id", nullable = false) + private Application application; + + @Getter + private LocalDateTime interviewDate; + + public RecruitStatus(Application application) { + this.application = application; + } + + public RecruitStatus(Application application, LocalDateTime interviewDate) { + this.application = application; + this.interviewDate = interviewDate; + } + + public void updateInterviewDate(LocalDateTime interviewDate) { + this.interviewDate = interviewDate; + } +} diff --git a/gg-data/src/main/java/gg/data/recruit/application/enums/ApplicationStatus.java b/gg-data/src/main/java/gg/data/recruit/application/enums/ApplicationStatus.java new file mode 100644 index 000000000..45e91c8cc --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/application/enums/ApplicationStatus.java @@ -0,0 +1,17 @@ +package gg.data.recruit.application.enums; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum ApplicationStatus { + + PROGRESS_DOCS("progress", "์„œ๋ฅ˜ ์ง„ํ–‰์ค‘", false), + PROGRESS_INTERVIEW("progress", "๋ฉด์ ‘ ์ง„ํ–‰์ค‘", false), + APPLICATION_FAIL("fail", "์„œ๋ฅ˜ ํƒˆ๋ฝ", false), + INTERVIEW_FAIL("fail", "๋ฉด์ ‘ ํƒˆ๋ฝ", true), + PASS("pass", "ํ•ฉ๊ฒฉ", true); + + private final String status; + private final String desc; + public final boolean isFinal; +} diff --git a/gg-data/src/main/java/gg/data/recruit/manage/ResultMessage.java b/gg-data/src/main/java/gg/data/recruit/manage/ResultMessage.java new file mode 100644 index 000000000..7dc83e4e8 --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/manage/ResultMessage.java @@ -0,0 +1,44 @@ +package gg.data.recruit.manage; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +import gg.data.BaseTimeEntity; +import gg.data.recruit.manage.enums.MessageType; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class ResultMessage extends BaseTimeEntity { + public static final int contentLimit = 100; + public static final int messageTypeLimit = 15; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(length = contentLimit) + private String content; + + @Column(length = messageTypeLimit, nullable = false) + @Enumerated(EnumType.STRING) + private MessageType messageType; + + @Column + private Boolean isUse = true; + + @Builder + public ResultMessage(String content, MessageType messageType) { + this.content = content; + this.messageType = messageType; + } +} diff --git a/gg-data/src/main/java/gg/data/recruit/manage/enums/MessageType.java b/gg-data/src/main/java/gg/data/recruit/manage/enums/MessageType.java new file mode 100644 index 000000000..96241d696 --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/manage/enums/MessageType.java @@ -0,0 +1,14 @@ +package gg.data.recruit.manage.enums; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum MessageType { + + INTERVIEW("interview", "๋ฉด์ ‘ ์•ˆ๋‚ด"), + PASS("pass", "ํ•ฉ๊ฒฉ ์•ˆ๋‚ด"), + FAIL("fail", "๋ถˆํ•ฉ๊ฒฉ ์•ˆ๋‚ด"); + + private final String messageType; + private final String desc; +} diff --git a/gg-data/src/main/java/gg/data/recruit/recruitment/CheckList.java b/gg-data/src/main/java/gg/data/recruit/recruitment/CheckList.java new file mode 100644 index 000000000..16ed746fd --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/recruitment/CheckList.java @@ -0,0 +1,38 @@ +package gg.data.recruit.recruitment; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +import gg.data.BaseTimeEntity; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class CheckList extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "question_id", nullable = false) + private Question question; + + @Column(length = 100) + private String content; + + public CheckList(Question question, String content) { + question.addCheckList(this); + this.question = question; + this.content = content; + } +} diff --git a/gg-data/src/main/java/gg/data/recruit/recruitment/Question.java b/gg-data/src/main/java/gg/data/recruit/recruitment/Question.java new file mode 100644 index 000000000..b749fdd31 --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/recruitment/Question.java @@ -0,0 +1,64 @@ +package gg.data.recruit.recruitment; + +import static gg.utils.exception.BusinessChecker.*; +import static gg.utils.exception.ErrorCode.*; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import gg.data.BaseTimeEntity; +import gg.data.recruit.recruitment.enums.InputType; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Question extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "recruit_id", nullable = false) + private Recruitment recruit; + + @Enumerated(EnumType.STRING) + @Column(length = 20, nullable = false) + private InputType inputType; + + @Column(length = 300) + private String question; + + @OneToMany(mappedBy = "question", orphanRemoval = true, cascade = CascadeType.ALL) + private List checkLists = new ArrayList<>(); + + private int sortNum; + + public Question(Recruitment recruit, InputType inputType, String question, int sortNum) { + recruit.addQuestions(this); + this.recruit = recruit; + this.inputType = inputType; + this.question = question; + this.sortNum = sortNum; + } + + protected void addCheckList(CheckList checkList) { + mustNotNull(checkList, NULL_POINT); + this.checkLists.add(checkList); + } +} diff --git a/gg-data/src/main/java/gg/data/recruit/recruitment/Recruitment.java b/gg-data/src/main/java/gg/data/recruit/recruitment/Recruitment.java new file mode 100644 index 000000000..669bd199c --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/recruitment/Recruitment.java @@ -0,0 +1,116 @@ +package gg.data.recruit.recruitment; + +import static gg.utils.exception.BusinessChecker.*; +import static gg.utils.exception.ErrorCode.*; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +import gg.data.BaseTimeEntity; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Recruitment extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String title; + + @Column(length = 3000) + private String contents; + + @Column(length = 50) + private String generation; + + private Boolean isFinish; + + private Boolean isDeleted; + + @Column(nullable = false) + private LocalDateTime startTime; + + @Column(nullable = false) + private LocalDateTime endTime; + + @OneToMany(mappedBy = "recruit", orphanRemoval = true, cascade = CascadeType.ALL) + private List questions = new ArrayList<>(); + + @Builder + public Recruitment(String title, String contents, String generation, LocalDateTime startTime, + LocalDateTime endTime) { + mustNotNull(title, NULL_POINT); + mustNotNull(contents, NULL_POINT); + mustNotNull(generation, NULL_POINT); + mustNotNull(startTime, NULL_POINT); + mustNotNull(endTime, NULL_POINT); + + this.title = title; + this.contents = contents; + this.generation = generation; + this.startTime = startTime; + this.endTime = endTime; + this.isFinish = false; + this.isDeleted = false; + } + + public void del() { + this.isDeleted = true; + } + + public Boolean isEnd() { + return LocalDateTime.now().isAfter(this.endTime); + } + + public void setFinish(Boolean finish) { + this.isFinish = finish; + } + + public boolean getIsFinsh() { + return this.isFinish; + } + + /** + * Question์—์„œ ํ˜ธ์ถœํ•˜๋Š” ์—ฐ๊ด€๊ด€๊ณ„ ํŽธ์˜ ๋ฉ”์„œ๋“œ, ๊ธฐํƒ€ ํ˜ธ์ถœ ๊ธˆ์ง€ + * @param question + */ + protected void addQuestions(Question question) { + mustNotNull(question, NULL_POINT); + this.questions.add(question); + } + + /** + * ์—ฐ๊ด€๊ด€๊ณ„ ์ฃผ์ธ๊นŒ์ง€ ์ „์ฒด ์ˆ˜์ • ๋ฉ”์„œ๋“œ + * @param updatedRecruitment + */ + public void update(Recruitment updatedRecruitment) { + mustNotNull(updatedRecruitment, NULL_POINT); + mustNotNull(questions, NULL_POINT); + + this.title = updatedRecruitment.getTitle(); + this.contents = updatedRecruitment.getContents(); + this.generation = updatedRecruitment.getGeneration(); + this.startTime = updatedRecruitment.getStartTime(); + this.endTime = updatedRecruitment.getEndTime(); + + for (Question question : this.questions) { + question.getCheckLists().clear(); + } + this.questions.clear(); + // this.questions = questions; + } +} diff --git a/gg-data/src/main/java/gg/data/recruit/recruitment/enums/InputType.java b/gg-data/src/main/java/gg/data/recruit/recruitment/enums/InputType.java new file mode 100644 index 000000000..6249b6b2b --- /dev/null +++ b/gg-data/src/main/java/gg/data/recruit/recruitment/enums/InputType.java @@ -0,0 +1,13 @@ +package gg.data.recruit.recruitment.enums; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum InputType { + + TEXT("text", "์ฃผ๊ด€์‹"), + SINGLE_CHECK("single check", "๋‹จ์ผ ์„ ํƒ์ง€"), + MULTI_CHECK("multi check", "๋ณต์ˆ˜ ์„ ํƒ์ง€"); + private final String type; + private final String desc; +} diff --git a/gg-data/src/test/java/gg/data/tournament/TournamentUnitTest.java b/gg-data/src/test/java/gg/data/pingpong/tournament/TournamentUnitTest.java similarity index 98% rename from gg-data/src/test/java/gg/data/tournament/TournamentUnitTest.java rename to gg-data/src/test/java/gg/data/pingpong/tournament/TournamentUnitTest.java index 555bc1bde..911b4c7b9 100644 --- a/gg-data/src/test/java/gg/data/tournament/TournamentUnitTest.java +++ b/gg-data/src/test/java/gg/data/pingpong/tournament/TournamentUnitTest.java @@ -1,4 +1,4 @@ -package gg.data.tournament; +package gg.data.pingpong.tournament; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -16,8 +16,8 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; import gg.data.user.User; import gg.utils.annotation.UnitTest; import gg.utils.exception.ErrorCode; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/PingpongApiApplication.java b/gg-pingpong-api/src/main/java/gg/PingpongApiApplication.java similarity index 79% rename from gg-pingpong-api/src/main/java/gg/pingpong/api/PingpongApiApplication.java rename to gg-pingpong-api/src/main/java/gg/PingpongApiApplication.java index 468f1ac8b..b61ffb94e 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/PingpongApiApplication.java +++ b/gg-pingpong-api/src/main/java/gg/PingpongApiApplication.java @@ -1,10 +1,10 @@ -package gg.pingpong.api; +package gg; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(scanBasePackages = {"gg.admin.repo", "gg.data", "gg.repo", - "gg.pingpong.api", "gg.utils"}) + "gg.pingpong.api", "gg.utils", "gg.party.api", "gg.auth", "gg.recruit.api"}) public class PingpongApiApplication { public static void main(String[] args) { diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/category/controller/CategoryAdminController.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/category/controller/CategoryAdminController.java new file mode 100644 index 000000000..a93e36e24 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/category/controller/CategoryAdminController.java @@ -0,0 +1,44 @@ +package gg.party.api.admin.category.controller; + +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.party.api.admin.category.controller.request.CategoryAddAdminReqDto; +import gg.party.api.admin.category.service.CategoryAdminService; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/admin/categories") +public class CategoryAdminController { + private final CategoryAdminService categoryAdminService; + + /** + * ์นดํ…Œ๊ณ ๋ฆฌ ์ถ”๊ฐ€ + * @param reqDto ์ถ”๊ฐ€ํ•  ์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„ + * @return ์ถ”๊ฐ€ ์„ฑ๊ณต ์—ฌ๋ถ€ + */ + @PostMapping + public ResponseEntity categoryAdd(@RequestBody @Valid CategoryAddAdminReqDto reqDto) { + categoryAdminService.addCategory(reqDto); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + /** + * ์นดํ…Œ๊ณ ๋ฆฌ ์‚ญ์ œ + * @return ์‚ญ์ œ ์„ฑ๊ณต ์—ฌ๋ถ€ + */ + @DeleteMapping("{category_id}") + public ResponseEntity categoryRemove(@PathVariable("category_id") Long categoryId) { + categoryAdminService.removeCategory(categoryId); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/category/controller/request/CategoryAddAdminReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/category/controller/request/CategoryAddAdminReqDto.java new file mode 100644 index 000000000..043053450 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/category/controller/request/CategoryAddAdminReqDto.java @@ -0,0 +1,19 @@ +package gg.party.api.admin.category.controller.request; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class CategoryAddAdminReqDto { + @NotBlank(message = "์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„์€ ๋น„์–ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + @Size(min = 1, max = 10, message = "์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„์€ 1์ž ์ด์ƒ 10์ž ์ดํ•˜์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private String categoryName; + + public CategoryAddAdminReqDto(String category) { + this.categoryName = category; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/category/service/CategoryAdminService.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/category/service/CategoryAdminService.java new file mode 100644 index 000000000..c351bcbdc --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/category/service/CategoryAdminService.java @@ -0,0 +1,60 @@ +package gg.party.api.admin.category.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.admin.repo.category.CategoryAdminRepository; +import gg.admin.repo.room.RoomAdminRepository; +import gg.data.party.Category; +import gg.party.api.admin.category.controller.request.CategoryAddAdminReqDto; +import gg.utils.exception.party.CategoryDuplicateException; +import gg.utils.exception.party.CategoryNotFoundException; +import gg.utils.exception.party.DefaultCategoryNeedException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class CategoryAdminService { + private final CategoryAdminRepository categoryAdminRepository; + private final RoomAdminRepository roomAdminRepository; + + /** + * ์นดํ…Œ๊ณ ๋ฆฌ ์ถ”๊ฐ€ + * @param reqDto ์ถ”๊ฐ€ํ•  ์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„ + * @throws CategoryDuplicateException ์ค‘๋ณต๋œ ์นดํ…Œ๊ณ ๋ฆฌ - 409 + */ + @Transactional + public void addCategory(CategoryAddAdminReqDto reqDto) { + String categoryName = reqDto.getCategoryName(); + + if (categoryAdminRepository.existsByName(categoryName)) { + throw new CategoryDuplicateException(); + } + categoryAdminRepository.save(new Category(categoryName)); + } + + /** + * ์นดํ…Œ๊ณ ๋ฆฌ ์‚ญ์ œ + * ์‚ญ์ œ ์‹œ ๊ธฐ์กด์— room์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋˜ ์นดํ…Œ๊ณ ๋ฆฌ๋Š” etc ๋กœ ๋ณ€๊ฒฝ + * @param categoryId ์‚ญ์ œํ•  ์นดํ…Œ๊ณ ๋ฆฌ id + * @throws CategoryNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ์นดํ…Œ๊ณ ๋ฆฌ - 404 + * @throws DefaultCategoryNeedException default ์นดํ…Œ๊ณ ๋ฆฌ ์กด์žฌ x ๋˜๋Š” default ์นดํ…Œ๊ณ ๋ฆฌ ์‚ญ์ œ ์š”์ฒญ - 400 + */ + @Transactional + public void removeCategory(Long categoryId) { + Category category = categoryAdminRepository.findById(categoryId) + .orElseThrow(CategoryNotFoundException::new); + + Category defaultCategory = categoryAdminRepository.findByName( + DefaultCategoryNeedException.DEFAULT_CATEGORY_NAME).orElseThrow(DefaultCategoryNeedException::new); + + if (category.equals(defaultCategory)) { + throw new DefaultCategoryNeedException(); + } + + roomAdminRepository.findByCategory(category) + .forEach(room -> room.updateCategory(defaultCategory)); + + categoryAdminRepository.deleteById(categoryId); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/comment/controller/CommentAdminController.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/comment/controller/CommentAdminController.java new file mode 100644 index 000000000..3ceddbc53 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/comment/controller/CommentAdminController.java @@ -0,0 +1,32 @@ +package gg.party.api.admin.comment.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.party.api.admin.comment.controller.request.CommentUpdateAdminReqDto; +import gg.party.api.admin.comment.service.CommentAdminService; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/admin/comments") +public class CommentAdminController { + private final CommentAdminService commentAdminService; + + /** + * ๋Œ“๊ธ€ ์ˆจ๊น€ + * @param commentId ๋Œ“๊ธ€ ๋ฒˆํ˜ธ + * @return ์ˆจ๊น€ ์„ฑ๊ณต ์—ฌ๋ถ€ + */ + @PatchMapping("/{commentId}") + public ResponseEntity hideComment(@PathVariable Long commentId, + @RequestBody CommentUpdateAdminReqDto reqDto) { + commentAdminService.modifyHideComment(commentId, reqDto); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/comment/controller/request/CommentUpdateAdminReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/comment/controller/request/CommentUpdateAdminReqDto.java new file mode 100644 index 000000000..4f9b7dc1e --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/comment/controller/request/CommentUpdateAdminReqDto.java @@ -0,0 +1,15 @@ +package gg.party.api.admin.comment.controller.request; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class CommentUpdateAdminReqDto { + private Boolean isHidden; + + public CommentUpdateAdminReqDto(Boolean isHidden) { + this.isHidden = isHidden; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/comment/service/CommentAdminService.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/comment/service/CommentAdminService.java new file mode 100644 index 000000000..b1399da3e --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/comment/service/CommentAdminService.java @@ -0,0 +1,34 @@ +package gg.party.api.admin.comment.service; + +import javax.transaction.Transactional; + +import org.springframework.stereotype.Service; + +import gg.admin.repo.comment.CommentAdminRepository; +import gg.data.party.Comment; +import gg.party.api.admin.comment.controller.request.CommentUpdateAdminReqDto; +import gg.utils.exception.party.ChangeSameStatusException; +import gg.utils.exception.party.CommentNotFoundException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class CommentAdminService { + private final CommentAdminRepository commentAdminRepository; + + /** + * ๋Œ“๊ธ€ ์ˆจ๊น€ + * @param commentId ๋Œ“๊ธ€ ๋ฒˆํ˜ธ + * @throws CommentNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ๋Œ“๊ธ€ ์ž…๋ ฅ - 404 + * @throws ChangeSameStatusException ๊ฐ™์€ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ - 409 + */ + @Transactional + public void modifyHideComment(Long commentId, CommentUpdateAdminReqDto reqDto) { + Comment comment = commentAdminRepository.findById(commentId) + .orElseThrow(CommentNotFoundException::new); + if (reqDto.getIsHidden() == comment.isHidden()) { + throw new ChangeSameStatusException(); + } + comment.updateHidden(reqDto.getIsHidden()); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/PartyPenaltyAdminController.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/PartyPenaltyAdminController.java new file mode 100644 index 000000000..6a507644e --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/PartyPenaltyAdminController.java @@ -0,0 +1,58 @@ +package gg.party.api.admin.penalty.controller; + +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.party.api.admin.penalty.controller.request.PageReqDto; +import gg.party.api.admin.penalty.controller.request.PartyPenaltyAdminReqDto; +import gg.party.api.admin.penalty.controller.response.PartyPenaltyListAdminResDto; +import gg.party.api.admin.penalty.service.PartyPenaltyAdminService; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/admin/penalties") +public class PartyPenaltyAdminController { + private final PartyPenaltyAdminService partyPenaltyAdminService; + + /** + * ํŒจ๋„ํ‹ฐ ์กฐํšŒ + * @param reqDto page size + * @return PenaltyListAdminResponseDto penaltyList totalPage + */ + @GetMapping + public ResponseEntity penaltyList(@ModelAttribute @Valid PageReqDto reqDto) { + return ResponseEntity.status(HttpStatus.OK).body(partyPenaltyAdminService.findAllPenalty(reqDto)); + } + + /** + * ํŒจ๋„ํ‹ฐ ์ˆ˜์ • + * @param penaltyId ํŒจ๋„ํ‹ฐ id + */ + @PatchMapping("/{penaltyId}") + public ResponseEntity modifyAdminPenalty(@PathVariable Long penaltyId, + @RequestBody @Valid PartyPenaltyAdminReqDto reqDto) { + partyPenaltyAdminService.modifyAdminPenalty(penaltyId, reqDto); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } + + /** + * ํŒจ๋„ํ‹ฐ ๋ถ€์—ฌ + */ + @PostMapping + public ResponseEntity addAdminPenalty( + @RequestBody @Valid PartyPenaltyAdminReqDto reqDto) { + partyPenaltyAdminService.addAdminPenalty(reqDto); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/request/PageReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/request/PageReqDto.java new file mode 100644 index 000000000..9d7242677 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/request/PageReqDto.java @@ -0,0 +1,27 @@ +package gg.party.api.admin.penalty.controller.request; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +import lombok.Getter; + +@Getter +public class PageReqDto { + @NotNull + @Min(value = 1) + private final Integer page; + + @Min(value = 1) + @Max(value = 30) + private final Integer size; + + public PageReqDto(Integer page, Integer size) { + this.page = page; + if (size == null) { + this.size = 10; + } else { + this.size = size; + } + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/request/PartyPenaltyAdminReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/request/PartyPenaltyAdminReqDto.java new file mode 100644 index 000000000..c51516a47 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/request/PartyPenaltyAdminReqDto.java @@ -0,0 +1,44 @@ +package gg.party.api.admin.penalty.controller.request; + +import java.time.LocalDateTime; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import gg.data.party.PartyPenalty; +import gg.data.user.User; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class PartyPenaltyAdminReqDto { + @NotBlank(message = "Penalty type์ด ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค") + @Size(max = 20, message = "Penalty type์€ ์ตœ๋Œ€ 20์ž์ž…๋‹ˆ๋‹ค") + String penaltyType; + + @NotBlank(message = "message๊ฐ€ ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค") + @Size(max = 100, message = "message๋Š” ์ตœ๋Œ€ 100์ž์ž…๋‹ˆ๋‹ค") + String message; + + @NotNull(message = "penaltyTime์ด ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค") + @Min(value = 0, message = "์˜ฌ๋ฐ”๋ฅธ penaltyTime์„ ๋„ฃ์–ด์ฃผ์„ธ์š”") + int penaltyTime; + + @NotBlank(message = "IntraId๊ฐ€ ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค") + String userIntraId; + + public PartyPenalty toEntity(User user, String penaltyType, String message, LocalDateTime startTime, + Integer penaltyTime) { + return new PartyPenalty(user, penaltyType, message, startTime, penaltyTime); + } + + public PartyPenaltyAdminReqDto(String penaltyType, String message, int penaltyTime, String userIntraId) { + this.penaltyType = penaltyType; + this.message = message; + this.penaltyTime = penaltyTime; + this.userIntraId = userIntraId; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/response/PartyPenaltyAdminResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/response/PartyPenaltyAdminResDto.java new file mode 100644 index 000000000..655d4e183 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/response/PartyPenaltyAdminResDto.java @@ -0,0 +1,27 @@ +package gg.party.api.admin.penalty.controller.response; + +import java.time.LocalDateTime; + +import gg.data.party.PartyPenalty; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class PartyPenaltyAdminResDto { + private Long id; + private String userIntraId; + private String penaltyType; + private String message; + private LocalDateTime startTime; + private Integer penaltyTime; + + public PartyPenaltyAdminResDto(PartyPenalty partyPenalty) { + this.id = partyPenalty.getId(); + this.userIntraId = partyPenalty.getUser().getIntraId(); + this.penaltyType = partyPenalty.getPenaltyType(); + this.message = partyPenalty.getMessage(); + this.startTime = partyPenalty.getStartTime(); + this.penaltyTime = partyPenalty.getPenaltyTime(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/response/PartyPenaltyListAdminResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/response/PartyPenaltyListAdminResDto.java new file mode 100644 index 000000000..d4cb66f3c --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/controller/response/PartyPenaltyListAdminResDto.java @@ -0,0 +1,18 @@ +package gg.party.api.admin.penalty.controller.response; + +import java.util.List; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class PartyPenaltyListAdminResDto { + private List penaltyList; + private int totalPage; + + public PartyPenaltyListAdminResDto(List penaltyList, int totalPage) { + this.penaltyList = penaltyList; + this.totalPage = totalPage; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/service/PartyPenaltyAdminService.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/service/PartyPenaltyAdminService.java new file mode 100644 index 000000000..5e0a1fb3a --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/penalty/service/PartyPenaltyAdminService.java @@ -0,0 +1,75 @@ +package gg.party.api.admin.penalty.service; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.data.party.PartyPenalty; +import gg.data.user.User; +import gg.party.api.admin.penalty.controller.request.PageReqDto; +import gg.party.api.admin.penalty.controller.request.PartyPenaltyAdminReqDto; +import gg.party.api.admin.penalty.controller.response.PartyPenaltyAdminResDto; +import gg.party.api.admin.penalty.controller.response.PartyPenaltyListAdminResDto; +import gg.repo.party.PartyPenaltyRepository; +import gg.repo.user.UserRepository; +import gg.utils.exception.party.PartyPenaltyNotFoundException; +import gg.utils.exception.user.UserNotFoundException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class PartyPenaltyAdminService { + private final PartyPenaltyRepository partyPenaltyRepository; + private final UserRepository userRepository; + + /** + * ํŒจ๋„ํ‹ฐ ์ „์ฒด ์กฐํšŒ + * @param reqDto page size + * @return PenaltyListAdminResDto penaltyList totalPage + */ + @Transactional(readOnly = true) + public PartyPenaltyListAdminResDto findAllPenalty(PageReqDto reqDto) { + int page = reqDto.getPage(); + int size = reqDto.getSize(); + + Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createdAt")); + + Page penaltyPage = partyPenaltyRepository.findUserFetchJoin(pageable); + + List penaltyList = penaltyPage.getContent().stream() + .map(PartyPenaltyAdminResDto::new) + .collect(Collectors.toList()); + + return new PartyPenaltyListAdminResDto(penaltyList, penaltyPage.getTotalPages()); + } + + /** + * ํŒจ๋„ํ‹ฐ ์ˆ˜์ • + * @param penaltyId ํŒจ๋„ํ‹ฐ ๋ฒˆํ˜ธ + * @throws PartyPenaltyNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ํŒจ๋„ํ‹ฐ - 404 + */ + @Transactional + public void modifyAdminPenalty(Long penaltyId, PartyPenaltyAdminReqDto reqDto) { + PartyPenalty partyPenalty = partyPenaltyRepository.findById(penaltyId) + .orElseThrow(PartyPenaltyNotFoundException::new); + partyPenalty.update(reqDto.getPenaltyType(), reqDto.getMessage(), reqDto.getPenaltyTime()); + } + + /** + * ํŒจ๋„ํ‹ฐ ๋ถ€์—ฌ + */ + @Transactional + public void addAdminPenalty(PartyPenaltyAdminReqDto reqDto) { + User userEntity = userRepository.getUserByIntraId(reqDto.getUserIntraId()) + .orElseThrow(UserNotFoundException::new); + partyPenaltyRepository.save(reqDto.toEntity(userEntity, reqDto.getPenaltyType(), + reqDto.getMessage(), LocalDateTime.now(), reqDto.getPenaltyTime())); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/ReportAdminController.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/ReportAdminController.java new file mode 100644 index 000000000..b42b80730 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/ReportAdminController.java @@ -0,0 +1,56 @@ +package gg.party.api.admin.report.controller; + +import javax.validation.Valid; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.party.api.admin.report.controller.request.ReportPageReqDto; +import gg.party.api.admin.report.controller.response.CommentReportListResDto; +import gg.party.api.admin.report.controller.response.RoomReportListResDto; +import gg.party.api.admin.report.controller.response.UserReportListResDto; +import gg.party.api.admin.report.service.ReportAdminService; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/admin/reports") +public class ReportAdminController { + private final ReportAdminService reportAdminService; + + /** + * ๋Œ“๊ธ€ ์‹ ๊ณ  ์ „์ฒด ๋ฆฌ์ŠคํŠธ ์กฐํšŒ + * return 200 status code(์„ฑ๊ณต status) + */ + @GetMapping("/comments") + public ResponseEntity getCommentReports( + @ModelAttribute @Valid ReportPageReqDto reportPageReqDto) { + CommentReportListResDto commentReportListResDto = reportAdminService.getCommentReports(reportPageReqDto); + return ResponseEntity.ok(commentReportListResDto); + } + + /** + * ๋ฐฉ ์‹ ๊ณ  ์ „์ฒด ๋ฆฌ์ŠคํŠธ ์กฐํšŒ + * return 200 status code(์„ฑ๊ณต status) + */ + @GetMapping("/rooms") + public ResponseEntity getRoomReports( + @ModelAttribute @Valid ReportPageReqDto reportPageReqDto) { + RoomReportListResDto roomReportListResDto = reportAdminService.getRoomReports(reportPageReqDto); + return ResponseEntity.ok(roomReportListResDto); + } + + /** + * ๋…ธ์‡ผ ์‹ ๊ณ  ์ „์ฒด ๋ฆฌ์ŠคํŠธ ์กฐํšŒ + * return 200 status code(์„ฑ๊ณต status) + */ + @GetMapping("/users") + public ResponseEntity getUserReports( + @ModelAttribute @Valid ReportPageReqDto reportPageReqDto) { + UserReportListResDto userReportListResDto = reportAdminService.getUserReports(reportPageReqDto); + return ResponseEntity.ok(userReportListResDto); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/request/ReportPageReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/request/ReportPageReqDto.java new file mode 100644 index 000000000..08bf49601 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/request/ReportPageReqDto.java @@ -0,0 +1,29 @@ +package gg.party.api.admin.report.controller.request; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ReportPageReqDto { + @Min(value = 1) + @NotNull + private Integer page; + + @Min(value = 1) + @Max(value = 30) + private Integer size = 10; + + public ReportPageReqDto(Integer page, Integer size) { + this.page = page; + if (size == null) { + this.size = 10; + } else { + this.size = size; + } + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/CommentReportAdminResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/CommentReportAdminResDto.java new file mode 100644 index 000000000..70a6592c9 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/CommentReportAdminResDto.java @@ -0,0 +1,27 @@ +package gg.party.api.admin.report.controller.response; + +import java.time.LocalDateTime; + +import gg.data.party.CommentReport; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class CommentReportAdminResDto { + private Long id; + private String reporterIntraId; + private Long commentId; + private Long roomId; + private String message; + private LocalDateTime createdAt; + + public CommentReportAdminResDto(CommentReport commentReport) { + this.id = commentReport.getId(); + this.reporterIntraId = commentReport.getReporter().getIntraId(); + this.commentId = commentReport.getComment().getId(); + this.roomId = commentReport.getRoom().getId(); + this.message = commentReport.getMessage(); + this.createdAt = commentReport.getCreatedAt(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/CommentReportListResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/CommentReportListResDto.java new file mode 100644 index 000000000..7e7b4da56 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/CommentReportListResDto.java @@ -0,0 +1,18 @@ +package gg.party.api.admin.report.controller.response; + +import java.util.List; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@Getter +public class CommentReportListResDto { + private List commentReportList; + private int totalPages; + + public CommentReportListResDto(List commentReportList, int totalPages) { + this.commentReportList = commentReportList; + this.totalPages = totalPages; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/RoomReportAdminResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/RoomReportAdminResDto.java new file mode 100644 index 000000000..4326fe751 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/RoomReportAdminResDto.java @@ -0,0 +1,27 @@ +package gg.party.api.admin.report.controller.response; + +import java.time.LocalDateTime; + +import gg.data.party.RoomReport; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class RoomReportAdminResDto { + private Long id; + private String reporterIntraId; + private String reporteeIntraId; + private Long roomId; + private String message; + private LocalDateTime createdAt; + + public RoomReportAdminResDto(RoomReport roomReport) { + this.id = roomReport.getId(); + this.reporterIntraId = roomReport.getReporter().getIntraId(); + this.reporteeIntraId = roomReport.getReportee().getIntraId(); + this.roomId = roomReport.getRoom().getId(); + this.message = roomReport.getMessage(); + this.createdAt = roomReport.getCreatedAt(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/RoomReportListResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/RoomReportListResDto.java new file mode 100644 index 000000000..1583de710 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/RoomReportListResDto.java @@ -0,0 +1,18 @@ +package gg.party.api.admin.report.controller.response; + +import java.util.List; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@Getter +public class RoomReportListResDto { + private List roomReportList; + private int totalPages; + + public RoomReportListResDto(List roomReportList, int totalPages) { + this.roomReportList = roomReportList; + this.totalPages = totalPages; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/UserReportAdminResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/UserReportAdminResDto.java new file mode 100644 index 000000000..134085fda --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/UserReportAdminResDto.java @@ -0,0 +1,27 @@ +package gg.party.api.admin.report.controller.response; + +import java.time.LocalDateTime; + +import gg.data.party.UserReport; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class UserReportAdminResDto { + private Long id; + private String reporterIntraId; + private String reporteeIntraId; + private Long roomId; + private String message; + private LocalDateTime createdAt; + + public UserReportAdminResDto(UserReport userReport) { + this.id = userReport.getId(); + this.reporterIntraId = userReport.getReporter().getIntraId(); + this.reporteeIntraId = userReport.getReportee().getIntraId(); + this.roomId = userReport.getRoom().getId(); + this.message = userReport.getMessage(); + this.createdAt = userReport.getCreatedAt(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/UserReportListResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/UserReportListResDto.java new file mode 100644 index 000000000..5c6f1c656 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/controller/response/UserReportListResDto.java @@ -0,0 +1,18 @@ +package gg.party.api.admin.report.controller.response; + +import java.util.List; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@Getter +public class UserReportListResDto { + private List userReportList; + private int totalPages; + + public UserReportListResDto(List userReportList, int totalPages) { + this.userReportList = userReportList; + this.totalPages = totalPages; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/report/service/ReportAdminService.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/service/ReportAdminService.java new file mode 100644 index 000000000..3eb7b4420 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/report/service/ReportAdminService.java @@ -0,0 +1,91 @@ +package gg.party.api.admin.report.service; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.data.party.CommentReport; +import gg.data.party.RoomReport; +import gg.data.party.UserReport; +import gg.party.api.admin.report.controller.request.ReportPageReqDto; +import gg.party.api.admin.report.controller.response.CommentReportAdminResDto; +import gg.party.api.admin.report.controller.response.CommentReportListResDto; +import gg.party.api.admin.report.controller.response.RoomReportAdminResDto; +import gg.party.api.admin.report.controller.response.RoomReportListResDto; +import gg.party.api.admin.report.controller.response.UserReportAdminResDto; +import gg.party.api.admin.report.controller.response.UserReportListResDto; +import gg.repo.party.CommentReportRepository; +import gg.repo.party.RoomReportRepository; +import gg.repo.party.UserReportRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class ReportAdminService { + private final CommentReportRepository commentReportRepository; + private final RoomReportRepository roomReportRepository; + private final UserReportRepository userReportRepository; + + /** + * ๋Œ“๊ธ€ ์‹ ๊ณ  ์ „์ฒด ๋ฆฌ์ŠคํŠธ๋ฅผ ์กฐํšŒํ•œ๋‹ค + * @return ์ „์ฒด ๋Œ“๊ธ€ ์‹ ๊ณ  ๋ฆฌ์ŠคํŠธ (์‹œ๊ฐ„์ˆœ ์ •๋ ฌ) + */ + @Transactional(readOnly = true) + public CommentReportListResDto getCommentReports(ReportPageReqDto reportPageReqDto) { + int page = reportPageReqDto.getPage(); + int size = reportPageReqDto.getSize(); + + Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createdAt")); + Page commentReportPage = commentReportRepository.findAllWithCommentReportFetchJoin(pageable); + + List commentReportPageResDto = commentReportPage.getContent().stream() + .map(CommentReportAdminResDto::new) + .collect(Collectors.toList()); + + return new CommentReportListResDto(commentReportPageResDto, commentReportPage.getTotalPages()); + } + + /** + * ๋ฐฉ ์‹ ๊ณ  ์ „์ฒด ๋ฆฌ์ŠคํŠธ๋ฅผ ์กฐํšŒํ•œ๋‹ค + * @return ์ „์ฒด ๋ฐฉ ์‹ ๊ณ  ๋ฆฌ์ŠคํŠธ (์‹œ๊ฐ„์ˆœ ์ •๋ ฌ) + */ + @Transactional(readOnly = true) + public RoomReportListResDto getRoomReports(ReportPageReqDto reportPageReqDto) { + int page = reportPageReqDto.getPage(); + int size = reportPageReqDto.getSize(); + + Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createdAt")); + Page roomReportPage = roomReportRepository.findAllWithRoomReportFetchJoin(pageable); + + List roomReportPageResDto = roomReportPage.getContent().stream() + .map(RoomReportAdminResDto::new) + .collect(Collectors.toList()); + + return new RoomReportListResDto(roomReportPageResDto, roomReportPage.getTotalPages()); + } + + /** + * ๋…ธ์‡ผ ์‹ ๊ณ  ์ „์ฒด ๋ฆฌ์ŠคํŠธ๋ฅผ ์กฐํšŒํ•œ๋‹ค + * @return ์ „์ฒด ๋…ธ์‡ผ ์‹ ๊ณ  ๋ฆฌ์ŠคํŠธ (์‹œ๊ฐ„์ˆœ ์ •๋ ฌ) + */ + @Transactional(readOnly = true) + public UserReportListResDto getUserReports(ReportPageReqDto reportPageReqDto) { + int page = reportPageReqDto.getPage(); + int size = reportPageReqDto.getSize(); + + Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createdAt")); + Page userReportPage = userReportRepository.findAllWithUserReportFetchJoin(pageable); + + List userReportPageResDto = userReportPage.getContent().stream() + .map(UserReportAdminResDto::new) + .collect(Collectors.toList()); + + return new UserReportListResDto(userReportPageResDto, userReportPage.getTotalPages()); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/RoomAdminController.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/RoomAdminController.java new file mode 100644 index 000000000..387fbfc25 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/RoomAdminController.java @@ -0,0 +1,72 @@ +package gg.party.api.admin.room.controller; + +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.data.party.type.RoomType; +import gg.party.api.admin.room.controller.request.PageReqDto; +import gg.party.api.admin.room.controller.request.RoomShowChangeReqDto; +import gg.party.api.admin.room.controller.response.AdminRoomDetailResDto; +import gg.party.api.admin.room.controller.response.AdminRoomListResDto; +import gg.party.api.admin.room.service.RoomAdminService; +import gg.utils.exception.party.RoomNotFoundException; +import gg.utils.exception.party.RoomStatNotFoundException; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/admin/rooms") +public class RoomAdminController { + private final RoomAdminService roomAdminService; + + /** + * ๋ฐฉ Status ๋ณ€๊ฒฝ + * @param roomId ๋ฐฉ id + * @param reqDto ๋ฐ”๊ฟ€ status + * @exception RoomNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฐฉ ์ž…๋ ฅ - 404 + */ + @PatchMapping("/{roomId}") + public ResponseEntity modifyRoomVisibility(@PathVariable Long roomId, + @Valid @RequestBody RoomShowChangeReqDto reqDto) throws RoomStatNotFoundException { + + RoomType roomType; + try { + roomType = RoomType.valueOf(reqDto.getStatus().toUpperCase()); + } catch (IllegalArgumentException e) { + throw new RoomStatNotFoundException(); + } + + roomAdminService.modifyRoomStatus(roomId, roomType); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } + + /** + * ๋ฐฉ ์ „์ฒด ์กฐํšŒ + * @param pageReqDto page๋ฒˆํ˜ธ ๋ฐ ์‚ฌ์ด์ฆˆ(10) + * @return ๋ฐฉ ์ •๋ณด ๋ฆฌ์ŠคํŠธ + totalpages dto + */ + @GetMapping + public ResponseEntity adminAllRoomList(@ModelAttribute @Valid PageReqDto pageReqDto) { + AdminRoomListResDto adminRoomListResDto = roomAdminService.findAllRoomList(pageReqDto); + return ResponseEntity.status(HttpStatus.OK).body(adminRoomListResDto); + } + + /** + * ๋ฐฉ ์ƒ์„ธ ์กฐํšŒ + * @return ๋ฐฉ ์ƒ์„ธ์ •๋ณด (๋“ค์–ด์™€ ์žˆ์ง€ ์•Š์€ ์‚ฌ๋žŒ์˜ intraId ํฌํ•จ) + */ + @GetMapping("/{room_id}") + public ResponseEntity adminRoomDetailInfo(@PathVariable("room_id") Long roomId) { + AdminRoomDetailResDto adminRoomDetailResDto = roomAdminService.findAdminDetailRoom(roomId); + return ResponseEntity.status(HttpStatus.OK).body(adminRoomDetailResDto); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/request/PageReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/request/PageReqDto.java new file mode 100644 index 000000000..ca2975c0b --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/request/PageReqDto.java @@ -0,0 +1,29 @@ +package gg.party.api.admin.room.controller.request; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PageReqDto { + @Min(value = 1) + @NotNull + private Integer page; + + @Min(value = 1) + @Max(value = 30) + private Integer size = 10; + + public PageReqDto(Integer page, Integer size) { + this.page = page; + if (size == null) { + this.size = 10; + } else { + this.size = size; + } + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/request/RoomShowChangeReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/request/RoomShowChangeReqDto.java new file mode 100644 index 000000000..881a7abe3 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/request/RoomShowChangeReqDto.java @@ -0,0 +1,18 @@ +package gg.party.api.admin.room.controller.request; + +import javax.validation.constraints.NotNull; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class RoomShowChangeReqDto { + @NotNull + private String status; + + public RoomShowChangeReqDto(String status) { + this.status = status; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminCommentResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminCommentResDto.java new file mode 100644 index 000000000..770e4c149 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminCommentResDto.java @@ -0,0 +1,29 @@ +package gg.party.api.admin.room.controller.response; + +import java.time.LocalDateTime; + +import gg.data.party.Comment; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class AdminCommentResDto { + private Long commentId; + private String nickname; + private String intraId; + private Boolean isExist; + private String content; + private Boolean isHidden; + private LocalDateTime createDate; + + public AdminCommentResDto(Comment comment) { + this.commentId = comment.getId(); + this.nickname = comment.getUserRoom().getNickname(); + this.intraId = comment.getUser().getIntraId(); + this.isExist = comment.getUserRoom().getIsExist(); + this.content = comment.getContent(); + this.isHidden = comment.isHidden(); + this.createDate = comment.getCreatedAt(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminRoomDetailResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminRoomDetailResDto.java new file mode 100644 index 000000000..fce298b86 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminRoomDetailResDto.java @@ -0,0 +1,49 @@ +package gg.party.api.admin.room.controller.response; + +import java.time.LocalDateTime; +import java.util.List; + +import gg.data.party.Room; +import gg.data.party.type.RoomType; +import gg.party.api.user.room.controller.response.UserRoomResDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@Getter +public class AdminRoomDetailResDto { + private Long roomId; + private String title; + private String content; + private String categoryName; + private Integer currentPeople; + private Integer minPeople; + private Integer maxPeople; + private RoomType status; + private LocalDateTime dueDate; + private LocalDateTime createDate; + private LocalDateTime startDate; + private String myNickname; + private String hostNickname; + private List roomUsers; + private List comments; + + public AdminRoomDetailResDto(Room room, String hostNickname, + List roomUsers, List comments) { + this.roomId = room.getId(); + this.title = room.getTitle(); + this.content = room.getContent(); + this.categoryName = room.getCategory().getName(); + this.currentPeople = room.getCurrentPeople(); + this.minPeople = room.getMinPeople(); + this.maxPeople = room.getMaxPeople(); + this.status = room.getStatus(); + this.dueDate = room.getDueDate(); + this.createDate = room.getCreatedAt(); + this.startDate = room.getStartDate(); + this.myNickname = null; + this.hostNickname = hostNickname; + this.roomUsers = roomUsers; + this.comments = comments; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminRoomListResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminRoomListResDto.java new file mode 100644 index 000000000..dee6cb9ed --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminRoomListResDto.java @@ -0,0 +1,18 @@ +package gg.party.api.admin.room.controller.response; + +import java.util.List; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@Getter +public class AdminRoomListResDto { + private List adminRoomList; + private int totalPages; + + public AdminRoomListResDto(List adminRoomList, int totalPages) { + this.adminRoomList = adminRoomList; + this.totalPages = totalPages; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminRoomResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminRoomResDto.java new file mode 100644 index 000000000..8a299f60e --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/controller/response/AdminRoomResDto.java @@ -0,0 +1,41 @@ +package gg.party.api.admin.room.controller.response; + +import java.time.LocalDateTime; + +import gg.data.party.Room; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class AdminRoomResDto { + private Long roomId; + private String hostIntraId; + private String creatorIntraId; + private String categoryName; + private String title; + private String content; + private Integer currentPeople; + private Integer maxPeople; + private Integer minPeople; + private LocalDateTime dueDate; + private LocalDateTime createDate; + private LocalDateTime startDate; + private String status; + + public AdminRoomResDto(Room room) { + this.roomId = room.getId(); + this.hostIntraId = room.getHost().getIntraId(); + this.creatorIntraId = room.getCreator().getIntraId(); + this.categoryName = room.getCategory().getName(); + this.title = room.getTitle(); + this.content = room.getContent(); + this.currentPeople = room.getCurrentPeople(); + this.maxPeople = room.getMaxPeople(); + this.minPeople = room.getMinPeople(); + this.dueDate = room.getDueDate(); + this.createDate = room.getCreatedAt(); + this.startDate = room.getStartDate(); + this.status = room.getStatus().toString(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/room/service/RoomAdminService.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/service/RoomAdminService.java new file mode 100644 index 000000000..2f54bea2e --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/service/RoomAdminService.java @@ -0,0 +1,102 @@ +package gg.party.api.admin.room.service; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.data.party.Room; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.party.api.admin.room.controller.request.PageReqDto; +import gg.party.api.admin.room.controller.response.AdminCommentResDto; +import gg.party.api.admin.room.controller.response.AdminRoomDetailResDto; +import gg.party.api.admin.room.controller.response.AdminRoomListResDto; +import gg.party.api.admin.room.controller.response.AdminRoomResDto; +import gg.party.api.user.room.controller.response.UserRoomResDto; +import gg.repo.party.CommentRepository; +import gg.repo.party.RoomRepository; +import gg.repo.party.UserRoomRepository; +import gg.utils.exception.party.ChangeSameStatusException; +import gg.utils.exception.party.RoomNotFoundException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class RoomAdminService { + private final RoomRepository roomRepository; + private final UserRoomRepository userRoomRepository; + private final CommentRepository commentRepository; + + /** + * ๋ฐฉ Status ๋ณ€๊ฒฝ + * @param roomId ๋ฐฉ id + * @param newStatus ๋ฐ”๊ฟ€ status + * @exception RoomNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฐฉ ์ž…๋ ฅ - 404 + * @exception ChangeSameStatusException ๊ฐ™์€ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ - 409 + */ + @Transactional + public void modifyRoomStatus(Long roomId, RoomType newStatus) { + Room room = roomRepository.findById(roomId) + .orElseThrow(RoomNotFoundException::new); + + if (room.getStatus() == newStatus) { + throw new ChangeSameStatusException(); + } + + room.changeRoomStatus(newStatus); + roomRepository.save(room); + } + + /** + * ๋ฐฉ ์ „์ฒด ์กฐํšŒ + * @param pageReqDto page๋ฒˆํ˜ธ ๋ฐ ์‚ฌ์ด์ฆˆ(10) + * @return ๋ฐฉ ์ •๋ณด ๋ฆฌ์ŠคํŠธ + totalpages dto + */ + @Transactional(readOnly = true) + public AdminRoomListResDto findAllRoomList(PageReqDto pageReqDto) { + int page = pageReqDto.getPage(); + int size = pageReqDto.getSize(); + + Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "createdAt")); + + Page roomPage = roomRepository.findAll(pageable); + + List adminRoomListResDto = roomPage.getContent().stream() + .map(AdminRoomResDto::new) + .collect(Collectors.toList()); + + return new AdminRoomListResDto(adminRoomListResDto, roomPage.getTotalPages()); + } + + /** + * ๋ฐฉ์˜ ์ƒ์„ธ์ •๋ณด๋ฅผ ์กฐํšŒํ•œ๋‹ค + * @param roomId ๋ฐฉ id + * @exception RoomNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฐฉ ์ž…๋ ฅ - 404 + * @return ๋ฐฉ ์ƒ์„ธ์ •๋ณด dto + */ + @Transactional(readOnly = true) + public AdminRoomDetailResDto findAdminDetailRoom(Long roomId) { + Room room = roomRepository.findById(roomId).orElseThrow(RoomNotFoundException::new); + + List comments = commentRepository.findAllWithCommentFetchJoin(roomId).stream() + .map(AdminCommentResDto::new) + .collect(Collectors.toList()); + + UserRoom hostUserRoom = userRoomRepository.findByUserAndRoom(room.getHost(), room) + .orElseThrow(RoomNotFoundException::new); + + List roomUsers = userRoomRepository.findByRoomId(roomId).stream() + .filter(UserRoom::getIsExist) + .map(userRoom -> new UserRoomResDto(userRoom, userRoom.getUser().getIntraId(), + userRoom.getUser().getImageUri())) + .collect(Collectors.toList()); + + return new AdminRoomDetailResDto(room, hostUserRoom.getNickname(), roomUsers, comments); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/room/service/RoomStatusService.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/service/RoomStatusService.java new file mode 100644 index 000000000..510c5b650 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/room/service/RoomStatusService.java @@ -0,0 +1,52 @@ +package gg.party.api.admin.room.service; + +import java.time.LocalDateTime; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.data.party.Room; +import gg.data.party.type.RoomType; +import gg.repo.party.RoomRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Service +@RequiredArgsConstructor +@Slf4j +public class RoomStatusService { + private final RoomRepository roomRepository; + + /** + * ๋ฐฉ FINISH ๋ณ€๊ฒฝ ์Šค์ผ€์ฅด๋Ÿฌ + * ์‹œ์ž‘ํ•œ ๋ฐฉ(START) 2์‹œ๊ฐ„ํ›„์— FINISH๋กœ ๋ณ€๊ฒฝ + */ + @Transactional + public void finishStartedRooms() { + LocalDateTime twoHoursAgo = LocalDateTime.now().minusHours(2); + List startedRooms = roomRepository.findByStatusAndStartDate(RoomType.START, twoHoursAgo); + for (Room room : startedRooms) { + room.roomFinish(); + roomRepository.save(room); + log.info("{}๋ฒˆ ๋ฐฉ์ด ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.", room.getId()); + } + } + + /** + * ๋ฐฉ FAIL ๋ณ€๊ฒฝ ์Šค์ผ€์ฅด๋Ÿฌ + * due date ์ง€๋‚ฌ๋Š”๋ฐ ์‹œ์ž‘ ์•ˆํ–ˆ์œผ๋ฉด FAIL๋กœ ๋ณ€๊ฒฝ + */ + @Transactional + public void failOpenedRooms() { + LocalDateTime now = LocalDateTime.now(); + List openRooms = roomRepository.findByStatus(RoomType.OPEN, null); + for (Room room : openRooms) { + if (room.getDueDate().isBefore(now)) { + room.roomFail(); + roomRepository.save(room); + log.info("{}๋ฒˆ ๋ฐฉ์ด ์‹œ๊ฐ„์ด ์ง€๋‚˜ Fail๋˜์—ˆ์Šต๋‹ˆ๋‹ค.", room.getId()); + } + } + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/scheduler/FailRoomScheduler.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/scheduler/FailRoomScheduler.java new file mode 100644 index 000000000..5218b70aa --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/scheduler/FailRoomScheduler.java @@ -0,0 +1,26 @@ +package gg.party.api.admin.scheduler; + +import org.springframework.stereotype.Component; + +import gg.party.api.admin.room.service.RoomStatusService; +import gg.pingpong.api.global.scheduler.AbstractScheduler; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class FailRoomScheduler extends AbstractScheduler { + private final RoomStatusService roomStatusService; + + public FailRoomScheduler(RoomStatusService roomStatusService) { + this.roomStatusService = roomStatusService; + this.setCron("0 0/5 * * * *"); + } + + @Override + public Runnable runnable() { + return () -> { + log.info("FailOpenedRoomsScheduler start"); + roomStatusService.failOpenedRooms(); + }; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/scheduler/FinishRoomScheduler.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/scheduler/FinishRoomScheduler.java new file mode 100644 index 000000000..6ef93cad0 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/scheduler/FinishRoomScheduler.java @@ -0,0 +1,26 @@ +package gg.party.api.admin.scheduler; + +import org.springframework.stereotype.Component; + +import gg.party.api.admin.room.service.RoomStatusService; +import gg.pingpong.api.global.scheduler.AbstractScheduler; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class FinishRoomScheduler extends AbstractScheduler { + private final RoomStatusService roomStatusService; + + public FinishRoomScheduler(RoomStatusService roomStatusService) { + this.roomStatusService = roomStatusService; + this.setCron("0 0/5 * * * *"); // Example: Run every 5 minutes + } + + @Override + public Runnable runnable() { + return () -> { + log.info("FinishStartedRoomsScheduler start"); + roomStatusService.finishStartedRooms(); + }; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/controller/TemplateAdminController.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/controller/TemplateAdminController.java new file mode 100644 index 000000000..ae095d25e --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/controller/TemplateAdminController.java @@ -0,0 +1,56 @@ +package gg.party.api.admin.templates.controller; + +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.party.api.admin.templates.controller.request.TemplateAdminCreateReqDto; +import gg.party.api.admin.templates.controller.request.TemplateAdminUpdateReqDto; +import gg.party.api.admin.templates.service.TemplateAdminService; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/admin/templates") +public class TemplateAdminController { + private final TemplateAdminService templateAdminService; + + /** + * ํ…œํ”Œ๋ฆฟ ์ถ”๊ฐ€ + * return 201 status code(์„ฑ๊ณต์ ์ธ ์ถ”๊ฐ€ status) + */ + @PostMapping + public ResponseEntity addTemplate(@RequestBody @Valid TemplateAdminCreateReqDto request) { + templateAdminService.addTemplate(request); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + /** + * ํ…œํ”Œ๋ฆฟ ์ˆ˜์ • + * return 204 status code(์„ฑ๊ณต์ ์ธ ์ˆ˜์ • status) + */ + @PatchMapping("/{templateId}") + public ResponseEntity updateTemplate(@PathVariable Long templateId, + @Valid @RequestBody TemplateAdminUpdateReqDto request) { + templateAdminService.modifyTemplate(templateId, request); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } + + /** + * ํ…œํ”Œ๋ฆฟ ์‚ญ์ œ + * return 204 status code(์„ฑ๊ณต์ ์ธ ์‚ญ์ œ status) + */ + @DeleteMapping("/{templateId}") + public ResponseEntity removeTemplate(@PathVariable Long templateId) { + templateAdminService.removeTemplate(templateId); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/controller/request/TemplateAdminCreateReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/controller/request/TemplateAdminCreateReqDto.java new file mode 100644 index 000000000..6ccd8ae6f --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/controller/request/TemplateAdminCreateReqDto.java @@ -0,0 +1,76 @@ +package gg.party.api.admin.templates.controller.request; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import gg.data.party.Category; +import gg.data.party.GameTemplate; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class TemplateAdminCreateReqDto { + @NotNull(message = "์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.") + private String categoryName; + + @NotBlank(message = "๊ฒŒ์ž„ ์ด๋ฆ„์€ ํ•„์ˆ˜์ด๋ฉฐ, ๋น„์–ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + @Size(max = 15, message = "๊ฒŒ์ž„ ์ด๋ฆ„์€ 15์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + private String gameName; + + @NotNull(message = "์ตœ๋Œ€ ๊ฒŒ์ž„ ์ธ์›์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.") + @Min(value = 2, message = "์ตœ๋Œ€ ๊ฒŒ์ž„ ์ธ์›์€ ์ตœ์†Œ 2๋ช… ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private Integer maxGamePeople; + + @NotNull(message = "์ตœ์†Œ ๊ฒŒ์ž„ ์ธ์›์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.") + @Min(value = 2, message = "์ตœ์†Œ ๊ฒŒ์ž„ ์ธ์›์€ ์ตœ์†Œ 2๋ช… ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private Integer minGamePeople; + + @NotNull(message = "์ตœ๋Œ€ ๊ฒŒ์ž„ ์‹œ๊ฐ„์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.") + @Min(value = 1, message = "์ตœ๋Œ€ ๊ฒŒ์ž„ ์‹œ๊ฐ„์€ ์ตœ์†Œ 1๋ถ„ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private Integer maxGameTime; + + @NotNull(message = "์ตœ์†Œ ๊ฒŒ์ž„ ์‹œ๊ฐ„์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.") + @Min(value = 1, message = "์ตœ์†Œ ๊ฒŒ์ž„ ์‹œ๊ฐ„์€ ์ตœ์†Œ 1๋ถ„ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private Integer minGameTime; + + @NotBlank(message = "์žฅ๋ฅด๋Š” ํ•„์ˆ˜์ด๋ฉฐ, ๋น„์–ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + @Size(max = 10, message = "์žฅ๋ฅด๋Š” 10์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + private String genre; + + @Size(max = 10, message = "๋‚œ์ด๋„๋Š” 10์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + private String difficulty; + + @NotBlank(message = "๋‚ด์šฉ์€ ํ•„์ˆ˜์ด๋ฉฐ, ๋น„์–ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + @Size(max = 100, message = "๋‚ด์šฉ์€ 100์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + private String summary; + + public TemplateAdminCreateReqDto(String categoryName, String gameName, int maxGamePeople, int minGamePeople, + int maxGameTime, int minGameTime, String genre, String difficulty, String summary) { + this.categoryName = categoryName; + this.gameName = gameName; + this.maxGamePeople = maxGamePeople; + this.minGamePeople = minGamePeople; + this.maxGameTime = maxGameTime; + this.minGameTime = minGameTime; + this.genre = genre; + this.difficulty = difficulty; + this.summary = summary; + } + + public static GameTemplate toEntity(TemplateAdminCreateReqDto dto, Category category) { + return GameTemplate.builder() + .category(category) + .gameName(dto.getGameName()) + .maxGamePeople(dto.getMaxGamePeople()) + .minGamePeople(dto.getMinGamePeople()) + .maxGameTime(dto.getMaxGameTime()) + .minGameTime(dto.getMinGameTime()) + .genre(dto.getGenre()) + .difficulty(dto.getDifficulty()) + .summary(dto.getSummary()) + .build(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/controller/request/TemplateAdminUpdateReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/controller/request/TemplateAdminUpdateReqDto.java new file mode 100644 index 000000000..92c2f1731 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/controller/request/TemplateAdminUpdateReqDto.java @@ -0,0 +1,74 @@ +package gg.party.api.admin.templates.controller.request; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import gg.data.party.GameTemplate; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class TemplateAdminUpdateReqDto { + @NotNull(message = "์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.") + private String categoryName; + + @NotBlank(message = "๊ฒŒ์ž„ ์ด๋ฆ„์€ ํ•„์ˆ˜์ด๋ฉฐ, ๋น„์–ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + @Size(max = 15, message = "๊ฒŒ์ž„ ์ด๋ฆ„์€ 15์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + private String gameName; + + @NotNull(message = "์ตœ๋Œ€ ๊ฒŒ์ž„ ์ธ์›์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.") + @Min(value = 2, message = "์ตœ๋Œ€ ๊ฒŒ์ž„ ์ธ์›์€ ์ตœ์†Œ 2๋ช… ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private Integer maxGamePeople; + + @NotNull(message = "์ตœ์†Œ ๊ฒŒ์ž„ ์ธ์›์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.") + @Min(value = 2, message = "์ตœ์†Œ ๊ฒŒ์ž„ ์ธ์›์€ ์ตœ์†Œ 2๋ช… ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private Integer minGamePeople; + + @NotNull(message = "์ตœ๋Œ€ ๊ฒŒ์ž„ ์‹œ๊ฐ„์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.") + @Min(value = 1, message = "์ตœ๋Œ€ ๊ฒŒ์ž„ ์‹œ๊ฐ„์€ ์ตœ์†Œ 1๋ถ„ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private Integer maxGameTime; + + @NotNull(message = "์ตœ์†Œ ๊ฒŒ์ž„ ์‹œ๊ฐ„์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.") + @Min(value = 1, message = "์ตœ์†Œ ๊ฒŒ์ž„ ์‹œ๊ฐ„์€ ์ตœ์†Œ 1๋ถ„ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private Integer minGameTime; + + @NotBlank(message = "์žฅ๋ฅด๋Š” ํ•„์ˆ˜์ด๋ฉฐ, ๋น„์–ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + @Size(max = 10, message = "์žฅ๋ฅด๋Š” 10์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + private String genre; + + @Size(max = 10, message = "๋‚œ์ด๋„๋Š” 10์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + private String difficulty; + + @NotBlank(message = "๋‚ด์šฉ์€ ํ•„์ˆ˜์ด๋ฉฐ, ๋น„์–ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + @Size(max = 100, message = "๋‚ด์šฉ์€ 100์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + private String summary; + + public TemplateAdminUpdateReqDto(String categoryName, String gameName, int maxGamePeople, int minGamePeople, + int maxGameTime, int minGameTime, String genre, String difficulty, String summary) { + this.categoryName = categoryName; + this.gameName = gameName; + this.maxGamePeople = maxGamePeople; + this.minGamePeople = minGamePeople; + this.maxGameTime = maxGameTime; + this.minGameTime = minGameTime; + this.genre = genre; + this.difficulty = difficulty; + this.summary = summary; + } + + public void updateEntity(GameTemplate template) { + template.modifyTemplateDetails( + this.getGameName(), + this.getMaxGamePeople(), + this.getMinGamePeople(), + this.getMaxGameTime(), + this.getMinGameTime(), + this.getGenre(), + this.getDifficulty(), + this.getSummary() + ); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/service/TemplateAdminService.java b/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/service/TemplateAdminService.java new file mode 100644 index 000000000..b1c52050d --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/admin/templates/service/TemplateAdminService.java @@ -0,0 +1,69 @@ +package gg.party.api.admin.templates.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.data.party.Category; +import gg.data.party.GameTemplate; +import gg.party.api.admin.templates.controller.request.TemplateAdminCreateReqDto; +import gg.party.api.admin.templates.controller.request.TemplateAdminUpdateReqDto; +import gg.repo.party.CategoryRepository; +import gg.repo.party.TemplateRepository; +import gg.utils.exception.ErrorCode; +import gg.utils.exception.party.CategoryNotFoundException; +import gg.utils.exception.party.RoomMinMaxPeople; +import gg.utils.exception.party.TemplateNotFoundException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class TemplateAdminService { + private final TemplateRepository templateRepository; + private final CategoryRepository categoryRepository; + + /** + * ํ…œํ”Œ๋ฆฟ ์ถ”๊ฐ€ + * @exception CategoryNotFoundException ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์นดํ…Œ๊ณ ๋ฆฌ ์ž…๋ ฅ - 404 + */ + public void addTemplate(TemplateAdminCreateReqDto request) { + Category category = categoryRepository.findByName(request.getCategoryName()) + .orElseThrow(CategoryNotFoundException::new); + GameTemplate gameTemplate = TemplateAdminCreateReqDto.toEntity(request, category); + templateRepository.save(gameTemplate); + } + + /** + * ํ…œํ”Œ๋ฆฟ ์ˆ˜์ • + * @throws TemplateNotFoundException ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ…œํ”Œ๋ฆฟ ์ž…๋ ฅ - 404 + * @throws RoomMinMaxPeople ์ตœ์†Œ์ธ์›์ด ์ตœ๋Œ€์ธ์›๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ - 400 + * @throws CategoryNotFoundException ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์นดํ…Œ๊ณ ๋ฆฌ ์ž…๋ ฅ - 404 + */ + @Transactional + public void modifyTemplate(Long templateId, TemplateAdminUpdateReqDto request) { + GameTemplate template = templateRepository.findById(templateId) + .orElseThrow(TemplateNotFoundException::new); + if (request.getMaxGamePeople() < request.getMinGamePeople()) { + throw new RoomMinMaxPeople(ErrorCode.ROOM_MIN_MAX_PEOPLE); + } + request.updateEntity(template); + + if (request.getCategoryName() != null) { + Category newCategory = categoryRepository.findByName(request.getCategoryName()) + .orElseThrow(CategoryNotFoundException::new); + template.modifyCategory(newCategory); + } + templateRepository.save(template); + } + + /** + * ํ…œํ”Œ๋ฆฟ ์‚ญ์ œ + * @exception TemplateNotFoundException ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ…œํ”Œ๋ฆฟ ์ž…๋ ฅ - 404 + */ + @Transactional + public void removeTemplate(Long templateId) { + if (!templateRepository.existsById(templateId)) { + throw new TemplateNotFoundException(); + } + templateRepository.deleteById(templateId); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/category/controller/CategoryController.java b/gg-pingpong-api/src/main/java/gg/party/api/user/category/controller/CategoryController.java new file mode 100644 index 000000000..afaa07cc0 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/category/controller/CategoryController.java @@ -0,0 +1,27 @@ +package gg.party.api.user.category.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.party.api.user.category.controller.response.CategoryListResDto; +import gg.party.api.user.category.service.CategoryService; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/categories") +public class CategoryController { + private final CategoryService categoryService; + + /** + * ์นดํ…Œ๊ณ ๋ฆฌ ์กฐํšŒ + * @return ์นดํ…Œ๊ณ ๋ฆฌ ์ „์ฒด ๋ฆฌ์ŠคํŠธ + */ + @GetMapping + public ResponseEntity categoryList() { + return ResponseEntity.status(HttpStatus.OK).body(categoryService.findCategoryList()); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/category/controller/response/CategoryListResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/category/controller/response/CategoryListResDto.java new file mode 100644 index 000000000..daede31fd --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/category/controller/response/CategoryListResDto.java @@ -0,0 +1,16 @@ +package gg.party.api.user.category.controller.response; + +import java.util.List; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class CategoryListResDto { + private List categoryList; + + public CategoryListResDto(List categoryList) { + this.categoryList = categoryList; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/category/controller/response/CategoryResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/category/controller/response/CategoryResDto.java new file mode 100644 index 000000000..9ada2bb25 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/category/controller/response/CategoryResDto.java @@ -0,0 +1,17 @@ +package gg.party.api.user.category.controller.response; + +import gg.data.party.Category; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class CategoryResDto { + private Long categoryId; + private String categoryName; + + public CategoryResDto(Category category) { + this.categoryId = category.getId(); + this.categoryName = category.getName(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/category/service/CategoryService.java b/gg-pingpong-api/src/main/java/gg/party/api/user/category/service/CategoryService.java new file mode 100644 index 000000000..4f9167b6b --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/category/service/CategoryService.java @@ -0,0 +1,30 @@ +package gg.party.api.user.category.service; + +import java.util.stream.Collectors; + +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.party.api.user.category.controller.response.CategoryListResDto; +import gg.party.api.user.category.controller.response.CategoryResDto; +import gg.repo.party.CategoryRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class CategoryService { + private final CategoryRepository categoryRepository; + + /** + * ์นดํ…Œ๊ณ ๋ฆฌ ์ „์ฒด ์กฐํšŒ + * @return ์นดํ…Œ๊ณ ๋ฆฌ ์ „์ฒด ๋ฆฌ์ŠคํŠธ (id ์ˆœ์œผ๋กœ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ) + */ + @Transactional(readOnly = true) + public CategoryListResDto findCategoryList() { + return new CategoryListResDto(categoryRepository.findAll(Sort.by(Sort.Direction.ASC, "id")).stream() + .map(CategoryResDto::new) + .collect(Collectors.toList())); + } + +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/comment/controller/CommentController.java b/gg-pingpong-api/src/main/java/gg/party/api/user/comment/controller/CommentController.java new file mode 100644 index 000000000..503bce24e --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/comment/controller/CommentController.java @@ -0,0 +1,38 @@ +package gg.party.api.user.comment.controller; + +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; +import gg.party.api.user.comment.controller.request.CommentCreateReqDto; +import gg.party.api.user.comment.service.CommentService; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/rooms/{roomId}/comments") +public class CommentController { + + private final CommentService commentService; + + /** + * ๋Œ“๊ธ€ ์ƒ์„ฑ + * @param reqDto ๋Œ“๊ธ€ ์ •๋ณด + * @param roomId ๋ฐฉ ๋ฒˆํ˜ธ + * @return ์ƒ์„ฑ ์„ฑ๊ณต ์—ฌ๋ถ€ + */ + @PostMapping + public ResponseEntity createComment(@PathVariable Long roomId, @RequestBody @Valid CommentCreateReqDto reqDto, + @Login UserDto user) { + commentService.addCreateComment(roomId, reqDto, user.getId()); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/comment/controller/request/CommentCreateReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/comment/controller/request/CommentCreateReqDto.java new file mode 100644 index 000000000..81d5ade4d --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/comment/controller/request/CommentCreateReqDto.java @@ -0,0 +1,17 @@ +package gg.party.api.user.comment.controller.request; + +import javax.validation.constraints.Size; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class CommentCreateReqDto { + @Size(min = 1, max = 100) + private String content; + + public CommentCreateReqDto(String content) { + this.content = content; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/comment/service/CommentService.java b/gg-pingpong-api/src/main/java/gg/party/api/user/comment/service/CommentService.java new file mode 100644 index 000000000..e04808480 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/comment/service/CommentService.java @@ -0,0 +1,64 @@ +package gg.party.api.user.comment.service; + +import java.util.Optional; + +import javax.transaction.Transactional; + +import org.springframework.stereotype.Service; + +import gg.data.party.Comment; +import gg.data.party.PartyPenalty; +import gg.data.party.Room; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import gg.party.api.user.comment.controller.request.CommentCreateReqDto; +import gg.repo.party.CommentRepository; +import gg.repo.party.PartyPenaltyRepository; +import gg.repo.party.RoomRepository; +import gg.repo.party.UserRoomRepository; +import gg.repo.user.UserRepository; +import gg.utils.exception.party.OnPenaltyException; +import gg.utils.exception.party.RoomNotFoundException; +import gg.utils.exception.party.RoomNotOpenException; +import gg.utils.exception.party.RoomNotParticipantException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class CommentService { + private final CommentRepository commentRepository; + private final RoomRepository roomRepository; + private final UserRepository userRepository; + private final UserRoomRepository userRoomRepository; + private final PartyPenaltyRepository partyPenaltyRepository; + + /** + * ๋Œ“๊ธ€ ์ƒ์„ฑ + * @param roomId ๋ฐฉ ๋ฒˆํ˜ธ + * @throws RoomNotFoundException ๋ฐฉ์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ - 404 + * @throws RoomNotOpenException ๋ฐฉ์ด ์—ด๋ ค์žˆ์ง€ ์•Š์Œ - 400 + * @throws OnPenaltyException ํŒจ๋„ํ‹ฐ ์ƒํƒœ์˜ ์œ ์ € ์ž…๋ ฅ - 403 + * @throws RoomNotParticipantException ๋ฐฉ ์ฐธ๊ฐ€์ž๊ฐ€ ์•„๋‹˜ - 400 + * @param reqDto ๋Œ“๊ธ€ ์ •๋ณด + */ + @Transactional + public void addCreateComment(Long roomId, CommentCreateReqDto reqDto, Long userId) { + User user = userRepository.getById(userId); + Room room = roomRepository.findById(roomId).orElseThrow(RoomNotFoundException::new); + if (!room.getStatus().equals(RoomType.OPEN)) { + throw new RoomNotOpenException(); + } + + Optional partyPenalty = partyPenaltyRepository.findTopByUserIdOrderByStartTimeDesc(userId); + if (partyPenalty.isPresent() && PartyPenalty.isFreeFromPenalty(partyPenalty.get())) { + throw new OnPenaltyException(); + } + + UserRoom userRoom = userRoomRepository.findByUserIdAndRoomIdAndIsExistTrue(userId, roomId) + .orElseThrow(RoomNotParticipantException::new); + Comment comment = new Comment(user, userRoom, room, reqDto.getContent()); + commentRepository.save(comment); + } + +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/penalty/controller/PartyPenaltyController.java b/gg-pingpong-api/src/main/java/gg/party/api/user/penalty/controller/PartyPenaltyController.java new file mode 100644 index 000000000..6a75f86bb --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/penalty/controller/PartyPenaltyController.java @@ -0,0 +1,30 @@ +package gg.party.api.user.penalty.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; +import gg.party.api.user.penalty.controller.response.PenaltyResDto; +import gg.party.api.user.penalty.service.PartyPenaltyService; +import io.swagger.v3.oas.annotations.Parameter; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/penalty") +public class PartyPenaltyController { + private final PartyPenaltyService partyPenaltyService; + + /** + * ํ˜„์žฌ ์œ ์ €๊ฐ€ ํŒจ๋„ํ‹ฐ ์ƒํƒœ์ธ์ง€ ์กฐํšŒ + * @return ์–ธ์ œ๊นŒ์ง€ ํŒจ๋„ํ‹ฐ์ธ์ง€ DateTime์œผ๋กœ ๋ฆฌํ„ด + */ + @GetMapping + public ResponseEntity findPenalty(@Parameter(hidden = true) @Login UserDto user) { + return ResponseEntity.status(HttpStatus.OK).body(partyPenaltyService.findIsPenalty(user)); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/penalty/controller/response/PenaltyResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/penalty/controller/response/PenaltyResDto.java new file mode 100644 index 000000000..2f3050b57 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/penalty/controller/response/PenaltyResDto.java @@ -0,0 +1,19 @@ +package gg.party.api.user.penalty.controller.response; + +import java.time.LocalDateTime; + +import gg.data.party.PartyPenalty; +import lombok.Getter; + +@Getter +public class PenaltyResDto { + private LocalDateTime penaltyEndTime; + + public PenaltyResDto(PartyPenalty partyPenalty) { + this.penaltyEndTime = partyPenalty.getStartTime().plusMinutes(partyPenalty.getPenaltyTime()); + } + + public PenaltyResDto() { + this.penaltyEndTime = null; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/penalty/service/PartyPenaltyService.java b/gg-pingpong-api/src/main/java/gg/party/api/user/penalty/service/PartyPenaltyService.java new file mode 100644 index 000000000..2ab2e0a6a --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/penalty/service/PartyPenaltyService.java @@ -0,0 +1,33 @@ +package gg.party.api.user.penalty.service; + +import java.util.Optional; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.auth.UserDto; +import gg.data.party.PartyPenalty; +import gg.party.api.user.penalty.controller.response.PenaltyResDto; +import gg.repo.party.PartyPenaltyRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class PartyPenaltyService { + private final PartyPenaltyRepository partyPenaltyRepository; + + /** + * ํ˜„์žฌ ์œ ์ €๊ฐ€ ํŒจ๋„ํ‹ฐ ์ƒํƒœ์ธ์ง€ ์กฐํšŒ + * @return ์–ธ์ œ๊นŒ์ง€ ํŒจ๋„ํ‹ฐ์ธ์ง€ DateTime์œผ๋กœ ๋ฆฌํ„ด + */ + @Transactional + public PenaltyResDto findIsPenalty(UserDto userDto) { + Optional partyPenalty = partyPenaltyRepository.findTopByUserIdOrderByStartTimeDesc( + userDto.getId()); + if (partyPenalty.isPresent() && PartyPenalty.isFreeFromPenalty(partyPenalty.get())) { + return new PenaltyResDto(partyPenalty.get()); + } else { + return new PenaltyResDto(); + } + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/report/controller/ReportController.java b/gg-pingpong-api/src/main/java/gg/party/api/user/report/controller/ReportController.java new file mode 100644 index 000000000..ecf25c2fc --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/report/controller/ReportController.java @@ -0,0 +1,66 @@ +package gg.party.api.user.report.controller; + +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; +import gg.party.api.user.report.controller.request.ReportReqDto; +import gg.party.api.user.report.service.ReportService; +import io.swagger.v3.oas.annotations.Parameter; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/reports") +public class ReportController { + private final ReportService reportService; + + /** + * ๋ฐฉ์„ ์‹ ๊ณ ํ•œ๋‹ค. + * @param reportReqDto ์‹ ๊ณ  ๋‚ด์šฉ + * @param roomId ๋ฐฉ ๋ฒˆํ˜ธ + */ + @PostMapping("/rooms/{room_id}") + public ResponseEntity reportRoomAdd(@PathVariable("room_id") Long roomId, + @RequestBody @Valid ReportReqDto reportReqDto, + @Parameter(hidden = true) @Login UserDto user) { + reportService.addReportRoom(roomId, reportReqDto, user); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + /** + * ๋Œ“๊ธ€์„ ์‹ ๊ณ ํ•œ๋‹ค. + * @param reportReqDto ์‹ ๊ณ  ๋‚ด์šฉ + * @param commentId ๋Œ“๊ธ€ ๋ฒˆํ˜ธ + */ + @PostMapping("/comments/{comment_id}") + public ResponseEntity reportCommentAdd(@PathVariable("comment_id") Long commentId, + @RequestBody @Valid ReportReqDto reportReqDto, + @Parameter(hidden = true) @Login UserDto user) { + reportService.addReportComment(commentId, reportReqDto, user); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + /** + * ์œ ์ € ๋…ธ์‡ผ ์‹ ๊ณ ํ•œ๋‹ค. + * @param reportReqDto ์‹ ๊ณ  ๋‚ด์šฉ + * @param roomId ๋ฐฉ ๋ฒˆํ˜ธ + * @param userIntraId ์œ ์ € ์ธํŠธ๋ผ ์•„์ด๋”” + */ + @PostMapping("/rooms/{room_id}/users/{user_intra_id}") + public ResponseEntity reportUserAdd(@PathVariable("room_id") Long roomId, + @PathVariable("user_intra_id") String userIntraId, + @RequestBody @Valid ReportReqDto reportReqDto, + @Parameter(hidden = true) @Login UserDto user) { + reportService.addReportUser(roomId, reportReqDto, userIntraId, user); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/report/controller/request/ReportReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/report/controller/request/ReportReqDto.java new file mode 100644 index 000000000..2ef81cd72 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/report/controller/request/ReportReqDto.java @@ -0,0 +1,19 @@ +package gg.party.api.user.report.controller.request; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class ReportReqDto { + @NotBlank(message = "message๊ฐ€ ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค") + @Size(min = 1, max = 200, message = "message๋Š” ์ตœ์†Œ 1์—์„œ ์ตœ๋Œ€ 200์ž์ž…๋‹ˆ๋‹ค") + private String content; + + public ReportReqDto(String content) { + this.content = content; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/report/service/ReportService.java b/gg-pingpong-api/src/main/java/gg/party/api/user/report/service/ReportService.java new file mode 100644 index 000000000..fc60a6ad5 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/report/service/ReportService.java @@ -0,0 +1,209 @@ +package gg.party.api.user.report.service; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import javax.transaction.Transactional; + +import org.springframework.stereotype.Service; + +import gg.auth.UserDto; +import gg.data.party.Comment; +import gg.data.party.CommentReport; +import gg.data.party.PartyPenalty; +import gg.data.party.Room; +import gg.data.party.RoomReport; +import gg.data.party.UserReport; +import gg.data.party.UserRoom; +import gg.data.user.User; +import gg.party.api.user.report.controller.request.ReportReqDto; +import gg.repo.party.CommentReportRepository; +import gg.repo.party.CommentRepository; +import gg.repo.party.PartyPenaltyRepository; +import gg.repo.party.RoomReportRepository; +import gg.repo.party.RoomRepository; +import gg.repo.party.UserReportRepository; +import gg.repo.party.UserRoomRepository; +import gg.repo.user.UserRepository; +import gg.utils.exception.party.AlreadyReportedException; +import gg.utils.exception.party.CommentNotFoundException; +import gg.utils.exception.party.OnPenaltyException; +import gg.utils.exception.party.RoomNotFoundException; +import gg.utils.exception.party.RoomNotParticipantException; +import gg.utils.exception.party.SelfReportException; +import gg.utils.exception.user.UserNotFoundException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class ReportService { + private static final int COMMENT_PENALTY_TIME = 60; // ๋Œ“๊ธ€ ํŒจ๋„ํ‹ฐ ์‹œ๊ฐ„ (๋ถ„) + private static final int NO_SHOW_PENALTY_TIME = 360; // ๋…ธ์‡ผ ํŒจ๋„ํ‹ฐ ์‹œ๊ฐ„ (๋ถ„) + private static final int ROOM_PENALTY_TIME = 1440; // ๋ฐฉ ํŒจ๋„ํ‹ฐ ์‹œ๊ฐ„ (๋ถ„) + private final RoomRepository roomRepository; + private final CommentRepository commentRepository; + private final UserRepository userRepository; + private final RoomReportRepository roomReportRepository; + private final CommentReportRepository commentReportRepository; + private final PartyPenaltyRepository partyPenaltyRepository; + private final UserRoomRepository userRoomRepository; + private final UserReportRepository userReportRepository; + + /** + * ๋ฐฉ์„ ์‹ ๊ณ ํ•œ๋‹ค. + * @param roomId ๋ฐฉ ๋ฒˆํ˜ธ + * @param reportReqDto ์‹ ๊ณ  ๋‚ด์šฉ + * @param userDto ์‹ ๊ณ ์ž + * @throws OnPenaltyException ํŒจ๋„ํ‹ฐ ์ƒํƒœ์˜ ์œ ์ € ์ž…๋ ฅ - 403 + * @throws RoomNotFoundException ๋ฐฉ์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ - 404 + * @throws AlreadyReportedException ์ด๋ฏธ ์‹ ๊ณ ํ•œ ๊ฒฝ์šฐ - 409 + * @throws SelfReportException ์ž์‹ ์„ ์‹ ๊ณ ํ•œ ๊ฒฝ์šฐ - 400 + */ + @Transactional + public void addReportRoom(Long roomId, ReportReqDto reportReqDto, UserDto userDto) { + User user = userRepository.getById(userDto.getId()); + Optional partyPenalty = partyPenaltyRepository.findTopByUserIdOrderByStartTimeDesc(user.getId()); + if (partyPenalty.isPresent() && PartyPenalty.isFreeFromPenalty(partyPenalty.get())) { + throw new OnPenaltyException(); + } + Room targetRoom = roomRepository.findById(roomId) + .orElseThrow(RoomNotFoundException::new); + if (Objects.equals(user.getId(), targetRoom.getCreator().getId())) { + throw new SelfReportException(); + } + roomReportRepository.findByReporterAndRoomId(user, targetRoom.getId()) + .ifPresent(report -> { + throw new AlreadyReportedException(); + }); + RoomReport roomReport = new RoomReport(user, targetRoom.getCreator(), targetRoom, + reportReqDto.getContent()); + roomReportRepository.save(roomReport); + + List allReportRoom = roomReportRepository.findByRoomId(targetRoom.getId()); + if (allReportRoom.size() == 5) { + targetRoom.roomHidden(); + roomRepository.save(targetRoom); + User targetUser = targetRoom.getCreator(); + partyGivePenalty(targetUser.getIntraId(), ROOM_PENALTY_TIME, "๋ฐฉ ํŒจ๋„ํ‹ฐ"); + } + } + + /** + * ๋Œ“๊ธ€์„ ์‹ ๊ณ ํ•œ๋‹ค. + * @param commentId ๋ฐฉ ๋ฒˆํ˜ธ + * @param reportReqDto ์‹ ๊ณ  ๋‚ด์šฉ + * @param userDto ์‹ ๊ณ ์ž + * @throws UserNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ์œ ์ € ์ž…๋ ฅ - 404 + * @throws OnPenaltyException ํŒจ๋„ํ‹ฐ ์ƒํƒœ์˜ ์œ ์ € ์ž…๋ ฅ - 403 + * @throws RoomNotFoundException ๋ฐฉ์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ - 404 + * @throws CommentNotFoundException ๋Œ“๊ธ€์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ - 404 + * @throws AlreadyReportedException ์ด๋ฏธ ์‹ ๊ณ ํ•œ ๊ฒฝ์šฐ - 409 + * @throws SelfReportException ์ž์‹ ์„ ์‹ ๊ณ ํ•œ ๊ฒฝ์šฐ - 400 + */ + @Transactional + public void addReportComment(Long commentId, ReportReqDto reportReqDto, UserDto userDto) { + User user = userRepository.findById(userDto.getId()).orElseThrow(UserNotFoundException::new); + Optional partyPenalty = partyPenaltyRepository.findTopByUserIdOrderByStartTimeDesc(user.getId()); + if (partyPenalty.isPresent() && PartyPenalty.isFreeFromPenalty(partyPenalty.get())) { + throw new OnPenaltyException(); + } + Comment targetComment = commentRepository.findById(commentId) + .orElseThrow(CommentNotFoundException::new); + if (Objects.equals(user.getId(), targetComment.getUser().getId())) { + throw new SelfReportException(); + } + commentReportRepository.findByReporterAndCommentId(user, targetComment.getId()) + .ifPresent(reporter -> { + throw new AlreadyReportedException(); + }); + Room targetRoom = roomRepository.findById(targetComment.getRoom().getId()) + .orElseThrow(RoomNotFoundException::new); + CommentReport commentReport = new CommentReport(user, targetComment, targetRoom, + reportReqDto.getContent()); + commentReportRepository.save(commentReport); + + List allReportComment = commentReportRepository.findByCommentId(targetComment.getId()); + if (allReportComment.size() == 3) { + targetComment.updateHidden(true); + commentRepository.save(targetComment); + User targetUser = targetComment.getUser(); + partyGivePenalty(targetUser.getIntraId(), COMMENT_PENALTY_TIME, "๋Œ“๊ธ€ ํŒจ๋„ํ‹ฐ"); + } + } + + /** + * ์œ ์ € ๋…ธ์‡ผ ์‹ ๊ณ ํ•œ๋‹ค. + * @param roomId ๋ฐฉ ๋ฒˆํ˜ธ + * @param reportReqDto ์‹ ๊ณ  ๋‚ด์šฉ + * @param user ์‹ ๊ณ ์ž + * @param userIntraId ํ”ผ์‹ ๊ณ ์ž + * @throws CommentNotFoundException ๋ฐฉ์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ - 404 + * @throws AlreadyReportedException ์ด๋ฏธ ์‹ ๊ณ ํ•œ ๊ฒฝ์šฐ - 409 + * @throws RoomNotParticipantException ๋ฐฉ์— ์ฐธ์—ฌํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ - 400 + * @throws SelfReportException ์ž์‹ ์„ ์‹ ๊ณ ํ•œ ๊ฒฝ์šฐ - 400 + */ + @Transactional + public void addReportUser(Long roomId, ReportReqDto reportReqDto, String userIntraId, UserDto user) { + // ์‹ ๊ณ ์ž์™€ ํ”ผ์‹ ๊ณ ์ž๊ฐ€ ๊ฐ™์€ ๊ฒฝ์šฐ + if (Objects.equals(user.getIntraId(), userIntraId)) { + throw new SelfReportException(); + } + // ์‹ ๊ณ ์ž์™€ ํ”ผ์‹ ๊ณ ์ž๊ฐ€ ๊ฐ™์€ ๋ฐฉ์— ์žˆ๋Š”์ง€ ํ™•์ธ + User reporteeEntity = userRepository.getUserByIntraId(userIntraId) + .orElseThrow(UserNotFoundException::new); + UserRoom reporterUserRoom = userRoomRepository.findByUserIdAndRoomIdAndIsExistTrue(user.getId(), roomId) + .orElseThrow(RoomNotParticipantException::new); + userRoomRepository.findByUserIdAndRoomIdAndIsExistTrue(reporteeEntity.getId(), roomId) + .orElseThrow(RoomNotParticipantException::new); + User reporterEntity = reporterUserRoom.getUser(); + Room targetRoom = reporterUserRoom.getRoom(); + if (targetRoom == null) { + throw new RoomNotFoundException(); + } + // ์ด๋ฏธ ์‹ ๊ณ ํ•œ ๊ฒฝ์šฐ + userReportRepository.findByReporterAndReporteeAndRoom(reporterEntity, reporteeEntity, targetRoom) + .ifPresent(userReport -> { + throw new AlreadyReportedException(); + }); + // ์‹ ๊ณ  ์ €์žฅ + UserReport userReport = new UserReport(reporterEntity, reporteeEntity, targetRoom, reportReqDto.getContent()); + userReportRepository.save(userReport); + // ๋…ธ์‡ผ ํŒจ๋„ํ‹ฐ ํŒ๋‹จ + List allReportUser = userReportRepository.findByReporteeAndRoomId(reporteeEntity, roomId); + if (allReportUser.size() == targetRoom.getCurrentPeople() / 2) { + partyGivePenalty(reporteeEntity.getIntraId(), NO_SHOW_PENALTY_TIME, "๋…ธ์‡ผ ํŒจ๋„ํ‹ฐ"); + } + } + + /** + * ํŒจ๋„ํ‹ฐ ๋ถ€์—ฌ + * @param intraId ์‹ ๊ณ ๋‹นํ•œ ์œ ์ € ์•„์ด๋”” + * @param penaltyTime ํŒจ๋„ํ‹ฐ ์‹œ๊ฐ„ + * @param penaltyType ํŒจ๋„ํ‹ฐ ํƒ€์ž… + * @throws UserNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ์œ ์ € ์ž…๋ ฅ - 404 + */ + @Transactional + public void partyGivePenalty(String intraId, Integer penaltyTime, String penaltyType) { + User user = userRepository.getUserByIntraId(intraId).orElseThrow(UserNotFoundException::new); + Optional pPenalty = partyPenaltyRepository.findTopByUserIdOrderByStartTimeDesc(user.getId()); + + if (pPenalty.isPresent() && LocalDateTime.now().isBefore(pPenalty.get().getStartTime() + .plusMinutes(pPenalty.get().getPenaltyTime()))) { + LocalDateTime dueDate = pPenalty.get().getStartTime().plusMinutes(pPenalty.get().getPenaltyTime()); + partyPenaltyRepository.save(new PartyPenalty( + user, penaltyType, penaltyType, dueDate, penaltyTime)); + } else { + partyPenaltyRepository.save(new PartyPenalty( + user, penaltyType, penaltyType, LocalDateTime.now(), penaltyTime)); + List userRoomList = userRoomRepository.findOpenRoomsByUserId(user.getId()); + for (Room room : userRoomList) { + UserRoom userRoom = userRoomRepository.findByUserIdAndRoomIdAndIsExistTrue(user.getId(), room.getId()) + .orElseThrow(RoomNotFoundException::new); + userRoom.updateIsExist(false); + userRoomRepository.save(userRoom); + } + } + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/RoomController.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/RoomController.java new file mode 100644 index 000000000..1934911c1 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/RoomController.java @@ -0,0 +1,126 @@ +package gg.party.api.user.room.controller; + +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; +import gg.party.api.user.room.controller.request.RoomCreateReqDto; +import gg.party.api.user.room.controller.response.LeaveRoomResDto; +import gg.party.api.user.room.controller.response.RoomCreateResDto; +import gg.party.api.user.room.controller.response.RoomDetailResDto; +import gg.party.api.user.room.controller.response.RoomJoinResDto; +import gg.party.api.user.room.controller.response.RoomListResDto; +import gg.party.api.user.room.controller.response.RoomStartResDto; +import gg.party.api.user.room.service.RoomFindService; +import gg.party.api.user.room.service.RoomManagementService; +import io.swagger.v3.oas.annotations.Parameter; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/rooms") +public class RoomController { + private final RoomFindService roomFindService; + private final RoomManagementService roomManagementService; + + /** + * ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ๋ฐฉ๊ณผ ์‹œ์ž‘ํ•œ ๋ฐฉ์„ ๋ชจ๋‘ ์กฐํšŒํ•œ๋‹ค + * @return ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ๋ฐฉ (์ตœ์‹ ์ˆœ) + ์‹œ์ž‘ํ•œ ๋ฐฉ(๋๋‚˜๋Š” ์‹œ๊ฐ„์ด ๋น ๋ฅธ ์ˆœ) ์ „์ฒด List - 200 + */ + @GetMapping + public ResponseEntity allActiveRoomList() { + RoomListResDto roomListResDto = roomFindService.findRoomList(); + return ResponseEntity.status(HttpStatus.OK).body(roomListResDto); + } + + /** + * ์ฐธ์—ฌ์ค‘์ธ ๋ฐฉ์„ ๋ชจ๋‘ ์กฐํšŒํ•œ๋‹ค(๋งŒ๋“  ๋ฐฉ ํฌํ•จ) + * @return ์ฐธ์—ฌ์ค‘์ธ ๋ฐฉ ์ „์ฒด List + */ + @GetMapping("/joined") + public ResponseEntity allJoinedRoomList(@Parameter(hidden = true) @Login UserDto user) { + RoomListResDto roomListResDto = roomFindService.findJoinedRoomList(user.getId()); + return ResponseEntity.status(HttpStatus.OK).body(roomListResDto); + } + + /** + * ์‹œ๊ฐ„์ด ์ง€๋‚˜ ๋ณด์ด์ง€ ์•Š๊ฒŒ ๋œ ๋‚ด๊ฐ€ ํ”Œ๋ ˆ์ดํ•œ(์‹œ์ž‘ํ•œ) ๋ฐฉ์„ ๋ชจ๋‘ ์กฐํšŒํ•œ๋‹ค + * @return ๋๋‚œ ๋ฐฉ ์ „์ฒด List + */ + @GetMapping("/history") + public ResponseEntity myHistoryRoomList(@Parameter(hidden = true) @Login UserDto user) { + RoomListResDto roomListResDto = roomFindService.findMyHistoryRoomList(user.getId()); + return ResponseEntity.status(HttpStatus.OK).body(roomListResDto); + } + + /** + * ๋ฐฉ์˜ ์ƒ์„ธ์ •๋ณด๋ฅผ ์กฐํšŒํ•œ๋‹ค + * @param roomId ๋ฐฉ id + * ์ต๋ช…์„ฑ์„ ์ง€ํ‚ค๊ธฐ ์œ„ํ•ด nickname์„ ๋ฆฌํ„ด + * @return ๋ฐฉ ์ƒ์„ธ์ •๋ณด dto + */ + @GetMapping("/{room_id}") + public ResponseEntity roomDetailInfo(@Parameter(hidden = true) @Login UserDto user, + @PathVariable("room_id") Long roomId) { + RoomDetailResDto roomDetailResDto = roomFindService.findRoomDetail(user.getId(), roomId); + return ResponseEntity.status(HttpStatus.OK).body(roomDetailResDto); + } + + /** + * ๋ฐฉ ๋งŒ๋“ค๊ธฐ + * @param roomCreateReqDto ์š”์ฒญ Dto + * @param user ์‚ฌ์šฉ์ž + * @return ์ƒ์„ฑ๋œ roomId - 201 + */ + @PostMapping + public ResponseEntity createRoom(@RequestBody @Valid RoomCreateReqDto roomCreateReqDto, + @Parameter(hidden = true) @Login UserDto user) { + RoomCreateResDto roomCreateResDto = roomManagementService.addCreateRoom(roomCreateReqDto, user); + return ResponseEntity.status(HttpStatus.CREATED).body(roomCreateResDto); + } + + /** + * ๋ฐฉ ๋‚˜๊ฐ€๊ธฐ + * @param roomId ๋ฐฉ id + * @param user ์œ ์ € ์ •๋ณด + * @return roomId + */ + @PatchMapping("/{room_id}") + public ResponseEntity leaveRoom(@PathVariable("room_id") Long roomId, + @Parameter(hidden = true) @Login UserDto user) { + return ResponseEntity.status(HttpStatus.OK).body(roomManagementService.modifyLeaveRoom(roomId, user)); + } + + /** + * ๋ฐฉ ์‹œ์ž‘ํ•˜๊ธฐ + * @return ๋ฐฉ id + */ + @PostMapping("/{room_id}/start") + public ResponseEntity startRoom(@PathVariable("room_id") Long roomId, + @Parameter(hidden = true) @Login UserDto user) { + return ResponseEntity.status(HttpStatus.CREATED).body(roomManagementService.modifyStartRoom(roomId, user)); + } + + /** + * ๋ฐฉ์— ์ฐธ์—ฌํ•œ๋‹ค + * @param roomId ๋ฐฉ id + * @param user ์œ ์ € ์ •๋ณด + * @return roomId + */ + @PostMapping("/{room_id}") + public ResponseEntity joinRoom(@Parameter(hidden = true) @Login UserDto user, + @PathVariable("room_id") Long roomId) { + RoomJoinResDto roomJoinResDto = roomManagementService.addJoinRoom(roomId, user); + return ResponseEntity.status(HttpStatus.CREATED).body(roomJoinResDto); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/request/RoomCreateReqDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/request/RoomCreateReqDto.java new file mode 100644 index 000000000..9efb5b7ae --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/request/RoomCreateReqDto.java @@ -0,0 +1,51 @@ +package gg.party.api.user.room.controller.request; + +import java.time.LocalDateTime; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; + +import gg.data.party.Category; +import gg.data.party.Room; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@AllArgsConstructor +public class RoomCreateReqDto { + @Size(min = 1, max = 15) + private String title; + @Size(min = 1, max = 100) + private String content; + @Size(min = 1, max = 10) + private String categoryName; + @Min(2) + @Max(8) + private Integer maxPeople; + @Min(1) + @Max(8) + private Integer minPeople; + @Min(1) + @Max(13 * 60) + private Integer openPeriod; + + public static Room toEntity(RoomCreateReqDto dto, User user, Category category) { + return Room.builder() + .host(user) + .creator(user) + .category(category) + .title(dto.getTitle()) + .content(dto.getContent()) + .currentPeople(1) + .maxPeople(dto.getMaxPeople()) + .minPeople(dto.getMinPeople()) + .dueDate(LocalDateTime.now().plusMinutes(dto.getOpenPeriod())) + .status(RoomType.OPEN) + .build(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/CommentResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/CommentResDto.java new file mode 100644 index 000000000..97988cc71 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/CommentResDto.java @@ -0,0 +1,39 @@ +package gg.party.api.user.room.controller.response; + +import java.time.LocalDateTime; + +import gg.data.party.Comment; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class CommentResDto { + private Long commentId; + private String nickname; + private String intraId; + private Boolean isExist; + private String content; + private Boolean isHidden; + private LocalDateTime createDate; + + public CommentResDto(Comment comment, String intraId) { + this.commentId = comment.getId(); + this.nickname = comment.getUserRoom().getNickname(); + this.intraId = intraId; + this.isExist = comment.getUserRoom().getIsExist(); + this.content = comment.getContent(); + this.isHidden = comment.isHidden(); + this.createDate = comment.getCreatedAt(); + } + + public CommentResDto(Comment comment) { + this.commentId = comment.getId(); + this.nickname = comment.getUserRoom().getNickname(); + this.intraId = null; + this.isExist = comment.getUserRoom().getIsExist(); + this.content = comment.getContent(); + this.isHidden = comment.isHidden(); + this.createDate = comment.getCreatedAt(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/LeaveRoomResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/LeaveRoomResDto.java new file mode 100644 index 000000000..a53ff0abb --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/LeaveRoomResDto.java @@ -0,0 +1,14 @@ +package gg.party.api.user.room.controller.response; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class LeaveRoomResDto { + private String nickname; + + public LeaveRoomResDto(String nickname) { + this.nickname = nickname; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomCreateResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomCreateResDto.java new file mode 100644 index 000000000..696353964 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomCreateResDto.java @@ -0,0 +1,14 @@ +package gg.party.api.user.room.controller.response; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class RoomCreateResDto { + private Long roomId; + + public RoomCreateResDto(Long roomId) { + this.roomId = roomId; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomDetailResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomDetailResDto.java new file mode 100644 index 000000000..6afba6241 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomDetailResDto.java @@ -0,0 +1,47 @@ +package gg.party.api.user.room.controller.response; + +import java.time.LocalDateTime; +import java.util.List; + +import gg.data.party.Room; +import gg.data.party.type.RoomType; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class RoomDetailResDto { + private Long roomId; + private String title; + private String content; + private String categoryName; + private Integer currentPeople; + private Integer minPeople; + private Integer maxPeople; + private RoomType status; + private LocalDateTime dueDate; + private LocalDateTime createDate; + private String myNickname; + private String hostNickname; + private List roomUsers; + private List comments; + + public RoomDetailResDto(Room room, String myNickname, String hostNickname, + List roomUsers, + List comments) { + this.roomId = room.getId(); + this.title = room.getTitle(); + this.content = room.getContent(); + this.categoryName = room.getCategory().getName(); + this.currentPeople = room.getCurrentPeople(); + this.minPeople = room.getMinPeople(); + this.maxPeople = room.getMaxPeople(); + this.status = room.getStatus(); + this.dueDate = room.getDueDate(); + this.createDate = room.getCreatedAt(); + this.myNickname = myNickname; + this.hostNickname = hostNickname; + this.roomUsers = roomUsers; + this.comments = comments; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomJoinResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomJoinResDto.java new file mode 100644 index 000000000..478b7ab13 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomJoinResDto.java @@ -0,0 +1,14 @@ +package gg.party.api.user.room.controller.response; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class RoomJoinResDto { + private Long roomId; + + public RoomJoinResDto(Long roomId) { + this.roomId = roomId; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomListResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomListResDto.java new file mode 100644 index 000000000..19e0e081a --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomListResDto.java @@ -0,0 +1,16 @@ +package gg.party.api.user.room.controller.response; + +import java.util.List; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class RoomListResDto { + private List roomList; + + public RoomListResDto(List roomList) { + this.roomList = roomList; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomResDto.java new file mode 100644 index 000000000..29fb4a92a --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomResDto.java @@ -0,0 +1,37 @@ +package gg.party.api.user.room.controller.response; + +import java.time.LocalDateTime; + +import gg.data.party.Room; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class RoomResDto { + private Long roomId; + private String categoryName; + private String title; + private String content; + private Integer currentPeople; + private Integer maxPeople; + private Integer minPeople; + private LocalDateTime dueDate; + private LocalDateTime createDate; + private LocalDateTime startDate; + private String status; + + public RoomResDto(Room room) { + this.roomId = room.getId(); + this.categoryName = room.getCategory().getName(); + this.title = room.getTitle(); + this.content = room.getContent(); + this.currentPeople = room.getCurrentPeople(); + this.maxPeople = room.getMaxPeople(); + this.minPeople = room.getMinPeople(); + this.dueDate = room.getDueDate(); + this.createDate = room.getCreatedAt(); + this.startDate = room.getStartDate(); + this.status = room.getStatus().toString(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomStartResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomStartResDto.java new file mode 100644 index 000000000..7a557d927 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/RoomStartResDto.java @@ -0,0 +1,14 @@ +package gg.party.api.user.room.controller.response; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class RoomStartResDto { + private Long roomId; + + public RoomStartResDto(Long roomId) { + this.roomId = roomId; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/UserRoomResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/UserRoomResDto.java new file mode 100644 index 000000000..90c042390 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/controller/response/UserRoomResDto.java @@ -0,0 +1,28 @@ +package gg.party.api.user.room.controller.response; + +import gg.data.party.UserRoom; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class UserRoomResDto { + private Long roomUserId; + private String nickname; + private String intraId; + private String userImage; + + public UserRoomResDto(UserRoom userRoom) { + this.roomUserId = userRoom.getId(); + this.nickname = userRoom.getNickname(); + this.intraId = null; + this.userImage = null; + } + + public UserRoomResDto(UserRoom userRoom, String intraId, String userImage) { + this.roomUserId = userRoom.getId(); + this.nickname = userRoom.getNickname(); + this.intraId = intraId; + this.userImage = userImage; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/service/RoomFindService.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/service/RoomFindService.java new file mode 100644 index 000000000..36d2ddb5a --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/service/RoomFindService.java @@ -0,0 +1,177 @@ +package gg.party.api.user.room.service; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.data.party.Room; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.party.api.user.room.controller.response.CommentResDto; +import gg.party.api.user.room.controller.response.RoomDetailResDto; +import gg.party.api.user.room.controller.response.RoomListResDto; +import gg.party.api.user.room.controller.response.RoomResDto; +import gg.party.api.user.room.controller.response.UserRoomResDto; +import gg.repo.party.CommentRepository; +import gg.repo.party.RoomRepository; +import gg.repo.party.UserRoomRepository; +import gg.utils.exception.party.RoomNotFoundException; +import gg.utils.exception.party.RoomReportedException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class RoomFindService { + private final RoomRepository roomRepository; + private final UserRoomRepository userRoomRepository; + private final CommentRepository commentRepository; + + /** + * ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ๋ฐฉ๊ณผ ์‹œ์ž‘ํ•œ ๋ฐฉ์„ ๋ชจ๋‘ ์กฐํšŒํ•œ๋‹ค + * @return ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ๋ฐฉ (์ตœ์‹ ์ˆœ) + ์‹œ์ž‘ํ•œ ๋ฐฉ(๋๋‚˜๋Š” ์‹œ๊ฐ„์ด ๋น ๋ฅธ ์ˆœ) ์ „์ฒด List + */ + @Transactional(readOnly = true) + public RoomListResDto findRoomList() { + List statuses = Arrays.asList(RoomType.OPEN, RoomType.START, RoomType.FINISH); + List rooms = roomRepository.findByStatusIn(statuses); + + List openRooms = rooms.stream() + .filter(room -> room.getStatus().equals(RoomType.OPEN)) + .sorted(Comparator.comparing(Room::getCreatedAt).reversed()) + .collect(Collectors.toList()); + + List startRooms = rooms.stream() + .filter(room -> room.getStatus().equals(RoomType.START)) + .sorted(Comparator.comparing(Room::getStartDate).reversed()) + .collect(Collectors.toList()); + + List finishRooms = rooms.stream() + .filter(room -> room.getStatus().equals(RoomType.FINISH)) + .sorted(Comparator.comparing(Room::getStartDate).reversed()) + .limit(10) + .collect(Collectors.toList()); + + List combinedRooms = Stream.of(openRooms, startRooms, finishRooms) + .flatMap(List::stream) + .collect(Collectors.toList()); + + List roomListResDto = combinedRooms.stream() + .map(RoomResDto::new) + .collect(Collectors.toList()); + + return new RoomListResDto(roomListResDto); + } + + /** + * ํ˜„์žฌ ์ฐธ์—ฌ์ค‘์ธ ๋ฐฉ์„ ๋ชจ๋‘ ์กฐํšŒํ•œ๋‹ค(๋งŒ๋“  ๋ฐฉ ํฌํ•จ) + * ์‹œ์ž‘ํ•œ ๋ฐฉ ๋’ค์— ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ๋ฐฉ์ด ์˜ค๊ฒŒ ์ž‘์„ฑ + * @param userId ์ž์‹ ์˜ id + * @return ์ฐธ์—ฌํ•œ ๋ฐฉ ์ „์ฒด List + */ + @Transactional(readOnly = true) + public RoomListResDto findJoinedRoomList(Long userId) { + List userRooms = userRoomRepository.findByUserIdAndIsExistTrue(userId); + List joinedRooms = userRooms.stream() + .map(UserRoom::getRoom) + .collect(Collectors.toList()); + + List openRoom = joinedRooms.stream() + .filter(room -> room.getStatus().equals(RoomType.OPEN)) + .sorted(Comparator.comparing(Room::getDueDate)) + .collect(Collectors.toList()); + + List startRoom = joinedRooms.stream() + .filter(room -> room.getStatus().equals(RoomType.START)) + .sorted(Comparator.comparing(Room::getStartDate)) + .collect(Collectors.toList()); + + openRoom.addAll(startRoom); + + List roomListResDto = openRoom.stream() + .map(RoomResDto::new) + .collect(Collectors.toList()); + + return new RoomListResDto(roomListResDto); + } + + /** + * ์‹œ๊ฐ„์ด ์ง€๋‚˜ ๋ณด์ด์ง€ ์•Š๊ฒŒ ๋œ ๋‚ด๊ฐ€ ํ”Œ๋ ˆ์ดํ•œ(FINISH) ๋ฐฉ์„ ๋ชจ๋‘ ์กฐํšŒํ•œ๋‹ค + * @param userId ์ž์‹ ์˜ id + * isExist์ด true(๋‚˜๊ฐ€์ง€ ์•Š์•˜์Œ)์ด๋ฉด์„œ status๊ฐ€ FINISH์ธ ๊ฒฝ์šฐ + * @return ์‹œ์ž‘์‹œ๊ฐ„์œผ๋กœ ์ •๋ ฌ๋œ ๋๋‚œ ๋ฐฉ ์ „์ฒด List + */ + @Transactional(readOnly = true) + public RoomListResDto findMyHistoryRoomList(Long userId) { + List finishRooms = userRoomRepository.findByUserIdAndStatusAndIsExistTrue(userId, RoomType.FINISH); + + List roomListResDto = finishRooms.stream() + .sorted(Comparator.comparing(Room::getStartDate)) + .map(RoomResDto::new) + .collect(Collectors.toList()); + + return new RoomListResDto(roomListResDto); + } + + /** + * ๋ฐฉ์˜ ์ƒ์„ธ์ •๋ณด๋ฅผ ์กฐํšŒํ•œ๋‹ค + * @param userId ์ž์‹ ์˜ id + * @param roomId ๋ฐฉ id + * @return ๋ฐฉ ์ƒ์„ธ์ •๋ณด dto + * @throws RoomNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฐฉ ์ž…๋ ฅ - 404 + * @throws RoomReportedException ์‹ ๊ณ  ๋ฐ›์€ ๋ฐฉ ์ฒ˜๋ฆฌ - 403 + * ์ต๋ช…์„ฑ์„ ์ง€ํ‚ค๊ธฐ ์œ„ํ•ด nickname์„ ๋ฆฌํ„ด + */ + @Transactional(readOnly = true) + public RoomDetailResDto findRoomDetail(Long userId, Long roomId) { + Room room = roomRepository.findById(roomId).orElseThrow(RoomNotFoundException::new); + if (room.getStatus().equals(RoomType.HIDDEN)) { + throw new RoomReportedException(); + } + + Optional userRoomOptional = userRoomRepository.findByUserIdAndRoomIdAndIsExistTrue(userId, roomId); + + String myNickname = userRoomOptional.stream() + .map(UserRoom::getNickname) + .findFirst() + .orElse(null); + + Optional hostUserRoom = userRoomRepository.findByUserIdAndRoomIdAndIsExistTrue(room.getHost().getId(), + roomId); + String hostNickname = hostUserRoom.stream() + .map(UserRoom::getNickname) + .findFirst() + .orElse(null); + + if ((room.getStatus().equals(RoomType.START) || room.getStatus().equals(RoomType.FINISH)) + && userRoomOptional.isPresent()) { + List roomUsers = userRoomRepository.findByRoomIdAndIsExistTrue(roomId).stream() + .map(userRoom -> new UserRoomResDto(userRoom, userRoom.getUser().getIntraId(), + userRoom.getUser().getImageUri())) + .collect(Collectors.toList()); + + List comments = commentRepository.findAllWithCommentFetchJoin(roomId).stream() + .filter(comment -> !comment.isHidden()) + .map(comment -> new CommentResDto(comment, comment.getUser().getIntraId())) + .collect(Collectors.toList()); + + return new RoomDetailResDto(room, myNickname, hostNickname, roomUsers, comments); + } else { // if ์ฐธ์—ฌ์ž && Start or Finish ์ƒํƒœ์ธ ๊ฒฝ์šฐ intraID ์ œ๊ณต || else intraId == null + List roomUsers = userRoomRepository.findByRoomIdAndIsExistTrue(roomId).stream() + .map(UserRoomResDto::new) + .collect(Collectors.toList()); + + List comments = commentRepository.findAllWithCommentFetchJoin(roomId).stream() + .filter(comment -> !comment.isHidden()) + .map(CommentResDto::new) + .collect(Collectors.toList()); + + return new RoomDetailResDto(room, myNickname, hostNickname, roomUsers, comments); + } + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/service/RoomManagementService.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/service/RoomManagementService.java new file mode 100644 index 000000000..1a485b769 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/service/RoomManagementService.java @@ -0,0 +1,212 @@ +package gg.party.api.user.room.service; + +import static gg.party.api.user.room.utils.GenerateRandomNickname.*; + +import java.util.List; +import java.util.Optional; + +import javax.transaction.Transactional; + +import org.springframework.stereotype.Service; + +import gg.auth.UserDto; +import gg.data.party.Category; +import gg.data.party.PartyPenalty; +import gg.data.party.Room; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import gg.party.api.user.room.controller.request.RoomCreateReqDto; +import gg.party.api.user.room.controller.response.LeaveRoomResDto; +import gg.party.api.user.room.controller.response.RoomCreateResDto; +import gg.party.api.user.room.controller.response.RoomJoinResDto; +import gg.party.api.user.room.controller.response.RoomStartResDto; +import gg.pingpong.api.user.noti.service.PartyNotiService; +import gg.repo.party.CategoryRepository; +import gg.repo.party.PartyPenaltyRepository; +import gg.repo.party.RoomRepository; +import gg.repo.party.UserRoomRepository; +import gg.repo.user.UserRepository; +import gg.utils.exception.ErrorCode; +import gg.utils.exception.party.CategoryNotFoundException; +import gg.utils.exception.party.OnPenaltyException; +import gg.utils.exception.party.RoomMinMaxPeople; +import gg.utils.exception.party.RoomNotEnoughPeopleException; +import gg.utils.exception.party.RoomNotFoundException; +import gg.utils.exception.party.RoomNotOpenException; +import gg.utils.exception.party.RoomNotParticipantException; +import gg.utils.exception.party.UserAlreadyInRoom; +import gg.utils.exception.party.UserNotHostException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class RoomManagementService { + private final RoomRepository roomRepository; + private final UserRepository userRepository; + private final CategoryRepository categoryRepository; + private final UserRoomRepository userRoomRepository; + private final PartyPenaltyRepository partyPenaltyRepository; + private final PartyNotiService partyNotiService; + + /** + * ๋ฐฉ ์ƒ์„ฑํ•˜๊ณ  ๋‹‰๋„ค์ž„ ๋ถ€์—ฌ + * @param roomCreateReqDto ์š”์ฒญ DTO + * @param userDto user๊ฐ์ฒด๋ฅผ ๋ณด๋‚ด๊ธฐ ์œ„ํ•œ DTO๊ฐ์ฒด + * @throws OnPenaltyException ํŒจ๋„ํ‹ฐ ์ƒํƒœ์˜ ์œ ์ € ์ž…๋ ฅ - 403 + * @throws RoomMinMaxPeople ์ตœ์†Œ์ธ์›์ด ์ตœ๋Œ€์ธ์›๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ - 400 + * @throws CategoryNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ์นดํ…Œ๊ณ ๋ฆฌ ์ž…๋ ฅ - 404 + * @return ๋งŒ๋“ค์–ด์ง„ ๋ฐฉ ID๊ฐ’ + */ + @Transactional + public RoomCreateResDto addCreateRoom(RoomCreateReqDto roomCreateReqDto, UserDto userDto) { + User user = userRepository.getById(userDto.getId()); + Optional partyPenalty = partyPenaltyRepository.findTopByUserIdOrderByStartTimeDesc(user.getId()); + if (partyPenalty.isPresent() && PartyPenalty.isFreeFromPenalty(partyPenalty.get())) { + throw new OnPenaltyException(); + } + if (roomCreateReqDto.getMaxPeople() < roomCreateReqDto.getMinPeople()) { + throw new RoomMinMaxPeople(ErrorCode.ROOM_MIN_MAX_PEOPLE); + } + Category category = categoryRepository.findByName(roomCreateReqDto.getCategoryName()) + .orElseThrow(CategoryNotFoundException::new); + Room room = roomRepository.save(RoomCreateReqDto.toEntity(roomCreateReqDto, user, category)); + + String randomNickname = generateRandomNickname(); + + UserRoom userRoom = new UserRoom(user, room, randomNickname); + userRoomRepository.save(userRoom); + return new RoomCreateResDto(room.getId()); + } + + /** + * ์œ ์ €๊ฐ€ ๋ฐฉ์„ ๋‚˜๊ฐ„๋‹ค + * ์ฐธ๊ฐ€์ž๊ฐ€ ๋ฐฉ์— ์ฐธ๊ฐ€ํ•œ ์ƒํƒœ์ผ๋•Œ๋งŒ ์ทจ์†Œํ•ด ์ค€๋‹ค. + * @param roomId, user + * @param userDto ์ฐธ์—ฌ ์œ ์ €(์‚ฌ์šฉ์ž ๋ณธ์ธ) + * @return ๋‚˜๊ฐ„ ์‚ฌ๋žŒ์˜ ๋‹‰๋„ค์ž„ + * @throws RoomNotFoundException ๋ฐฉ ์—†์Œ - 404 + * @throws RoomNotOpenException ๋ฐฉ์ด ๋Œ€๊ธฐ ์ƒํƒœ๊ฐ€ ์•„๋‹˜ - 400 + * @throws RoomNotParticipantException ๋ฐฉ ์ฐธ์—ฌ์ž๊ฐ€ ์•„๋‹˜ - 400 + */ + @Transactional + public LeaveRoomResDto modifyLeaveRoom(Long roomId, UserDto userDto) { + User user = userRepository.getById(userDto.getId()); + Room targetRoom = roomRepository.findById(roomId) + .orElseThrow(RoomNotFoundException::new); + if (!targetRoom.getStatus().equals(RoomType.OPEN)) { + throw new RoomNotOpenException(); + } + UserRoom targetUserRoom = userRoomRepository.findByUserAndRoom(user, targetRoom) + .orElseThrow(RoomNotParticipantException::new); + + // ๋ชจ๋‘ ๋‚˜๊ฐˆ ๋•Œ ๋ฐฉ fail์ฒ˜๋ฆฌ + if (targetRoom.getCurrentPeople() == 1) { + targetRoom.updateCurrentPeople(0); + targetUserRoom.updateIsExist(false); + targetRoom.roomFail(); + roomRepository.save(targetRoom); + userRoomRepository.save(targetUserRoom); + return new LeaveRoomResDto(targetUserRoom.getNickname()); + } + + targetRoom.updateCurrentPeople(targetRoom.getCurrentPeople() - 1); + targetUserRoom.updateIsExist(false); + + // ๋ฐฉ์žฅ ์ด๊ถŒ + if (user.getId().equals(targetRoom.getHost().getId())) { + List existUser = userRoomRepository.findByIsExist(roomId); + targetRoom.updateHost(existUser.get(0)); + } + + roomRepository.save(targetRoom); + userRoomRepository.save(targetUserRoom); + + return new LeaveRoomResDto(targetUserRoom.getNickname()); + } + + /** + * ๋ฐฉ์„ ์‹œ์ž‘ ์ƒํƒœ๋กœ ๋ฐ”๊พผ๋‹ค + * ๋ฐฉ์˜ ์ƒํƒœ๋ฅผ ์‹œ์ž‘ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ. + * @param roomId, user + * @return ๋ฐฉ id + * @throws RoomNotFoundException ๋ฐฉ ์—†์Œ - 404 + * @throws RoomNotParticipantException ๋ฐฉ์— ์ฐธ๊ฐ€ํ•˜์ง€ ์•Š์€ ์œ ์ € - 400 + * @throws UserNotHostException ๋ฐฉ์žฅ์ด ์•„๋‹Œ ๊ฒฝ์šฐ - 403 + * @throws RoomNotOpenException ๋ฐฉ์ด ์—ด๋ฆฌ์ง€ ์•Š์€ ์ƒํƒœ - 400 + * @throws RoomNotEnoughPeopleException ๋ฐฉ์— ์ถฉ๋ถ„ํ•œ ์ธ์›์ด ์—†์Œ - 400 + */ + @Transactional + public RoomStartResDto modifyStartRoom(Long roomId, UserDto userDto) { + User user = userRepository.getById(userDto.getId()); + Room targetRoom = roomRepository.findById(roomId) + .orElseThrow(RoomNotFoundException::new); + UserRoom targetUserRoom = userRoomRepository.findByUserAndRoom(user, targetRoom) + .orElseThrow(RoomNotParticipantException::new); + if (!targetRoom.getHost().equals(targetUserRoom.getUser())) { + throw new UserNotHostException(); + } + if (!targetRoom.getStatus().equals(RoomType.OPEN)) { + throw new RoomNotOpenException(); + } + if (targetRoom.getMinPeople() > targetRoom.getCurrentPeople()) { + throw new RoomNotEnoughPeopleException(); + } + List users = userRoomRepository.findByIsExist(roomId); + targetRoom.roomStart(); + partyNotiService.sendPartyNotifications(users); + roomRepository.save(targetRoom); + + return new RoomStartResDto(targetRoom.getId()); + } + + /** + * ๋ฐฉ์— ์ฐธ์—ฌํ•œ๋‹ค + * @param roomId ๋ฐฉ id + * @param userDto ์œ ์ € ์ •๋ณด + * @return roomId + * @throws RoomNotFoundException ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฐฉ ์ž…๋ ฅ - 404 + * @throws OnPenaltyException ํŒจ๋„ํ‹ฐ ์ƒํƒœ์ธ ์œ ์ € - 403 + * @throws RoomNotOpenException ๋ชจ์ง‘์ค‘์ธ ๋ฐฉ์ด ์•„๋‹˜ - 400 + * @throws UserAlreadyInRoom ์ด๋ฏธ ์ฐธ์—ฌํ•œ ๋ฐฉ ์ž…๋ ฅ - 409 + * ๊ณผ๊ฑฐ ์ฐธ์—ฌ ์ด๋ ฅ์ด ์žˆ์„ ๊ฒฝ์šฐ ๊ทธ ์•„์ด๋””๋กœ, ์—†์„๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ์•„์ด๋””๋ฅผ ์ƒ์„ฑ ํ›„ currentPeople์„ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค + */ + @Transactional + public RoomJoinResDto addJoinRoom(Long roomId, UserDto userDto) { + User user = userRepository.getById(userDto.getId()); + Room room = roomRepository.findById(roomId).orElseThrow(RoomNotFoundException::new); + Optional partyPenalty = partyPenaltyRepository.findTopByUserIdOrderByStartTimeDesc(user.getId()); + if (partyPenalty.isPresent() && PartyPenalty.isFreeFromPenalty(partyPenalty.get())) { + throw new OnPenaltyException(); + } + if (!room.getStatus().equals(RoomType.OPEN)) { + throw new RoomNotOpenException(); + } + UserRoom userRoom = userRoomRepository.findByUserAndRoom(user, room) + .orElseGet(() -> { + String randomNickname; + do { + randomNickname = generateRandomNickname(); + } while (userRoomRepository.existsByRoomAndNickname(room, randomNickname)); + + UserRoom newUserRoom = new UserRoom(user, room, randomNickname); + newUserRoom.updateIsExist(false); + return newUserRoom; + }); + if (userRoom.getIsExist()) { + throw new UserAlreadyInRoom(ErrorCode.USER_ALREADY_IN_ROOM); + } else { + userRoom.updateIsExist(true); + userRoomRepository.save(userRoom); + } + + room.updateCurrentPeople(room.getCurrentPeople() + 1); + if (room.getCurrentPeople() == room.getMaxPeople()) { + List users = userRoomRepository.findByIsExist(roomId); + room.roomStart(); + partyNotiService.sendPartyNotifications(users); + } + roomRepository.save(room); + return new RoomJoinResDto(roomId); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/room/utils/GenerateRandomNickname.java b/gg-pingpong-api/src/main/java/gg/party/api/user/room/utils/GenerateRandomNickname.java new file mode 100644 index 000000000..42683fd52 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/room/utils/GenerateRandomNickname.java @@ -0,0 +1,28 @@ +package gg.party.api.user.room.utils; + +import java.util.Random; + +/* + * ์ต๋ช… ๋‹‰๋„ค์ž„์„ ๋งŒ๋“œ๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. + * PREFIX์™€ SUFFIX ๋ฐฐ์—ด์—์„œ ๋žœ๋ค์œผ๋กœ ๋‹จ์–ด๋ฅผ ์„ ํƒํ•˜์—ฌ ์กฐํ•ฉํ•ฉ๋‹ˆ๋‹ค. + * ๋‘˜ ์ค‘ ์ค‘๋ณต๋˜๋Š” ์š”์†Œ๋„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ex) ์šฉ๊ฐํ•œ int, ์šฉ๊ฐํ•œ string์ด ๊ณต์กดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + * ์ตœ๋Œ€ 4๊ธ€์ž || 7๊ธ€์ž๋กœ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. + */ +public class GenerateRandomNickname { + private static final String[] PREFIX = {"์šฉ๊ฐํ•œ", "๋Œ€๋‹ดํ•œ", "๋ฐ์€", "๋›ฐ์–ด๋‚œ", "์พŒํ™œํ•œ", "์˜๋ฆฌํ•œ", "๋„๋ง๊ฐ€๋Š”", "๋“ ๋“ ํ•œ", + "๋Œ€๋‹ดํ•œ", "์—ด์‹ฌ์ธ", "ํž˜์ฐฌ", "๋ถˆ๊ฐ™์€", "์‹ ์„ ํ•œ", "๊ด€๋Œ€ํ•œ", "์œ ์พŒํ•œ", "ํ–‰๋ณตํ•œ", "ํฌ๋ง์ฐฌ", "๋ช…๋ž‘ํ•œ", "์นœ์ ˆํ•œ", "ํ™œ๊ธฐ์ฐฌ", + "์ฐฉํ•œ", "์ด์ƒํ•œ", "๋น ๋ฅธ", "์•ˆ๋„ํ•˜๋Š”", "์ˆ˜์ค์€", "์–ด๋ฆฌ์„์€", "๊ฐ•ํ•œ", "๊ฐ์‚ฌํ•˜๋Š”", "ํž˜๋“ ", "์šฉ๊ฐํ•œ", "์—ด์ •์ ์ธ", "์กธ๋ฆฐ", + "๋˜‘๋˜‘ํ•œ", "์ฆ๊ฑฐ์šด", "๊ต‰์žฅํ•œ", "๊ณ ์ˆ˜", "์—„์ฒญ๋‚œ", "๋œฌ๊ธˆ์—†๋Š”", "์ถฉ๋ฌด๊ณต", "์ œ๋„ˆ๋Ÿด", "์— ํŽ˜๋Ÿฌ", "๋งˆ์ œ์Šคํ‹ฐ", "ํŒํƒ€์Šคํ‹ฑ", "๋ ˆ์ „๋”๋ฆฌ", + "๋จผ์น˜ํ‚จ", "๋‹คํฌํ˜ธ์Šค", "์Šˆํผ๋ฃจํ‚ค", "์—˜๋ฆฌํŠธ", "์ •์ ", "์ „๊ตํšŒ์žฅ", "๋ฒ ํ…Œ๋ž‘", "ํ‚น", "ํ€ธ", "์ฑ”ํ”ผ์–ธ"}; + + private static final String[] SUFFIX = {"list", "vector", "string", "bool", "number", "object", "array", + "set", "map", "date", "null", "buffer", "json", "error", "stack", "queue", "deque", "struct", "tree", + "graph", "pair", "int", "char", "float", "double", "long", "size_t", "short", "byte", "bit", "pointer"}; + + public static String generateRandomNickname() { + Random random = new Random(); + String randomAdjective = PREFIX[random.nextInt(PREFIX.length)]; + String randomNoun = SUFFIX[random.nextInt(SUFFIX.length)]; + return randomAdjective + " " + randomNoun; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/template/controller/TemplateController.java b/gg-pingpong-api/src/main/java/gg/party/api/user/template/controller/TemplateController.java new file mode 100644 index 000000000..37b5d237d --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/template/controller/TemplateController.java @@ -0,0 +1,27 @@ +package gg.party.api.user.template.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.party.api.user.template.controller.response.TemplateListResDto; +import gg.party.api.user.template.service.TemplateService; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/party/templates") +public class TemplateController { + private final TemplateService templateService; + + /** + * ํ…œํ”Œ๋ฆฟ ์ „์ฒด ์กฐํšŒ + * @return ํ…œํ”Œ๋ฆฟ ์ „์ฒด ๋ฆฌ์ŠคํŠธ (๊ฐ€๋‚˜๋‹ค ์ˆœ์œผ๋กœ ์ •๋ ฌ) 200 + */ + @GetMapping + public ResponseEntity templateList() { + return ResponseEntity.status(HttpStatus.OK).body(templateService.findTemplateList()); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/template/controller/response/TemplateListResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/template/controller/response/TemplateListResDto.java new file mode 100644 index 000000000..f593b6e24 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/template/controller/response/TemplateListResDto.java @@ -0,0 +1,16 @@ +package gg.party.api.user.template.controller.response; + +import java.util.List; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class TemplateListResDto { + private List templateList; + + public TemplateListResDto(List templateListResDto) { + this.templateList = templateListResDto; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/template/controller/response/TemplateResDto.java b/gg-pingpong-api/src/main/java/gg/party/api/user/template/controller/response/TemplateResDto.java new file mode 100644 index 000000000..3b6dfc773 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/template/controller/response/TemplateResDto.java @@ -0,0 +1,33 @@ +package gg.party.api.user.template.controller.response; + +import gg.data.party.GameTemplate; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class TemplateResDto { + private Long gameTemplateId; + private String categoryName; + private String gameName; + private Integer maxGamePeople; + private Integer minGamePeople; + private Integer maxGameTime; + private Integer minGameTime; + private String genre; + private String difficulty; + private String summary; + + public TemplateResDto(GameTemplate template) { + this.gameTemplateId = template.getId(); + this.categoryName = template.getCategory().getName(); + this.gameName = template.getGameName(); + this.maxGamePeople = template.getMaxGamePeople(); + this.minGamePeople = template.getMinGamePeople(); + this.maxGameTime = template.getMaxGameTime(); + this.minGameTime = template.getMinGameTime(); + this.genre = template.getGenre(); + this.difficulty = template.getDifficulty(); + this.summary = template.getSummary(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/party/api/user/template/service/TemplateService.java b/gg-pingpong-api/src/main/java/gg/party/api/user/template/service/TemplateService.java new file mode 100644 index 000000000..b2a9af2d5 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/party/api/user/template/service/TemplateService.java @@ -0,0 +1,34 @@ +package gg.party.api.user.template.service; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.party.api.user.template.controller.response.TemplateListResDto; +import gg.party.api.user.template.controller.response.TemplateResDto; +import gg.repo.party.TemplateRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class TemplateService { + private final TemplateRepository templateRepository; + + /** + * ํ…œํ”Œ๋ฆฟ ์ „์ฒด ์กฐํšŒ + * @return ํ…œํ”Œ๋ฆฟ ์ „์ฒด ๋ฆฌ์ŠคํŠธ (๊ฐ€๋‚˜๋‹ค ์ˆœ์œผ๋กœ ์ •๋ ฌ) + */ + @Transactional(readOnly = true) + public TemplateListResDto findTemplateList() { + List sortedTemplates = templateRepository.findAll() + .stream() + .map(TemplateResDto::new) + .sorted(Comparator.comparing(TemplateResDto::getGameName, Comparator.nullsLast(Comparator.naturalOrder()))) + .collect(Collectors.toList()); + + return new TemplateListResDto(sortedTemplates); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/controller/GameAdminController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/controller/GameAdminController.java index 3391d8cb1..43d77c7f1 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/controller/GameAdminController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/controller/GameAdminController.java @@ -20,8 +20,8 @@ import gg.pingpong.api.admin.game.dto.GameUserLogAdminReqDto; import gg.pingpong.api.admin.game.dto.RankGamePPPModifyReqDto; import gg.pingpong.api.admin.game.service.GameAdminService; -import gg.pingpong.api.global.dto.PageRequestDto; import gg.pingpong.api.user.rank.redis.RankRedisService; +import gg.utils.dto.PageRequestDto; import gg.utils.exception.ErrorCode; import gg.utils.exception.custom.InvalidParameterException; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/dto/GameLogAdminDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/dto/GameLogAdminDto.java index 52f622d4c..d70f105fe 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/dto/GameLogAdminDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/dto/GameLogAdminDto.java @@ -4,7 +4,7 @@ import java.time.LocalDateTime; import gg.admin.repo.game.out.GameTeamUser; -import gg.data.game.type.StatusType; +import gg.data.pingpong.game.type.StatusType; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/dto/GameUserLogAdminReqDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/dto/GameUserLogAdminReqDto.java index ea4b42050..70d700ef9 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/dto/GameUserLogAdminReqDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/dto/GameUserLogAdminReqDto.java @@ -2,7 +2,7 @@ import javax.validation.constraints.NotNull; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.utils.dto.PageRequestDto; import lombok.Getter; @Getter diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/service/GameAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/service/GameAdminService.java index 26e581a1d..39951ffff 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/service/GameAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/game/service/GameAdminService.java @@ -20,13 +20,13 @@ import gg.admin.repo.game.out.GameTeamUser; import gg.admin.repo.season.SeasonAdminRepository; import gg.admin.repo.user.UserAdminRepository; -import gg.data.game.Game; -import gg.data.game.PChange; -import gg.data.game.TeamUser; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.PChange; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.pingpong.api.admin.game.controller.response.GameLogListAdminResponseDto; import gg.pingpong.api.admin.game.dto.GameLogAdminDto; @@ -164,11 +164,9 @@ public void rankResultEdit(RankGamePPPModifyReqDto reqDto, Long gameId) { } RankRedis rankRedis2 = rollbackGameResult(game.getSeason(), teamUsers.get(1), pChanges); pChangeAdminRepository.deleteById(pChanges.get(0).getId()); - entityManager.flush(); for (int i = 0; i < teamUsers.size(); i++) { updateScore(reqDto, teamUsers.get(i)); } - teamUserAdminRepository.flush(); rankRedisService.updateAdminRankData(teamUsers.get(0), teamUsers.get(1), game, rankRedis1, rankRedis2); tierService.updateAllTier(game.getSeason()); } diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/AnnouncementAdminController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/AnnouncementAdminController.java index 7f9ef0498..cdd2c326d 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/AnnouncementAdminController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/AnnouncementAdminController.java @@ -20,7 +20,7 @@ import gg.pingpong.api.admin.manage.controller.response.AnnouncementAdminListResponseDto; import gg.pingpong.api.admin.manage.dto.AnnouncementAdminAddDto; import gg.pingpong.api.admin.manage.service.AnnouncementAdminService; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.utils.dto.PageRequestDto; import lombok.AllArgsConstructor; @RestController diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/PenaltyAdminController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/PenaltyAdminController.java index 69375f5de..771b4ba97 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/PenaltyAdminController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/PenaltyAdminController.java @@ -22,7 +22,7 @@ import gg.pingpong.api.admin.manage.controller.request.PenaltyRequestDto; import gg.pingpong.api.admin.manage.controller.response.PenaltyListResponseDto; import gg.pingpong.api.admin.manage.service.PenaltyAdminService; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.utils.dto.PageRequestDto; import lombok.RequiredArgsConstructor; @RestController diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/request/FeedbackAdminPageRequestDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/request/FeedbackAdminPageRequestDto.java index 80fbdb426..81daef33e 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/request/FeedbackAdminPageRequestDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/controller/request/FeedbackAdminPageRequestDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.admin.manage.controller.request; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.utils.dto.PageRequestDto; import lombok.Getter; @Getter diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/dto/SlotAdminDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/dto/SlotAdminDto.java index 2fbc5ad5b..3e16e0046 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/dto/SlotAdminDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/dto/SlotAdminDto.java @@ -2,7 +2,7 @@ import java.time.LocalDateTime; -import gg.data.manage.SlotManagement; +import gg.data.pingpong.manage.SlotManagement; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/service/SlotAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/service/SlotAdminService.java index fbb735a00..7896d1a95 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/service/SlotAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/manage/service/SlotAdminService.java @@ -8,7 +8,7 @@ import org.springframework.transaction.annotation.Transactional; import gg.admin.repo.manage.AdminSlotManagementsRepository; -import gg.data.manage.SlotManagement; +import gg.data.pingpong.manage.SlotManagement; import gg.pingpong.api.admin.manage.controller.request.SlotCreateRequestDto; import gg.pingpong.api.admin.manage.controller.response.SlotListAdminResponseDto; import gg.pingpong.api.admin.manage.dto.SlotAdminDto; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/controller/MatchAdminController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/controller/MatchAdminController.java new file mode 100644 index 000000000..93e294f25 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/controller/MatchAdminController.java @@ -0,0 +1,41 @@ +package gg.pingpong.api.admin.match.controller; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +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 gg.data.pingpong.match.type.Option; +import gg.pingpong.api.admin.match.controller.response.EnrolledMatchesResponseDto; +import gg.pingpong.api.admin.match.service.MatchAdminService; +import gg.pingpong.api.admin.match.service.dto.MatchUser; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/pingpong/admin/match") +@Validated +public class MatchAdminController { + private final MatchAdminService matchAdminService; + + /** + * ๋งค์นญํ ์กฐํšŒ + * @param mode : BOTH, NORMAL, RANK, ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ null (์ „์ฒด ์กฐํšŒ) + * @return + */ + @GetMapping + public ResponseEntity getMatch( + @RequestParam(name = "mode", required = false) Option mode) { + Map> matches = matchAdminService.getMatches(mode); + int gameInterval = matchAdminService.getGameInterval(); + EnrolledMatchesResponseDto response = EnrolledMatchesResponseDto.of(matches, gameInterval); + return ResponseEntity.status(HttpStatus.OK).body(response); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/controller/response/EnrolledMatch.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/controller/response/EnrolledMatch.java new file mode 100644 index 000000000..e33086923 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/controller/response/EnrolledMatch.java @@ -0,0 +1,26 @@ +package gg.pingpong.api.admin.match.controller.response; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import gg.pingpong.api.admin.match.service.dto.MatchUser; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class EnrolledMatch { + private LocalDateTime startTime; + private LocalDateTime endTime; + private List waitList = new ArrayList<>(); + + public static EnrolledMatch of(LocalDateTime startTime, List waitList, int interval) { + EnrolledMatch enrolledMatch = new EnrolledMatch(); + enrolledMatch.startTime = startTime; + enrolledMatch.endTime = startTime.plusMinutes(interval); + enrolledMatch.waitList.addAll(waitList); + return enrolledMatch; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/controller/response/EnrolledMatchesResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/controller/response/EnrolledMatchesResponseDto.java new file mode 100644 index 000000000..820677287 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/controller/response/EnrolledMatchesResponseDto.java @@ -0,0 +1,31 @@ +package gg.pingpong.api.admin.match.controller.response; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import gg.pingpong.api.admin.match.service.dto.MatchUser; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class EnrolledMatchesResponseDto { + private List matches = new ArrayList<>(); + + public EnrolledMatchesResponseDto(List matches) { + this.matches = matches; + } + + public static EnrolledMatchesResponseDto of(Map> matchesMap, int interval) { + EnrolledMatchesResponseDto enrolledMatchesResponseDto = new EnrolledMatchesResponseDto(); + List matches1 = enrolledMatchesResponseDto.matches; + + for (Map.Entry> entry : matchesMap.entrySet()) { + matches1.add(EnrolledMatch.of(entry.getKey(), entry.getValue(), interval)); + } + return enrolledMatchesResponseDto; + } +} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/service/MatchAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/service/MatchAdminService.java new file mode 100644 index 000000000..f6c3239ae --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/service/MatchAdminService.java @@ -0,0 +1,77 @@ +package gg.pingpong.api.admin.match.service; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; + +import gg.admin.repo.manage.AdminSlotManagementsRepository; +import gg.admin.repo.match.RedisMatchTimeAdminRepository; +import gg.admin.repo.user.UserAdminRepository; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.Option; +import gg.pingpong.api.admin.match.service.dto.MatchUser; +import gg.utils.exception.match.SlotNotFoundException; +import gg.utils.exception.user.UserNotFoundException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class MatchAdminService { + private final RedisMatchTimeAdminRepository redisMatchTimeAdminRepository; + private final AdminSlotManagementsRepository adminSlotManagementsRepository; + private final UserAdminRepository userAdminRepository; + + /** + * redis ๋งค์นญํ ์กฐํšŒ + * @param option : BOTH, NORMAL, RANK (null์ผ ๊ฒฝ์šฐ BOTH ์กฐํšŒ) + * @return ๋งค์นญํ + */ + public Map> getMatches(Option option) { + Map> allEnrolledSlots = redisMatchTimeAdminRepository.getAllEnrolledSlots(); + Map> response = new HashMap<>(); + + for (Map.Entry> entry : allEnrolledSlots.entrySet()) { + List matchUsers = convertToMatchUser(entry.getValue()); + response.put(entry.getKey(), matchUsers); + } + + if (option == null || Option.BOTH.equals(option)) { + return response; + } + for (Map.Entry> entry : response.entrySet()) { + entry.getValue().removeIf( + matchUser -> !Option.BOTH.equals(matchUser.getOption()) && !matchUser.getOption().equals(option)); + } + return response; + } + + /** + * @return gameInterval (๋ถ„) + */ + public int getGameInterval() { + SlotManagement slotManagement = adminSlotManagementsRepository.findCurrent(LocalDateTime.now()) + .orElseThrow(SlotNotFoundException::new); + return slotManagement.getGameInterval(); + } + + /** + * RedisMatchUser -> MatchUser ๋ณ€ํ™˜ + * @param redisMatchUsers ๋ณ€ํ™˜ํ•  RedisMatchUser ๋ฆฌ์ŠคํŠธ + * @return ๋ณ€ํ™˜๋œ MatchUser ๋ฆฌ์ŠคํŠธ + */ + private List convertToMatchUser(List redisMatchUsers) { + return redisMatchUsers.stream() + .map(redisMatchUser -> { + String intraId = userAdminRepository.findById(redisMatchUser.getUserId()) + .orElseThrow(UserNotFoundException::new) + .getIntraId(); + return MatchUser.of(redisMatchUser, intraId); + }) + .collect(Collectors.toList()); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/service/dto/MatchUser.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/service/dto/MatchUser.java new file mode 100644 index 000000000..d52ccd844 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/match/service/dto/MatchUser.java @@ -0,0 +1,34 @@ +package gg.pingpong.api.admin.match.service.dto; + +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.Option; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class MatchUser { + private Long userId; + private String intraId; + private Integer ppp; + private Option option; + + @Builder + public MatchUser(Long userId, String intraId, Integer ppp, Option option) { + this.userId = userId; + this.intraId = intraId; + this.ppp = ppp; + this.option = option; + } + + public static MatchUser of(RedisMatchUser user, String intraId) { + return MatchUser.builder() + .userId(user.getUserId()) + .intraId(intraId) + .ppp(user.getPpp()) + .option(user.getOption()) + .build(); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/noti/controller/request/NotiListAdminRequestDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/noti/controller/request/NotiListAdminRequestDto.java index 2d545d127..edf72b834 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/noti/controller/request/NotiListAdminRequestDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/noti/controller/request/NotiListAdminRequestDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.admin.noti.controller.request; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.utils.dto.PageRequestDto; import lombok.Getter; import lombok.Setter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/noti/service/NotiAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/noti/service/NotiAdminService.java index 1982e1bc1..1764f7a8c 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/noti/service/NotiAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/noti/service/NotiAdminService.java @@ -7,6 +7,7 @@ import gg.admin.repo.noti.NotiAdminRepository; import gg.admin.repo.user.UserAdminRepository; +import gg.auth.UserDto; import gg.data.noti.Noti; import gg.data.noti.type.NotiType; import gg.data.user.User; @@ -14,7 +15,6 @@ import gg.pingpong.api.admin.noti.controller.response.NotiListAdminResponseDto; import gg.pingpong.api.admin.noti.dto.NotiAdminDto; import gg.pingpong.api.user.noti.service.SnsNotiService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.exception.user.UserNotFoundException; import lombok.AllArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/rank/service/RankAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/rank/service/RankAdminService.java index eef02cdc5..e015a440c 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/rank/service/RankAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/rank/service/RankAdminService.java @@ -10,9 +10,9 @@ import org.springframework.transaction.annotation.Transactional; import gg.admin.repo.user.UserAdminRepository; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.season.Season; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.pingpong.api.admin.season.dto.SeasonAdminDto; import gg.repo.rank.RankRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/rank/service/RankRedisAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/rank/service/RankRedisAdminService.java index 1c903d6ad..9d35e80de 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/rank/service/RankRedisAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/rank/service/RankRedisAdminService.java @@ -7,8 +7,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; import gg.data.user.User; import gg.pingpong.api.admin.season.dto.SeasonAdminDto; import gg.repo.rank.TierRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/controller/request/SeasonCreateRequestDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/controller/request/SeasonCreateRequestDto.java index 484f5a65d..c89f9ef23 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/controller/request/SeasonCreateRequestDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/controller/request/SeasonCreateRequestDto.java @@ -7,7 +7,7 @@ import org.springframework.format.annotation.DateTimeFormat; -import gg.data.season.Season; +import gg.data.pingpong.season.Season; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/dto/SeasonAdminDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/dto/SeasonAdminDto.java index b65c3070d..5d1f21c16 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/dto/SeasonAdminDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/dto/SeasonAdminDto.java @@ -2,7 +2,7 @@ import java.time.LocalDateTime; -import gg.data.season.Season; +import gg.data.pingpong.season.Season; import gg.pingpong.api.admin.season.type.SeasonStatus; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/service/SeasonAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/service/SeasonAdminService.java index 639439fe2..24f6fcffe 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/service/SeasonAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/season/service/SeasonAdminService.java @@ -8,7 +8,7 @@ import org.springframework.transaction.annotation.Transactional; import gg.admin.repo.season.SeasonAdminRepository; -import gg.data.season.Season; +import gg.data.pingpong.season.Season; import gg.pingpong.api.admin.rank.service.RankAdminService; import gg.pingpong.api.admin.rank.service.RankRedisAdminService; import gg.pingpong.api.admin.season.controller.request.SeasonCreateRequestDto; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/CoinPolicyAdminController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/CoinPolicyAdminController.java index 5a6b8f406..f05386eda 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/CoinPolicyAdminController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/CoinPolicyAdminController.java @@ -15,12 +15,12 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; import gg.pingpong.api.admin.store.controller.response.CoinPolicyAdminListResponseDto; import gg.pingpong.api.admin.store.dto.CoinPolicyAdminAddDto; import gg.pingpong.api.admin.store.service.CoinPolicyAdminService; -import gg.pingpong.api.global.dto.PageRequestDto; -import gg.pingpong.api.global.utils.argumentresolver.Login; -import gg.pingpong.api.user.user.dto.UserDto; +import gg.utils.dto.PageRequestDto; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/ItemAdminController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/ItemAdminController.java index 8fa6a208e..837c482cb 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/ItemAdminController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/ItemAdminController.java @@ -20,12 +20,12 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; import gg.pingpong.api.admin.store.controller.request.ItemUpdateRequestDto; import gg.pingpong.api.admin.store.controller.response.ItemListResponseDto; import gg.pingpong.api.admin.store.service.ItemAdminService; -import gg.pingpong.api.global.dto.PageRequestDto; -import gg.pingpong.api.global.utils.argumentresolver.Login; -import gg.pingpong.api.user.user.dto.UserDto; +import gg.utils.dto.PageRequestDto; import gg.utils.exception.item.ItemImageLargeException; import gg.utils.exception.item.ItemImageTypeException; import io.swagger.v3.oas.annotations.Parameter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/MegaphoneAdminController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/MegaphoneAdminController.java index 79e67c696..79814830b 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/MegaphoneAdminController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/MegaphoneAdminController.java @@ -13,7 +13,7 @@ import gg.pingpong.api.admin.store.controller.response.MegaphoneHistoryResponseDto; import gg.pingpong.api.admin.store.service.MegaphoneAdminService; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.utils.dto.PageRequestDto; import lombok.RequiredArgsConstructor; @RestController diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/request/ItemUpdateRequestDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/request/ItemUpdateRequestDto.java index 8b48862db..8b6acb88e 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/request/ItemUpdateRequestDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/request/ItemUpdateRequestDto.java @@ -4,8 +4,8 @@ import javax.validation.constraints.NotNull; -import gg.data.store.Item; -import gg.data.store.type.ItemType; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.type.ItemType; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/request/ReceiptAdminPageRequestDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/request/ReceiptAdminPageRequestDto.java index 89a895eaa..f3d90d132 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/request/ReceiptAdminPageRequestDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/request/ReceiptAdminPageRequestDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.admin.store.controller.request; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.utils.dto.PageRequestDto; import lombok.Getter; @Getter diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/CoinPolicyAdminResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/CoinPolicyAdminResponseDto.java index c6370a3b2..2d81d421f 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/CoinPolicyAdminResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/CoinPolicyAdminResponseDto.java @@ -1,8 +1,11 @@ package gg.pingpong.api.admin.store.controller.response; import java.time.LocalDateTime; +import java.util.Optional; -import gg.data.store.CoinPolicy; +import gg.data.pingpong.store.CoinPolicy; +import gg.data.user.User; +import gg.utils.exception.user.UserNotFoundException; import lombok.Getter; import lombok.NoArgsConstructor; @@ -19,7 +22,9 @@ public class CoinPolicyAdminResponseDto { public CoinPolicyAdminResponseDto(CoinPolicy coinPolicyAdmin) { this.coinPolicyId = coinPolicyAdmin.getId(); - this.createUserId = coinPolicyAdmin.getUser().getIntraId(); + User user = Optional.ofNullable(coinPolicyAdmin.getUser()) + .orElseThrow(UserNotFoundException::new); + this.createUserId = user.getIntraId(); this.attendance = coinPolicyAdmin.getAttendance(); this.normal = coinPolicyAdmin.getNormal(); this.rankWin = coinPolicyAdmin.getRankWin(); diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/ItemHistoryResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/ItemHistoryResponseDto.java index 5855e6766..89dd7ac8c 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/ItemHistoryResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/ItemHistoryResponseDto.java @@ -2,7 +2,7 @@ import java.time.LocalDateTime; -import gg.data.store.Item; +import gg.data.pingpong.store.Item; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/MegaphoneAdminResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/MegaphoneAdminResponseDto.java index e09f2633a..536466abd 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/MegaphoneAdminResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/MegaphoneAdminResponseDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.admin.store.controller.response; -import gg.data.store.Megaphone; +import gg.data.pingpong.store.Megaphone; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/ReceiptResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/ReceiptResponseDto.java index 026f4f448..0ffecc3df 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/ReceiptResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/controller/response/ReceiptResponseDto.java @@ -2,9 +2,9 @@ import java.time.LocalDateTime; -import gg.data.store.Item; -import gg.data.store.Receipt; -import gg.data.store.type.ItemStatus; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.type.ItemStatus; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/CoinAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/CoinAdminService.java index 6a52d9781..1465a04b1 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/CoinAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/CoinAdminService.java @@ -3,7 +3,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.store.CoinHistory; +import gg.data.pingpong.store.CoinHistory; import gg.data.user.User; import gg.pingpong.api.admin.store.controller.request.CoinUpdateRequestDto; import gg.pingpong.api.user.store.service.CoinHistoryService; @@ -17,6 +17,11 @@ public class CoinAdminService { private final UserRepository userRepository; private final CoinHistoryService coinHistoryService; + /** + * ์œ ์ €์˜ ์ฝ”์ธ ์ •๋ณด๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. + * @param coinUpdateRequestDto ์ฝ”์ธ ์—…๋ฐ์ดํŠธ์— ํ•„์š”ํ•œ Dto + * @throws UserNotFoundException ์œ ์ €๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ + */ @Transactional public void updateUserCoin(CoinUpdateRequestDto coinUpdateRequestDto) { User user = userRepository.findByIntraId(coinUpdateRequestDto.getIntraId()) diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/CoinPolicyAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/CoinPolicyAdminService.java index b0644ae52..6112f218a 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/CoinPolicyAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/CoinPolicyAdminService.java @@ -7,12 +7,12 @@ import gg.admin.repo.store.CoinPolicyAdminRepository; import gg.admin.repo.user.UserAdminRepository; -import gg.data.store.CoinPolicy; +import gg.auth.UserDto; +import gg.data.pingpong.store.CoinPolicy; import gg.data.user.User; import gg.pingpong.api.admin.store.controller.response.CoinPolicyAdminListResponseDto; import gg.pingpong.api.admin.store.controller.response.CoinPolicyAdminResponseDto; import gg.pingpong.api.admin.store.dto.CoinPolicyAdminAddDto; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.exception.user.UserNotFoundException; import lombok.AllArgsConstructor; @@ -22,6 +22,11 @@ public class CoinPolicyAdminService { private final CoinPolicyAdminRepository coinPolicyAdminRepository; private final UserAdminRepository userAdminRepository; + /** + * ์ฝ”์ธ ์ •์ฑ…์„ ํŽ˜์ด์ง€๋ณ„๋กœ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค. + * @param pageable + * @return ์ฝ”์ธ ์ •์ฑ… ๋ฆฌ์ŠคํŠธ ์‘๋‹ต Dto + */ @Transactional(readOnly = true) public CoinPolicyAdminListResponseDto findAllCoinPolicy(Pageable pageable) { Page allCoinPolicy = coinPolicyAdminRepository.findAll(pageable); @@ -31,6 +36,12 @@ public CoinPolicyAdminListResponseDto findAllCoinPolicy(Pageable pageable) { responseDtos.getTotalPages()); } + /** + * ์ƒˆ๋กœ์šด ์ฝ”์ธ ์ •์ฑ…์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. + * @param userDto ์œ ์ € Dto + * @param addDto ์ƒˆ๋กœ ์ถ”๊ฐ€ ํ•  ์ฝ”์ธ ์ •์ฑ… Dto + * @exception UserNotFoundException ์œ ์ €๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ + */ @Transactional public void addCoinPolicy(UserDto userDto, CoinPolicyAdminAddDto addDto) { User user = userAdminRepository.findByIntraId(userDto.getIntraId()).orElseThrow(UserNotFoundException::new); diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/ItemAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/ItemAdminService.java index 363aded6b..4fa42f0e6 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/ItemAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/ItemAdminService.java @@ -9,12 +9,12 @@ import org.springframework.web.multipart.MultipartFile; import gg.admin.repo.store.ItemAdminRepository; -import gg.data.store.Item; +import gg.auth.UserDto; +import gg.data.pingpong.store.Item; import gg.pingpong.api.admin.store.controller.request.ItemUpdateRequestDto; import gg.pingpong.api.admin.store.controller.response.ItemHistoryResponseDto; import gg.pingpong.api.admin.store.controller.response.ItemListResponseDto; import gg.pingpong.api.global.utils.aws.AsyncNewItemImageUploader; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.exception.item.ItemNotAvailableException; import gg.utils.exception.item.ItemNotFoundException; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/ReceiptAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/ReceiptAdminService.java index 560a3510c..8b7a76c2d 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/ReceiptAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/store/service/ReceiptAdminService.java @@ -6,7 +6,7 @@ import org.springframework.transaction.annotation.Transactional; import gg.admin.repo.store.ReceiptAdminRepository; -import gg.data.store.Receipt; +import gg.data.pingpong.store.Receipt; import gg.pingpong.api.admin.store.controller.response.ReceiptListResponseDto; import gg.pingpong.api.admin.store.controller.response.ReceiptResponseDto; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/controller/request/TournamentAdminCreateRequestDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/controller/request/TournamentAdminCreateRequestDto.java index f31951cbc..9fdc726ea 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/controller/request/TournamentAdminCreateRequestDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/controller/request/TournamentAdminCreateRequestDto.java @@ -7,7 +7,7 @@ import org.hibernate.validator.constraints.Length; import org.springframework.format.annotation.DateTimeFormat; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.tournament.type.TournamentType; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/controller/request/TournamentAdminUpdateRequestDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/controller/request/TournamentAdminUpdateRequestDto.java index 6121e4722..58c9777c2 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/controller/request/TournamentAdminUpdateRequestDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/controller/request/TournamentAdminUpdateRequestDto.java @@ -8,7 +8,7 @@ import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat.ISO; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.tournament.type.TournamentType; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/service/TournamentAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/service/TournamentAdminService.java index 09385a366..d7467a8d4 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/service/TournamentAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/tournament/service/TournamentAdminService.java @@ -1,6 +1,6 @@ package gg.pingpong.api.admin.tournament.service; -import static gg.data.match.type.TournamentMatchStatus.*; +import static gg.data.pingpong.match.type.TournamentMatchStatus.*; import java.time.LocalDate; import java.time.LocalDateTime; @@ -10,17 +10,17 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.game.type.StatusType; -import gg.data.manage.SlotManagement; -import gg.data.match.type.TournamentMatchStatus; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.match.type.TournamentMatchStatus; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; import gg.data.user.User; import gg.pingpong.api.admin.tournament.controller.request.TournamentAdminAddUserRequestDto; import gg.pingpong.api.admin.tournament.controller.request.TournamentAdminCreateRequestDto; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/UserAdminController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/UserAdminController.java index ebffae2c6..0ec5c085e 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/UserAdminController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/UserAdminController.java @@ -24,7 +24,7 @@ import gg.pingpong.api.admin.user.controller.response.UserImageListAdminResponseDto; import gg.pingpong.api.admin.user.controller.response.UserSearchAdminResponseDto; import gg.pingpong.api.admin.user.service.UserAdminService; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.utils.dto.PageRequestDto; import gg.utils.exception.user.UserImageLargeException; import gg.utils.exception.user.UserImageTypeException; import lombok.AllArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/request/UserSearchAdminRequestDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/request/UserSearchAdminRequestDto.java index 13eb69f47..4fe7bcba1 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/request/UserSearchAdminRequestDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/request/UserSearchAdminRequestDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.admin.user.controller.request; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.utils.dto.PageRequestDto; import lombok.Getter; import lombok.Setter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/response/UserDetailAdminResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/response/UserDetailAdminResponseDto.java index 09a1ead42..007c8b280 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/response/UserDetailAdminResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/controller/response/UserDetailAdminResponseDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.admin.user.controller.response; -import gg.data.rank.redis.RankRedis; +import gg.data.pingpong.rank.redis.RankRedis; import gg.data.user.User; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/service/UserAdminService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/service/UserAdminService.java index f56d50271..7362c8ec1 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/service/UserAdminService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/admin/user/service/UserAdminService.java @@ -14,9 +14,9 @@ import gg.admin.repo.season.SeasonAdminRepository; import gg.admin.repo.user.UserAdminRepository; import gg.admin.repo.user.UserImageAdminRepository; -import gg.data.rank.Rank; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.data.user.UserImage; import gg.data.user.type.RoleType; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/JpaAuditingConfig.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/JpaAuditingConfig.java deleted file mode 100644 index 5405f9fbe..000000000 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/JpaAuditingConfig.java +++ /dev/null @@ -1,10 +0,0 @@ -package gg.pingpong.api.global.config; - -import org.springframework.context.annotation.Configuration; -import org.springframework.data.jpa.repository.config.EnableJpaAuditing; - -@Configuration -@EnableJpaAuditing -public class JpaAuditingConfig { - -} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/JpaConfig.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/JpaConfig.java index 6bb8e11f9..2ff8da1c8 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/JpaConfig.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/JpaConfig.java @@ -2,9 +2,11 @@ import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @Configuration +@EnableJpaAuditing @EnableJpaRepositories(basePackages = {"gg.repo", "gg.admin.repo"}) @EntityScan(basePackages = "gg.data") public class JpaConfig { diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/SwaggerConfig.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/SwaggerConfig.java index 7af1049e5..e120dcb56 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/SwaggerConfig.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/SwaggerConfig.java @@ -13,6 +13,25 @@ @Configuration public class SwaggerConfig { + + @Bean + public GroupedOpenApi partyGroup() { + return GroupedOpenApi.builder() + .group("party") + .pathsToMatch("/party/**") + .packagesToScan("gg.party.api.user") + .build(); + } + + @Bean + public GroupedOpenApi partyAdminGroup() { + return GroupedOpenApi.builder() + .group("party admin") + .pathsToMatch("/party/admin/**") + .packagesToScan("gg.party.api.admin") + .build(); + } + @Bean public GroupedOpenApi group1() { return GroupedOpenApi.builder() @@ -22,6 +41,24 @@ public GroupedOpenApi group1() { .build(); } + @Bean + public GroupedOpenApi recruitGroup() { + return GroupedOpenApi.builder() + .group("recruit") + .pathsToMatch("/recruitments/**") + .packagesToScan("gg.recruit.api.user") + .build(); + } + + @Bean + public GroupedOpenApi recruitAdminGroup() { + return GroupedOpenApi.builder() + .group("recruit admin") + .pathsToMatch("/admin/recruitments/**") + .packagesToScan("gg.recruit.api.admin") + .build(); + } + @Bean public GroupedOpenApi admin_group() { return GroupedOpenApi.builder() diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/WebConfig.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/WebConfig.java index 9b8e1c539..1dbce5b5f 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/WebConfig.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/config/WebConfig.java @@ -1,30 +1,17 @@ package gg.pingpong.api.global.config; -import java.util.List; - import org.springframework.context.annotation.Configuration; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; -import gg.pingpong.api.global.utils.argumentresolver.LoginMemberArgumentResolver; import gg.pingpong.api.global.utils.querytracker.LoggingInterceptor; -import gg.repo.user.UserRepository; import lombok.RequiredArgsConstructor; @Configuration @RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { - private final UserRepository userRepository; - private final AuthTokenProvider tokenProvider; private final LoggingInterceptor loggingInterceptor; - @Override - public void addArgumentResolvers(List resolvers) { - resolvers.add(new LoginMemberArgumentResolver(userRepository, tokenProvider)); - } - @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loggingInterceptor); diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/exception/GlobalExceptionHandler.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/exception/GlobalExceptionHandler.java index 697150080..9e0365043 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/exception/GlobalExceptionHandler.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/exception/GlobalExceptionHandler.java @@ -16,6 +16,7 @@ import gg.utils.exception.ErrorCode; import gg.utils.exception.ErrorResponse; import gg.utils.exception.custom.AuthenticationException; +import gg.utils.exception.custom.BusinessException; import gg.utils.exception.custom.CustomRuntimeException; import gg.utils.exception.custom.DBConsistencyException; import gg.utils.exception.custom.DuplicationException; @@ -118,6 +119,7 @@ protected ResponseEntity httpRequestMethodNotSupportedExceptionHa @ExceptionHandler(Exception.class) public ResponseEntity handleException(Exception ex) { log.error("!!!!!! SERVER ERROR !!!!!!", ex.getMessage()); + ex.printStackTrace(); ErrorResponse response = new ErrorResponse(ErrorCode.INTERNAL_SERVER_ERR); return new ResponseEntity<>(response, HttpStatus.valueOf(response.getStatus())); } @@ -131,4 +133,12 @@ protected ResponseEntity handleException(HttpMessageNotReadableException excepti protected ResponseEntity handleException(MissingServletRequestParameterException exception) { return ResponseEntity.badRequest().body(ErrorCode.BAD_ARGU.getMessage()); } + + @ExceptionHandler(BusinessException.class) + protected ResponseEntity handleException(BusinessException exception) { + log.error("SERVER BUSINESS EXCEPTION", exception.getMessage()); + exception.printStackTrace(); + ErrorResponse response = new ErrorResponse(exception.getErrorCode()); + return new ResponseEntity<>(response, HttpStatus.valueOf(response.getStatus())); + } } diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/config/SecurityConfig.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/config/SecurityConfig.java index d753dc531..aedb2ed41 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/config/SecurityConfig.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/config/SecurityConfig.java @@ -4,8 +4,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.http.HttpMethod; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -18,30 +16,17 @@ import gg.pingpong.api.global.security.handler.OAuthAuthenticationSuccessHandler; import gg.pingpong.api.global.security.jwt.utils.TokenAuthenticationFilter; import gg.pingpong.api.global.security.repository.OAuthAuthorizationRequestBasedOnCookieRepository; -import gg.pingpong.api.global.security.service.CustomUserDetailsService; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { - private final CustomUserDetailsService userDetailsService; private final OAuthAuthenticationSuccessHandler oAuth2AuthenticationSuccessHandler; private final CorsProperties corsProperties; private final TokenAuthenticationFilter tokenAuthenticationFilter; private final OAuthAuthorizationRequestBasedOnCookieRepository oAuth2AuthorizationRequestBasedOnCookieRepository; - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.userDetailsService(userDetailsService); - } - - @Bean - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); - } - @Override protected void configure(HttpSecurity http) throws Exception { http @@ -52,6 +37,8 @@ protected void configure(HttpSecurity http) throws Exception { .and() .authorizeRequests() .antMatchers("/pingpong/admin/**").hasRole("ADMIN") + .antMatchers("/party/admin/**").hasRole("ADMIN") + .antMatchers("/admin/recruitments/**").hasRole("ADMIN") .antMatchers(HttpMethod.PUT, "/pingpong/users/{intraId}").hasAnyRole("USER", "ADMIN") .antMatchers(HttpMethod.POST, "/pingpong/match").hasAnyRole("USER", "ADMIN") .antMatchers(HttpMethod.POST, "/pingpong/tournaments/{tournamentId}/users").hasAnyRole("USER", "ADMIN") diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/handler/OAuthAuthenticationSuccessHandler.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/handler/OAuthAuthenticationSuccessHandler.java index 85fd9754a..5edce39f5 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/handler/OAuthAuthenticationSuccessHandler.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/handler/OAuthAuthenticationSuccessHandler.java @@ -12,13 +12,13 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.util.UriComponentsBuilder; +import gg.auth.properties.AppProperties; +import gg.auth.utils.AuthTokenProvider; import gg.data.user.User; import gg.data.user.type.RoleType; import gg.pingpong.api.global.security.UserPrincipal; -import gg.pingpong.api.global.security.config.properties.AppProperties; import gg.pingpong.api.global.security.cookie.CookieUtil; import gg.pingpong.api.global.security.jwt.repository.JwtRedisRepository; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.global.security.jwt.utils.TokenHeaders; import gg.pingpong.api.global.utils.ApplicationYmlRead; import gg.repo.user.UserRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/jwt/utils/TokenAuthenticationFilter.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/jwt/utils/TokenAuthenticationFilter.java index f9beda9b5..9758a9f54 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/jwt/utils/TokenAuthenticationFilter.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/jwt/utils/TokenAuthenticationFilter.java @@ -18,8 +18,11 @@ import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; -import gg.pingpong.api.global.security.service.CustomUserDetailsService; -import gg.pingpong.api.global.utils.HeaderUtil; +import gg.auth.utils.AuthTokenProvider; +import gg.auth.utils.HeaderUtil; +import gg.data.user.User; +import gg.pingpong.api.global.security.UserPrincipal; +import gg.repo.user.UserRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -28,7 +31,7 @@ @Component public class TokenAuthenticationFilter extends OncePerRequestFilter { private final AuthTokenProvider tokenProvider; - private final CustomUserDetailsService customUserDetailsService; + private final UserRepository userRepository; @Override protected void doFilterInternal( @@ -55,7 +58,9 @@ private OAuth2AuthenticationToken validate(HttpServletRequest request) { Long userId = tokenProvider.getUserIdFromAccessToken(accessToken); //access token ๊ฒ€์ฆ if (userId != null) { - UserDetails userDetails = customUserDetailsService.loadUserById(userId); + User loginUser = userRepository.findById(userId) + .orElseThrow(() -> new RuntimeException("user not found in db")); + UserDetails userDetails = UserPrincipal.create(loginUser); return new OAuth2AuthenticationToken((OAuth2User)userDetails, userDetails.getAuthorities(), "42"); } throw new RuntimeException("token not validated"); diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/service/CustomOAuth2UserService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/service/CustomOAuth2UserService.java index 3976762b5..288d049d4 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/service/CustomOAuth2UserService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/service/CustomOAuth2UserService.java @@ -12,9 +12,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.SnsType; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/service/CustomUserDetailsService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/service/CustomUserDetailsService.java deleted file mode 100644 index ea0fd803d..000000000 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/security/service/CustomUserDetailsService.java +++ /dev/null @@ -1,31 +0,0 @@ -package gg.pingpong.api.global.security.service; - -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import gg.data.user.User; -import gg.pingpong.api.global.security.UserPrincipal; -import gg.pingpong.api.user.user.service.UserFindService; -import gg.utils.exception.user.UserNotFoundException; -import lombok.RequiredArgsConstructor; - -@Service -@RequiredArgsConstructor -@Transactional -public class CustomUserDetailsService implements UserDetailsService { - - private final UserFindService userFindService; - - @Override - public UserDetails loadUserByUsername(String username) throws UserNotFoundException { - User user = userFindService.findByIntraId(username); - return UserPrincipal.create(user); - } - - public UserDetails loadUserById(Long id) { - User user = userFindService.findUserById(id); - return UserPrincipal.create(user); - } -} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/ItemImageHandler.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/ItemImageHandler.java index 5b87aacc4..cd61914f0 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/ItemImageHandler.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/ItemImageHandler.java @@ -13,7 +13,7 @@ import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; -import gg.data.store.Item; +import gg.data.pingpong.store.Item; @Component public class ItemImageHandler { diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/aws/AsyncNewItemImageUploader.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/aws/AsyncNewItemImageUploader.java index fafc55d89..341643928 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/aws/AsyncNewItemImageUploader.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/global/utils/aws/AsyncNewItemImageUploader.java @@ -7,7 +7,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -import gg.data.store.Item; +import gg.data.pingpong.store.Item; import gg.pingpong.api.global.utils.ItemImageHandler; @Component diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/GameController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/GameController.java index b8138959c..74543d8d8 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/GameController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/GameController.java @@ -16,8 +16,9 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import gg.data.game.type.Mode; -import gg.pingpong.api.global.utils.argumentresolver.Login; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; +import gg.data.pingpong.game.type.Mode; import gg.pingpong.api.user.game.controller.request.GameListReqDto; import gg.pingpong.api.user.game.controller.request.NormalGameListReqDto; import gg.pingpong.api.user.game.controller.request.NormalResultReqDto; @@ -30,7 +31,6 @@ import gg.pingpong.api.user.game.service.GameFindService; import gg.pingpong.api.user.game.service.GameService; import gg.pingpong.api.user.rank.redis.RankRedisService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.exception.ErrorCode; import gg.utils.exception.custom.BusinessException; import gg.utils.exception.custom.InvalidParameterException; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/request/GameListReqDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/request/GameListReqDto.java index 0ec4e79aa..b1a5a5cdf 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/request/GameListReqDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/request/GameListReqDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.game.controller.request; -import gg.data.game.type.StatusType; +import gg.data.pingpong.game.type.StatusType; import lombok.Getter; @Getter diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/request/NormalGameListReqDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/request/NormalGameListReqDto.java index 98c4380ea..2ebcd14d5 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/request/NormalGameListReqDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/request/NormalGameListReqDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.game.controller.request; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.utils.dto.PageRequestDto; import lombok.Getter; import lombok.Setter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/response/GameResultResDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/response/GameResultResDto.java index 77e51ae73..1235d9176 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/response/GameResultResDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/controller/response/GameResultResDto.java @@ -8,7 +8,7 @@ import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; -import gg.data.game.type.Mode; +import gg.data.pingpong.game.type.Mode; import gg.pingpong.api.user.game.dto.TeamUserInfoDto; import gg.pingpong.api.user.game.dto.TeamUserListDto; import gg.repo.game.out.GameTeamUser; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/dto/GameTeamInfo.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/dto/GameTeamInfo.java index e0016a67d..50f2f2255 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/dto/GameTeamInfo.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/dto/GameTeamInfo.java @@ -3,8 +3,8 @@ import java.time.LocalDateTime; import java.util.List; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; import gg.repo.game.out.GameTeamUserInfo; import gg.utils.exception.game.GameDataConsistencyException; import lombok.Getter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameFindService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameFindService.java index caaf78c60..35fd2ab3e 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameFindService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameFindService.java @@ -1,5 +1,6 @@ package gg.pingpong.api.user.game.service; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -10,9 +11,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; import gg.pingpong.api.user.game.controller.response.GameListResDto; import gg.pingpong.api.user.game.controller.response.GameResultResDto; import gg.repo.game.GameRepository; @@ -124,7 +125,7 @@ public GameListResDto allGameList(Pageable pageable, String status) { @Cacheable(value = "allGameListByUser", cacheManager = "gameCacheManager", key = "#pageable.pageNumber + #pageable.pageSize + #pageable.sort.toString() + #status + #intra") public GameListResDto allGameListUser(Pageable pageable, String intra, String status) { - List statusTypes = Arrays.asList(StatusType.END.name()); + List statusTypes = new ArrayList<>(List.of(StatusType.END.name())); if (status != null && status.equals("LIVE")) { statusTypes.add(StatusType.LIVE.name()); statusTypes.add(StatusType.WAIT.name()); diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameService.java index 9f9fba0ab..23c306514 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameService.java @@ -8,15 +8,15 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.PChange; -import gg.data.game.TeamUser; -import gg.data.game.type.StatusType; -import gg.data.match.type.TournamentMatchStatus; -import gg.data.season.Season; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.type.RoundNumber; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.PChange; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.match.type.TournamentMatchStatus; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.type.RoundNumber; import gg.pingpong.api.global.utils.ExpLevelCalculator; import gg.pingpong.api.user.game.controller.request.NormalResultReqDto; import gg.pingpong.api.user.game.controller.request.RankResultReqDto; @@ -254,27 +254,34 @@ private TeamUser findTeamId(Long teamId, List teamUsers) { throw new TeamIdNotMatchException(); } + /** + *

์ด๋ฏธ ์ ์ˆ˜๊ฐ€ ์ž…๋ ฅ ๋˜์ง€ ์•Š์€ ๊ฒŒ์ž„์ด๋ผ๋ฉด scoreDto์˜ ์ ์ˆ˜๋กœ ๊ฐฑ์‹ ์‹œ์ผœ์ค๋‹ˆ๋‹ค.

+ *

์œ ์ €์˜ ๊ฒฝ๊ธฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด InvalidParameterException ๋ฐ˜ํ™˜

+ * @param game + * @param scoreDto ํƒ€๊ฒŸ ์ ์ˆ˜ + * @param userId ์œ ์ € + * @return + */ private Boolean updateRankGameScore(Game game, RankResultReqDto scoreDto, Long userId) { List teams = teamUserRepository.findAllByGameId(game.getId()); TeamUser myTeam = findTeamId(scoreDto.getMyTeamId(), teams); TeamUser enemyTeam = findTeamId(scoreDto.getEnemyTeamId(), teams); if (!myTeam.getUser().getId().equals(userId)) { throw new InvalidParameterException("team user ์ •๋ณด ๋ถˆ์ผ์น˜.", ErrorCode.VALID_FAILED); + } + if (myTeam.getTeam().getScore().equals(-1) && enemyTeam.getTeam().getScore().equals(-1)) { + setTeamScore(myTeam, scoreDto.getMyTeamScore(), + scoreDto.getMyTeamScore() > scoreDto.getEnemyTeamScore()); + setTeamScore(enemyTeam, scoreDto.getEnemyTeamScore(), + scoreDto.getMyTeamScore() < scoreDto.getEnemyTeamScore()); + expUpdates(game, teams); + rankRedisService.updateRankRedis(myTeam, enemyTeam, game); + tierService.updateAllTier(game.getSeason()); } else { - if (myTeam.getTeam().getScore().equals(-1) && enemyTeam.getTeam().getScore().equals(-1)) { - setTeamScore(myTeam, scoreDto.getMyTeamScore(), - scoreDto.getMyTeamScore() > scoreDto.getEnemyTeamScore()); - setTeamScore(enemyTeam, scoreDto.getEnemyTeamScore(), - scoreDto.getMyTeamScore() < scoreDto.getEnemyTeamScore()); - expUpdates(game, teams); - rankRedisService.updateRankRedis(myTeam, enemyTeam, game); - tierService.updateAllTier(game.getSeason()); - } else { - // score ๊ฐ€ ์ด๋ฏธ ์ž…๋ ฅ๋จ - return false; - } - return true; + // score ๊ฐ€ ์ด๋ฏธ ์ž…๋ ฅ๋จ + return false; } + return true; } /** diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameStatusService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameStatusService.java index 987541416..a04c426d9 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameStatusService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/GameStatusService.java @@ -8,11 +8,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.type.StatusType; -import gg.data.manage.SlotManagement; import gg.data.noti.Noti; import gg.data.noti.type.NotiType; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.manage.SlotManagement; import gg.pingpong.api.user.noti.dto.UserNotiDto; import gg.pingpong.api.user.noti.service.NotiService; import gg.pingpong.api.user.noti.service.SnsNotiService; @@ -36,12 +36,14 @@ public class GameStatusService { private final UserService userService; private final SlotManagementRepository slotManagementRepository; + /** + *

game before ์ค‘์— ํ˜„์žฌ ์‹œ์ž‘ ์‹œ๊ฐ„์ธ ๊ฒฝ์šฐ LIVE๋กœ update

+ */ @Transactional @Caching(evict = { @CacheEvict(value = "allGameList", allEntries = true), }) public void updateBeforeToLiveStatus() { - // game before ์ค‘์— ํ˜„์žฌ ์‹œ์ž‘ ์‹œ๊ฐ„์ธ ๊ฒฝ์šฐ LIVE๋กœ update List game = gameRepository.findAllByStatusAndStartTimeLessThanEqual(StatusType.BEFORE, getTime(0)); if (!game.isEmpty()) { cacheDelete(); @@ -54,12 +56,14 @@ public void updateBeforeToLiveStatus() { void cacheDelete() { } + /** + *

game live ์ค‘์— ์ข…๋ฃŒ ์‹œ๊ฐ„์ธ ๊ฒฝ์šฐ wait ๋กœ update

+ */ @Transactional @Caching(evict = { @CacheEvict(value = "allGameList", allEntries = true), }) public void updateLiveToWaitStatus() { - // game live ์ค‘์— ์ข…๋ฃŒ ์‹œ๊ฐ„์ธ ๊ฒฝ์šฐ wait ๋กœ update LocalDateTime endTime = getTime(1); List game = gameRepository.findAllByStatusAndEndTimeLessThanEqual(StatusType.LIVE, endTime); if (!game.isEmpty()) { @@ -70,12 +74,15 @@ public void updateLiveToWaitStatus() { } } + /** + *

๊ฒŒ์ž„์ด ์ œ๋Œ€๋กœ ์„ฑ์‚ฌ๋˜์—ˆ๋‹ค๋ฉด ์•Œ๋ฆผ์„ ๋ณด๋‚ธ๋‹ค.

+ */ @Transactional public void imminentGame() { SlotManagement slotManagement = slotManagementRepository.findCurrent(LocalDateTime.now()) .orElseThrow(SlotNotFoundException::new); List games = gameRepository.findAllByStartTimeLessThanEqual(getTime(slotManagement.getOpenMinute())); - if (games.size() > 2) { + if (games.size() > 2 || games.size() == 1) { log.error("imminent game size is not 2 -> size: " + games.size() + ", check time: " + getTime( slotManagement.getOpenMinute())); throw new GameDataConsistencyException(); @@ -89,7 +96,7 @@ public void imminentGame() { } /** - * private method + *

์œ ์ €์—๊ฒŒ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๋Š” ๋ฉ”์„œ๋“œ

*/ private void notiProcess(GameUser game, String enemyIntra, Integer gameOpenMinute) { Noti noti = notiService.createImminentNoti(userService.getUser(game.getUserId()), enemyIntra, NotiType.IMMINENT, @@ -97,6 +104,11 @@ private void notiProcess(GameUser game, String enemyIntra, Integer gameOpenMinut snsNotiService.sendSnsNotification(noti, new UserNotiDto(game)); } + /** + *

์‹œ๊ฐ„ ๊ตฌํ•˜๋Š” ๋ฉ”์„œ๋“œ

+ * @param plusMiniute + * @return + */ private LocalDateTime getTime(int plusMiniute) { LocalDateTime now = LocalDateTime.now(); LocalDateTime endTime = LocalDateTime.of(now.getYear(), now.getMonthValue(), now.getDayOfMonth(), diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/PChangeService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/PChangeService.java index 53150d946..3f01c1398 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/PChangeService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/game/service/PChangeService.java @@ -5,8 +5,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.PChange; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.PChange; import gg.data.user.User; import gg.repo.game.PChangeRepository; import gg.utils.exception.pchange.PChangeNotExistException; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/manage/controller/FeedbackController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/manage/controller/FeedbackController.java index d66bafeaf..d13fff195 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/manage/controller/FeedbackController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/manage/controller/FeedbackController.java @@ -9,10 +9,10 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import gg.pingpong.api.global.utils.argumentresolver.Login; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; import gg.pingpong.api.user.manage.controller.request.FeedbackRequestDto; import gg.pingpong.api.user.manage.service.FeedbackService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.user.UserRepository; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/manage/service/PenaltyService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/manage/service/PenaltyService.java index 107eb584d..ced4fa96e 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/manage/service/PenaltyService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/manage/service/PenaltyService.java @@ -5,12 +5,12 @@ import org.springframework.stereotype.Service; +import gg.auth.UserDto; import gg.data.manage.Penalty; import gg.data.manage.redis.RedisPenaltyUser; import gg.data.manage.type.PenaltyType; import gg.data.user.User; import gg.pingpong.api.user.manage.redis.PenaltyUserRedisRepository; -import gg.pingpong.api.user.user.dto.UserDto; import gg.pingpong.api.user.user.service.UserFindService; import gg.repo.manage.PenaltyRepository; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/controller/MatchController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/controller/MatchController.java index f515312ba..64f2eae70 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/controller/MatchController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/controller/MatchController.java @@ -15,14 +15,14 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import gg.data.match.type.Option; -import gg.pingpong.api.global.utils.argumentresolver.Login; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; +import gg.data.pingpong.match.type.Option; import gg.pingpong.api.user.match.controller.request.MatchRequestDto; import gg.pingpong.api.user.match.controller.response.MatchStatusResponseListDto; import gg.pingpong.api.user.match.controller.response.SlotStatusResponseListDto; import gg.pingpong.api.user.match.service.MatchFindService; import gg.pingpong.api.user.match.service.MatchService; -import gg.pingpong.api.user.user.dto.UserDto; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/controller/request/MatchRequestDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/controller/request/MatchRequestDto.java index 46f588629..1802e316c 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/controller/request/MatchRequestDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/controller/request/MatchRequestDto.java @@ -8,7 +8,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; -import gg.data.match.type.Option; +import gg.data.pingpong.match.type.Option; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/GameAddDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/GameAddDto.java index 2938b7b14..369e222ae 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/GameAddDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/GameAddDto.java @@ -3,10 +3,10 @@ import java.time.LocalDateTime; import java.util.List; -import gg.data.game.type.Mode; -import gg.data.match.RedisMatchUser; -import gg.data.match.type.Option; -import gg.data.season.Season; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.Option; +import gg.data.pingpong.season.Season; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/MatchStatusDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/MatchStatusDto.java index 62f813079..fff3a5b6d 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/MatchStatusDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/MatchStatusDto.java @@ -5,10 +5,10 @@ import com.fasterxml.jackson.annotation.JsonFormat; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.manage.SlotManagement; -import gg.data.match.RedisMatchTime; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.match.RedisMatchTime; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/SlotStatusDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/SlotStatusDto.java index dbab08775..c831b42d7 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/SlotStatusDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/dto/SlotStatusDto.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; -import gg.data.match.type.SlotStatus; +import gg.data.pingpong.match.type.SlotStatus; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/GameUpdateService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/GameUpdateService.java index 90753d0ab..a42deb0c9 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/GameUpdateService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/GameUpdateService.java @@ -5,16 +5,16 @@ import org.springframework.stereotype.Service; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.manage.SlotManagement; +import gg.auth.UserDto; import gg.data.noti.Noti; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.manage.SlotManagement; import gg.data.user.User; import gg.pingpong.api.user.match.dto.GameAddDto; import gg.pingpong.api.user.noti.service.NotiService; import gg.pingpong.api.user.noti.service.SnsNotiService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.game.GameRepository; import gg.repo.game.TeamRepository; import gg.repo.game.TeamUserRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchFindService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchFindService.java index 0b928053b..1a5d9f4af 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchFindService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchFindService.java @@ -10,15 +10,16 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.type.StatusType; -import gg.data.manage.SlotManagement; -import gg.data.match.RedisMatchTime; -import gg.data.match.RedisMatchUser; -import gg.data.match.type.Option; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; +import gg.auth.UserDto; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.match.RedisMatchTime; +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.Option; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.data.user.type.RoleType; import gg.pingpong.api.user.match.controller.response.MatchStatusResponseListDto; @@ -26,7 +27,6 @@ import gg.pingpong.api.user.match.dto.MatchStatusDto; import gg.pingpong.api.user.match.utils.SlotGenerator; import gg.pingpong.api.user.season.service.SeasonFindService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.game.GameRepository; import gg.repo.manage.SlotManagementRepository; import gg.repo.match.RedisMatchTimeRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchService.java index 42993ffcb..5dbd3c9c8 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchService.java @@ -9,22 +9,22 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.match.RedisMatchTime; -import gg.data.match.RedisMatchUser; -import gg.data.match.type.Option; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; -import gg.data.tournament.Tournament; -import gg.data.tournament.type.TournamentStatus; +import gg.auth.UserDto; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.match.RedisMatchTime; +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.Option; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.type.TournamentStatus; import gg.data.user.User; import gg.pingpong.api.user.manage.service.PenaltyService; import gg.pingpong.api.user.match.dto.GameAddDto; import gg.pingpong.api.user.match.utils.MatchCalculator; import gg.pingpong.api.user.season.service.SeasonFindService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.game.GameRepository; import gg.repo.manage.SlotManagementRepository; import gg.repo.match.RedisMatchTimeRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchTournamentService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchTournamentService.java index 1b03f19b5..5afbf150b 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchTournamentService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/service/MatchTournamentService.java @@ -1,7 +1,7 @@ package gg.pingpong.api.user.match.service; -import static gg.data.match.type.TournamentMatchStatus.*; -import static gg.data.tournament.type.RoundNumber.*; +import static gg.data.pingpong.match.type.TournamentMatchStatus.*; +import static gg.data.pingpong.tournament.type.RoundNumber.*; import java.time.LocalDateTime; import java.util.ArrayList; @@ -16,21 +16,21 @@ import org.springframework.stereotype.Service; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.manage.SlotManagement; -import gg.data.match.type.TournamentMatchStatus; import gg.data.noti.type.NotiType; -import gg.data.season.Season; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.RoundNumber; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.match.type.TournamentMatchStatus; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.RoundNumber; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; import gg.data.user.User; import gg.pingpong.api.admin.noti.controller.request.SendNotiAdminRequestDto; import gg.pingpong.api.admin.noti.service.NotiAdminService; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/utils/MatchCalculator.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/utils/MatchCalculator.java index 413bb987e..e34dbb94a 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/utils/MatchCalculator.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/utils/MatchCalculator.java @@ -3,9 +3,9 @@ import java.util.List; import java.util.Optional; -import gg.data.match.RedisMatchUser; -import gg.data.match.type.Option; -import gg.data.match.type.SlotStatus; +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.Option; +import gg.data.pingpong.match.type.SlotStatus; public class MatchCalculator { private final Integer pppGap; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/utils/SlotGenerator.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/utils/SlotGenerator.java index da68bcb16..0622b4ebe 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/utils/SlotGenerator.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/match/utils/SlotGenerator.java @@ -6,15 +6,15 @@ import java.util.List; import java.util.Set; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.manage.SlotManagement; -import gg.data.match.RedisMatchTime; -import gg.data.match.RedisMatchUser; -import gg.data.match.type.Option; -import gg.data.match.type.SlotStatus; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.match.RedisMatchTime; +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.Option; +import gg.data.pingpong.match.type.SlotStatus; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; import gg.pingpong.api.user.match.controller.response.SlotStatusResponseListDto; import gg.pingpong.api.user.match.dto.SlotStatusDto; import lombok.Getter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/controller/NotiController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/controller/NotiController.java index f964c11c6..04b07ab36 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/controller/NotiController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/controller/NotiController.java @@ -9,11 +9,11 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import gg.pingpong.api.global.utils.argumentresolver.Login; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; import gg.pingpong.api.user.noti.controller.response.NotiListResponseDto; import gg.pingpong.api.user.noti.controller.response.NotiResponseDto; import gg.pingpong.api.user.noti.service.NotiService; -import gg.pingpong.api.user.user.dto.UserDto; import lombok.AllArgsConstructor; @RestController diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/dto/NotiDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/dto/NotiDto.java index 9d38ca674..b77855a21 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/dto/NotiDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/dto/NotiDto.java @@ -3,9 +3,9 @@ import java.time.LocalDateTime; import java.util.Objects; +import gg.auth.UserDto; import gg.data.noti.Noti; import gg.data.noti.type.NotiType; -import gg.pingpong.api.user.user.dto.UserDto; import lombok.Builder; import lombok.Getter; @@ -56,7 +56,7 @@ public boolean equals(Object obj) { if (!(obj instanceof NotiDto)) { return false; } - NotiDto other = (NotiDto)obj; + NotiDto other = (NotiDto) obj; return Objects.equals(id, other.id) && Objects.equals(user, other.user) && Objects.equals(type, other.type) diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/NotiService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/NotiService.java index 94dce8928..c7d6148ed 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/NotiService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/NotiService.java @@ -8,12 +8,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import gg.auth.UserDto; import gg.data.noti.Noti; import gg.data.noti.type.NotiType; import gg.data.user.User; import gg.pingpong.api.user.noti.controller.response.NotiResponseDto; import gg.pingpong.api.user.noti.dto.NotiDto; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.noti.NotiRepository; import gg.repo.user.UserRepository; import gg.utils.exception.ErrorCode; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/PartyNotiService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/PartyNotiService.java new file mode 100644 index 000000000..efbfe9deb --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/PartyNotiService.java @@ -0,0 +1,25 @@ +package gg.pingpong.api.user.noti.service; + +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.data.user.User; +import gg.pingpong.api.user.noti.service.sns.SlackPartybotService; +import lombok.extern.slf4j.Slf4j; + +@Service +@Slf4j +public class PartyNotiService { + private final SlackPartybotService slackPartybotService; + + public PartyNotiService(SlackPartybotService slackPartybotService) { + this.slackPartybotService = slackPartybotService; + } + + @Transactional(readOnly = true) + public void sendPartyNotifications(List users) { + slackPartybotService.partySend(users); + } +} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/SnsNotiService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/SnsNotiService.java index 656a9958f..3287ee3e1 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/SnsNotiService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/SnsNotiService.java @@ -3,12 +3,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import gg.auth.UserDto; import gg.data.noti.Noti; import gg.data.user.type.SnsType; import gg.pingpong.api.user.noti.dto.UserNotiDto; import gg.pingpong.api.user.noti.service.sns.NotiMailSender; import gg.pingpong.api.user.noti.service.sns.SlackbotService; -import gg.pingpong.api.user.user.dto.UserDto; import lombok.extern.slf4j.Slf4j; @Service diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/NotiMailSender.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/NotiMailSender.java index 970a1cff6..3cbc55c50 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/NotiMailSender.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/NotiMailSender.java @@ -7,11 +7,11 @@ import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Component; +import gg.auth.UserDto; import gg.data.noti.Noti; import gg.pingpong.api.global.utils.AsyncMailSender; import gg.pingpong.api.user.noti.dto.UserNotiDto; import gg.pingpong.api.user.noti.service.NotiService; -import gg.pingpong.api.user.user.dto.UserDto; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/SlackPartybotService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/SlackPartybotService.java new file mode 100644 index 000000000..16cb97331 --- /dev/null +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/SlackPartybotService.java @@ -0,0 +1,113 @@ +package gg.pingpong.api.user.noti.service.sns; + +import static gg.pingpong.api.user.noti.service.sns.SlackbotUtils.*; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import gg.data.user.User; +import gg.pingpong.api.global.utils.external.ApiUtil; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Component +@Slf4j +@RequiredArgsConstructor +public class SlackPartybotService { + @Value("${slack.xoxbToken}") + private String authenticationToken; + + private final ApiUtil apiUtil; + + private String getSlackUserId(String intraId) { + String userEmail = intraId + intraEmailSuffix; + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + headers.add(HttpHeaders.AUTHORIZATION, authenticationPrefix + authenticationToken); + + MultiValueMap parameters = new LinkedMultiValueMap<>(); + parameters.add("email", userEmail); + + SlackUserInfoRes res = apiUtil.apiCall(userIdGetUrl, SlackUserInfoRes.class, + headers, parameters, HttpMethod.POST); + + if (res == null || res.getUser() == null) { + throw new RuntimeException("์Šฌ๋ž™ API ๊ณ ์žฅ์œผ๋กœ ์ธํ•œ NULL ์ฐธ์กฐ" + intraId); + } + + return res.user.id; + } + + private String createGroupChannelId(List slackUserIds) { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add(HttpHeaders.AUTHORIZATION, authenticationPrefix + authenticationToken); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + + Map bodyMap = new HashMap<>(); + bodyMap.put("users", String.join(",", slackUserIds)); + + ConversationRes res = apiUtil.apiCall(conversationsUrl, ConversationRes.class, + httpHeaders, bodyMap, HttpMethod.POST); + + return res.channel.id; + } + + @Async("asyncExecutor") + public void partySend(List users) { + List slackUserIds = users.stream() + .map(User::getIntraId) + .map(this::getSlackUserId) + .collect(Collectors.toList()); + + String slackChannelId = createGroupChannelId(slackUserIds); + sendGroupMessage(slackChannelId, "ํŒŒํ‹ฐ์š”์ •๐Ÿงš์œผ๋กœ๋ถ€ํ„ฐ ํŽธ์ง€๊ฐ€ ๋„์ฐฉํ–ˆ์Šต๋‹ˆ๋‹ค." + + "\n์žฅ์†Œ ๋ฐ ์‹œ๊ฐ„์„ ์ƒํ˜ธ ํ˜‘์˜ํ•ด์„œ ์ง„ํ–‰ํ•ด์ฃผ์„ธ์š”." + + "\nํŒŒํ‹ฐ์›์ด ์—ฐ๋ฝ๋‘์ ˆ์ด๋ผ๋ฉด $$๋งˆ์ง€ ๋ชปํ•ด ์‹ ๊ณ $$ ----> https://42gg.kr"); + } + + private void sendGroupMessage(String channelId, String message) { + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.AUTHORIZATION, authenticationPrefix + authenticationToken); + headers.setContentType(MediaType.APPLICATION_JSON); + + Map bodyMap = new HashMap<>(); + bodyMap.put("channel", channelId); + bodyMap.put("text", message); + + apiUtil.apiCall(sendMessageUrl, String.class, headers, bodyMap, HttpMethod.POST); + } + + @Getter + static class ConversationRes { + private Boolean ok; + private Channel channel; + + @Getter + static class Channel { + private String id; + } + } + + @Getter + static class SlackUserInfoRes { + private Boolean ok; + private SlackUser user; + + @Getter + static class SlackUser { + private String id; + } + } +} diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/SlackbotService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/SlackbotService.java index f645b9d4b..c6660b8bc 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/SlackbotService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/noti/service/sns/SlackbotService.java @@ -14,11 +14,11 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import gg.auth.UserDto; import gg.data.noti.Noti; import gg.pingpong.api.global.utils.external.ApiUtil; import gg.pingpong.api.user.noti.dto.UserNotiDto; import gg.pingpong.api.user.noti.service.NotiService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.exception.noti.SlackSendException; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -45,6 +45,11 @@ private String getSlackUserId(String intraId) { SlackUserInfoResponse res = apiUtil.apiCall(userIdGetUrl, SlackUserInfoResponse.class, headers, parameters, HttpMethod.POST); + + if (res == null || res.getUser() == null) { + throw new RuntimeException("์Šฌ๋ž™ API ๊ณ ์žฅ์œผ๋กœ ์ธํ•œ NULL ์ฐธ์กฐ" + intraId); + } + return res.user.id; } @@ -108,7 +113,6 @@ static class ConversationResponse { static class Channel { private String id; } - } @Getter diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/controller/RankController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/controller/RankController.java index 825c3b5e4..9ffefe890 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/controller/RankController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/controller/RankController.java @@ -8,12 +8,12 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import gg.pingpong.api.global.dto.PageRequestDto; -import gg.pingpong.api.global.utils.argumentresolver.Login; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; import gg.pingpong.api.user.rank.controller.response.ExpRankPageResponseDto; import gg.pingpong.api.user.rank.controller.response.RankPageResponseDto; import gg.pingpong.api.user.rank.service.RankService; -import gg.pingpong.api.user.user.dto.UserDto; +import gg.utils.dto.PageRequestDto; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/controller/RankV2Controller.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/controller/RankV2Controller.java index c625edb4c..8384c4347 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/controller/RankV2Controller.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/controller/RankV2Controller.java @@ -10,12 +10,12 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import gg.pingpong.api.global.dto.PageRequestDto; -import gg.pingpong.api.global.utils.argumentresolver.Login; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; import gg.pingpong.api.user.rank.controller.response.ExpRankPageResponseDto; import gg.pingpong.api.user.rank.controller.response.RankPageResponseDto; import gg.pingpong.api.user.rank.service.RankService; -import gg.pingpong.api.user.user.dto.UserDto; +import gg.utils.dto.PageRequestDto; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/dto/RankDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/dto/RankDto.java index ca045c620..854c4b1a2 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/dto/RankDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/dto/RankDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.rank.dto; -import gg.data.rank.redis.RankRedis; +import gg.data.pingpong.rank.redis.RankRedis; import gg.data.user.User; import gg.repo.rank.RankV2Dto; import lombok.AllArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/redis/RankRedisService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/redis/RankRedisService.java index 945a9d3e4..56768c8ff 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/redis/RankRedisService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/redis/RankRedisService.java @@ -8,12 +8,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.TeamUser; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; import gg.pingpong.api.global.utils.EloRating; import gg.pingpong.api.user.game.service.PChangeService; import gg.pingpong.api.user.season.service.SeasonFindService; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/redis/RedisUploadService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/redis/RedisUploadService.java index e494a6255..a16fbd540 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/redis/RedisUploadService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/redis/RedisUploadService.java @@ -11,7 +11,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.rank.redis.RankRedis; +import gg.data.pingpong.rank.redis.RankRedis; import gg.repo.rank.RankRepository; import gg.repo.rank.redis.RankRedisRepository; import gg.repo.season.SeasonRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/RankFindService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/RankFindService.java index 5ad1053dd..f339eadc4 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/RankFindService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/RankFindService.java @@ -2,7 +2,7 @@ import org.springframework.stereotype.Service; -import gg.data.rank.Rank; +import gg.data.pingpong.rank.Rank; import gg.repo.rank.RankRepository; import gg.utils.exception.rank.RankNotFoundException; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/RankService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/RankService.java index affb950d5..82e31ba3b 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/RankService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/RankService.java @@ -11,15 +11,15 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; +import gg.auth.UserDto; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.pingpong.api.user.rank.controller.response.ExpRankPageResponseDto; import gg.pingpong.api.user.rank.controller.response.RankPageResponseDto; import gg.pingpong.api.user.rank.dto.ExpRankDto; import gg.pingpong.api.user.rank.dto.RankDto; import gg.pingpong.api.user.season.service.SeasonFindService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.rank.RankRepository; import gg.repo.rank.redis.RankRedisRepository; import gg.repo.user.ExpRankV2Dto; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/TierService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/TierService.java index f692dd0cb..9253e3af0 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/TierService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/rank/service/TierService.java @@ -6,9 +6,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.season.Season; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.season.Season; import gg.repo.rank.RankRepository; import gg.repo.rank.TierRepository; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/controller/response/SeasonResDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/controller/response/SeasonResDto.java index 9b86af272..aee16d5aa 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/controller/response/SeasonResDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/controller/response/SeasonResDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.season.controller.response; -import gg.data.season.Season; +import gg.data.pingpong.season.Season; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/dto/CurSeason.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/dto/CurSeason.java index e171e925b..44c3dddf9 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/dto/CurSeason.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/dto/CurSeason.java @@ -2,7 +2,7 @@ import java.time.LocalDateTime; -import gg.data.season.Season; +import gg.data.pingpong.season.Season; import lombok.Getter; @Getter diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/service/SeasonFindService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/service/SeasonFindService.java index 766376a37..3f20659df 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/service/SeasonFindService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/season/service/SeasonFindService.java @@ -5,8 +5,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.season.Season; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.season.Season; import gg.repo.game.GameRepository; import gg.repo.season.SeasonRepository; import gg.utils.exception.game.GameNotExistException; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/ItemController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/ItemController.java index 194b4cbaa..4e60188d5 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/ItemController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/ItemController.java @@ -15,13 +15,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import gg.pingpong.api.global.dto.PageRequestDto; -import gg.pingpong.api.global.utils.argumentresolver.Login; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; import gg.pingpong.api.user.store.controller.request.ItemGiftRequestDto; import gg.pingpong.api.user.store.controller.response.ItemStoreListResponseDto; import gg.pingpong.api.user.store.controller.response.UserItemListResponseDto; import gg.pingpong.api.user.store.service.ItemService; -import gg.pingpong.api.user.user.dto.UserDto; +import gg.utils.dto.PageRequestDto; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/MegaphoneController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/MegaphoneController.java index b7ac85a83..682006d6a 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/MegaphoneController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/MegaphoneController.java @@ -15,12 +15,12 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import gg.pingpong.api.global.utils.argumentresolver.Login; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; import gg.pingpong.api.user.store.controller.request.MegaphoneUseRequestDto; import gg.pingpong.api.user.store.controller.response.MegaphoneDetailResponseDto; import gg.pingpong.api.user.store.controller.response.MegaphoneTodayListResponseDto; import gg.pingpong.api.user.store.service.MegaphoneService; -import gg.pingpong.api.user.user.dto.UserDto; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/ItemStoreResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/ItemStoreResponseDto.java index 619125bc3..645635b0a 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/ItemStoreResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/ItemStoreResponseDto.java @@ -1,7 +1,7 @@ package gg.pingpong.api.user.store.controller.response; -import gg.data.store.Item; -import gg.data.store.type.ItemType; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.type.ItemType; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/MegaphoneDetailResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/MegaphoneDetailResponseDto.java index 4b9d4b0b9..5d47f0e7c 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/MegaphoneDetailResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/MegaphoneDetailResponseDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.store.controller.response; -import gg.data.store.Megaphone; +import gg.data.pingpong.store.Megaphone; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/MegaphoneTodayListResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/MegaphoneTodayListResponseDto.java index 6cc63351a..2c213eb78 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/MegaphoneTodayListResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/MegaphoneTodayListResponseDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.store.controller.response; -import gg.data.store.redis.MegaphoneRedis; +import gg.data.pingpong.store.redis.MegaphoneRedis; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/UserItemResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/UserItemResponseDto.java index 43a4a31ca..84597a665 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/UserItemResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/controller/response/UserItemResponseDto.java @@ -1,9 +1,9 @@ package gg.pingpong.api.user.store.controller.response; -import gg.data.store.Item; -import gg.data.store.Receipt; -import gg.data.store.type.ItemStatus; -import gg.data.store.type.ItemType; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.type.ItemStatus; +import gg.data.pingpong.store.type.ItemType; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/redis/MegaphoneRedisRepository.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/redis/MegaphoneRedisRepository.java index 564cd7848..7d06098fd 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/redis/MegaphoneRedisRepository.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/redis/MegaphoneRedisRepository.java @@ -6,7 +6,7 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Repository; -import gg.data.store.redis.MegaphoneRedis; +import gg.data.pingpong.store.redis.MegaphoneRedis; import lombok.RequiredArgsConstructor; @Repository diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/CoinHistoryService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/CoinHistoryService.java index 530ad372c..ce28f84ae 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/CoinHistoryService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/CoinHistoryService.java @@ -5,9 +5,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.store.CoinHistory; -import gg.data.store.Item; -import gg.data.store.type.HistoryType; +import gg.data.pingpong.store.CoinHistory; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.type.HistoryType; import gg.data.user.User; import gg.repo.store.CoinHistoryRepository; import gg.repo.store.CoinPolicyRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/ItemService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/ItemService.java index 6df2287e1..a63463d63 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/ItemService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/ItemService.java @@ -9,10 +9,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.store.Item; -import gg.data.store.Receipt; -import gg.data.store.type.ItemStatus; -import gg.data.store.type.ItemType; +import gg.auth.UserDto; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.type.ItemStatus; +import gg.data.pingpong.store.type.ItemType; import gg.data.user.User; import gg.data.user.type.RoleType; import gg.pingpong.api.user.noti.service.NotiService; @@ -20,7 +21,6 @@ import gg.pingpong.api.user.store.controller.response.ItemStoreResponseDto; import gg.pingpong.api.user.store.controller.response.UserItemListResponseDto; import gg.pingpong.api.user.store.controller.response.UserItemResponseDto; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.store.ItemRepository; import gg.repo.store.ReceiptRepository; import gg.repo.store.UserItemRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/MegaphoneService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/MegaphoneService.java index b478ed9dd..0449a70ea 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/MegaphoneService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/MegaphoneService.java @@ -9,18 +9,18 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.store.Megaphone; -import gg.data.store.Receipt; -import gg.data.store.redis.MegaphoneRedis; -import gg.data.store.type.ItemStatus; -import gg.data.store.type.ItemType; +import gg.auth.UserDto; +import gg.data.pingpong.store.Megaphone; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.redis.MegaphoneRedis; +import gg.data.pingpong.store.type.ItemStatus; +import gg.data.pingpong.store.type.ItemType; import gg.data.user.User; import gg.data.user.type.RoleType; import gg.pingpong.api.user.store.controller.request.MegaphoneUseRequestDto; import gg.pingpong.api.user.store.controller.response.MegaphoneDetailResponseDto; import gg.pingpong.api.user.store.controller.response.MegaphoneTodayListResponseDto; import gg.pingpong.api.user.store.redis.MegaphoneRedisRepository; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.store.MegaphoneRepository; import gg.repo.store.ReceiptRepository; import gg.repo.user.UserRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/UserCoinChangeService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/UserCoinChangeService.java index e0bbe3ad6..e8358f9db 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/UserCoinChangeService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/store/service/UserCoinChangeService.java @@ -5,9 +5,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.store.Item; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.store.Item; import gg.data.user.User; import gg.pingpong.api.user.game.service.GameFindService; import gg.pingpong.api.user.store.dto.UserGameCoinResultDto; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/TournamentController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/TournamentController.java index c2294aa7c..8026836e2 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/TournamentController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/TournamentController.java @@ -17,14 +17,14 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import gg.pingpong.api.global.utils.argumentresolver.Login; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; import gg.pingpong.api.user.tournament.controller.request.TournamentFilterRequestDto; import gg.pingpong.api.user.tournament.controller.response.TournamentGameListResponseDto; import gg.pingpong.api.user.tournament.controller.response.TournamentListResponseDto; import gg.pingpong.api.user.tournament.controller.response.TournamentResponseDto; import gg.pingpong.api.user.tournament.controller.response.TournamentUserRegistrationResponseDto; import gg.pingpong.api.user.tournament.service.TournamentService; -import gg.pingpong.api.user.user.dto.UserDto; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/request/TournamentFilterRequestDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/request/TournamentFilterRequestDto.java index a0f1d7621..ee16b1870 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/request/TournamentFilterRequestDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/request/TournamentFilterRequestDto.java @@ -1,8 +1,8 @@ package gg.pingpong.api.user.tournament.controller.request; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; -import gg.pingpong.api.global.dto.PageRequestDto; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; +import gg.utils.dto.PageRequestDto; import lombok.Getter; @Getter diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentGameResDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentGameResDto.java index 246488cc0..364d0c49a 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentGameResDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentGameResDto.java @@ -1,7 +1,7 @@ package gg.pingpong.api.user.tournament.controller.response; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.type.TournamentRound; import gg.pingpong.api.user.game.controller.response.GameResultResDto; import gg.repo.game.out.GameTeamUser; import lombok.AccessLevel; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentResponseDto.java index 2a10b819e..6a5b14322 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentResponseDto.java @@ -2,10 +2,10 @@ import java.time.LocalDateTime; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; import gg.pingpong.api.user.user.dto.UserImageDto; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserListResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserListResponseDto.java index 818afd763..5f98bca9e 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserListResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserListResponseDto.java @@ -4,7 +4,7 @@ import java.util.Comparator; import java.util.List; -import gg.data.tournament.TournamentUser; +import gg.data.pingpong.tournament.TournamentUser; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserRegistrationResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserRegistrationResponseDto.java index 5858017cb..dfcba4508 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserRegistrationResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserRegistrationResponseDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.tournament.controller.response; -import gg.data.tournament.type.TournamentUserStatus; +import gg.data.pingpong.tournament.type.TournamentUserStatus; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserResponseDto.java index acb5f83ae..bc6ab8e8b 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/controller/response/TournamentUserResponseDto.java @@ -2,7 +2,7 @@ import java.time.LocalDateTime; -import gg.data.tournament.TournamentUser; +import gg.data.pingpong.tournament.TournamentUser; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/service/TournamentService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/service/TournamentService.java index 854e3b995..4d71e4f2e 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/service/TournamentService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/tournament/service/TournamentService.java @@ -14,15 +14,16 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import gg.auth.UserDto; import gg.data.noti.type.NotiType; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.RoundNumber; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; -import gg.data.tournament.type.TournamentUserStatus; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.RoundNumber; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; +import gg.data.pingpong.tournament.type.TournamentUserStatus; import gg.data.user.User; import gg.pingpong.api.admin.noti.controller.request.SendNotiAdminRequestDto; import gg.pingpong.api.admin.noti.service.NotiAdminService; @@ -32,7 +33,6 @@ import gg.pingpong.api.user.tournament.controller.response.TournamentListResponseDto; import gg.pingpong.api.user.tournament.controller.response.TournamentResponseDto; import gg.pingpong.api.user.tournament.controller.response.TournamentUserRegistrationResponseDto; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.game.GameRepository; import gg.repo.game.out.GameTeamUser; import gg.repo.tournarment.TournamentGameRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/UserController.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/UserController.java index 3afc31df1..a8f277cc6 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/UserController.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/UserController.java @@ -26,13 +26,13 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import gg.data.game.type.Mode; +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; +import gg.data.pingpong.game.type.Mode; import gg.data.user.type.OauthType; import gg.data.user.type.RoleType; -import gg.pingpong.api.global.dto.PageRequestDto; import gg.pingpong.api.global.security.cookie.CookieUtil; import gg.pingpong.api.global.security.jwt.utils.TokenHeaders; -import gg.pingpong.api.global.utils.argumentresolver.Login; import gg.pingpong.api.user.user.controller.request.UserModifyRequestDto; import gg.pingpong.api.user.user.controller.request.UserProfileImageRequestDto; import gg.pingpong.api.user.user.controller.response.UserAttendanceResponseDto; @@ -47,13 +47,13 @@ import gg.pingpong.api.user.user.controller.response.UserSearchResponseDto; import gg.pingpong.api.user.user.dto.UserAccessTokenDto; import gg.pingpong.api.user.user.dto.UserBackgroundDto; -import gg.pingpong.api.user.user.dto.UserDto; import gg.pingpong.api.user.user.dto.UserEdgeDto; import gg.pingpong.api.user.user.dto.UserOauthDto; import gg.pingpong.api.user.user.dto.UserTextColorDto; import gg.pingpong.api.user.user.service.UserAuthenticationService; import gg.pingpong.api.user.user.service.UserCoinService; import gg.pingpong.api.user.user.service.UserService; +import gg.utils.dto.PageRequestDto; import gg.utils.exception.user.KakaoOauth2AlreadyExistException; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/CoinHistoryResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/CoinHistoryResponseDto.java index 8fc5badb6..cf195b575 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/CoinHistoryResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/CoinHistoryResponseDto.java @@ -2,7 +2,7 @@ import java.time.LocalDateTime; -import gg.data.store.CoinHistory; +import gg.data.pingpong.store.CoinHistory; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/UserDetailResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/UserDetailResponseDto.java index 9ed2874b5..806d2f592 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/UserDetailResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/UserDetailResponseDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.user.controller.response; -import gg.data.rank.Tier; +import gg.data.pingpong.rank.Tier; import gg.data.user.User; import gg.data.user.type.BackgroundType; import gg.data.user.type.EdgeType; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/UserLiveResponseDto.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/UserLiveResponseDto.java index 780d552f6..0e5a9e5b2 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/UserLiveResponseDto.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/controller/response/UserLiveResponseDto.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.user.controller.response; -import gg.data.game.type.Mode; +import gg.data.pingpong.game.type.Mode; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/dto/UserHistoryData.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/dto/UserHistoryData.java index 6648c9f6b..2766868fb 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/dto/UserHistoryData.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/dto/UserHistoryData.java @@ -2,7 +2,7 @@ import java.time.LocalDateTime; -import gg.data.game.PChange; +import gg.data.pingpong.game.PChange; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserAuthenticationService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserAuthenticationService.java index cc79e0045..71456b835 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserAuthenticationService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserAuthenticationService.java @@ -2,8 +2,8 @@ import org.springframework.stereotype.Service; +import gg.auth.utils.AuthTokenProvider; import gg.pingpong.api.global.security.jwt.repository.JwtRedisRepository; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.utils.exception.user.TokenNotValidException; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserCoinService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserCoinService.java index afa6c7408..1fd993319 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserCoinService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserCoinService.java @@ -5,7 +5,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.store.CoinHistory; +import gg.data.pingpong.store.CoinHistory; import gg.data.user.User; import gg.pingpong.api.user.user.controller.response.CoinHistoryResponseDto; import gg.pingpong.api.user.user.controller.response.UserCoinHistoryListResponseDto; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserFindService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserFindService.java index 0f6f6a7d6..0d2b9ca7f 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserFindService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserFindService.java @@ -5,8 +5,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.pingpong.api.user.season.service.SeasonFindService; import gg.repo.rank.redis.RankRedisRepository; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserService.java index eeae4bcdc..0303d0b7a 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserService.java @@ -16,16 +16,17 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -import gg.data.game.Game; -import gg.data.game.PChange; -import gg.data.game.type.StatusType; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; -import gg.data.store.Receipt; -import gg.data.store.type.ItemStatus; -import gg.data.store.type.ItemType; +import gg.auth.UserDto; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.PChange; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.type.ItemStatus; +import gg.data.pingpong.store.type.ItemType; import gg.data.user.User; import gg.data.user.UserImage; import gg.data.user.type.BackgroundType; @@ -49,7 +50,6 @@ import gg.pingpong.api.user.user.controller.response.UserNormalDetailResponseDto; import gg.pingpong.api.user.user.controller.response.UserRankResponseDto; import gg.pingpong.api.user.user.dto.UserBackgroundDto; -import gg.pingpong.api.user.user.dto.UserDto; import gg.pingpong.api.user.user.dto.UserEdgeDto; import gg.pingpong.api.user.user.dto.UserHistoryData; import gg.pingpong.api.user.user.dto.UserImageDto; diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserTextColorCheckService.java b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserTextColorCheckService.java index 34614ca41..087d2f40e 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserTextColorCheckService.java +++ b/gg-pingpong-api/src/main/java/gg/pingpong/api/user/user/service/UserTextColorCheckService.java @@ -7,23 +7,13 @@ @Service @RequiredArgsConstructor public class UserTextColorCheckService { + + /** + * textColor ์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ + * @param textColor + * @return boolean + */ public static boolean check(String textColor) { - if (textColor == null) { - return false; - } - if (textColor.length() != 7) { - return false; - } - if (textColor.charAt(0) != '#') { - return false; - } - for (int i = 1; i < 7; i++) { - char charTestColor = textColor.charAt(i); - if (!((charTestColor >= '0' && charTestColor <= '9') || (charTestColor >= 'a' && charTestColor <= 'f') || ( - charTestColor >= 'A' && charTestColor <= 'F'))) { - return false; - } - } - return true; + return textColor != null && textColor.matches("#[0-9a-fA-F]{6}"); } } diff --git a/gg-pingpong-api/src/main/resources/db/migration/V1.3__update_party_content.sql b/gg-pingpong-api/src/main/resources/db/migration/V1.3__update_party_content.sql new file mode 100644 index 000000000..6306b78b9 --- /dev/null +++ b/gg-pingpong-api/src/main/resources/db/migration/V1.3__update_party_content.sql @@ -0,0 +1,127 @@ +CREATE TABLE category +( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(10) NOT NULL, + created_at DATETIME NOT NULL, + modified_at DATETIME NOT NULL +); + +CREATE TABLE room +( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + host_id BIGINT NOT NULL, + creator_id BIGINT NOT NULL, + category_id BIGINT NOT NULL, + title VARCHAR(15) NOT NULL, + content VARCHAR(100) NOT NULL, + current_people INT NOT NULL, + max_people INT NOT NULL, + min_people INT NOT NULL DEFAULT 2, + due_date DATETIME NOT NULL, + start_date DATETIME, + created_at DATETIME NOT NULL, + modified_at DATETIME NOT NULL, + status VARCHAR(10) NOT NULL, + FOREIGN KEY (host_id) REFERENCES user (id), + FOREIGN KEY (creator_id) REFERENCES user (id), + FOREIGN KEY (category_id) REFERENCES category (id) +); + +CREATE TABLE user_room +( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + user_id BIGINT NOT NULL, + room_id BIGINT NOT NULL, + nickname VARCHAR(20) NOT NULL, + is_exist BOOLEAN NOT NULL, + created_at DATETIME NOT NULL, + modified_at DATETIME NOT NULL, + FOREIGN KEY (user_id) REFERENCES user (id), + FOREIGN KEY (room_id) REFERENCES room (id) +); + +CREATE TABLE comment +( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + user_id BIGINT NOT NULL, + user_room_id BIGINT NOT NULL, + room_id BIGINT NOT NULL, + content VARCHAR(100) NOT NULL, + is_hidden BOOLEAN NOT NULL, + created_at DATETIME NOT NULL, + modified_at DATETIME NOT NULL, + FOREIGN KEY (user_id) REFERENCES user (id), + FOREIGN KEY (user_room_id) REFERENCES user_room (id), + FOREIGN KEY (room_id) REFERENCES room (id) +); + +CREATE TABLE comment_report +( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + room_id BIGINT NOT NULL, + reporter_id BIGINT NOT NULL, + comment_id BIGINT NOT NULL, + message VARCHAR(100) NOT NULL, + created_at DATETIME NOT NULL, + modified_at DATETIME NOT NULL, + FOREIGN KEY (reporter_id) REFERENCES user (id), + FOREIGN KEY (comment_id) REFERENCES comment (id), + FOREIGN KEY (room_id) REFERENCES room (id) +); + +CREATE TABLE game_template +( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + category_id BIGINT NOT NULL, + game_name VARCHAR(20) NOT NULL, + max_game_people INT NOT NULL, + min_game_people INT NOT NULL, + max_game_time INT NOT NULL, + min_game_time INT NOT NULL, + genre VARCHAR(10), + difficulty VARCHAR(10), + summary VARCHAR(100) NOT NULL, + created_at DATETIME NOT NULL, + modified_at DATETIME NOT NULL, + FOREIGN KEY (category_id) REFERENCES category (id) +); + +CREATE TABLE room_report +( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + reporter_id BIGINT NOT NULL, + reportee_id BIGINT NOT NULL, + room_id BIGINT NOT NULL, + message VARCHAR(100) NOT NULL, + created_at DATETIME NOT NULL, + modified_at DATETIME NOT NULL, + FOREIGN KEY (reporter_id) REFERENCES user (id), + FOREIGN KEY (reportee_id) REFERENCES user (id), + FOREIGN KEY (room_id) REFERENCES room (id) +); + +CREATE TABLE user_report +( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + reporter_id BIGINT NOT NULL, + reportee_id BIGINT NOT NULL, + room_id BIGINT NOT NULL, + created_at DATETIME NOT NULL, + modified_at DATETIME NOT NULL, + message VARCHAR(100) NOT NULL, + FOREIGN KEY (reporter_id) REFERENCES user (id), + FOREIGN KEY (reportee_id) REFERENCES user (id), + FOREIGN KEY (room_id) REFERENCES room (id) +); + +CREATE TABLE party_penalty ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + user_id BIGINT NOT NULL, + penalty_type VARCHAR(20) NOT NULL, + message VARCHAR(100) NOT NULL, + start_time DATETIME NOT NULL, + penalty_time INT NOT NULL, + created_at DATETIME NOT NULL, + modified_at DATETIME NOT NULL, + FOREIGN KEY (user_id) REFERENCES user(id) +); diff --git a/gg-pingpong-api/src/main/resources/db/migration/V2__recruit.sql b/gg-pingpong-api/src/main/resources/db/migration/V2__recruit.sql new file mode 100644 index 000000000..aba72354f --- /dev/null +++ b/gg-pingpong-api/src/main/resources/db/migration/V2__recruit.sql @@ -0,0 +1,105 @@ +CREATE TABLE `recruitment` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `created_at` datetime(6) NOT NULL, + `modified_at` datetime(6) DEFAULT NULL, + `contents` varchar(3000) DEFAULT NULL, + `end_time` datetime(6) NOT NULL, + `generation` varchar(50) DEFAULT NULL, + `is_deleted` bit(1) DEFAULT false, + `is_finish` bit(1) DEFAULT false, + `start_time` datetime(6) NOT NULL, + `title` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +CREATE TABLE `application` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `created_at` datetime(6) NOT NULL, + `modified_at` datetime(6) DEFAULT NULL, + `is_deleted` bit(1) DEFAULT false, + `status` varchar(15) NOT NULL , + `recruit_id` bigint NOT NULL , + `user_id` bigint NOT NULL , + PRIMARY KEY (`id`), + KEY `FKnmih1vdymw1494hdj04in2e5h` (`recruit_id`), + KEY `FKldca8xj6lqb3rsqawrowmkqbg` (`user_id`), + CONSTRAINT `FKldca8xj6lqb3rsqawrowmkqbg` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`), + CONSTRAINT `FKnmih1vdymw1494hdj04in2e5h` FOREIGN KEY (`recruit_id`) REFERENCES `recruitment` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +CREATE TABLE `question` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `created_at` datetime(6) NOT NULL, + `modified_at` datetime(6) DEFAULT NULL, + `input_type` varchar(20) NOT NULL, + `question` varchar(300) DEFAULT NULL, + `sort_num` int NOT NULL, + `recruit_id` bigint NOT NULL , + PRIMARY KEY (`id`), + KEY `FK44dkmx1sa8ssxjd7u5ne0ti30` (`recruit_id`), + CONSTRAINT `FK44dkmx1sa8ssxjd7u5ne0ti30` FOREIGN KEY (`recruit_id`) REFERENCES `recruitment` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +CREATE TABLE `application_answer` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `created_at` datetime(6) NOT NULL, + `modified_at` datetime(6) DEFAULT NULL, + `application_id` bigint NOT NULL , + `question_id` bigint NOT NULL , + `answer_type` varchar(20) NOT NULL, + PRIMARY KEY (`id`), + KEY `FKn2ayp7tptdv0yycdqkp2hcm63` (`application_id`), + KEY `FK59sj9jdfki14kkp34kc2jdhyj` (`question_id`), + CONSTRAINT `FK59sj9jdfki14kkp34kc2jdhyj` FOREIGN KEY (`question_id`) REFERENCES `question` (`id`), + CONSTRAINT `FKn2ayp7tptdv0yycdqkp2hcm63` FOREIGN KEY (`application_id`) REFERENCES `application` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +CREATE TABLE `check_list` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `created_at` datetime(6) NOT NULL, + `modified_at` datetime(6) DEFAULT NULL, + `content` varchar(100) DEFAULT NULL, + `question_id` bigint NOT NULL, + PRIMARY KEY (`id`), + KEY `FKksl9r4adqk1aih1fn5kihxh7b` (`question_id`), + CONSTRAINT `FKksl9r4adqk1aih1fn5kihxh7b` FOREIGN KEY (`question_id`) REFERENCES `question` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +CREATE TABLE `application_answer_check_list` ( + `id` bigint NOT NULL, + `check_list_id` bigint NOT NULL, + KEY `FKqdnt92yg8t27q74he0ersyiax` (`id`), + KEY `FK3mf6hfr08f2ex01aqejikxk9w` (`check_list_id`), + CONSTRAINT `FK3mf6hfr08f2ex01aqejikxk9w` FOREIGN KEY (`check_list_id`) REFERENCES `check_list` (`id`), + CONSTRAINT `FKqdnt92yg8t27q74he0ersyiax` FOREIGN KEY (`id`) REFERENCES `application_answer` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +CREATE TABLE `application_answer_text` ( + `id` bigint NOT NULL , + `answer` varchar(1000) DEFAULT NULL, + KEY `FKlhk4m3hi4r3v8xqk8lx4bx5g7` (`id`), + CONSTRAINT `FKlhk4m3hi4r3v8xqk8lx4bx5g7` FOREIGN KEY (`id`) REFERENCES `application_answer` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + + +CREATE TABLE `recruit_status` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `created_at` datetime(6) NOT NULL, + `modified_at` datetime(6) DEFAULT NULL, + `interview_date` datetime(6) DEFAULT NULL, + `application_id` bigint NOT NULL , + PRIMARY KEY (`id`), + KEY `FKrn9y1gwvfmkkoshsxyx3l4pbn` (`application_id`), + CONSTRAINT `FKrn9y1gwvfmkkoshsxyx3l4pbn` FOREIGN KEY (`application_id`) REFERENCES `application` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + + +CREATE TABLE `result_message` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `created_at` datetime(6) NOT NULL, + `modified_at` datetime(6) DEFAULT NULL, + `content` varchar(100) DEFAULT NULL, + `is_use` bit(1) DEFAULT false, + `message_type` varchar(15) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/ServerPingpongApiApplicationTests.java b/gg-pingpong-api/src/test/java/gg/ServerPingpongApiApplicationTests.java similarity index 95% rename from gg-pingpong-api/src/test/java/gg/pingpong/api/ServerPingpongApiApplicationTests.java rename to gg-pingpong-api/src/test/java/gg/ServerPingpongApiApplicationTests.java index d6350dc89..e60782588 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/ServerPingpongApiApplicationTests.java +++ b/gg-pingpong-api/src/test/java/gg/ServerPingpongApiApplicationTests.java @@ -1,4 +1,4 @@ -package gg.pingpong.api; +package gg; import java.util.TimeZone; diff --git a/gg-pingpong-api/src/test/java/gg/party/api/admin/category/CategoryAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/admin/category/CategoryAdminControllerTest.java new file mode 100644 index 000000000..596cae580 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/admin/category/CategoryAdminControllerTest.java @@ -0,0 +1,159 @@ +package gg.party.api.admin.category; + +import static org.assertj.core.api.Assertions.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.apache.http.HttpHeaders; +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.party.Category; +import gg.data.party.Room; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.admin.category.controller.request.CategoryAddAdminReqDto; +import gg.repo.party.CategoryRepository; +import gg.repo.party.RoomRepository; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class CategoryAdminControllerTest { + @Autowired + MockMvc mockMvc; + @Autowired + TestDataUtils testDataUtils; + @Autowired + ObjectMapper objectMapper; + @Autowired + AuthTokenProvider tokenProvider; + @Autowired + RoomRepository roomRepository; + @Autowired + CategoryRepository categoryRepository; + User userTester; + String userAccessToken; + Category defaultCategory; + Category testCategory; + Room testRoom; + + @Nested + @DisplayName("์นดํ…Œ๊ณ ๋ฆฌ ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ") + class CategoryAdd { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + userAccessToken = tokenProvider.createToken(userTester.getId()); + defaultCategory = testDataUtils.createNewCategory("๊ธฐํƒ€"); + } + + @Test + @DisplayName("์นดํ…Œ๊ณ ๋ฆฌ ์ถ”๊ฐ€ ์„ฑ๊ณต 201") + public void success() throws Exception { + //given + String url = "/party/admin/categories"; + CategoryAddAdminReqDto categoryAddAdminReqDto = new CategoryAddAdminReqDto("category"); + String jsonRequest = objectMapper.writeValueAsString(categoryAddAdminReqDto); + //when + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isCreated()) + .andReturn().getResponse(); + //then + assertThat(categoryRepository.findAll()).size().isEqualTo(2); + } + + @Test + @DisplayName("์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ์ธํ•œ ์—๋Ÿฌ 409") + public void fail() throws Exception { + //given + String url = "/party/admin/categories"; + testDataUtils.createNewCategory("category"); + CategoryAddAdminReqDto categoryAddAdminReqDto = new CategoryAddAdminReqDto("category"); + String jsonRequest = objectMapper.writeValueAsString(categoryAddAdminReqDto); + //when & then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isConflict()); + } + } + + @Nested + @DisplayName("์นดํ…Œ๊ณ ๋ฆฌ ์‚ญ์ œ ํ…Œ์ŠคํŠธ") + class CategoryRemove { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + userAccessToken = tokenProvider.createToken(userTester.getId()); + testCategory = testDataUtils.createNewCategory("test"); + testRoom = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 1, + 3, 2, 180, RoomType.OPEN); + defaultCategory = testDataUtils.createNewCategory("๊ธฐํƒ€"); + } + + @Test + @DisplayName("์นดํ…Œ๊ณ ๋ฆฌ ์‚ญ์ œ ์„ฑ๊ณต 204") + public void success() throws Exception { + //given + String categoryID = testCategory.getId().toString(); + String url = "/party/admin/categories/" + categoryID; + //when + mockMvc.perform(delete(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isNoContent()) + .andReturn().getResponse(); + //then + assertThat(categoryRepository.findAll()).size().isEqualTo(1); + assertThat(roomRepository.findById(testRoom.getId()).get().getCategory().getName()).isEqualTo("๊ธฐํƒ€"); + } + + @Test + @DisplayName("์กด์žฌํ•˜์ง€ ์•Š๋Š” ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ์ธํ•œ ์—๋Ÿฌ 404") + public void noCategoryFail() throws Exception { + //given + String categoryID = "10"; + String url = "/party/admin/categories/" + categoryID; + //when & then + mockMvc.perform(delete(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("default ์นดํ…Œ๊ณ ๋ฆฌ ์‚ญ์ œ ์š”์ฒญ์— ๋Œ€ํ•œ ์—๋Ÿฌ 400") + public void fail() throws Exception { + //given + String categoryID = defaultCategory.getId().toString(); + String url = "/party/admin/categories/" + categoryID; + //when & then + mockMvc.perform(delete(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/party/api/admin/comment/CommentAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/admin/comment/CommentAdminControllerTest.java new file mode 100644 index 000000000..1928db117 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/admin/comment/CommentAdminControllerTest.java @@ -0,0 +1,152 @@ +package gg.party.api.admin.comment; + +import static java.lang.Boolean.*; +import static org.assertj.core.api.AssertionsForClassTypes.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDateTime; + +import org.apache.http.HttpHeaders; +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.party.Category; +import gg.data.party.Comment; +import gg.data.party.Room; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.admin.comment.controller.request.CommentUpdateAdminReqDto; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class CommentAdminControllerTest { + @Autowired + MockMvc mockMvc; + @Autowired + TestDataUtils testDataUtils; + @Autowired + ObjectMapper objectMapper; + @Autowired + AuthTokenProvider tokenProvider; + User userTester; + User reportedTester; + User adminTester; + String adminAccessToken; + Room testRoom; + Room reportTestRoom; + Comment testComment; + Comment reportComment; + + @Nested + @DisplayName("Comment Show ์—ฌ๋ถ€ ์ˆ˜์ • ํ…Œ์ŠคํŠธ") + class HideComment { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewImageUser("findTester", "findTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER, "userImage"); + reportedTester = testDataUtils.createNewImageUser("reportedTester", "reportedTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER, "reportedImage"); + testDataUtils.createNewPenalty(reportedTester, "test", "test", LocalDateTime.now(), 60); + adminTester = testDataUtils.createNewImageUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN, "adminImage"); + adminAccessToken = tokenProvider.createToken(adminTester.getId()); + Category testCategory = testDataUtils.createNewCategory("test"); + testRoom = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 1, 3, 2, 180, + RoomType.OPEN); + reportTestRoom = testDataUtils.createNewRoom(reportedTester, reportedTester, testCategory, 1, 1, 3, 2, 180, + RoomType.OPEN); + UserRoom testUserRoom = testDataUtils.createNewUserRoom(userTester, testRoom, "testNickname", TRUE); + UserRoom reportUserRoom = testDataUtils.createNewUserRoom(reportedTester, reportTestRoom, "reportNickname", + TRUE); + testComment = testDataUtils.createComment(userTester, testUserRoom, testRoom, "testComment"); + reportComment = testDataUtils.createReportComment(reportedTester, reportUserRoom, reportTestRoom, + "reportComment"); + } + + @Test + @DisplayName("isHidden False -> True ๋ณ€๊ฒฝ ์„ฑ๊ณต 204") + public void success() throws Exception { + //given + String commentId = testComment.getId().toString(); + String url = "/party/admin/comments/" + commentId; + CommentUpdateAdminReqDto commentUpdateAdminReqDto = new CommentUpdateAdminReqDto(TRUE); + String requestBody = objectMapper.writeValueAsString(commentUpdateAdminReqDto); + //when + mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isNoContent()); + //then + assertThat(testComment.isHidden()).isEqualTo(TRUE); + } + + @Test + @DisplayName("isHidden True -> False ๋ณ€๊ฒฝ ์„ฑ๊ณต 204") + public void reportCommentSuccess() throws Exception { + //given + String commentId = reportComment.getId().toString(); + String url = "/party/admin/comments/" + commentId; + CommentUpdateAdminReqDto commentUpdateAdminReqDto = new CommentUpdateAdminReqDto(FALSE); + String requestBody = objectMapper.writeValueAsString(commentUpdateAdminReqDto); + //when + mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isNoContent()); + //then + assertThat(reportComment.isHidden()).isEqualTo(FALSE); + } + + @Test + @DisplayName("๊ฐ™์€ ๋‚ด์šฉ์œผ๋กœ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ 409") + public void duplicationFail() throws Exception { + //given + String commentId = reportComment.getId().toString(); + String url = "/party/admin/comments/" + commentId; + CommentUpdateAdminReqDto commentUpdateAdminReqDto = new CommentUpdateAdminReqDto(TRUE); + String requestBody = objectMapper.writeValueAsString(commentUpdateAdminReqDto); + //when && then + mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isConflict()); + } + + @Test + @DisplayName("์—†๋Š” Comment๋กœ ์ธํ•œ ์—๋Ÿฌ 404") + public void fail() throws Exception { + //given + String commentId = "1000"; + String url = "/party/admin/comments/" + commentId; + CommentUpdateAdminReqDto commentUpdateAdminReqDto = new CommentUpdateAdminReqDto(TRUE); + String requestBody = objectMapper.writeValueAsString(commentUpdateAdminReqDto); + //when && then + mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isNotFound()); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/party/api/admin/penalty/PartyPenaltyControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/admin/penalty/PartyPenaltyControllerTest.java new file mode 100644 index 000000000..1d380400c --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/admin/penalty/PartyPenaltyControllerTest.java @@ -0,0 +1,224 @@ +package gg.party.api.admin.penalty; + +import static org.junit.Assert.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDateTime; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.party.PartyPenalty; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.admin.penalty.controller.request.PartyPenaltyAdminReqDto; +import gg.party.api.admin.penalty.controller.response.PartyPenaltyListAdminResDto; +import gg.repo.party.PartyPenaltyRepository; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class PartyPenaltyControllerTest { + @Autowired + private MockMvc mockMvc; + @Autowired + private TestDataUtils testDataUtils; + @Autowired + private ObjectMapper objectMapper; + @Autowired + private AuthTokenProvider tokenProvider; + @Autowired + private PartyPenaltyRepository partyPenaltyRepository; + private User userTester; + private User reportedTester; + private User adminUser; + private String adminAccessToken; + private Long testPenaltyId; + + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("user1", "emailTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + reportedTester = testDataUtils.createNewUser("reportedUser", "reportedTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + adminUser = testDataUtils.createNewUser("adminUser", "adminTester@example.com", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + PartyPenalty testPenalty = testDataUtils.createNewPenalty(reportedTester, "test_penalty", + "์ด์œ ๋Š”_ํ…Œ์ŠคํŠธ๋ผ์„œ", LocalDateTime.now(), 60); + testPenaltyId = testPenalty.getId(); + adminAccessToken = tokenProvider.createToken(adminUser.getId()); + } + + @Nested + @DisplayName("ํŒจ๋„ํ‹ฐ ํ…Œ์ŠคํŠธ") + class PenaltyAdminTests { + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ์กฐํšŒ - 200") + void testRetrievePenaltiesList() throws Exception { + //given + for (int i = 1; i <= 9; i++) { + testDataUtils.createNewPenalty(reportedTester, "test_penalty_" + i, + "test_reason" + i, LocalDateTime.now(), 60); + } + int pageSize = 10; + int pageNumber = 1; + String url = String.format("/party/admin/penalties?page=%d&size=%d", pageNumber, pageSize); + + //when + MvcResult result = mockMvc.perform(get(url) + .header("Authorization", "Bearer " + adminAccessToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + //then + String content = result.getResponse().getContentAsString(); + PartyPenaltyListAdminResDto responseDto = + objectMapper.readValue(content, PartyPenaltyListAdminResDto.class); + + assertEquals(pageSize, responseDto.getPenaltyList().size()); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ์กฐํšŒ(pagination) - 200") + void testPaginationPenaltiesList() throws Exception { + //given + for (int i = 1; i <= 15; i++) { + testDataUtils.createNewPenalty(reportedTester, "test_penalty_" + i, + "test_reason" + i, LocalDateTime.now(), 60); + } + int pageSize = 10; + int pageNumber = 2; + String url = String.format("/party/admin/penalties?page=%d&size=%d", pageNumber, pageSize); + + //when + MvcResult result = mockMvc.perform(get(url) + .header("Authorization", "Bearer " + adminAccessToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + //then + String content = result.getResponse().getContentAsString(); + PartyPenaltyListAdminResDto responseDto = + objectMapper.readValue(content, PartyPenaltyListAdminResDto.class); + + int expectedPageSize = 6; + assertEquals(expectedPageSize, responseDto.getPenaltyList().size()); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ์ˆ˜์ • - 204") + void testModifyAdminPenalty() throws Exception { + //given + PartyPenaltyAdminReqDto penaltyDto = new PartyPenaltyAdminReqDto("test_penalty", "Test reason", 60, + reportedTester.getIntraId()); + + //when + mockMvc.perform(patch("/party/admin/penalties/{penaltyId}", testPenaltyId) + .header("Authorization", "Bearer " + adminAccessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(penaltyDto))) + .andExpect(status().isNoContent()); + + //then + PartyPenalty updatedPenalty = partyPenaltyRepository.findById(testPenaltyId).orElseThrow(); + + assertEquals(penaltyDto.getPenaltyType(), updatedPenalty.getPenaltyType()); + assertEquals(penaltyDto.getMessage(), updatedPenalty.getMessage()); + assertEquals(penaltyDto.getPenaltyTime(), updatedPenalty.getPenaltyTime()); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ์ˆ˜์ • - ์‹คํŒจ ์‹œ๋‚˜๋ฆฌ์˜ค(์—†๋Š” ์œ ์ €) - 404") + void testModifyAdminPenalty_NotFound() throws Exception { + //given + Long nonExistentPenaltyId = 999L; + + PartyPenaltyAdminReqDto penaltyDto = new PartyPenaltyAdminReqDto("test_penalty", "Test reason", 60, + reportedTester.getIntraId()); + + //when + mockMvc.perform(patch("/party/admin/penalties/{penaltyId}", nonExistentPenaltyId) + .header("Authorization", "Bearer " + adminAccessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(penaltyDto))) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ๋ถ€์—ฌ (์ผ๋ฐ˜์ ์ธ ์ƒํ™ฉ) - 201") + void testGiveAdminPenalty() throws Exception { + //given + PartyPenaltyAdminReqDto penaltyDto = new PartyPenaltyAdminReqDto("test_penalty", "Test reason", 60, + userTester.getIntraId()); + + long penaltyCountBefore = partyPenaltyRepository.count(); + + //when + mockMvc.perform(post("/party/admin/penalties") + .header("Authorization", "Bearer " + adminAccessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(penaltyDto))) + .andExpect(status().isCreated()); + + //then + long penaltyCountAfter = partyPenaltyRepository.count(); + assertEquals(penaltyCountBefore + 1, penaltyCountAfter); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ๋ถ€์—ฌ (ํŒจ๋„ํ‹ฐ๋œ ์œ ์ €์—๊ฒŒ ์ถ”๊ฐ€ ํŒจ๋„ํ‹ฐ ๋ถ€์—ฌ) - 201") + void testAddAdminPenalty() throws Exception { + //given + PartyPenaltyAdminReqDto morePenaltyDto = new PartyPenaltyAdminReqDto("test_penalty", "Test reason", 60, + reportedTester.getIntraId()); + + //when + mockMvc.perform(post("/party/admin/penalties") + .header("Authorization", "Bearer " + adminAccessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(morePenaltyDto))) + .andExpect(status().isCreated()); + + //then + List penalties = partyPenaltyRepository.findAllByUserId(reportedTester.getId()); + int totalPenaltyTime = penalties.stream().mapToInt(PartyPenalty::getPenaltyTime).sum(); + + assertEquals(120, totalPenaltyTime); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ๋ถ€์—ฌ - ์‹คํŒจ ์‹œ๋‚˜๋ฆฌ์˜ค(์—†๋Š” ์œ ์ €) - 404") + void testAddAdminPenalty_UserNotFound() throws Exception { + //given + PartyPenaltyAdminReqDto penaltyDto = new PartyPenaltyAdminReqDto("test_penalty", "Test reason", 60, + "nonexistentIntraId"); + + //when + mockMvc.perform(post("/party/admin/penalties") + .header("Authorization", "Bearer " + adminAccessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(penaltyDto))) + .andExpect(status().isNotFound()); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/party/api/admin/report/ReportAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/admin/report/ReportAdminControllerTest.java new file mode 100644 index 000000000..2f13ba577 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/admin/report/ReportAdminControllerTest.java @@ -0,0 +1,253 @@ +package gg.party.api.admin.report; + +import static java.lang.Boolean.*; +import static org.assertj.core.api.AssertionsForClassTypes.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.apache.http.HttpHeaders; +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.party.Category; +import gg.data.party.Comment; +import gg.data.party.Room; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.admin.report.controller.response.CommentReportListResDto; +import gg.party.api.admin.report.controller.response.RoomReportListResDto; +import gg.party.api.admin.report.controller.response.UserReportListResDto; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class ReportAdminControllerTest { + @Autowired + MockMvc mockMvc; + @Autowired + TestDataUtils testDataUtils; + @Autowired + ObjectMapper objectMapper; + @Autowired + AuthTokenProvider tokenProvider; + User userTester; + String userAccessToken; + Category testCategory; + + @Nested + @DisplayName("๋Œ“๊ธ€ ์‹ ๊ณ  ๋ฆฌ์ŠคํŠธ ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class GetCommentReports { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + User user1 = testDataUtils.createNewUser("user1", "user1", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + User user2 = testDataUtils.createNewUser("user2", "user2", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + User user3 = testDataUtils.createNewUser("user3", "user3", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + testCategory = testDataUtils.createNewCategory("test"); + Room room1 = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 1, + 3, 2, 180, RoomType.OPEN); + Room room2 = testDataUtils.createNewRoom(userTester, userTester, testCategory, 2, 1, + 3, 2, 180, RoomType.OPEN); + Room room3 = testDataUtils.createNewRoom(userTester, userTester, testCategory, 3, 1, + 3, 2, 180, RoomType.OPEN); + UserRoom userRoom1 = testDataUtils.createNewUserRoom(user1, room1, "user1", TRUE); + UserRoom userRoom2 = testDataUtils.createNewUserRoom(user2, room2, "user2", TRUE); + UserRoom userRoom3 = testDataUtils.createNewUserRoom(user2, room3, "user3", TRUE); + Comment comment1 = testDataUtils.createComment(user1, userRoom1, room1, "user1 comment"); + Comment comment2 = testDataUtils.createComment(user2, userRoom2, room2, "user2 comment"); + Comment comment3 = testDataUtils.createComment(user3, userRoom3, room3, "user3 comment"); + for (int i = 0; i < 5; i++) { + testDataUtils.createCommentReport(user1, room1, comment1); + testDataUtils.createCommentReport(user2, room2, comment2); + testDataUtils.createCommentReport(user3, room3, comment3); + } + } + + @Test + @DisplayName("์ฒซ ํŽ˜์ด์ง€ ์กฐํšŒ ์„ฑ๊ณต 200") + public void startPageSuccess() throws Exception { + //given + String currentPage = "1"; + String pageSize = "10"; + String url = "/party/admin/reports/comments?page=" + currentPage + "&size=" + pageSize; + //when + String contentAsString = mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + CommentReportListResDto crlrd = objectMapper.readValue(contentAsString, CommentReportListResDto.class); + assertThat(crlrd.getCommentReportList().size()).isEqualTo(10); + } + + @Test + @DisplayName("๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€ ์กฐํšŒ ์„ฑ๊ณต 200") + public void lastPageSuccess() throws Exception { + //given + String currentPage = "2"; + String pageSize = "10"; + String url = "/party/admin/reports/comments?page=" + currentPage + "&size=" + pageSize; + //when + String contentAsString = mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + CommentReportListResDto crlrd = objectMapper.readValue(contentAsString, CommentReportListResDto.class); + assertThat(crlrd.getCommentReportList().size()).isEqualTo(5); + } + } + + @Nested + @DisplayName("๋ฐฉ ์‹ ๊ณ  ๋ฆฌ์ŠคํŠธ ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class GetRoomReports { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + User user1 = testDataUtils.createNewUser("user1", "user1", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + User user2 = testDataUtils.createNewUser("user2", "user2", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + User user3 = testDataUtils.createNewUser("user3", "user3", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + testCategory = testDataUtils.createNewCategory("test"); + Room room1 = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 1, + 3, 2, 180, RoomType.OPEN); + Room room2 = testDataUtils.createNewRoom(userTester, userTester, testCategory, 2, 1, + 3, 2, 180, RoomType.OPEN); + Room room3 = testDataUtils.createNewRoom(userTester, userTester, testCategory, 3, 1, + 3, 2, 180, RoomType.OPEN); + for (int i = 0; i < 5; i++) { + testDataUtils.createRoomReport(user1, user2, room1); + testDataUtils.createRoomReport(user2, user3, room2); + testDataUtils.createRoomReport(user3, user1, room3); + } + } + + @Test + @DisplayName("์ฒซ ํŽ˜์ด์ง€ ์กฐํšŒ ์„ฑ๊ณต 200") + public void startPageSuccess() throws Exception { + //given + String currentPage = "1"; + String pageSize = "10"; + String url = "/party/admin/reports/rooms?page=" + currentPage + "&size=" + pageSize; + //when + String contentAsString = mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomReportListResDto rrlrd = objectMapper.readValue(contentAsString, RoomReportListResDto.class); + assertThat(rrlrd.getRoomReportList().size()).isEqualTo(10); + } + + @Test + @DisplayName("๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€ ์กฐํšŒ ์„ฑ๊ณต 200") + public void lastPageSuccess() throws Exception { + //given + String currentPage = "2"; + String pageSize = "10"; + String url = "/party/admin/reports/rooms?page=" + currentPage + "&size=" + pageSize; + //when + String contentAsString = mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomReportListResDto rrlrd = objectMapper.readValue(contentAsString, RoomReportListResDto.class); + assertThat(rrlrd.getRoomReportList().size()).isEqualTo(5); + } + } + + @Nested + @DisplayName("์œ ์ €(๋…ธ์‡ผ) ์‹ ๊ณ  ๋ฆฌ์ŠคํŠธ ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class GetUserReports { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + User user1 = testDataUtils.createNewUser("user1", "user1", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + User user2 = testDataUtils.createNewUser("user2", "user2", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + User user3 = testDataUtils.createNewUser("user3", "user3", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + testCategory = testDataUtils.createNewCategory("test"); + Room room1 = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 1, + 3, 2, 180, RoomType.OPEN); + Room room2 = testDataUtils.createNewRoom(userTester, userTester, testCategory, 2, 1, + 3, 2, 180, RoomType.OPEN); + Room room3 = testDataUtils.createNewRoom(userTester, userTester, testCategory, 3, 1, + 3, 2, 180, RoomType.OPEN); + for (int i = 0; i < 5; i++) { + testDataUtils.createUserReport(user1, user2, room1); + testDataUtils.createUserReport(user2, user3, room2); + testDataUtils.createUserReport(user3, user1, room3); + } + } + + @Test + @DisplayName("์ฒซ ํŽ˜์ด์ง€ ์กฐํšŒ ์„ฑ๊ณต 200") + public void startPageSuccess() throws Exception { + //given + String currentPage = "1"; + String pageSize = "10"; + String url = "/party/admin/reports/users?page=" + currentPage + "&size=" + pageSize; + //when + String contentAsString = mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + UserReportListResDto urlrd = objectMapper.readValue(contentAsString, UserReportListResDto.class); + assertThat(urlrd.getUserReportList().size()).isEqualTo(10); + } + + @Test + @DisplayName("๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€ ์กฐํšŒ ์„ฑ๊ณต 200") + public void lastPageSuccess() throws Exception { + //given + String currentPage = "2"; + String pageSize = "10"; + String url = "/party/admin/reports/users?page=" + currentPage + "&size=" + pageSize; + //when + String contentAsString = mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + UserReportListResDto urlrd = objectMapper.readValue(contentAsString, UserReportListResDto.class); + assertThat(urlrd.getUserReportList().size()).isEqualTo(5); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/party/api/admin/room/RoomAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/admin/room/RoomAdminControllerTest.java new file mode 100644 index 000000000..6ac1012d0 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/admin/room/RoomAdminControllerTest.java @@ -0,0 +1,307 @@ +package gg.party.api.admin.room; + +import static java.lang.Boolean.*; +import static org.assertj.core.api.Assertions.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDateTime; + +import org.apache.http.HttpHeaders; +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.party.Category; +import gg.data.party.Room; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.admin.room.controller.request.RoomShowChangeReqDto; +import gg.party.api.admin.room.controller.response.AdminCommentResDto; +import gg.party.api.admin.room.controller.response.AdminRoomDetailResDto; +import gg.party.api.admin.room.controller.response.AdminRoomListResDto; +import gg.party.api.user.room.controller.response.UserRoomResDto; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class RoomAdminControllerTest { + @Autowired + MockMvc mockMvc; + @Autowired + TestDataUtils testDataUtils; + @Autowired + ObjectMapper objectMapper; + @Autowired + AuthTokenProvider tokenProvider; + User userTester; + User adminTester; + User reportedTester; + String userAccessToken; + String adminAccessToken; + String reportedAccessToken; + Category testCategory; + Room openRoom; + Room startRoom; + Room finishRoom; + Room hiddenRoom; + Room failRoom; + Room pageTestRoom; + Room openReportedRoom; + Room startReportedRoom; + Room finishReportedRoom; + Room hiddenReportedRoom; + Room failReportedRoom; + Room[] rooms = {openRoom, startRoom, finishRoom, hiddenRoom, failRoom, openReportedRoom, startReportedRoom, + finishReportedRoom, hiddenReportedRoom, failReportedRoom, pageTestRoom}; + RoomType[] roomTypes = {RoomType.OPEN, RoomType.START, RoomType.FINISH, RoomType.HIDDEN, RoomType.FAIL, + RoomType.OPEN, RoomType.START, RoomType.FINISH, RoomType.HIDDEN, RoomType.FAIL, RoomType.OPEN}; + + @Nested + @DisplayName("Admin ๋ฐฉ Status ๋ณ€๊ฒฝ ํ…Œ์ŠคํŠธ") + class ModifyRoomVisibility { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("findTester", "findTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + adminTester = testDataUtils.createNewUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + adminAccessToken = tokenProvider.createToken(adminTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + openRoom = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 1, 3, 2, 180, + RoomType.OPEN); + } + + @Test + @DisplayName("๋ฐฉ Status ๋ณ€๊ฒฝ ์„ฑ๊ณต 204") + public void success() throws Exception { + //given + String roomId = openRoom.getId().toString(); + String url = "/party/admin/rooms/" + roomId; + RoomShowChangeReqDto roomShowChangeReqDto = new RoomShowChangeReqDto(RoomType.START.toString()); + String jsonRequest = objectMapper.writeValueAsString(roomShowChangeReqDto); + //when + mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isNoContent()) + .andReturn().getResponse(); + //then + assertThat(openRoom.getStatus()).isEqualTo(RoomType.START); + } + + @Test + @DisplayName("๋ฐฉ์ด ์—†์Œ์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ 404") + public void noRoomFail() throws Exception { + //given + String roomId = "1000"; + String url = "/party/admin/rooms/" + roomId; + RoomShowChangeReqDto roomShowChangeReqDto = new RoomShowChangeReqDto(RoomType.START.toString()); + String jsonRequest = objectMapper.writeValueAsString(roomShowChangeReqDto); + //when && then + mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("๋™์ผํ•œ Status ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ 409") + public void sameStatusFail() throws Exception { + //given + String roomId = openRoom.getId().toString(); + String url = "/party/admin/rooms/" + roomId; + RoomShowChangeReqDto roomShowChangeReqDto = new RoomShowChangeReqDto(RoomType.OPEN.toString()); + String jsonRequest = objectMapper.writeValueAsString(roomShowChangeReqDto); + //when && then + mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isConflict()); + } + } + + @Nested + @DisplayName("Admin ๋ฐฉ ์ „์ฒด ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class FindAllActiveRoomList { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("findTester", "findTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + reportedTester = testDataUtils.createNewUser("reportedTester", "reportedTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + reportedAccessToken = tokenProvider.createToken(reportedTester.getId()); + testDataUtils.createNewPenalty(reportedTester, "test", "test", + LocalDateTime.now(), 60); + adminTester = testDataUtils.createNewUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + adminAccessToken = tokenProvider.createToken(adminTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + for (int i = 0; i < rooms.length; i++) { + if (i < 5) { + rooms[i] = testDataUtils.createNewRoom(userTester, userTester, testCategory, i, 1, 3, 2, 180, + roomTypes[i]); + } else { + rooms[i] = testDataUtils.createNewRoom(reportedTester, reportedTester, testCategory, i, 1, 3, 2, + 180, roomTypes[i]); + } + } + } + + @Test + @DisplayName("์ฒซ ํŽ˜์ด์ง€ ์กฐํšŒ ์„ฑ๊ณต 200") + public void startPageSuccess() throws Exception { + //given + String currentPage = "1"; + String pageSize = "10"; + String url = "/party/admin/rooms?page=" + currentPage + "&size=" + pageSize; + //when + String contentAsString = mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + AdminRoomListResDto arlrd = objectMapper.readValue(contentAsString, AdminRoomListResDto.class); + assertThat(arlrd.getAdminRoomList().size()).isEqualTo(10); + } + + @Test + @DisplayName("๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€ ์กฐํšŒ ์„ฑ๊ณต 200") + public void lastPageSuccess() throws Exception { + //given + String currentPage = "2"; + String pageSize = "10"; + String url = "/party/admin/rooms?page=" + currentPage + "&size=" + pageSize; + //when + String contentAsString = mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + AdminRoomListResDto arlrd = objectMapper.readValue(contentAsString, AdminRoomListResDto.class); + assertThat(arlrd.getAdminRoomList().size()).isEqualTo(1); + } + } + + @Nested + @DisplayName("๋ฐฉ ์ƒ์„ธ ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class AdminRoomDetailInfo { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewImageUser("findTester", "findTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER, "userImage"); + userAccessToken = tokenProvider.createToken(userTester.getId()); + reportedTester = testDataUtils.createNewImageUser("reportedTester", "reportedTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER, "reportedImage"); + reportedAccessToken = tokenProvider.createToken(reportedTester.getId()); + testDataUtils.createNewPenalty(reportedTester, "test", "test", + LocalDateTime.now(), 60); + adminTester = testDataUtils.createNewImageUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN, "adminImage"); + adminAccessToken = tokenProvider.createToken(adminTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + for (int i = 0; i < rooms.length - 1; i++) { + if (i < 5) { + rooms[i] = testDataUtils.createNewRoom(userTester, userTester, testCategory, i, 1, 3, 2, 180, + roomTypes[i]); + } else { + rooms[i] = testDataUtils.createNewRoom(reportedTester, reportedTester, testCategory, i, 1, 3, 2, + 180, roomTypes[i]); + } + UserRoom testUserRoom = testDataUtils.createNewUserRoom(userTester, rooms[i], "testNickname", TRUE); + UserRoom reportUserRoom = testDataUtils.createNewUserRoom(reportedTester, rooms[i], + "reportNickname", TRUE); + testDataUtils.createComment(userTester, testUserRoom, rooms[i], "testComment" + i); + testDataUtils.createReportComment(reportedTester, reportUserRoom, rooms[i], "reportComment" + i); + + } + } + + @Test + @DisplayName("๋ชจ๋“  ์ข…๋ฅ˜์— ๋Œ€ํ•œ ์ƒ์„ธ์ •๋ณด ์กฐํšŒ ์„ฑ๊ณต 200") + public void success() throws Exception { + for (int i = 0; i < rooms.length - 1; i++) { // pageTestRoom ์ œ์™ธ + //given + String roomId = (rooms[i].getId()).toString(); + String url = "/party/admin/rooms/" + roomId; + //when + String contentAsString = mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + AdminRoomDetailResDto ardrd = objectMapper.readValue(contentAsString, AdminRoomDetailResDto.class); + for (UserRoomResDto roomUser : ardrd.getRoomUsers()) { + assertThat(roomUser.getIntraId()).isNotNull(); + assertThat(roomUser.getUserImage()).isNotNull(); + } + for (AdminCommentResDto comment : ardrd.getComments()) { + assertThat(comment.getIntraId()).isNotNull(); + } + } + } + + @Test + @DisplayName("๋ฐฉ์— ์•„๋ฌด๋„ ์—†์–ด์„œ FAIL ๋œ ๋ฐฉ ์ƒ์„ธ์ •๋ณด ์กฐํšŒ ์„ฑ๊ณต 200") + public void failRoomSuccess() throws Exception { + //given + Room failToNoUserRoom = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 0, 3, 2, + 180, + RoomType.FAIL); + testDataUtils.createNewUserRoom(userTester, failToNoUserRoom, "testNickname", FALSE); + String roomId = failToNoUserRoom.getId().toString(); + String url = "/party/admin/rooms/" + roomId; + //when + String contentAsString = mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + AdminRoomDetailResDto ardrd = objectMapper.readValue(contentAsString, AdminRoomDetailResDto.class); + for (UserRoomResDto roomUser : ardrd.getRoomUsers()) { + assertThat(roomUser.getIntraId()).isNotNull(); + assertThat(roomUser.getUserImage()).isNotNull(); + } + for (AdminCommentResDto comment : ardrd.getComments()) { + assertThat(comment.getIntraId()).isNotNull(); + } + } + + @Test + @DisplayName("์—†๋Š” ๋ฐฉ์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ 404") + public void lastPageSuccess() throws Exception { + //given + String roomId = "1000"; + String url = "/party/admin/rooms/" + roomId; + //when + mockMvc.perform(get(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + adminAccessToken)) + .andExpect(status().isNotFound()); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/party/api/admin/template/TemplateAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/admin/template/TemplateAdminControllerTest.java new file mode 100644 index 000000000..65b66931b --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/admin/template/TemplateAdminControllerTest.java @@ -0,0 +1,256 @@ +package gg.party.api.admin.template; + +import static org.assertj.core.api.Assertions.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.apache.http.HttpHeaders; +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.party.Category; +import gg.data.party.GameTemplate; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.admin.templates.controller.request.TemplateAdminCreateReqDto; +import gg.party.api.admin.templates.controller.request.TemplateAdminUpdateReqDto; +import gg.repo.party.CategoryRepository; +import gg.repo.party.TemplateRepository; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class TemplateAdminControllerTest { + @Autowired + MockMvc mockMvc; + @Autowired + TestDataUtils testDataUtils; + @Autowired + ObjectMapper objectMapper; + @Autowired + AuthTokenProvider tokenProvider; + @Autowired + CategoryRepository categoryRepository; + @Autowired + TemplateRepository templateRepository; + User userTester; + String userAccessToken; + Category testCategory; + GameTemplate testTemplate; + + @Nested + @DisplayName("ํ…œํ”Œ๋ฆฟ ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ") + class AddTemplate { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + userAccessToken = tokenProvider.createToken(userTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + } + + /** + * ํ…œํ”Œ๋ฆฟ์„ ์ถ”๊ฐ€ + * ์–ด๋“œ๋ฏผ๋งŒ ํ•  ์ˆ˜ ์žˆ์Œ. + */ + @Test + @DisplayName("์ถ”๊ฐ€ ์„ฑ๊ณต 201") + public void success() throws Exception { + //given + String url = "/party/admin/templates"; + TemplateAdminCreateReqDto templateAdminCreateReqDto = new TemplateAdminCreateReqDto( + testCategory.getName(), "gameName", 4, 2, + 180, 180, "genre", "hard", "summary"); + String jsonRequest = objectMapper.writeValueAsString(templateAdminCreateReqDto); + //when + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isCreated()) + .andReturn().getResponse(); + //then + assertThat(templateRepository.findAll()).isNotNull(); + } + + @Test + @DisplayName("์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ์œผ๋กœ ์ธํ•œ ์ถ”๊ฐ€ ์‹คํŒจ 404") + public void fail() throws Exception { + //given + String url = "/party/admin/templates"; + TemplateAdminCreateReqDto templateAdminCreateReqDto = new TemplateAdminCreateReqDto( + "NOTFOUND", "gameName", 4, 2, + 180, 180, "genre", "hard", "summary"); + String jsonRequest = objectMapper.writeValueAsString(templateAdminCreateReqDto); + //when && then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isNotFound()); + } + } + + @Nested + @DisplayName("ํ…œํ”Œ๋ฆฟ ์ˆ˜์ • ํ…Œ์ŠคํŠธ") + class UpdateTemplate { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + userAccessToken = tokenProvider.createToken(userTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + testTemplate = testDataUtils.createNewTemplate(testCategory, "gameName", 4, + 2, 180, 180, "genre", "hard", "summary"); + } + + /** + * ํ…œํ”Œ๋ฆฟ ์ˆ˜์ • + * ์–ด๋“œ๋ฏผ๋งŒ ํ•  ์ˆ˜ ์žˆ์Œ. + */ + @Test + @DisplayName("์ˆ˜์ • ์„ฑ๊ณต 204") + public void success() throws Exception { + //given + String templateId = testTemplate.getId().toString(); + String url = "/party/admin/templates/" + templateId; + Category newTestCategory = testDataUtils.createNewCategory("newCate"); + TemplateAdminUpdateReqDto templateAdminUpdateReqDto = new TemplateAdminUpdateReqDto( + newTestCategory.getName(), "newGameName", 8, 4, + 90, 90, "newGenre", "easy", "newSummary"); + String jsonRequest = objectMapper.writeValueAsString(templateAdminUpdateReqDto); + //when + mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isNoContent()) + .andReturn().getResponse(); + //then + assertThat(testTemplate.getGameName()).isEqualTo(templateAdminUpdateReqDto.getGameName()); + assertThat(testTemplate.getCategory()).isEqualTo(newTestCategory); + assertThat(testTemplate.getMaxGamePeople()).isEqualTo(templateAdminUpdateReqDto.getMaxGamePeople()); + assertThat(testTemplate.getMinGamePeople()).isEqualTo(templateAdminUpdateReqDto.getMinGamePeople()); + assertThat(testTemplate.getMaxGameTime()).isEqualTo(templateAdminUpdateReqDto.getMaxGameTime()); + assertThat(testTemplate.getMinGameTime()).isEqualTo(templateAdminUpdateReqDto.getMinGameTime()); + assertThat(testTemplate.getGenre()).isEqualTo(templateAdminUpdateReqDto.getGenre()); + assertThat(testTemplate.getDifficulty()).isEqualTo(templateAdminUpdateReqDto.getDifficulty()); + assertThat(testTemplate.getSummary()).isEqualTo(templateAdminUpdateReqDto.getSummary()); + } + + @Test + @DisplayName("์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ์œผ๋กœ ์ธํ•œ ์ˆ˜์ • ์‹คํŒจ 404") + public void noCategoryFail() throws Exception { + //given + String templateId = testTemplate.getId().toString(); + String url = "/party/admin/templates/" + templateId; + TemplateAdminUpdateReqDto templateAdminUpdateReqDto = new TemplateAdminUpdateReqDto( + "NOTFOUND", "newGameName", 8, 4, + 90, 90, "newGenre", "easy", "newSummary"); + String jsonRequest = objectMapper.writeValueAsString(templateAdminUpdateReqDto); + //when && then + mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("์ตœ์†Œ์ธ์›์ด ์ตœ๋Œ€์ธ์›๋ณด๋‹ค ํฐ ์˜ค๋ฅ˜ 400") + public void notValidMinMaxFail() throws Exception { + //given + String templateId = testTemplate.getId().toString(); + String url = "/party/admin/templates/" + templateId; + TemplateAdminUpdateReqDto templateAdminUpdateReqDto = new TemplateAdminUpdateReqDto( + testCategory.getName(), "newGameName", 4, 8, + 90, 90, "newGenre", "easy", "newSummary"); + String jsonRequest = objectMapper.writeValueAsString(templateAdminUpdateReqDto); + //when && then + mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("ํ…œํ”Œ๋ฆฟ ์—†์Œ์œผ๋กœ ์ธํ•œ ์ˆ˜์ • ์‹คํŒจ 404") + public void noTemplateFail() throws Exception { + //given + String templateId = "1000"; + String url = "/party/admin/templates/" + templateId; + Category newTestCategory = testDataUtils.createNewCategory("newCate"); + TemplateAdminUpdateReqDto templateAdminUpdateReqDto = new TemplateAdminUpdateReqDto( + newTestCategory.getName(), "newGameName", 8, 4, + 90, 90, "newGenre", "easy", "newSummary"); + String jsonRequest = objectMapper.writeValueAsString(templateAdminUpdateReqDto); + //when && then + String contentAsString = mockMvc.perform(patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isNotFound()).toString(); + } + } + + @Nested + @DisplayName("ํ…œํ”Œ๋ฆฟ ์‚ญ์ œ ํ…Œ์ŠคํŠธ") + class RemoveTemplate { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("adminTester", "adminTester", + RacketType.DUAL, SnsType.SLACK, RoleType.ADMIN); + userAccessToken = tokenProvider.createToken(userTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + testTemplate = testDataUtils.createNewTemplate(testCategory, "gameName", 4, + 2, 180, 180, "genre", "hard", "summary"); + } + + /** + * ํ…œํ”Œ๋ฆฟ ์‚ญ์ œ + * ์–ด๋“œ๋ฏผ๋งŒ ํ•  ์ˆ˜ ์žˆ์Œ. + */ + @Test + @DisplayName("์‚ญ์ œ ์„ฑ๊ณต 204") + public void success() throws Exception { + //given + String templateId = testTemplate.getId().toString(); + String url = "/party/admin/templates/" + templateId; + //when + mockMvc.perform(delete(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isNoContent()); + //then + assertThat(templateRepository.findAll()).isEmpty(); + } + + @Test + @DisplayName("ํ…œํ”Œ๋ฆฟ ์—†์Œ์œผ๋กœ ์ธํ•œ ์‚ญ์ œ ์‹คํŒจ 404") + public void fail() throws Exception { + //given + String templateId = "10"; + String url = "/party/admin/templates/" + templateId; + //when && then + mockMvc.perform(delete(url) + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isNotFound()); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/party/api/user/category/CategoryControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/user/category/CategoryControllerTest.java new file mode 100644 index 000000000..f54967eeb --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/user/category/CategoryControllerTest.java @@ -0,0 +1,99 @@ +package gg.party.api.user.category; + +import static org.assertj.core.api.AssertionsForClassTypes.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDateTime; + +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.user.category.controller.response.CategoryListResDto; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class CategoryControllerTest { + @Autowired + private MockMvc mockMvc; + @Autowired + ObjectMapper objectMapper; + @Autowired + private TestDataUtils testDataUtils; + @Autowired + private AuthTokenProvider tokenProvider; + User userTester; + User anotherTester; + String userAccessToken; + String anotherAccessToken; + + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("commentUserTester", "emailTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + anotherTester = testDataUtils.createNewUser("anotherUserTester", "anotherUserTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + testDataUtils.createNewPenalty(anotherTester, "test1", "test1", + LocalDateTime.now(), 0); + testDataUtils.createNewPenalty(anotherTester, "test2", "test2", + LocalDateTime.now(), 0); + userAccessToken = tokenProvider.createToken(userTester.getId()); + anotherAccessToken = tokenProvider.createToken(anotherTester.getId()); + for (int i = 0; i < 10; i++) { + testDataUtils.createNewCategory("ํ…Œ์ŠคํŠธ ์นดํ…Œ๊ณ ๋ฆฌ" + i); + } + } + + @Nested + @DisplayName("์นดํ…Œ๊ณ ๋ฆฌ ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class FindCategoryList { + @Test + @DisplayName("์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ ์„ฑ๊ณต 200") + void success() throws Exception { + //given + String uri = "/party/categories"; + //when + String contentAsString = mockMvc.perform(get(uri) + .header("Authorization", "Bearer " + userAccessToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + CategoryListResDto clrd = objectMapper.readValue(contentAsString, CategoryListResDto.class); + assertThat(clrd.getCategoryList().size()).isEqualTo(10); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ๋ฐ›์•˜๋‹ค๊ฐ€ ํ’€๋ฆฐ ์œ ์ € ์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ์กฐํšŒ ์„ฑ๊ณต 200") + void unLockPenaltySuccess() throws Exception { + //given + String uri = "/party/categories"; + //when + String contentAsString = mockMvc.perform(get(uri) + .header("Authorization", "Bearer " + anotherAccessToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + CategoryListResDto clrd = objectMapper.readValue(contentAsString, CategoryListResDto.class); + assertThat(clrd.getCategoryList().size()).isEqualTo(10); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/party/api/user/comment/CommentControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/user/comment/CommentControllerTest.java new file mode 100644 index 000000000..0e3dd3103 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/user/comment/CommentControllerTest.java @@ -0,0 +1,171 @@ +package gg.party.api.user.comment; + +import static org.assertj.core.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDateTime; +import java.util.EnumSet; + +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.party.Category; +import gg.data.party.Room; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.user.comment.controller.request.CommentCreateReqDto; +import gg.repo.party.CommentRepository; +import gg.repo.party.RoomRepository; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class CommentControllerTest { + @Autowired + private MockMvc mockMvc; + @Autowired + private TestDataUtils testDataUtils; + @Autowired + private ObjectMapper objectMapper; + @Autowired + private AuthTokenProvider tokenProvider; + @Autowired + private CommentRepository commentRepository; + @Autowired + private RoomRepository roomRepository; + User userTester; + User reportedTester; + User anotherUser; + String userAccessToken; + String reportedAccessToken; + String anotherAccessToken; + Room openRoom; + + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("commentUserTester", "emailTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + reportedTester = testDataUtils.createNewUser("reportedTester", "reportedTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + anotherUser = testDataUtils.createNewUser("anotherUser", "anotherUser", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + testDataUtils.createNewPenalty(reportedTester, "penaltytype", "becauseTest", + LocalDateTime.now(), 60); + userAccessToken = tokenProvider.createToken(userTester.getId()); + reportedAccessToken = tokenProvider.createToken(reportedTester.getId()); + anotherAccessToken = tokenProvider.createToken(anotherUser.getId()); + Category category = testDataUtils.createNewCategory("category"); + openRoom = testDataUtils.createNewRoom(userTester, userTester, category, 1, 1, 10, 2, 120, RoomType.OPEN); + testDataUtils.createNewUserRoom(userTester, openRoom, "๋‹‰๋„ค์ž„ํ…Œ์ŠคํŠธ", true); + } + + @Nested + @DisplayName("๋Œ“๊ธ€ ์ƒ์„ฑ ํ…Œ์ŠคํŠธ") + class CreateCommentTest { + + /** + * ๋Œ“๊ธ€ ์ƒ์„ฑ ์„ฑ๊ณต์‹œ 201 ๋ฐ˜ํ™˜ + * ์œ ์ €๊ฐ€ ๋ฐฉ์— ์ฐธ์—ฌ ํ•œ ์ƒํƒœ์ผ๋•Œ๋งŒ ๋Œ“๊ธ€ ์ƒ์„ฑ ๊ฐ€๋Šฅ (์ฐธ์—ฌ ์•ˆํ•˜๋ฉด ๋Œ“๊ธ€ ์ƒ์„ฑ ๋ถˆ๊ฐ€) + */ + @Test + @DisplayName("๋Œ“๊ธ€ ์ƒ์„ฑ ์„ฑ๊ณต 201") + void createCommentSuccess() throws Exception { + //given + String uri = "/party/rooms/{room_id}/comments"; + CommentCreateReqDto reqDto = new CommentCreateReqDto("testComment"); + String content = objectMapper.writeValueAsString(reqDto); + //when + mockMvc.perform(post(uri, openRoom.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(content) + .header("Authorization", "Bearer " + userAccessToken)) + .andExpect(status().isCreated()); + //then + assertThat(commentRepository.findByRoomId(openRoom.getId())).hasSize(1); + } + + @Test + @DisplayName("์—†๋Š” ๋ฐฉ์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ 404") + void roomNotFoundFail() throws Exception { + //given + String uri = "/party/rooms/{room_id}/comments"; + CommentCreateReqDto reqDto = new CommentCreateReqDto("testComment"); + String content = objectMapper.writeValueAsString(reqDto); + //when && then + mockMvc.perform(post(uri, 1000) + .contentType(MediaType.APPLICATION_JSON) + .content(content) + .header("Authorization", "Bearer " + userAccessToken)) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("์‹ ๊ณ ๋œ ์‚ฌ์šฉ์ž ๋Œ“๊ธ€ ์ƒ์„ฑ ์‹คํŒจ 403") + void createCommentFailForReportedUser() throws Exception { + //given + String uri = "/party/rooms/{room_id}/comments"; + CommentCreateReqDto reqDto = new CommentCreateReqDto("testComment"); + String content = objectMapper.writeValueAsString(reqDto); + //when && then + mockMvc.perform(post(uri, openRoom.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(content) + .header("Authorization", "Bearer " + reportedAccessToken)) + .andExpect(status().isForbidden()); + } + + @Test + @DisplayName("๋ฐฉ์˜ STATUS๊ฐ€ OPEN์ด ์•„๋‹๋•Œ(START, FINISH, HIDDEN, FAIl) ๋Œ“๊ธ€ ์ƒ์„ฑ ์‹คํŒจ 400") + void createCommentFailWhenRoomNotOpen() throws Exception { + //given + String uri = "/party/rooms/{room_id}/comments"; + EnumSet notOpenStatuses = EnumSet.of(RoomType.START, RoomType.FINISH, RoomType.HIDDEN, + RoomType.FAIL); + for (RoomType status : notOpenStatuses) { + openRoom.changeRoomStatus(status); + roomRepository.save(openRoom); + + CommentCreateReqDto reqDto = new CommentCreateReqDto("testComment"); + String content = objectMapper.writeValueAsString(reqDto); + //when && then + mockMvc.perform(post(uri, openRoom.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(content) + .header("Authorization", "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + } + + @Test + @DisplayName("๋ฐฉ ์ฐธ๊ฐ€์ž๊ฐ€ ์•„๋‹˜์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ 400") + void roomNotParticipantUserFail() throws Exception { + //given + String uri = "/party/rooms/{room_id}/comments"; + CommentCreateReqDto reqDto = new CommentCreateReqDto("testComment"); + String content = objectMapper.writeValueAsString(reqDto); + //when && then + mockMvc.perform(post(uri, openRoom.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(content) + .header("Authorization", "Bearer " + anotherAccessToken)) + .andExpect(status().isBadRequest()); + } + } +} + diff --git a/gg-pingpong-api/src/test/java/gg/party/api/user/penalty/PartyPenaltyControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/user/penalty/PartyPenaltyControllerTest.java new file mode 100644 index 000000000..bdf48602d --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/user/penalty/PartyPenaltyControllerTest.java @@ -0,0 +1,92 @@ +package gg.party.api.user.penalty; + +import static org.assertj.core.api.AssertionsForClassTypes.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDateTime; + +import org.apache.http.HttpHeaders; +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.user.penalty.controller.response.PenaltyResDto; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@Transactional +@AutoConfigureMockMvc +public class PartyPenaltyControllerTest { + @Autowired + MockMvc mockMvc; + @Autowired + TestDataUtils testDataUtils; + @Autowired + ObjectMapper objectMapper; + @Autowired + AuthTokenProvider tokenProvider; + User userTester; + User reportedTester; + String userAccessToken; + String reportedAccessToken; + + @Nested + @DisplayName("ํŒจ๋„ํ‹ฐ ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class FindPenaltyTest { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("userTester", "userTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + reportedTester = testDataUtils.createNewUser("reportedTester", "reportedTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + reportedAccessToken = tokenProvider.createToken(reportedTester.getId()); + testDataUtils.createNewPenalty(reportedTester, "test", "test", LocalDateTime.of(2222, 2, 22, 2, 22), 60); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ์กฐํšŒ ์„ฑ๊ณต 200") + public void penaltySuccess() throws Exception { + //given + String url = "/party/penalty"; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + reportedAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + PenaltyResDto prd = objectMapper.readValue(contentAsString, PenaltyResDto.class); + assertThat(prd.getPenaltyEndTime()).isEqualTo(LocalDateTime.of(2222, 2, 22, 3, 22)); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ์—†๋Š” ์‚ฌ๋žŒ ์กฐํšŒ ์„ฑ๊ณต 200") + public void userSuccess() throws Exception { + //given + String url = "/party/penalty"; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + PenaltyResDto prd = objectMapper.readValue(contentAsString, PenaltyResDto.class); + assertThat(prd.getPenaltyEndTime()).isNull(); + } + } +} + diff --git a/gg-pingpong-api/src/test/java/gg/party/api/user/report/ReportControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/user/report/ReportControllerTest.java new file mode 100644 index 000000000..d9b1360e5 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/user/report/ReportControllerTest.java @@ -0,0 +1,395 @@ +package gg.party.api.user.report; + +import static java.lang.Boolean.*; +import static org.assertj.core.api.Assertions.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.util.Optional; + +import org.apache.http.HttpHeaders; +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.party.Category; +import gg.data.party.Comment; +import gg.data.party.CommentReport; +import gg.data.party.Room; +import gg.data.party.RoomReport; +import gg.data.party.UserReport; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.user.report.controller.request.ReportReqDto; +import gg.repo.party.CommentReportRepository; +import gg.repo.party.RoomReportRepository; +import gg.repo.party.UserReportRepository; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Rollback(value = true) +public class ReportControllerTest { + @Autowired + MockMvc mockMvc; + @Autowired + TestDataUtils testDataUtils; + @Autowired + ObjectMapper objectMapper; + @Autowired + AuthTokenProvider tokenProvider; + @Autowired + RoomReportRepository roomReportRepository; + @Autowired + CommentReportRepository commentReportRepository; + @Autowired + UserReportRepository userReportRepository; + User userTester; + User reporterTester; + User otherTester; + String userAccessToken; + String reporterAccessToken; + String otherAccessToken; + Category testCategory; + Comment comment; + Room openRoom; + Room startRoom; + Room finishRoom; + Room hiddenRoom; + Room failRoom; + Room[] rooms = {openRoom, startRoom, finishRoom, hiddenRoom, failRoom}; + RoomType[] roomTypes = {RoomType.OPEN, RoomType.START, RoomType.FINISH, RoomType.HIDDEN, RoomType.FAIL}; + + @Nested + @DisplayName("๋ฐฉ ์‹ ๊ณ  ํ…Œ์ŠคํŠธ") + class CreateRoomReport { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("userTester", "userTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + reporterTester = testDataUtils.createNewUser("reporterTester", "reporterTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + reporterAccessToken = tokenProvider.createToken(reporterTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + openRoom = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 1, + 7, 2, 180, RoomType.OPEN); + testDataUtils.createNewUserRoom(userTester, openRoom, "nickname", true); + } + + @Test + @Transactional + @DisplayName("๋ฐฉ ์‹ ๊ณ  ์„ฑ๊ณต CREATED-201") + public void reportRoomAddValidInputs() throws Exception { + //given + String url = "/party/reports/rooms/" + openRoom.getId(); + ReportReqDto reportReqDto = new ReportReqDto("report"); + //when + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(reportReqDto)) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isCreated()); + //then + RoomReport roomReport = roomReportRepository.findByRoomId(openRoom.getId()).get(0); + assertThat(roomReport.getRoom().getId()).isEqualTo(openRoom.getId()); + assertThat(roomReport.getReporter().getId()).isEqualTo(reporterTester.getId()); + assertThat(roomReport.getMessage()).isEqualTo("report"); + } + + @Test + @Transactional + @DisplayName("์ค‘๋ณต ์‹ ๊ณ ๋กœ ์ธํ•œ ์‹ ๊ณ  ์‹คํŒจ 409") + public void reportRoomDuplicateFail() throws Exception { + //given + String url = "/party/reports/rooms/" + openRoom.getId(); + ReportReqDto reportReqDto = new ReportReqDto("test report"); + String jsonRequest = objectMapper.writeValueAsString(reportReqDto); + //when & then + // ์ฒซ ๋ฒˆ์งธ ์‹ ๊ณ  ์š”์ฒญ + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isCreated()); + + // ์ค‘๋ณต ์‹ ๊ณ  ์š”์ฒญ + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isConflict()); + } + + @Test + @Transactional + @DisplayName("์ž์ง„ ์‹ ๊ณ ๋กœ ์ธํ•œ ์‹ ๊ณ  ์‹คํŒจ 400") + public void reportRoomSelfFail() throws Exception { + //given + String url = "/party/reports/rooms/" + openRoom.getId(); + ReportReqDto reportReqDto = new ReportReqDto("test report"); + String jsonRequest = objectMapper.writeValueAsString(reportReqDto); + //when & then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + + @Test + @Transactional + @DisplayName("๋ฐฉ ์—†์Œ ์‹คํŒจ 404") + public void reportRoomNotFoundFail() throws Exception { + //given + String openRoomId = "999"; + String url = "/party/reports/rooms/" + openRoomId; + ReportReqDto reportReqDto = new ReportReqDto("test report"); + String jsonRequest = objectMapper.writeValueAsString(reportReqDto); + //when & then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isNotFound()); + } + } + + @Nested + @DisplayName("๋Œ“๊ธ€ ์‹ ๊ณ  ํ…Œ์ŠคํŠธ") + class CreateCommentReport { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("userTester", "userTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + reporterTester = testDataUtils.createNewUser("reporterTester", "reporterTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + reporterAccessToken = tokenProvider.createToken(reporterTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + openRoom = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 1, + 7, 2, 180, RoomType.OPEN); + UserRoom openUserRoom = testDataUtils.createNewUserRoom(userTester, openRoom, "nickname", true); + comment = testDataUtils.createComment(userTester, openUserRoom, openRoom, "test_comment"); + } + + @Test + @Transactional + @DisplayName("๋Œ“๊ธ€ ์‹ ๊ณ  ์„ฑ๊ณต CREATED-201") + public void reportCommentAddValidInputs() throws Exception { + //given + String url = "/party/reports/comments/" + comment.getId(); + ReportReqDto reportReqDto = new ReportReqDto("report"); + //when + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(reportReqDto)) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isCreated()); + //then + CommentReport commentReport = commentReportRepository.findByCommentId(comment.getId()).get(0); + assertThat(commentReport.getComment().getId()).isEqualTo(comment.getId()); + assertThat(commentReport.getReporter().getId()).isEqualTo(reporterTester.getId()); + assertThat(commentReport.getMessage()).isEqualTo("report"); + } + + @Test + @Transactional + @DisplayName("์ค‘๋ณต ์‹ ๊ณ ๋กœ ์ธํ•œ ์‹ ๊ณ  ์‹คํŒจ 409") + public void reportCommentDuplicateFail() throws Exception { + //given + String url = "/party/reports/comments/" + comment.getId(); + String jsonRequest = objectMapper.writeValueAsString(new ReportReqDto("report")); + //when & then + // ์ฒซ ๋ฒˆ์งธ ์‹ ๊ณ  ์š”์ฒญ + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isCreated()); + + // ์ค‘๋ณต ์‹ ๊ณ  ์š”์ฒญ + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isConflict()); + } + + @Test + @Transactional + @DisplayName("์ž์ง„ ์‹ ๊ณ ๋กœ ์ธํ•œ ์‹ ๊ณ  ์‹คํŒจ 400") + public void reportCommentSelfFail() throws Exception { + //given + String url = "/party/reports/comments/" + comment.getId(); + String jsonRequest = objectMapper.writeValueAsString(new ReportReqDto("report")); + //when & then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + + @Test + @Transactional + @DisplayName("๋Œ“๊ธ€ ์—†์Œ ์‹คํŒจ 404") + public void reportCommentNotFoundFail() throws Exception { + //given + String commentId = "999"; + String url = "/party/reports/comments/" + commentId; + String jsonRequest = objectMapper.writeValueAsString(new ReportReqDto("report")); + //when & then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isNotFound()); + } + } + + @Nested + @DisplayName("์œ ์ € ์‹ ๊ณ  ํ…Œ์ŠคํŠธ") + class CreateUserReport { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("userTester", "userTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + reporterTester = testDataUtils.createNewUser("reporterTester", "reporterTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + reporterAccessToken = tokenProvider.createToken(reporterTester.getId()); + otherTester = testDataUtils.createNewUser("otherTester", "otherTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + otherAccessToken = tokenProvider.createToken(otherTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + for (int i = 0; i < rooms.length - 1; i++) { + rooms[i] = testDataUtils.createNewRoom(userTester, userTester, testCategory, i, 1, 3, 2, 180, + roomTypes[i]); + testDataUtils.createNewUserRoom(userTester, rooms[i], "testNickname", TRUE); + testDataUtils.createNewUserRoom(reporterTester, rooms[i], + "reportNickname", TRUE); + } + } + + @Test + @Transactional + @DisplayName("์œ ์ € ์‹ ๊ณ  ์„ฑ๊ณต 201") + public void reportUserAddValidInputs() throws Exception { + for (int i = 1; i < rooms.length - 2; i++) { // open, hidden, fail ์ œ์™ธ + //given + String url = "/party/reports/rooms/" + rooms[i].getId() + "/users/" + userTester.getIntraId(); + String jsonRequest = objectMapper.writeValueAsString(new ReportReqDto("test report")); + //when + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isCreated()) + .andReturn().getResponse().getContentAsString(); + + //then + Optional roomReports = userReportRepository.findByReporterAndReporteeAndRoom( + reporterTester, + userTester, rooms[i]); + if (roomReports.isPresent()) { + assertThat(roomReports.get().getReporter().getId()).isEqualTo(reporterTester.getId()); + assertThat(roomReports.get().getReportee().getId()).isEqualTo(userTester.getId()); + assertThat(roomReports.get().getMessage()).isEqualTo("test report"); + } + } + } + + @Test + @Transactional + @DisplayName("์ค‘๋ณต ์œ ์ € ์‹ ๊ณ ๋กœ ์ธํ•œ ์‹ ๊ณ  ์‹คํŒจ 409") + public void reportUserDuplicateFail() throws Exception { + for (int i = 1; i < rooms.length - 2; i++) { // open, hidden, fail ์ œ์™ธ + //given + String url = "/party/reports/rooms/" + rooms[i].getId() + "/users/" + userTester.getIntraId(); + String jsonRequest = objectMapper.writeValueAsString(new ReportReqDto("test report")); + //when & then + // ์ฒซ ๋ฒˆ์งธ ์‹ ๊ณ  ์š”์ฒญ + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isCreated()); + + // ์ค‘๋ณต ์‹ ๊ณ  ์š”์ฒญ + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isConflict()); + } + } + + @Test + @Transactional + @DisplayName("์ž์ง„ ์‹ ๊ณ ๋กœ ์ธํ•œ ์‹ ๊ณ  ์‹คํŒจ 400") + public void reportCommentSelfFail() throws Exception { + for (int i = 1; i < rooms.length - 2; i++) { // open, hidden, fail ์ œ์™ธ + //given + String url = "/party/reports/rooms/" + rooms[i].getId() + "/users/" + userTester.getIntraId(); + String jsonRequest = objectMapper.writeValueAsString(new ReportReqDto("report")); + //when & then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + } + + @Test + @Transactional + @DisplayName("์œ ์ € ์—†์Œ ์‹คํŒจ 404") + public void reportCommentNotFoundFail() throws Exception { + for (int i = 1; i < rooms.length - 2; i++) { // open, hidden, fail ์ œ์™ธ + //given + String intraId = "9999"; + String url = "/party/reports/rooms/" + rooms[i].getId() + "/users/" + intraId; + String jsonRequest = objectMapper.writeValueAsString(new ReportReqDto("report")); + //when & then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reporterAccessToken)) + .andExpect(status().isNotFound()); + } + } + + @Test + @Transactional + @DisplayName("์‹ ๊ณ ์ž, ํ”ผ์‹ ๊ณ ์ž๊ฐ€ ๊ฐ™์€ ๋ฐฉ์— ์—†์Œ 400") + public void reportUserNotParticipantFail() throws Exception { + for (int i = 1; i < rooms.length - 2; i++) { // open, hidden, fail ์ œ์™ธ + //given + String url = "/party/reports/rooms/" + rooms[i].getId() + "/users/" + userTester.getIntraId(); + String jsonRequest = objectMapper.writeValueAsString(new ReportReqDto("report")); + //when & then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + otherAccessToken)) + .andExpect(status().isBadRequest()); + } + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/party/api/user/room/RoomControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/user/room/RoomControllerTest.java new file mode 100644 index 000000000..a59a30c61 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/user/room/RoomControllerTest.java @@ -0,0 +1,764 @@ +package gg.party.api.user.room; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.BDDMockito.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDateTime; +import java.util.List; + +import org.apache.http.HttpHeaders; +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.party.Category; +import gg.data.party.Room; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.user.room.controller.request.RoomCreateReqDto; +import gg.party.api.user.room.controller.response.LeaveRoomResDto; +import gg.party.api.user.room.controller.response.RoomCreateResDto; +import gg.party.api.user.room.controller.response.RoomDetailResDto; +import gg.party.api.user.room.controller.response.RoomJoinResDto; +import gg.party.api.user.room.controller.response.RoomListResDto; +import gg.party.api.user.room.controller.response.RoomResDto; +import gg.party.api.user.room.controller.response.RoomStartResDto; +import gg.party.api.user.room.controller.response.UserRoomResDto; +import gg.party.api.user.room.service.RoomManagementService; +import gg.pingpong.api.user.noti.service.PartyNotiService; +import gg.repo.party.CategoryRepository; +import gg.repo.party.PartyPenaltyRepository; +import gg.repo.party.RoomRepository; +import gg.repo.party.UserRoomRepository; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class RoomControllerTest { + @Autowired + MockMvc mockMvc; + @Autowired + TestDataUtils testDataUtils; + @Autowired + ObjectMapper objectMapper; + @Autowired + AuthTokenProvider tokenProvider; + @Autowired + RoomRepository roomRepository; + @Autowired + UserRoomRepository userRoomRepository; + @Autowired + CategoryRepository categoryRepository; + @Autowired + PartyPenaltyRepository partyPenaltyRepository; + @Autowired + RoomManagementService roomManagementService; + @MockBean + PartyNotiService partyNotiService; + User userTester; + User anotherTester; + User otherTester; + User reportedTester; + String userAccessToken; + String anotherAccessToken; + String otherAccessToken; + String reportedAccessToken; + Category testCategory; + Room openRoom; + Room startRoom; + Room finishRoom; + Room hiddenRoom; + Room failRoom; + Room[] rooms = {openRoom, startRoom, finishRoom, hiddenRoom, failRoom}; + RoomType[] roomTypes = {RoomType.OPEN, RoomType.START, RoomType.FINISH, RoomType.HIDDEN, RoomType.FAIL}; + + @Nested + @DisplayName("๋ฐฉ ์ „์ฒด ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class FindAllActiveRoomList { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("findTester", "findTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + for (int i = 0; i < rooms.length; i++) { + rooms[i] = testDataUtils.createNewRoom(userTester, userTester, testCategory, i, 1, 3, 2, 180, + roomTypes[i]); + } + } + + /** + * ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š” ๋ฐฉ์ด ์—†์„๋•Œ ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ + * Penalty ์ƒํƒœ์˜ ์‚ฌ์šฉ์ž๋„ ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก์€ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•˜๊ธฐ์— ์œ ์ €๋ฅผ ๋‚˜๋ˆ„์ง€ ์•Š์•˜์Œ. + */ + @Test + @DisplayName("์กฐํšŒ ์„ฑ๊ณต 200") + public void success() throws Exception { + //given + String url = "/party/rooms"; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomListResDto rlrd = objectMapper.readValue(contentAsString, RoomListResDto.class); + List roomList = rlrd.getRoomList(); + for (RoomResDto responseDto : roomList) { + assertThat(responseDto.getStatus()).isIn(RoomType.OPEN.toString(), RoomType.START.toString(), + RoomType.FINISH.toString()); + } + } + } + + @Nested + @DisplayName("๋ฐฉ ์ƒ์„ฑ ํ…Œ์ŠคํŠธ") + class CreateRoom { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("userTester", "userTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + reportedTester = testDataUtils.createNewUser("reportedTester", "reportedTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + testDataUtils.createNewPenalty(reportedTester, "test", "test", + LocalDateTime.now(), 60); + userAccessToken = tokenProvider.createToken(userTester.getId()); + reportedAccessToken = tokenProvider.createToken(reportedTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + } + + @Test + @DisplayName("์ƒ์„ฑ ์„ฑ๊ณต 201") + public void success() throws Exception { + //given + String url = "/party/rooms"; + RoomCreateReqDto roomCreateReqDto = new RoomCreateReqDto("title", "content", testCategory.getName(), + 4, 2, 180); + String jsonRequest = objectMapper.writeValueAsString(roomCreateReqDto); + //when + String contentAsString = mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(jsonRequest) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isCreated()) + .andReturn().getResponse().getContentAsString(); + //then + RoomCreateResDto rcrd = objectMapper.readValue(contentAsString, RoomCreateResDto.class); + assertThat(rcrd.getRoomId()).isNotNull(); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ์ƒํƒœ๋กœ ์ธํ•œ ์ƒ์„ฑ ์‹คํŒจ 403") + public void penaltyUserFail() throws Exception { + //given + String url = "/party/rooms"; + RoomCreateReqDto roomCreateReqDto = new RoomCreateReqDto("title", "content", testCategory.getName(), 4, 2, + 180); + String requestBody = objectMapper.writeValueAsString(roomCreateReqDto); + // when && then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + reportedAccessToken)) + .andExpect(status().isForbidden()); + } + + @Test + @DisplayName("์—†๋Š” ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ์ธํ•œ ์ƒ์„ฑ ์‹คํŒจ 404") + public void notValidCategoryFail() throws Exception { + //given + String url = "/party/rooms"; + RoomCreateReqDto roomCreateReqDto = new RoomCreateReqDto("title", "content", "NOTFOUND", 4, 2, 180); + String requestBody = objectMapper.writeValueAsString(roomCreateReqDto); + // when && then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("์ตœ์†Œ์ธ์› > ์ตœ๋Œ€์ธ์› ์ƒ์„ฑ ์‹คํŒจ 400") + public void minOverMaxFail() throws Exception { + //given + String url = "/party/rooms"; + RoomCreateReqDto roomCreateReqDto = new RoomCreateReqDto("title", "content", testCategory.getName(), 2, 4, + 180); + String requestBody = objectMapper.writeValueAsString(roomCreateReqDto); + // when && then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("์ด์ƒํ•œ ์‹œ๊ฐ„์œผ๋กœ ์ธํ•œ ์ƒ์„ฑ ์‹คํŒจ 400") + public void notValidTimeFail() throws Exception { + //given + String url = "/party/rooms"; + RoomCreateReqDto roomCreateReqDto = new RoomCreateReqDto("title", "content", testCategory.getName(), 4, 2, + -180); + String requestBody = objectMapper.writeValueAsString(roomCreateReqDto); + // when && then + mockMvc.perform(post(url) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + } + + @Nested + @DisplayName("์ฐธ์—ฌํ•œ ๋ฐฉ ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class FindAllJoinedRoomListRoom { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("findTester", "findTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + for (int i = 0; i < rooms.length; i++) { + rooms[i] = testDataUtils.createNewRoom(userTester, userTester, testCategory, i, 1, 3, 2, 180, + roomTypes[i]); + } + } + + /** + * ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š” ๋ฐฉ์ด ์—†์„๋•Œ ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ + * Penalty ์ƒํƒœ์˜ ์‚ฌ์šฉ์ž๋„ ์ฐธ์—ฌ์ค‘์ธ ๋ฐฉ ๋ชฉ๋ก์€ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•˜๊ธฐ์— ์œ ์ €๋ฅผ ๋‚˜๋ˆ„์ง€ ์•Š์•˜์Œ. + * Penalty ์ƒํƒœ์˜ ์œ ์ €๋Š” ์‹œ์ž‘ํ•˜๊ธฐ ์ „์ธ ๋ฐฉ์—์„œ ๋‚˜๊ฐ€์ง€๊ฒŒ ์ž‘์„ฑํ–ˆ์œผ๋ฏ€๋กœ ์ด๋ฏธ ์‹œ์ž‘ํ•œ ๋ฐฉ์— ํ•œํ•ด์„œ๋งŒ ์กฐํšŒ๋˜์–ด์•ผํ•จ + */ + @Test + @DisplayName("์กฐํšŒ ์„ฑ๊ณต 200") + public void success() throws Exception { + //given + String url = "/party/rooms/joined"; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomListResDto resp = objectMapper.readValue(contentAsString, RoomListResDto.class); + List roomList = resp.getRoomList(); + for (RoomResDto responseDto : roomList) { + assertThat(responseDto.getStatus()).isIn(RoomType.OPEN.toString(), RoomType.START.toString()); + } + } + } + + @Nested + @DisplayName("์ฐธ์—ฌํ–ˆ๋˜ ๋ฐฉ ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class FindMyHistoryRoomList { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("findTester", "findTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + for (int i = 0; i < rooms.length; i++) { + rooms[i] = testDataUtils.createNewRoom(userTester, userTester, testCategory, i, 1, 3, 2, 180, + roomTypes[i]); + } + } + + /** + * ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š” ๋ฐฉ์ด ์—†์„๋•Œ ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ + * Penalty ์ƒํƒœ์˜ ์‚ฌ์šฉ์ž๋„ ์ฐธ์—ฌํ–ˆ๋˜ ๋ฐฉ ๋ชฉ๋ก์€ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•˜๊ธฐ์— ์œ ์ €๋ฅผ ๋‚˜๋ˆ„์ง€ ์•Š์•˜์Œ. + */ + @Test + @DisplayName("์กฐํšŒ ์„ฑ๊ณต 200") + public void success() throws Exception { + //given + String url = "/party/rooms/joined"; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomListResDto resp = objectMapper.readValue(contentAsString, RoomListResDto.class); + List roomList = resp.getRoomList(); + for (RoomResDto responseDto : roomList) { + assertThat(responseDto.getStatus()).isIn(RoomType.FINISH.toString()); + } + } + } + + @Nested + @DisplayName("๋ฐฉ ์ƒ์„ธ ์กฐํšŒ ํ…Œ์ŠคํŠธ") // penalty ์ƒํƒœ์˜ ์œ ์ €๋„ ๋ฐฉ์„ ์ƒ์„ธ ์กฐํšŒํ•  ์ˆ˜๋Š” ์žˆ๋‹ค. + class FindRoomDetailInfo { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewImageUser("findTester", "findTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER, "image"); + anotherTester = testDataUtils.createNewImageUser("anotherTester", "anotherTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER, "image"); + otherTester = testDataUtils.createNewImageUser("otherTester", "otherTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER, "image"); + userAccessToken = tokenProvider.createToken(userTester.getId()); + anotherAccessToken = tokenProvider.createToken(anotherTester.getId()); + otherAccessToken = tokenProvider.createToken(otherTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + for (int i = 0; i < rooms.length; i++) { + rooms[i] = testDataUtils.createNewRoom(userTester, userTester, testCategory, i, 1, 3, 2, 180, + roomTypes[i]); + testDataUtils.createNewUserRoom(userTester, rooms[i], "nickname" + i, true); + testDataUtils.createNewUserRoom(otherTester, rooms[i], "nickname" + i, true); + } + } + + @Test + @DisplayName("OPEN ๋ฐ ์ฐธ์—ฌํ•œ ๋ฐฉ ์กฐํšŒ ์„ฑ๊ณต 200") + public void inOpenRoomSuccess() throws Exception { + //given + String roomId = rooms[0].getId().toString(); // openRoom + String url = "/party/rooms/" + roomId; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomDetailResDto rdrd = objectMapper.readValue(contentAsString, RoomDetailResDto.class); + assertThat(rdrd.getStatus().toString()).isEqualTo(RoomType.OPEN.toString()); + for (UserRoomResDto roomUser : rdrd.getRoomUsers()) { + assertThat(roomUser.getIntraId()).isNull(); + assertThat(roomUser.getUserImage()).isNull(); + } + } + + @Test + @DisplayName("OPEN ๋ฐ ์ฐธ์—ฌํ•˜์ง€ ์•Š์€ ๋ฐฉ ์กฐํšŒ ์„ฑ๊ณต 200") + public void outOpenRoomSuccess() throws Exception { + //given + String roomId = rooms[0].getId().toString(); // openRoom + String url = "/party/rooms/" + roomId; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + anotherAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomDetailResDto rdrd = objectMapper.readValue(contentAsString, RoomDetailResDto.class); + assertThat(rdrd.getStatus().toString()).isEqualTo(RoomType.OPEN.toString()); + for (UserRoomResDto roomUser : rdrd.getRoomUsers()) { + assertThat(roomUser.getIntraId()).isNull(); + assertThat(roomUser.getUserImage()).isNull(); + } + } + + @Test + @DisplayName("START ๋ฐ ์ฐธ์—ฌํ•œ ๋ฐฉ ์กฐํšŒ ์„ฑ๊ณต 200") + public void inStartRoomSuccess() throws Exception { + //given + String roomId = rooms[1].getId().toString(); // startRoom + String url = "/party/rooms/" + roomId; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomDetailResDto rdrd = objectMapper.readValue(contentAsString, RoomDetailResDto.class); + assertThat(rdrd.getStatus().toString()).isEqualTo(RoomType.START.toString()); + for (UserRoomResDto roomUser : rdrd.getRoomUsers()) { + assertThat(roomUser.getIntraId()).isNotNull(); + assertThat(roomUser.getUserImage()).isNotNull(); + } + } + + @Test + @DisplayName("START ๋ฐ ์ฐธ์—ฌํ•˜์ง€ ์•Š์€ ๋ฐฉ ์กฐํšŒ ์„ฑ๊ณต 200") + public void outStartRoomSuccess() throws Exception { + //given + String roomId = rooms[1].getId().toString(); // startRoom + String url = "/party/rooms/" + roomId; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + anotherAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomDetailResDto rdrd = objectMapper.readValue(contentAsString, RoomDetailResDto.class); + assertThat(rdrd.getStatus().toString()).isEqualTo(RoomType.START.toString()); + for (UserRoomResDto roomUser : rdrd.getRoomUsers()) { + assertThat(roomUser.getIntraId()).isNull(); + assertThat(roomUser.getUserImage()).isNull(); + } + } + + @Test + @DisplayName("START ๋ฐ ์ฐธ์—ฌํ•œ ๋ฐฉ์žฅ์ด ์•„๋‹Œ ๋ฐฉ ์กฐํšŒ ์„ฑ๊ณต 200") + public void otherStartRoomSuccess() throws Exception { + //given + String roomId = rooms[1].getId().toString(); // startRoom + String url = "/party/rooms/" + roomId; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + otherAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomDetailResDto rdrd = objectMapper.readValue(contentAsString, RoomDetailResDto.class); + assertThat(rdrd.getStatus().toString()).isEqualTo(RoomType.START.toString()); + for (UserRoomResDto roomUser : rdrd.getRoomUsers()) { + assertThat(roomUser.getIntraId()).isNotNull(); + assertThat(roomUser.getUserImage()).isNotNull(); + } + } + + @Test + @DisplayName("Finish ๋ฐ ์ฐธ์—ฌํ•œ ๋ฐฉ์žฅ์ด ์•„๋‹Œ ๋ฐฉ ์กฐํšŒ ์„ฑ๊ณต 200") + public void otherFinishRoomSuccess() throws Exception { + //given + String roomId = rooms[2].getId().toString(); // finishRoom + String url = "/party/rooms/" + roomId; + //when + String contentAsString = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + otherAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + RoomDetailResDto rdrd = objectMapper.readValue(contentAsString, RoomDetailResDto.class); + assertThat(rdrd.getStatus().toString()).isEqualTo(RoomType.FINISH.toString()); + for (UserRoomResDto roomUser : rdrd.getRoomUsers()) { + assertThat(roomUser.getIntraId()).isNotNull(); + assertThat(roomUser.getUserImage()).isNotNull(); + } + } + + @Test + @DisplayName("HIDDEN๋œ ๋ฐฉ ์กฐํšŒ ์‹คํŒจ 404") + public void hiddenRoomFail() throws Exception { + // given + String roomId = rooms[3].getId().toString(); + String url = "/party/rooms/" + roomId; + // when && then + ResultActions resultActions = mockMvc.perform( + get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)); + resultActions.andExpect(status().isNotFound()); + } + } + + @Nested + @DisplayName("๋ฐฉ ์‹œ์ž‘ ํ…Œ์ŠคํŠธ") + class StartRoom { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("userTester", "userTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + anotherTester = testDataUtils.createNewUser("anotherTester", "anotherTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + otherTester = testDataUtils.createNewUser("otherTester", "otherTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + anotherAccessToken = tokenProvider.createToken(anotherTester.getId()); + otherAccessToken = tokenProvider.createToken(otherTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + openRoom = testDataUtils.createNewRoom(userTester, userTester, testCategory, 0, 2, 3, 2, 180, + RoomType.OPEN); + startRoom = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 2, 3, 2, 180, + RoomType.START); + testDataUtils.createNewUserRoom(userTester, openRoom, "nickname", true); + testDataUtils.createNewUserRoom(otherTester, openRoom, "nickname2", true); + } + + @Test + @DisplayName("์‹œ์ž‘ ์„ฑ๊ณต 201") + public void success() throws Exception { + // given + String roomId = openRoom.getId().toString(); + String url = "/party/rooms/" + roomId + "/start"; + // when + String contentAsString = mockMvc.perform( + post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isCreated()) + .andReturn().getResponse().getContentAsString(); + // then + RoomStartResDto rsrd = objectMapper.readValue(contentAsString, RoomStartResDto.class); + assertThat(rsrd.getRoomId()).isEqualTo(openRoom.getId()); + then(partyNotiService).should(times(1)).sendPartyNotifications(any()); + } + + @Test + @DisplayName("๋ฐฉ ์—†์Œ์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ 404") + public void noRoomFail() throws Exception { + // given + String roomId = "1000"; + String url = "/party/rooms/" + roomId + "/start"; + // when && then + mockMvc.perform(post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("Open์ด ์•„๋‹Œ ์ƒํƒœ๋กœ ์ธํ•œ ์—๋Ÿฌ 400") + public void notOpenFail() throws Exception { + // given + String roomId = startRoom.getId().toString(); + String url = "/party/rooms/" + roomId + "/start"; + // when && then + mockMvc.perform(post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("์ธ์›๋ถ€์กฑ์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ 400") + public void notNotEnoughPeopleFail() throws Exception { + // given + Room room = testDataUtils.createNewRoom(userTester, userTester, testCategory, 1, 1, 3, 2, 180, + RoomType.OPEN); + String roomId = room.getId().toString(); + String url = "/party/rooms/" + roomId + "/start"; + // when && then + mockMvc.perform(post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("๋ฐฉ์— ์ฐธ๊ฐ€ํ•˜์ง€ ์•Š์Œ์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ 400") + public void notCurrentFail() throws Exception { + // given + String roomId = openRoom.getId().toString(); + String url = "/party/rooms/" + roomId + "/start"; + // when && then + mockMvc.perform(post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + anotherAccessToken)) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("๋ฐฉ์žฅ์ด ์•„๋‹˜์œผ๋กœ ์ธํ•œ ์—๋Ÿฌ 403") + public void notHostFail() throws Exception { + // given + String roomId = openRoom.getId().toString(); + String url = "/party/rooms/" + roomId + "/start"; + // when && then + mockMvc.perform(post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + otherAccessToken)) + .andExpect(status().isForbidden()); + } + } + + @Nested + @DisplayName("๋ฐฉ ์ฐธ์—ฌ ํ…Œ์ŠคํŠธ") + class JoinRoom { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("userTester", "userTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + anotherTester = testDataUtils.createNewUser("anotherTester", "anotherTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + reportedTester = testDataUtils.createNewUser("reportedTester", "reportedTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + testDataUtils.createNewPenalty(reportedTester, "test", "test", LocalDateTime.now(), 60); + userAccessToken = tokenProvider.createToken(userTester.getId()); + anotherAccessToken = tokenProvider.createToken(anotherTester.getId()); + reportedAccessToken = tokenProvider.createToken(reportedTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + for (int i = 0; i < rooms.length; i++) { + rooms[i] = testDataUtils.createNewRoom(userTester, userTester, testCategory, i, 1, 3, 2, 180, + roomTypes[i]); + testDataUtils.createNewUserRoom(userTester, rooms[i], "nickname" + i, true); + } + openRoom = testDataUtils.createNewRoom(userTester, userTester, testCategory, 0, 1, 2, 2, 180, + RoomType.OPEN); + testDataUtils.createNewUserRoom(userTester, openRoom, "nickname", true); + } + + @Test + @DisplayName("์ฐธ์—ฌ ์„ฑ๊ณต 201") + public void success() throws Exception { + // given + String roomId = rooms[0].getId().toString(); // openRoom + String url = "/party/rooms/" + roomId; + // when + String contentAsString = mockMvc.perform( + post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + anotherAccessToken)) + .andExpect(status().isCreated()) + .andReturn().getResponse().getContentAsString(); + // then + RoomJoinResDto rjrd = objectMapper.readValue(contentAsString, RoomJoinResDto.class); + Room updatedRoom = roomRepository.findById(rooms[0].getId()).orElse(null); + assertThat(updatedRoom).isNotNull(); + assertThat(updatedRoom.getCurrentPeople()).isEqualTo(2); + assertThat(rjrd.getRoomId()).isEqualTo(rooms[0].getId()); + } + + @Test + @DisplayName("์ฐธ์—ฌ๋กœ ์ธํ•œ ์ตœ๋Œ€์ธ์›์œผ๋กœ ์‹œ์ž‘ ์„ฑ๊ณต 201") + public void startSuccess() throws Exception { + // given + String roomId = openRoom.getId().toString(); + String url = "/party/rooms/" + roomId; + // when + String contentAsString = mockMvc.perform( + post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + anotherAccessToken)) + .andExpect(status().isCreated()) + .andReturn().getResponse().getContentAsString(); + // then + RoomJoinResDto rjrd = objectMapper.readValue(contentAsString, RoomJoinResDto.class); + Room updatedRoom = roomRepository.findById(openRoom.getId()).orElse(null); + assertThat(updatedRoom).isNotNull(); + assertThat(updatedRoom.getCurrentPeople()).isEqualTo(2); + assertThat(rjrd.getRoomId()).isEqualTo(openRoom.getId()); + then(partyNotiService).should(times(1)).sendPartyNotifications(any()); + } + + @Test + @DisplayName("ํŒจ๋„ํ‹ฐ ์ƒํƒœ๋กœ ์ธํ•œ ์ฐธ์—ฌ ์‹คํŒจ 403") + public void penaltyUserFail() throws Exception { + // given + String roomId = rooms[0].getId().toString(); // openRoom + String url = "/party/rooms/" + roomId; + // when && then + mockMvc.perform( + post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + reportedAccessToken)) + .andExpect(status().isForbidden()); + } + + @Test + @DisplayName("OPEN์ด ์•„๋‹Œ ์ƒํƒœ๋กœ ์ธํ•œ ์‹คํŒจ 400") + public void notOpenRoomFail() throws Exception { + for (int i = 1; i < rooms.length; i++) { + //given + String roomId = (rooms[i].getId()).toString(); + String url = "/party/rooms/" + roomId; + // when && then + mockMvc.perform(post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + anotherAccessToken)) + .andExpect(status().isBadRequest()); + } + } + + @Test + @DisplayName("์ด๋ฏธ ์ฐธ์—ฌ ์ค‘์ธ ์ƒํƒœ๋กœ ์ธํ•œ ์‹คํŒจ 409") + public void alreadyInRoomFail() throws Exception { + // given + String roomId = rooms[0].getId().toString(); // openRoom + String url = "/party/rooms/" + roomId; + // when && then + mockMvc.perform(post(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isConflict()); + } + } + + @Nested + @DisplayName("๋ฐฉ ๋‚˜๊ฐ€๊ธฐ ํ…Œ์ŠคํŠธ") + class ExitRoom { + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("userTester", "userTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + anotherTester = testDataUtils.createNewUser("anotherTester", "anotherTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + otherTester = testDataUtils.createNewUser("otherTester", "otherTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + userAccessToken = tokenProvider.createToken(userTester.getId()); + otherAccessToken = tokenProvider.createToken(otherTester.getId()); + testCategory = testDataUtils.createNewCategory("category"); + for (int i = 1; i < rooms.length; i++) { + rooms[i] = testDataUtils.createNewRoom(userTester, userTester, testCategory, i, 1, 3, 2, 180, + roomTypes[i]); + testDataUtils.createNewUserRoom(userTester, rooms[i], "nickname" + i, true); + } + rooms[0] = testDataUtils.createNewRoom(userTester, userTester, testCategory, 0, 2, 3, 2, 180, + roomTypes[0]); + testDataUtils.createNewUserRoom(userTester, rooms[0], "nickname", true); + testDataUtils.createNewUserRoom(anotherTester, rooms[0], "nickname", true); + openRoom = testDataUtils.createNewRoom(userTester, userTester, testCategory, 0, 1, 3, 2, 180, + RoomType.OPEN); + testDataUtils.createNewUserRoom(userTester, openRoom, "nickname", true); + } + + @Test + @DisplayName("ํ˜ธ์ŠคํŠธ ์ด์ „ ์„ฑ๊ณต 200") + public void hostSuccess() throws Exception { + // given + String roomId = rooms[0].getId().toString(); // openRoom + String url = "/party/rooms/" + roomId; + // when + String contentAsString = mockMvc.perform( + patch(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + // then + Room updatedRoom = roomRepository.findById(rooms[0].getId()).orElse(null); + UserRoom newHostUserRoom = userRoomRepository.findByUserAndRoom(anotherTester, rooms[0]).orElse(null); + UserRoom exitUserRoom = userRoomRepository.findByUserAndRoom(userTester, rooms[0]).orElse(null); + assertThat(updatedRoom).isNotNull(); + assertThat(updatedRoom.getCurrentPeople()).isEqualTo(1); + assertThat(newHostUserRoom).isNotNull(); + assertThat(newHostUserRoom.getUser()).isEqualTo(updatedRoom.getHost()); + assertThat(exitUserRoom).isNotNull(); + assertThat(exitUserRoom.getIsExist()).isFalse(); + LeaveRoomResDto lrrd = objectMapper.readValue(contentAsString, LeaveRoomResDto.class); + assertThat(lrrd.getNickname()).isEqualTo(exitUserRoom.getNickname()); + } + + @Test + @DisplayName("๋ฐฉ FAIL ์„ฑ๊ณต 200") + public void failSuccess() throws Exception { + // given + String roomId = openRoom.getId().toString(); // openRoom + String url = "/party/rooms/" + roomId; + // when + String contentAsString = mockMvc.perform( + patch(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + // then + LeaveRoomResDto lrrd = objectMapper.readValue(contentAsString, LeaveRoomResDto.class); + Room updatedRoom = roomRepository.findById(openRoom.getId()).orElse(null); + UserRoom exitUserRoom = userRoomRepository.findByUserAndRoom(userTester, openRoom).orElse(null); + assertThat(updatedRoom).isNotNull(); + assertThat(updatedRoom.getCurrentPeople()).isEqualTo(0); + assertThat(updatedRoom.getStatus()).isEqualTo(RoomType.FAIL); + assertThat(exitUserRoom).isNotNull(); + assertThat(exitUserRoom.getIsExist()).isFalse(); + assertThat(lrrd.getNickname()).isEqualTo(exitUserRoom.getNickname()); + } + + @Test + @DisplayName("๋ฐฉ์— ์—†๋Š” ์œ ์ €๋กœ ์ธํ•œ ๋‚˜๊ฐ€๊ธฐ ์‹คํŒจ 404") + public void notInFail() throws Exception { + // given + String roomId = rooms[0].getId().toString(); // openRoom + String url = "/party/rooms/" + roomId; + // when && then + mockMvc.perform(patch(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + otherAccessToken)) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("OPEN์ด ์•„๋‹Œ ๋ฐฉ์œผ๋กœ ์ธํ•œ ๋‚˜๊ฐ€๊ธฐ ์‹คํŒจ 400") + public void startFail() throws Exception { + // given + String startRoomId = rooms[1].getId().toString(); // startRoom + String url = "/party/rooms/" + startRoomId; + // when && then + mockMvc.perform(patch(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + userAccessToken)) + .andExpect(status().isBadRequest()); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/party/api/user/template/TemplateControllerTest.java b/gg-pingpong-api/src/test/java/gg/party/api/user/template/TemplateControllerTest.java new file mode 100644 index 000000000..37ab5975e --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/party/api/user/template/TemplateControllerTest.java @@ -0,0 +1,83 @@ +package gg.party.api.user.template; + +import static org.assertj.core.api.AssertionsForClassTypes.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDateTime; + +import org.junit.jupiter.api.BeforeEach; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.auth.utils.AuthTokenProvider; +import gg.data.party.Category; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.party.api.user.template.controller.response.TemplateListResDto; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class TemplateControllerTest { + @Autowired + private MockMvc mockMvc; + @Autowired + ObjectMapper objectMapper; + @Autowired + private TestDataUtils testDataUtils; + @Autowired + private AuthTokenProvider tokenProvider; + User userTester; + User reportedTester; + String userAccessToken; + String reportedAccessToken; + + @BeforeEach + void beforeEach() { + userTester = testDataUtils.createNewUser("commentUserTester", "emailTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + reportedTester = testDataUtils.createNewUser("reportedTester", "reportedTester", + RacketType.DUAL, SnsType.SLACK, RoleType.USER); + testDataUtils.createNewPenalty(reportedTester, "test", "test", + LocalDateTime.now(), 60); + userAccessToken = tokenProvider.createToken(userTester.getId()); + reportedAccessToken = tokenProvider.createToken(reportedTester.getId()); + Category testCategory = testDataUtils.createNewCategory("test"); + for (int i = 0; i < 15; i++) { + testDataUtils.createNewTemplate(testCategory, "test" + i, 4, 2, 60, 30, "test" + i, "test" + i, "test" + i); + } + } + + @Nested + @DisplayName("ํ…œํ”Œ๋ฆฟ ์กฐํšŒ ํ…Œ์ŠคํŠธ") + class TemplateList { + @Test + @DisplayName("ํ…œํ”Œ๋ฆฟ ๋ชฉ๋ก ์กฐํšŒ ์„ฑ๊ณต 200") + void success() throws Exception { + //given + String uri = "/party/templates"; + //when + String contentAsString = mockMvc.perform(get(uri) + .header("Authorization", "Bearer " + userAccessToken) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + //then + TemplateListResDto tlrd = objectMapper.readValue(contentAsString, TemplateListResDto.class); + assertThat(tlrd.getTemplateList().size()).isEqualTo(15); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerFailTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerFailTest.java index f16fdb198..9d4fc9af7 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerFailTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerFailTest.java @@ -14,7 +14,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.manage.AnnouncementAdminRepository; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; +import gg.auth.utils.AuthTokenProvider; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerTest.java index bfa486b51..d03b9695b 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerTest.java @@ -16,10 +16,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.manage.AnnouncementAdminRepository; +import gg.auth.utils.AuthTokenProvider; import gg.data.manage.Announcement; import gg.pingpong.api.admin.manage.controller.response.AnnouncementAdminListResponseDto; import gg.pingpong.api.admin.manage.dto.AnnouncementAdminAddDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; import gg.utils.exception.announcement.AnnounceNotFoundException; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerUnitTest.java index bea390428..7b071e15e 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/announcement/controller/AnnouncementAdminControllerUnitTest.java @@ -16,8 +16,8 @@ import gg.pingpong.api.admin.manage.controller.response.AnnouncementAdminListResponseDto; import gg.pingpong.api.admin.manage.dto.AnnouncementAdminAddDto; import gg.pingpong.api.admin.manage.service.AnnouncementAdminService; -import gg.pingpong.api.global.dto.PageRequestDto; import gg.utils.annotation.UnitTest; +import gg.utils.dto.PageRequestDto; @UnitTest @ExtendWith(MockitoExtension.class) diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/feedback/controller/FeedbackAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/feedback/controller/FeedbackAdminControllerTest.java index 4f3d7304e..14e11b961 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/feedback/controller/FeedbackAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/feedback/controller/FeedbackAdminControllerTest.java @@ -15,11 +15,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.manage.FeedbackAdminRepository; +import gg.auth.utils.AuthTokenProvider; import gg.data.manage.Feedback; import gg.data.manage.type.FeedbackType; import gg.data.user.User; import gg.pingpong.api.admin.manage.controller.response.FeedbackListAdminResponseDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.repo.user.UserRepository; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/game/controller/GameAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/game/controller/GameAdminControllerTest.java index 5c7f3b35c..57e53a5b4 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/game/controller/GameAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/game/controller/GameAdminControllerTest.java @@ -25,14 +25,14 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.game.type.Mode; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.season.Season; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.pingpong.api.admin.game.controller.response.GameLogListAdminResponseDto; import gg.pingpong.api.admin.game.dto.RankGamePPPModifyReqDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.game.controller.request.RankResultReqDto; import gg.pingpong.api.user.game.service.GameService; import gg.pingpong.api.user.match.service.GameUpdateService; @@ -54,122 +54,32 @@ class GameAdminControllerTest { @Autowired TestDataUtils testDataUtils; - - @Autowired - private MockMvc mockMvc; - @Autowired ObjectMapper objectMapper; - @Autowired AuthTokenProvider tokenProvider; - @Autowired GameRepository gameRepository; - @Autowired UserRepository userRepository; - @Autowired GameUpdateService gameUpdateService; - @Autowired GameService gameService; - @Autowired RankRepository rankRepository; - @Autowired RankRedisRepository rankRedisRepository; @Autowired EntityManager entityManager; + @Autowired + private MockMvc mockMvc; @AfterEach void redisDown() { rankRedisRepository.deleteAll(); } - @Nested - @DisplayName("[GET] /pingpong/admin/games/users?intraId=${intraId}&page=${pageNumber}&size={sizeNum}") - class GetUserGameList { - String accessToken; - Long userId; - User user; - Season season; - - static final int TOTAL_PAGE_SIZE = 18; - static final int TOURNAMENT_GAME_SIZE = 4; - static final String INTRA_ID = "nheo"; - - @BeforeEach - void setUp() { - accessToken = testDataUtils.getAdminLoginAccessToken(); - userId = tokenProvider.getUserIdFromAccessToken(accessToken); - user = testDataUtils.createNewUser(INTRA_ID); - season = testDataUtils.createSeason(); - testDataUtils.createUserRank(user, "status message", season); - for (int i = 0; i < TOTAL_PAGE_SIZE; i++) { - testDataUtils.createMockMatchWithMockRank(user, season, LocalDateTime.now().minusMinutes(20 + i * 15), - LocalDateTime.now().minusMinutes(5 + i * 15)); - } - for (int i = TOTAL_PAGE_SIZE; i < TOTAL_PAGE_SIZE + TOURNAMENT_GAME_SIZE; i++) { - testDataUtils.createMockMatch(testDataUtils.createNewUser("testUser" + i), season, - LocalDateTime.now().minusMinutes(20 + i * 15), LocalDateTime.now().minusMinutes(5 + i * 15), - Mode.TOURNAMENT); - } - } - - private GameLogListAdminResponseDto getPageResult(int currentPage, int pageSize) - throws Exception { - String url = "/pingpong/admin/games/users?intraId=" - + INTRA_ID + "&page=" + currentPage + "&size=" + pageSize; - - String contentAsString = mockMvc - .perform(get(url) - .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)) - .andExpect(status().isOk()) - .andReturn().getResponse().getContentAsString(); - - return objectMapper.readValue(contentAsString, GameLogListAdminResponseDto.class); - } - - @Test - @Transactional - @DisplayName("First page") - void getUserGameListFirstPage() throws Exception { - //given - int pageSize = 5; - //when - GameLogListAdminResponseDto result = getPageResult(1, pageSize); - //then - assertThat(result.getGameLogList().size()).isEqualTo(pageSize); - } - - @Test - @Transactional - @DisplayName("Middle page") - void getUserGameListMidPage() throws Exception { - //given - int pageSize = 5; - //when - GameLogListAdminResponseDto result = getPageResult(2, pageSize); - //then - assertThat(result.getGameLogList().size()).isEqualTo(pageSize); - } - - @Test - @Transactional - @DisplayName("End page") - void getUserGameListEndPage() throws Exception { - //given - int pageSize = 5; - //when - GameLogListAdminResponseDto result = getPageResult(4, pageSize); - //then - assertThat(result.getGameLogList().size()).isEqualTo(TOTAL_PAGE_SIZE % pageSize); - } - } - @Test @DisplayName("[PUT] /pingpong/admin/games ๊ด€๋ฆฌ์ž๊ฒŒ์ž„์ „์ ์ˆ˜์ •ํ…Œ์ŠคํŠธ") @Transactional @@ -281,4 +191,84 @@ public void admingamestatUpdate() throws Exception { assertThat(enemyUser2Rank.getLosses()).isEqualTo(1); // assertThat(enemyUser2Rank.getPpp()).isEqualTo() } + + @Nested + @DisplayName("[GET] /pingpong/admin/games/users?intraId=${intraId}&page=${pageNumber}&size={sizeNum}") + class GetUserGameList { + static final int TOTAL_PAGE_SIZE = 18; + static final int TOURNAMENT_GAME_SIZE = 4; + static final String INTRA_ID = "nheo"; + String accessToken; + Long userId; + User user; + Season season; + + @BeforeEach + void setUp() { + accessToken = testDataUtils.getAdminLoginAccessToken(); + userId = tokenProvider.getUserIdFromAccessToken(accessToken); + user = testDataUtils.createNewUser(INTRA_ID); + season = testDataUtils.createSeason(); + testDataUtils.createUserRank(user, "status message", season); + for (int i = 0; i < TOTAL_PAGE_SIZE; i++) { + testDataUtils.createMockMatchWithMockRank(user, season, LocalDateTime.now().minusMinutes(20 + i * 15), + LocalDateTime.now().minusMinutes(5 + i * 15)); + } + for (int i = TOTAL_PAGE_SIZE; i < TOTAL_PAGE_SIZE + TOURNAMENT_GAME_SIZE; i++) { + testDataUtils.createMockMatch(testDataUtils.createNewUser("testUser" + i), season, + LocalDateTime.now().minusMinutes(20 + i * 15), LocalDateTime.now().minusMinutes(5 + i * 15), + Mode.TOURNAMENT); + } + } + + private GameLogListAdminResponseDto getPageResult(int currentPage, int pageSize) + throws Exception { + String url = "/pingpong/admin/games/users?intraId=" + + INTRA_ID + "&page=" + currentPage + "&size=" + pageSize; + + String contentAsString = mockMvc + .perform(get(url) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + + return objectMapper.readValue(contentAsString, GameLogListAdminResponseDto.class); + } + + @Test + @Transactional + @DisplayName("First page") + void getUserGameListFirstPage() throws Exception { + //given + int pageSize = 5; + //when + GameLogListAdminResponseDto result = getPageResult(1, pageSize); + //then + assertThat(result.getGameLogList().size()).isEqualTo(pageSize); + } + + @Test + @Transactional + @DisplayName("Middle page") + void getUserGameListMidPage() throws Exception { + //given + int pageSize = 5; + //when + GameLogListAdminResponseDto result = getPageResult(2, pageSize); + //then + assertThat(result.getGameLogList().size()).isEqualTo(pageSize); + } + + @Test + @Transactional + @DisplayName("End page") + void getUserGameListEndPage() throws Exception { + //given + int pageSize = 5; + //when + GameLogListAdminResponseDto result = getPageResult(4, pageSize); + //then + assertThat(result.getGameLogList().size()).isEqualTo(TOTAL_PAGE_SIZE % pageSize); + } + } } diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/item/controller/ItemAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/item/controller/ItemAdminControllerTest.java index 734c16218..eaefbf250 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/item/controller/ItemAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/item/controller/ItemAdminControllerTest.java @@ -25,12 +25,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.store.ItemAdminRepository; -import gg.data.store.Item; -import gg.data.store.type.ItemType; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.type.ItemType; import gg.pingpong.api.admin.store.controller.request.ItemUpdateRequestDto; import gg.pingpong.api.admin.store.controller.response.ItemListResponseDto; import gg.pingpong.api.admin.store.service.ItemAdminService; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.global.utils.ItemImageHandler; import gg.repo.user.UserRepository; import gg.utils.ItemTestUtils; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/item/service/ItemAdminServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/item/service/ItemAdminServiceUnitTest.java index 18a30742d..b520c6f5b 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/item/service/ItemAdminServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/item/service/ItemAdminServiceUnitTest.java @@ -21,7 +21,8 @@ import org.springframework.web.multipart.MultipartFile; import gg.admin.repo.store.ItemAdminRepository; -import gg.data.store.Item; +import gg.auth.UserDto; +import gg.data.pingpong.store.Item; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; @@ -29,7 +30,6 @@ import gg.pingpong.api.admin.store.controller.request.ItemUpdateRequestDto; import gg.pingpong.api.admin.store.service.ItemAdminService; import gg.pingpong.api.global.utils.aws.AsyncNewItemImageUploader; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.annotation.UnitTest; import gg.utils.exception.item.ItemNotAvailableException; import gg.utils.exception.item.ItemNotFoundException; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/match/service/MatchAdminServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/match/service/MatchAdminServiceTest.java new file mode 100644 index 000000000..3fa2745b9 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/match/service/MatchAdminServiceTest.java @@ -0,0 +1,52 @@ +package gg.pingpong.api.admin.match.service; + +import static org.junit.Assert.*; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +import javax.transaction.Transactional; + +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 gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.MatchKey; +import gg.data.pingpong.match.type.Option; +import gg.data.user.User; +import gg.pingpong.api.admin.match.service.dto.MatchUser; +import gg.pingpong.api.user.match.utils.MatchIntegrationTestUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@Transactional +class MatchAdminServiceTest { + @Autowired + private MatchAdminService matchAdminService; + @Autowired + private MatchIntegrationTestUtils matchTestSetting; + @Autowired + private RedisTemplate redisTemplate; + + @Test + @DisplayName("๋งค์นญํ์— 2๋ช…์˜ ์œ ์ €๊ฐ€ ์žˆ๊ณ  BOTH ์˜ต์…˜์œผ๋กœ ์กฐํšŒํ•˜๋ฉด 2๋ช…์˜ ์œ ์ €๊ฐ€ ์กฐํšŒ๋œ๋‹ค.") + void getMatches() { + // given + User user1 = matchTestSetting.createUser(); + User user2 = matchTestSetting.createUser(); + LocalDateTime startTime = LocalDateTime.of(2021, 1, 1, 0, 0); + RedisMatchUser redisMatchUser1 = new RedisMatchUser(user1.getId(), 123, Option.BOTH); + RedisMatchUser redisMatchUser2 = new RedisMatchUser(user2.getId(), 100, Option.RANK); + redisTemplate.opsForList().rightPush(MatchKey.getTime(startTime), redisMatchUser1); + redisTemplate.opsForList().rightPush(MatchKey.getTime(startTime), redisMatchUser2); + + // when + Map> matches = matchAdminService.getMatches(Option.BOTH); + + // then + assertEquals(2, matches.get(startTime).size()); + } +} diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/match/service/MatchAdminServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/match/service/MatchAdminServiceUnitTest.java new file mode 100644 index 000000000..1dfc5b60e --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/match/service/MatchAdminServiceUnitTest.java @@ -0,0 +1,81 @@ +package gg.pingpong.api.admin.match.service; + +import static org.hamcrest.MatcherAssert.*; +import static org.hamcrest.Matchers.*; +import static org.mockito.BDDMockito.*; + +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import gg.admin.repo.match.RedisMatchTimeAdminRepository; +import gg.admin.repo.user.UserAdminRepository; +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.Option; +import gg.data.user.User; +import gg.pingpong.api.admin.match.service.dto.MatchUser; +import gg.utils.annotation.UnitTest; + +@UnitTest +public class MatchAdminServiceUnitTest { + @InjectMocks + private MatchAdminService matchAdminService; + + @Mock + private RedisMatchTimeAdminRepository redisMatchTimeAdminRepository; + + @Mock + private UserAdminRepository userAdminRepository; + + @ParameterizedTest + @MethodSource("parameterProvider") + @DisplayName("๋งค์นญํ ๋ฐ์ดํ„ฐ๋ฅผ Option(BOTH, RANK, NORMAL, null)์— ๋”ฐ๋ผ ํ•„ํ„ฐ๋งํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.") + public void testGetMatches(Map> allEnrolledSlots, Option option) { + // given + given(redisMatchTimeAdminRepository.getAllEnrolledSlots()).willReturn(allEnrolledSlots); + given(userAdminRepository.findById(anyLong())) + .willReturn(Optional.of(User.builder().intraId("user").build())); + + // when + Map> response = matchAdminService.getMatches(option); + + // then + if (option == null || option == Option.BOTH) { + assertThat(response.size(), is(allEnrolledSlots.size())); + return; + } + for (Map.Entry> entry : response.entrySet()) { + for (MatchUser matchUser : entry.getValue()) { + assertThat(matchUser.getOption(), either(is(option)).or(is(Option.BOTH))); + } + } + } + + private static Stream parameterProvider() { + LocalDateTime localDateTime1 = LocalDateTime.of(2021, 1, 1, 0, 0, 0); + LocalDateTime localDateTime2 = LocalDateTime.of(2022, 1, 1, 0, 0, 0); + RedisMatchUser user1 = new RedisMatchUser(1L, 210, Option.NORMAL); + RedisMatchUser user2 = new RedisMatchUser(2L, 100, Option.BOTH); + RedisMatchUser user3 = new RedisMatchUser(3L, 150, Option.RANK); + + return Stream.of( + Arguments.arguments(Map.of(localDateTime1, Arrays.asList(user1, user2, user3), + localDateTime2, Arrays.asList(user1, user2, user3)), + Option.RANK), + Arguments.arguments(Map.of(localDateTime1, Arrays.asList(user1, user2, user3)), Option.RANK), + Arguments.arguments(Map.of(localDateTime1, Arrays.asList(user1, user2, user3)), Option.NORMAL), + Arguments.arguments(Map.of(localDateTime1, Arrays.asList(user1, user2, user3)), Option.NORMAL) + ); + } + +} diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/megaphone/controller/MegaphoneAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/megaphone/controller/MegaphoneAdminControllerTest.java index 7a8201a63..2d2992418 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/megaphone/controller/MegaphoneAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/megaphone/controller/MegaphoneAdminControllerTest.java @@ -12,7 +12,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.test.web.servlet.MockMvc; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; +import gg.auth.utils.AuthTokenProvider; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/noti/controller/NotiAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/noti/controller/NotiAdminControllerTest.java index 71343707a..b65aa8378 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/noti/controller/NotiAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/noti/controller/NotiAdminControllerTest.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.noti.NotiAdminRepository; +import gg.auth.utils.AuthTokenProvider; import gg.data.noti.Noti; import gg.data.noti.type.NotiType; import gg.data.user.User; @@ -31,7 +32,6 @@ import gg.pingpong.api.admin.noti.controller.response.NotiListAdminResponseDto; import gg.pingpong.api.admin.noti.dto.NotiAdminDto; import gg.pingpong.api.admin.noti.service.NotiAdminService; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.repo.noti.NotiRepository; import gg.repo.user.UserRepository; import gg.utils.TestDataUtils; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/noti/service/NotiAdminServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/noti/service/NotiAdminServiceUnitTest.java index 62a19d4fa..bc80a9211 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/noti/service/NotiAdminServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/noti/service/NotiAdminServiceUnitTest.java @@ -20,11 +20,11 @@ import gg.admin.repo.noti.NotiAdminRepository; import gg.admin.repo.user.UserAdminRepository; +import gg.auth.UserDto; import gg.data.noti.Noti; import gg.data.user.User; import gg.pingpong.api.admin.noti.controller.request.SendNotiAdminRequestDto; import gg.pingpong.api.user.noti.service.SnsNotiService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.annotation.UnitTest; import gg.utils.exception.user.UserNotFoundException; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/penalty/controller/PenaltyAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/penalty/controller/PenaltyAdminControllerTest.java index c67f02ef6..6db18709a 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/penalty/controller/PenaltyAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/penalty/controller/PenaltyAdminControllerTest.java @@ -30,6 +30,7 @@ import gg.admin.repo.manage.PenaltyAdminRepository; import gg.admin.repo.manage.PenaltyUserAdminRedisRepository; +import gg.auth.utils.AuthTokenProvider; import gg.data.manage.Penalty; import gg.data.manage.redis.RedisPenaltyUser; import gg.data.manage.type.PenaltyType; @@ -40,7 +41,6 @@ import gg.pingpong.api.admin.manage.controller.request.PenaltyRequestDto; import gg.pingpong.api.admin.manage.controller.response.PenaltyListResponseDto; import gg.pingpong.api.admin.manage.service.PenaltyAdminService; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.repo.user.UserRepository; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; @@ -160,12 +160,12 @@ public void checkPagination() throws Exception { for (int i = 0; i < 20; i++) { User newUser = testDataUtils.createNewUser(); users.add(newUser); - penaltyAdminService.givePenalty(newUser.getIntraId(), 3, "test" + String.valueOf(i)); + penaltyAdminService.givePenalty(newUser.getIntraId(), 3, "test" + i); } List sizeCounts = new ArrayList(); Integer totalPages = -1; for (int i = 1; i <= 3; i++) { - String url = "/pingpong/admin/penalty?page=" + String.valueOf(i) + "&size=10¤t=true"; + String url = "/pingpong/admin/penalty?page=" + i + "&size=10¤t=true"; String contentAsString = mockMvc.perform( get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)) .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); @@ -207,19 +207,19 @@ public void checkPaginationWithKeyword() throws Exception { User newUser = testDataUtils.createNewUser(intraId, "test", RacketType.NONE, SnsType.EMAIL, RoleType.USER); users.add(newUser); - penaltyAdminService.givePenalty(newUser.getIntraId(), 3, "test" + String.valueOf(i)); + penaltyAdminService.givePenalty(newUser.getIntraId(), 3, "test" + i); } for (int i = 0; i < 20; i++) { - String intraId = "dummy" + String.valueOf(i); + String intraId = "dummy" + i; User newUser = testDataUtils.createNewUser(intraId, "test", RacketType.NONE, SnsType.EMAIL, RoleType.USER); users.add(newUser); - penaltyAdminService.givePenalty(newUser.getIntraId(), 3, "test" + String.valueOf(i)); + penaltyAdminService.givePenalty(newUser.getIntraId(), 3, "test" + i); } List sizeCounts = new ArrayList(); Integer totalPages = -1; for (int i = 1; i <= 3; i++) { - String url = "/pingpong/admin/penalty?page=" + String.valueOf(i) + "&size=10¤t=true&intraId=test"; + String url = "/pingpong/admin/penalty?page=" + i + "&size=10¤t=true&intraId=test"; String contentAsString = mockMvc.perform( get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)) .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); @@ -332,13 +332,13 @@ public void getCurrentPenalties() throws Exception { //ํ˜„์žฌ ํŒจ๋„ํ‹ฐ ๋ถ€์—ฌ for (int i = 0; i < 20; i++) { - penaltyAdminService.givePenalty(users.get(i).getIntraId(), 3, "test" + String.valueOf(i)); + penaltyAdminService.givePenalty(users.get(i).getIntraId(), 3, "test" + i); } List sizeCounts = new ArrayList(); Integer totalPages = -1; for (int i = 1; i <= 3; i++) { - String url = "/pingpong/admin/penalty?page=" + String.valueOf(i) + "&size=10¤t=true"; + String url = "/pingpong/admin/penalty?page=" + i + "&size=10¤t=true"; String contentAsString = mockMvc.perform( get(url).header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)) .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/receipt/controller/ReceiptAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/receipt/controller/ReceiptAdminControllerTest.java index 3a157f59e..02efd5849 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/receipt/controller/ReceiptAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/receipt/controller/ReceiptAdminControllerTest.java @@ -19,13 +19,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.store.ReceiptAdminRepository; -import gg.data.store.Item; -import gg.data.store.type.ItemType; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.type.ItemType; import gg.data.user.User; import gg.pingpong.api.admin.store.controller.request.ItemUpdateRequestDto; import gg.pingpong.api.admin.store.controller.response.ReceiptListResponseDto; import gg.pingpong.api.admin.store.service.ReceiptAdminService; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.utils.ItemTestUtils; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/receipt/service/ReceiptAdminServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/receipt/service/ReceiptAdminServiceUnitTest.java index be06a7587..27e06b6a6 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/receipt/service/ReceiptAdminServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/receipt/service/ReceiptAdminServiceUnitTest.java @@ -15,7 +15,7 @@ import org.springframework.data.domain.Pageable; import gg.admin.repo.store.ReceiptAdminRepository; -import gg.data.store.Receipt; +import gg.data.pingpong.store.Receipt; import gg.pingpong.api.admin.store.service.ReceiptAdminService; import gg.utils.annotation.UnitTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/season/controller/SeasonAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/season/controller/SeasonAdminControllerTest.java index fdc758d2e..86dc08f88 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/season/controller/SeasonAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/season/controller/SeasonAdminControllerTest.java @@ -20,8 +20,9 @@ import com.google.common.net.HttpHeaders; import gg.admin.repo.season.SeasonAdminRepository; -import gg.data.rank.Tier; -import gg.data.season.Season; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.season.Season; import gg.pingpong.api.admin.rank.service.RankAdminService; import gg.pingpong.api.admin.rank.service.RankRedisAdminService; import gg.pingpong.api.admin.season.controller.request.SeasonCreateRequestDto; @@ -29,7 +30,6 @@ import gg.pingpong.api.admin.season.controller.response.SeasonListAdminResponseDto; import gg.pingpong.api.admin.season.dto.SeasonAdminDto; import gg.pingpong.api.admin.season.service.SeasonAdminService; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.repo.rank.RankRepository; import gg.repo.rank.redis.RankRedisRepository; import gg.utils.RedisKeyManager; @@ -50,33 +50,24 @@ class SeasonAdminControllerTest { @Autowired ObjectMapper objectMapper; - - @Autowired - private SeasonAdminRepository seasonAdminRepository; - @Autowired AuthTokenProvider tokenProvider; - @Autowired TestDataUtils testDataUtils; - @Autowired RankRepository rankRepository; - @Autowired RankRedisRepository rankRedisRepository; - @Autowired SeasonAdminService seasonAdminService; - @Autowired RankAdminService rankAdminService; - @Autowired RankRedisAdminService rankRedisAdminService; - SeasonListAdminResponseDto responseDto; Long dbSeasonId; + @Autowired + private SeasonAdminRepository seasonAdminRepository; @AfterEach void tearDown() { diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/season/service/SeasonAdminServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/season/service/SeasonAdminServiceUnitTest.java index 1022bcc8f..a2c35aaad 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/season/service/SeasonAdminServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/season/service/SeasonAdminServiceUnitTest.java @@ -20,7 +20,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import gg.admin.repo.season.SeasonAdminRepository; -import gg.data.season.Season; +import gg.data.pingpong.season.Season; import gg.pingpong.api.admin.rank.service.RankAdminService; import gg.pingpong.api.admin.rank.service.RankRedisAdminService; import gg.pingpong.api.admin.season.controller.request.SeasonCreateRequestDto; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/controller/SlotAdminControllerFailTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/controller/SlotAdminControllerFailTest.java index 2d6f207cd..406cd80ad 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/controller/SlotAdminControllerFailTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/controller/SlotAdminControllerFailTest.java @@ -18,9 +18,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.manage.AdminSlotManagementsRepository; -import gg.data.manage.SlotManagement; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.manage.SlotManagement; import gg.pingpong.api.admin.manage.controller.request.SlotCreateRequestDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.repo.manage.SlotManagementRepository; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; @@ -33,21 +33,16 @@ public class SlotAdminControllerFailTest { @Autowired TestDataUtils testDataUtils; - - @Autowired - private MockMvc mockMvc; - @Autowired ObjectMapper objectMapper; - @Autowired AuthTokenProvider tokenProvider; - @Autowired AdminSlotManagementsRepository adminSlotManagementRepository; - @Autowired SlotManagementRepository slotManagementRepository; + @Autowired + private MockMvc mockMvc; @Test @DisplayName("fail[Post]/pingpong/admin/slot-management") diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/controller/SlotAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/controller/SlotAdminControllerTest.java index f41d37e56..1c1094393 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/controller/SlotAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/controller/SlotAdminControllerTest.java @@ -19,11 +19,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.manage.AdminSlotManagementsRepository; -import gg.data.manage.SlotManagement; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.manage.SlotManagement; import gg.pingpong.api.admin.manage.controller.request.SlotCreateRequestDto; import gg.pingpong.api.admin.manage.controller.response.SlotListAdminResponseDto; import gg.pingpong.api.admin.manage.dto.SlotAdminDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.repo.manage.SlotManagementRepository; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; @@ -36,21 +36,16 @@ class SlotAdminControllerTest { @Autowired TestDataUtils testDataUtils; - - @Autowired - private MockMvc mockMvc; - @Autowired ObjectMapper objectMapper; - @Autowired AuthTokenProvider tokenProvider; - @Autowired AdminSlotManagementsRepository adminSlotManagementRepository; - @Autowired SlotManagementRepository slotManagementRepository; + @Autowired + private MockMvc mockMvc; @BeforeEach void setUp() { diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/service/SlotAdminServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/service/SlotAdminServiceUnitTest.java index 63fe2d374..ab4d6ab1a 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/service/SlotAdminServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/slotmanagement/service/SlotAdminServiceUnitTest.java @@ -19,7 +19,7 @@ import org.mockito.quality.Strictness; import gg.admin.repo.manage.AdminSlotManagementsRepository; -import gg.data.manage.SlotManagement; +import gg.data.pingpong.manage.SlotManagement; import gg.pingpong.api.admin.manage.controller.request.SlotCreateRequestDto; import gg.pingpong.api.admin.manage.service.SlotAdminService; import gg.utils.annotation.UnitTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/controller/CoinAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/controller/CoinAdminControllerTest.java similarity index 94% rename from gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/controller/CoinAdminControllerTest.java rename to gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/controller/CoinAdminControllerTest.java index 7c793e47c..54dcca9e8 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/controller/CoinAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/controller/CoinAdminControllerTest.java @@ -1,4 +1,4 @@ -package gg.pingpong.api.admin.coin.controller; +package gg.pingpong.api.admin.store.controller; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -15,8 +15,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import gg.auth.utils.AuthTokenProvider; import gg.pingpong.api.admin.store.controller.request.CoinUpdateRequestDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.repo.user.UserRepository; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/controller/CoinPolicyAdminControllerFailTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/controller/CoinPolicyAdminControllerFailTest.java similarity index 94% rename from gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/controller/CoinPolicyAdminControllerFailTest.java rename to gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/controller/CoinPolicyAdminControllerFailTest.java index 269e280fc..60c919cc9 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/controller/CoinPolicyAdminControllerFailTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/controller/CoinPolicyAdminControllerFailTest.java @@ -1,4 +1,4 @@ -package gg.pingpong.api.admin.coin.controller; +package gg.pingpong.api.admin.store.controller; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -15,8 +15,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.store.CoinPolicyAdminRepository; +import gg.auth.utils.AuthTokenProvider; import gg.pingpong.api.admin.store.dto.CoinPolicyAdminAddDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/controller/CoinPolicyAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/controller/CoinPolicyAdminControllerTest.java similarity index 96% rename from gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/controller/CoinPolicyAdminControllerTest.java rename to gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/controller/CoinPolicyAdminControllerTest.java index b31cc0581..4ec0ff349 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/controller/CoinPolicyAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/controller/CoinPolicyAdminControllerTest.java @@ -1,4 +1,4 @@ -package gg.pingpong.api.admin.coin.controller; +package gg.pingpong.api.admin.store.controller; import static org.assertj.core.api.Assertions.*; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; @@ -18,11 +18,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.store.CoinPolicyAdminRepository; -import gg.data.store.CoinPolicy; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.store.CoinPolicy; import gg.data.user.User; import gg.pingpong.api.admin.store.controller.response.CoinPolicyAdminListResponseDto; import gg.pingpong.api.admin.store.dto.CoinPolicyAdminAddDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; import gg.utils.exception.coin.CoinPolicyNotFoundException; @@ -35,18 +35,14 @@ class CoinPolicyAdminControllerTest { @Autowired TestDataUtils testDataUtils; - - @Autowired - private MockMvc mockMvc; - @Autowired ObjectMapper objectMapper; - @Autowired AuthTokenProvider tokenProvider; - @Autowired CoinPolicyAdminRepository coinPolicyAdminRepository; + @Autowired + private MockMvc mockMvc; @Test @DisplayName("[Get]/pingpong/admin/coinpolicy") diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/service/CoinAdminServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/service/CoinAdminServiceUnitTest.java similarity index 87% rename from gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/service/CoinAdminServiceTest.java rename to gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/service/CoinAdminServiceUnitTest.java index 18e7d0916..04961e19a 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/coin/service/CoinAdminServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/service/CoinAdminServiceUnitTest.java @@ -1,6 +1,5 @@ -package gg.pingpong.api.admin.coin.service; +package gg.pingpong.api.admin.store.service; -import static org.mockito.ArgumentMatchers.*; import static org.mockito.BDDMockito.*; import java.util.Optional; @@ -14,10 +13,9 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import gg.data.store.CoinHistory; +import gg.data.pingpong.store.CoinHistory; import gg.data.user.User; import gg.pingpong.api.admin.store.controller.request.CoinUpdateRequestDto; -import gg.pingpong.api.admin.store.service.CoinAdminService; import gg.pingpong.api.user.store.service.CoinHistoryService; import gg.repo.user.UserRepository; import gg.utils.annotation.UnitTest; @@ -25,8 +23,8 @@ @UnitTest @ExtendWith(MockitoExtension.class) -@DisplayName("CoinAdminServiceTest") -class CoinAdminServiceTest { +@DisplayName("CoinAdminServiceUnitTest") +class CoinAdminServiceUnitTest { @Mock UserRepository userRepository; @Mock diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/service/CoinPolicyAdminServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/service/CoinPolicyAdminServiceUnitTest.java new file mode 100644 index 000000000..f6e933fa0 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/store/service/CoinPolicyAdminServiceUnitTest.java @@ -0,0 +1,113 @@ +package gg.pingpong.api.admin.store.service; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.BDDMockito.*; + +import java.util.Collections; +import java.util.Optional; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; + +import gg.admin.repo.store.CoinPolicyAdminRepository; +import gg.admin.repo.user.UserAdminRepository; +import gg.auth.UserDto; +import gg.data.pingpong.store.CoinPolicy; +import gg.data.user.User; +import gg.pingpong.api.admin.store.controller.response.CoinPolicyAdminListResponseDto; +import gg.pingpong.api.admin.store.dto.CoinPolicyAdminAddDto; +import gg.utils.annotation.UnitTest; +import gg.utils.exception.user.UserNotFoundException; + +@UnitTest +@ExtendWith(MockitoExtension.class) +@DisplayName("CoinPolicyAdminServiceUnitTest") +class CoinPolicyAdminServiceUnitTest { + @Mock + CoinPolicyAdminRepository coinPolicyAdminRepository; + @Mock + UserAdminRepository userAdminRepository; + @InjectMocks + CoinPolicyAdminService coinPolicyAdminService; + + @Nested + @DisplayName("findAllCoinPolicy ๋ฉ”์„œ๋“œ unitTest") + class FindAllCoinPolicyTest { + @Test + @DisplayName("success") + void success() { + //given + Pageable pageable = PageRequest.of(0, 10); + CoinPolicy coinPolicy = mock(CoinPolicy.class); + Page coinPolicyPage = new PageImpl<>(Collections.singletonList(coinPolicy)); + when(coinPolicy.getUser()).thenReturn(mock(User.class)); + when(coinPolicyAdminRepository.findAll(pageable)).thenReturn(coinPolicyPage); + //when + CoinPolicyAdminListResponseDto responseDto = coinPolicyAdminService.findAllCoinPolicy(pageable); + //then + assertNotNull(responseDto); + verify(coinPolicyAdminRepository).findAll(pageable); + } + + @Test + @DisplayName("UserNotFoundException") + void userNotFoundException() { + //given + Pageable pageable = PageRequest.of(0, 10); + CoinPolicy coinPolicy = mock(CoinPolicy.class); + Page coinPolicyPage = new PageImpl<>(Collections.singletonList(coinPolicy)); + when(coinPolicyAdminRepository.findAll(pageable)).thenReturn(coinPolicyPage); + //when + assertThatThrownBy(() -> coinPolicyAdminService.findAllCoinPolicy(pageable)) + .isInstanceOf(UserNotFoundException.class); + //then + verify(coinPolicyAdminRepository).findAll(pageable); + } + } + + @Nested + @DisplayName("addCoinPolicy ๋ฉ”์„œ๋“œ unitTest") + class AddCoinPolicyTest { + @Test + @DisplayName("success") + void success() { + //given + String userId = "testId"; + UserDto userDto = mock(UserDto.class); + when(userDto.getIntraId()).thenReturn(userId); + given(userAdminRepository.findByIntraId(any(String.class))).willReturn(Optional.of(mock(User.class))); + given(coinPolicyAdminRepository.save(any(CoinPolicy.class))).willReturn(new CoinPolicy()); + //when + coinPolicyAdminService.addCoinPolicy(userDto, new CoinPolicyAdminAddDto()); + //then + verify(userAdminRepository).findByIntraId(any(String.class)); + verify(coinPolicyAdminRepository).save(any(CoinPolicy.class)); + } + + @Test + @DisplayName("UserNotFoundException") + void userNotFoundException() { + //given + String userId = "testId"; + UserDto userDto = mock(UserDto.class); + when(userDto.getIntraId()).thenReturn(userId); + given(userAdminRepository.findByIntraId(any(String.class))).willReturn(Optional.empty()); + //when, then + assertThatThrownBy(() -> coinPolicyAdminService.addCoinPolicy(userDto, new CoinPolicyAdminAddDto())) + .isInstanceOf(UserNotFoundException.class); + verify(userAdminRepository).findByIntraId(any(String.class)); + verify(coinPolicyAdminRepository, never()).save(any(CoinPolicy.class)); + } + } +} + diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/controller/TournamentAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/controller/TournamentAdminControllerTest.java index f5aa141e6..6666fa2df 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/controller/TournamentAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/controller/TournamentAdminControllerTest.java @@ -21,21 +21,21 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.game.type.Mode; -import gg.data.season.Season; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; import gg.data.user.User; import gg.pingpong.api.admin.tournament.controller.request.TournamentAdminAddUserRequestDto; import gg.pingpong.api.admin.tournament.controller.request.TournamentAdminCreateRequestDto; import gg.pingpong.api.admin.tournament.controller.request.TournamentAdminUpdateRequestDto; import gg.pingpong.api.admin.tournament.controller.request.TournamentGameUpdateRequestDto; import gg.pingpong.api.admin.tournament.service.TournamentAdminService; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.game.dto.TeamReqDto; import gg.pingpong.api.user.match.utils.MatchIntegrationTestUtils; import gg.repo.game.PChangeRepository; @@ -899,10 +899,10 @@ void userNotFound() throws Exception { @Nested @DisplayName("[Patch] /pingpong/admin/tournaments/{tournamentId}/games") class AdminUpdateTournamentGameTest { + Season season; private String accessToken; private Tournament tournament; private List allTournamentGames; - Season season; @BeforeEach void setUp() { diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/controller/TournamentAdminUserControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/controller/TournamentAdminUserControllerTest.java index 3ed665cae..fe293e8ff 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/controller/TournamentAdminUserControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/controller/TournamentAdminUserControllerTest.java @@ -16,12 +16,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.tournament.Tournament; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.tournament.Tournament; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; import gg.data.user.type.SnsType; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.tournament.controller.response.TournamentUserListResponseDto; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; @@ -33,6 +33,8 @@ @Slf4j public class TournamentAdminUserControllerTest { + final int joinUserCnt = 8; + final int notJoinUserCnt = 4; @Autowired MockMvc mockMvc; @Autowired @@ -41,10 +43,7 @@ public class TournamentAdminUserControllerTest { ObjectMapper objectMapper; @Autowired AuthTokenProvider tokenProvider; - String accessToken; - final int joinUserCnt = 8; - final int notJoinUserCnt = 4; String testName = "42_gg_tester_"; Tournament tournament; String adminUrl = "/pingpong/admin/tournaments/"; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/service/TournamentAdminServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/service/TournamentAdminServiceTest.java index e34413789..313153be3 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/service/TournamentAdminServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/tournament/service/TournamentAdminServiceTest.java @@ -17,14 +17,14 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import gg.data.game.Game; -import gg.data.manage.SlotManagement; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/user/controller/UserAdminControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/user/controller/UserAdminControllerTest.java index f07602ba8..8e5c69726 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/user/controller/UserAdminControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/admin/user/controller/UserAdminControllerTest.java @@ -24,6 +24,7 @@ import gg.admin.repo.user.UserAdminRepository; import gg.admin.repo.user.UserImageAdminRepository; +import gg.auth.utils.AuthTokenProvider; import gg.data.user.User; import gg.data.user.UserImage; import gg.pingpong.api.admin.user.controller.response.UserDetailAdminResponseDto; @@ -32,7 +33,6 @@ import gg.pingpong.api.admin.user.dto.UserImageAdminDto; import gg.pingpong.api.admin.user.dto.UserSearchAdminDto; import gg.pingpong.api.admin.user.service.UserAdminService; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.repo.user.UserRepository; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/GameUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/GameUnitTest.java index ce67c4ca7..433f53c9f 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/GameUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/GameUnitTest.java @@ -13,8 +13,8 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import gg.data.game.Game; -import gg.data.game.Team; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; import gg.utils.annotation.UnitTest; import gg.utils.exception.ErrorCode; import gg.utils.exception.custom.BusinessException; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/PChangeDataTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/PChangeDataTest.java index 3db8c6c64..813bab08a 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/PChangeDataTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/PChangeDataTest.java @@ -5,7 +5,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; -import gg.data.game.PChange; +import gg.data.pingpong.game.PChange; import gg.utils.annotation.UnitTest; @UnitTest diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TeamUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TeamUnitTest.java index 1bb720d3a..f9bf108a7 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TeamUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TeamUnitTest.java @@ -13,8 +13,8 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import gg.data.game.Team; -import gg.data.game.TeamUser; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; import gg.utils.annotation.UnitTest; import gg.utils.exception.ErrorCode; import gg.utils.exception.custom.BusinessException; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TournamentGameUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TournamentGameUnitTest.java index 27519a10e..7857afa6d 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TournamentGameUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TournamentGameUnitTest.java @@ -8,11 +8,11 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import gg.data.game.Game; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; import gg.utils.annotation.UnitTest; @UnitTest diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TournamentUserUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TournamentUserUnitTest.java index f96c9afc0..ea0d614a6 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TournamentUserUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/game/TournamentUserUnitTest.java @@ -8,10 +8,10 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; import gg.data.user.User; import gg.utils.annotation.UnitTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/store/ItemUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/store/ItemUnitTest.java index 33da59006..50d2376ab 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/data/store/ItemUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/data/store/ItemUnitTest.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; -import gg.data.store.Item; +import gg.data.pingpong.store.Item; import gg.utils.annotation.UnitTest; @UnitTest diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/announcement/controller/AnnouncementControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/announcement/controller/AnnouncementControllerTest.java index f8c207877..d25ecc550 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/announcement/controller/AnnouncementControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/announcement/controller/AnnouncementControllerTest.java @@ -16,9 +16,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import gg.auth.utils.AuthTokenProvider; import gg.data.manage.Announcement; import gg.data.user.User; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.repo.manage.AnnouncementRepository; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/coin/service/CoinHistoryServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/coin/service/CoinHistoryServiceTest.java index 3b61b83ba..7a4893131 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/coin/service/CoinHistoryServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/coin/service/CoinHistoryServiceTest.java @@ -10,10 +10,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; -import gg.data.store.CoinHistory; -import gg.data.store.CoinPolicy; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.store.CoinHistory; +import gg.data.pingpong.store.CoinPolicy; import gg.data.user.User; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.store.service.CoinHistoryService; import gg.repo.store.CoinHistoryRepository; import gg.repo.store.CoinPolicyRepository; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/coin/service/UserCoinChangeServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/coin/service/UserCoinChangeServiceTest.java index afcf7a41b..4b5cd8551 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/coin/service/UserCoinChangeServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/coin/service/UserCoinChangeServiceTest.java @@ -10,14 +10,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.season.Season; -import gg.data.store.CoinPolicy; -import gg.data.store.Item; -import gg.data.store.type.ItemType; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.store.CoinPolicy; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.type.ItemType; import gg.data.user.User; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.store.dto.UserGameCoinResultDto; import gg.pingpong.api.user.store.service.CoinHistoryService; import gg.pingpong.api.user.store.service.UserCoinChangeService; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/feedback/controller/FeedbackControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/feedback/controller/FeedbackControllerTest.java index ea796ed73..7d18ef831 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/feedback/controller/FeedbackControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/feedback/controller/FeedbackControllerTest.java @@ -15,9 +15,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import gg.auth.utils.AuthTokenProvider; import gg.data.manage.Feedback; import gg.data.manage.type.FeedbackType; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.manage.controller.request.FeedbackRequestDto; import gg.repo.manage.FeedbackRepository; import gg.utils.TestDataUtils; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/feedback/controller/FeedbackControllerUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/feedback/controller/FeedbackControllerUnitTest.java index be96ba9ac..0587cd669 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/feedback/controller/FeedbackControllerUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/feedback/controller/FeedbackControllerUnitTest.java @@ -10,10 +10,10 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import gg.auth.UserDto; import gg.pingpong.api.user.manage.controller.FeedbackController; import gg.pingpong.api.user.manage.controller.request.FeedbackRequestDto; import gg.pingpong.api.user.manage.service.FeedbackService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.annotation.UnitTest; @UnitTest diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/GameControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/GameControllerTest.java index ff71b42b0..bb4542ff0 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/GameControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/GameControllerTest.java @@ -25,23 +25,23 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.game.Game; -import gg.data.game.PChange; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.PChange; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; import gg.data.user.type.SnsType; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.game.controller.request.RankResultReqDto; import gg.pingpong.api.user.game.controller.request.TournamentResultReqDto; import gg.pingpong.api.user.game.controller.response.GameListResDto; @@ -97,11 +97,12 @@ public class GameControllerTest { @Autowired GameFindService gameFindService; @Autowired - private MockMvc mockMvc; - @Autowired ObjectMapper objectMapper; @Autowired AuthTokenProvider tokenProvider; + ArrayList tiers; + @Autowired + private MockMvc mockMvc; private String accessToken; private Season season; private User user1; @@ -109,7 +110,6 @@ public class GameControllerTest { private User user3; private Game game1; private Game game2; - ArrayList tiers; @BeforeEach void init() { diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameDBTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameDBTest.java index dd1fad1e7..817d29b9e 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameDBTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameDBTest.java @@ -17,14 +17,14 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.game.type.Mode; -import gg.data.season.Season; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.pingpong.api.admin.game.service.GameAdminService; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.repo.game.GameRepository; import gg.repo.game.PChangeRepository; import gg.repo.game.TeamRepository; @@ -75,9 +75,9 @@ public void cascadeTest() throws Exception { List gameList = gameRepository.findAll(); List teamList = teamRepository.findAll(); List teamUserList = teamUserRepository.findAll(); - log.info("GAME LIST SIZE : " + Integer.toString(gameList.size())); - log.info("TEAM LIST SIZE: " + Integer.toString(teamList.size())); - log.info("TEAM_USER LIST SIZE: " + Integer.toString(teamUserList.size())); + log.info("GAME LIST SIZE : " + gameList.size()); + log.info("TEAM LIST SIZE: " + teamList.size()); + log.info("TEAM_USER LIST SIZE: " + teamUserList.size()); Assertions.assertThat(teamList.size()).isEqualTo(0); Assertions.assertThat(teamUserList.size()).isEqualTo(0); } diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameFindServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameFindServiceTest.java index deca8b8f5..5c5c8ab3a 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameFindServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameFindServiceTest.java @@ -16,14 +16,14 @@ import org.springframework.data.domain.Sort; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; import gg.data.user.User; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.game.controller.response.GameListResDto; import gg.pingpong.api.user.game.controller.response.GameResultResDto; import gg.repo.game.GameRepository; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameFindServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameFindServiceUnitTest.java new file mode 100644 index 000000000..8a5b582eb --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameFindServiceUnitTest.java @@ -0,0 +1,171 @@ +package gg.pingpong.api.user.game.service; + +import static org.mockito.BDDMockito.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.SliceImpl; + +import gg.data.pingpong.game.Game; +import gg.repo.game.GameRepository; +import gg.utils.annotation.UnitTest; + +@UnitTest +class GameFindServiceUnitTest { + @Mock + GameRepository gameRepository; + @InjectMocks + GameFindService gameFindService; + + List gameIdList; + List gameList; + + @BeforeEach + void beforeEach() { + int size = 5; + gameIdList = new ArrayList<>(); + for (long i = 0; i < size; i++) { + gameIdList.add(i); + } + gameList = new ArrayList<>(); + for (int i = 0; i < size; i++) { + gameList.add(mock(Game.class)); + } + } + + @Nested + @DisplayName("normalGameListByIntra ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class NormalGameListByIntra { + @Test + @DisplayName("success") + void success() { + // given + given(gameRepository.findGamesByUserAndModeAndStatus(any(), any(), any(), any())) + .willReturn(new SliceImpl<>(gameIdList)); + // when, then + gameFindService.normalGameListByIntra(mock(Pageable.class), "intraId"); + } + } + + @Nested + @DisplayName("getNormalGameList ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class GetNormalGameList { + @Test + @DisplayName("success") + void success() { + // given + given(gameRepository.findAllByModeAndStatus(any(), any(), any())) + .willReturn(new SliceImpl<>(gameList)); + // when, then + gameFindService.getNormalGameList(mock(Pageable.class)); + } + } + + @Nested + @DisplayName("rankGameListByIntra ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class RankGameListByIntra { + @Test + @DisplayName("success") + void success() { + // given + given(gameRepository.findGamesByUserAndModeAndSeason(any(), any(), any(), any(), any())) + .willReturn(new SliceImpl<>(gameIdList)); + // when, then + gameFindService.rankGameListByIntra(mock(Pageable.class), 1L, "intraId"); + } + } + + @Nested + @DisplayName("rankGameList ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class RankGameList { + @Test + @DisplayName("success") + void success() { + // given + given(gameRepository.findAllByModeAndStatusAndSeasonId(any(), any(), any(), any())) + .willReturn(new SliceImpl<>(gameList)); + // when, then + gameFindService.rankGameList(mock(Pageable.class), 1L); + } + } + + @Nested + @DisplayName("allGameList ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + @MockitoSettings(strictness = Strictness.LENIENT) + class AllGameList { + @ParameterizedTest + @ValueSource(strings = {"LIVE", "END"}) + @DisplayName("success") + void success(String status) { + // given + given(gameRepository.findAllByModeInAndStatusIn(anyList(), anyList(), any())) + .willReturn(new SliceImpl<>(gameList)); + given(gameRepository.findAllByModeInAndStatus(anyList(), any(), any())) + .willReturn(new SliceImpl<>(gameList)); + // when, then + gameFindService.allGameList(mock(Pageable.class), status); + if (status.equals("LIVE")) { + verify(gameRepository, times(1)).findAllByModeInAndStatusIn(anyList(), anyList(), any()); + } else { + verify(gameRepository, times(1)).findAllByModeInAndStatus(anyList(), any(), any()); + } + } + } + + @Nested + @DisplayName("allGameListUser ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class AllGameListUser { + @ParameterizedTest + @ValueSource(strings = {"END", "LIVE"}) + @DisplayName("success") + void success(String status) { + // given + given(gameRepository.findGamesByUserAndModeInAndStatusIn(any(), anyList(), anyList(), any())) + .willReturn(new SliceImpl<>(gameIdList)); + // when, then + gameFindService.allGameListUser(mock(Pageable.class), "intraId", status); + + verify(gameRepository, times(1)) + .findGamesByUserAndModeInAndStatusIn(any(), anyList(), anyList(), any()); + } + } + + @Nested + @DisplayName("findByGameId ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class FindByGameId { + @Test + @DisplayName("success") + void success() { + // given + given(gameRepository.findById(any())).willReturn(Optional.of(mock(Game.class))); + // when, then + gameFindService.findByGameId(1L); + } + } + + @Nested + @DisplayName("findGameWithPessimisticLockById ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class FindGameWithPessimisticLockById { + @Test + @DisplayName("success") + void success() { + // given + given(gameRepository.findWithPessimisticLockById(any())).willReturn(Optional.of(mock(Game.class))); + // when, then + gameFindService.findGameWithPessimisticLockById(1L); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameServiceTest.java index e26469fe4..e9fed2e93 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameServiceTest.java @@ -10,17 +10,17 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; import gg.data.user.User; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.game.controller.request.RankResultReqDto; import gg.repo.game.GameRepository; import gg.repo.game.TeamRepository; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameServiceUnitTest.java new file mode 100644 index 000000000..00439ba21 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameServiceUnitTest.java @@ -0,0 +1,178 @@ +package gg.pingpong.api.user.game.service; + +import static gg.pingpong.api.utils.ReflectionUtilsForUnitTest.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.BDDMockito.*; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.StatusType; +import gg.data.user.User; +import gg.data.user.type.RacketType; +import gg.data.user.type.RoleType; +import gg.data.user.type.SnsType; +import gg.pingpong.api.user.game.controller.request.RankResultReqDto; +import gg.pingpong.api.user.match.service.MatchTournamentService; +import gg.pingpong.api.user.rank.redis.RankRedisService; +import gg.pingpong.api.user.rank.service.TierService; +import gg.pingpong.api.user.store.service.UserCoinChangeService; +import gg.repo.game.GameRepository; +import gg.repo.game.PChangeRepository; +import gg.repo.game.TeamUserRepository; +import gg.repo.game.out.GameTeamUserInfo; +import gg.repo.tournarment.TournamentGameRepository; +import gg.utils.annotation.UnitTest; +import gg.utils.exception.custom.InvalidParameterException; +import gg.utils.exception.game.GameNotExistException; + +@UnitTest +class GameServiceUnitTest { + @Mock + GameRepository gameRepository; + @Mock + TeamUserRepository teamUserRepository; + @Mock + RankRedisService rankRedisService; + @Mock + PChangeService pChangeService; + @Mock + PChangeRepository pChangeRepository; + @Mock + GameFindService gameFindService; + @Mock + UserCoinChangeService userCoinChangeService; + @Mock + TierService tierService; + @Mock + TournamentGameRepository tournamentGameRepository; + @Mock + MatchTournamentService matchTournamentService; + @InjectMocks + GameService gameService; + + @Nested + @DisplayName("getUserGameInfo ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class GetUserGameInfo { + List infos; + + @BeforeEach + void beforeEach() { + int infoCnt = 5; + infos = new ArrayList<>(); + for (int i = 0; i < infoCnt; i++) { + GameTeamUserInfo info = mock(GameTeamUserInfo.class); + infos.add(info); + } + } + + @Test + @DisplayName("GameNotExistException") + void gameNotExistException() { + // given + given(gameRepository.findTeamGameUser(any())).willReturn(new ArrayList<>()); + // when, then + assertThatThrownBy(() -> gameService.getUserGameInfo(1L, 1L)) + .isInstanceOf(GameNotExistException.class); + } + } + + @Nested + @MockitoSettings(strictness = Strictness.LENIENT) + @DisplayName("createRankResult ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class CreateRankResult { + RankResultReqDto scoreDto; + Game game; + List teams; + Team myTeam; + Team enemyTeam; + User me; + User enemy; + + @BeforeEach + void beforeEach() { + game = new Game(); + setFieldWithReflection(game, "id", 1L); + setFieldWithReflection(game, "startTime", LocalDateTime.now()); + + myTeam = new Team(game, 2, true); + setFieldWithReflection(myTeam, "id", 1L); + enemyTeam = new Team(game, 1, false); + setFieldWithReflection(enemyTeam, "id", 2L); + + me = new User("", "", "", RacketType.SHAKEHAND, + RoleType.USER, 0, SnsType.NONE, 1L); + enemy = new User("", "", "", RacketType.SHAKEHAND, + RoleType.USER, 0, SnsType.NONE, 1L); + setFieldWithReflection(me, "id", 1L); + setFieldWithReflection(enemy, "id", 2L); + + teams = new ArrayList<>(); + teams.add(new TeamUser(1L, myTeam, me)); + teams.add(new TeamUser(2L, enemyTeam, enemy)); + + scoreDto = new RankResultReqDto(1L, myTeam.getId(), 2, + enemyTeam.getId(), 1); + } + + @ParameterizedTest + @EnumSource(value = StatusType.class) + @DisplayName("success -> false") + void successFalse(StatusType type) { + // given + setFieldWithReflection(game, "status", type); + given(gameFindService.findGameWithPessimisticLockById(scoreDto.getGameId())).willReturn(game); + given(teamUserRepository.findAllByGameId(game.getId())).willReturn(teams); + // when + Boolean result = gameService.createRankResult(scoreDto, me.getId()); + // then + assertThat(result).isEqualTo(false); + } + + @ParameterizedTest + @EnumSource(value = StatusType.class, names = {"WAIT", "LIVE"}) + @DisplayName("success -> true") + void successTrue(StatusType type) { + // given + setFieldWithReflection(game, "status", type); + setFieldWithReflection(myTeam, "score", -1); + setFieldWithReflection(enemyTeam, "score", -1); + given(gameFindService.findGameWithPessimisticLockById(scoreDto.getGameId())).willReturn(game); + given(teamUserRepository.findAllByGameId(game.getId())).willReturn(teams); + // when + Boolean result = gameService.createRankResult(scoreDto, me.getId()); + // then + assertThat(result).isEqualTo(true); + assertThat(myTeam.getScore()).isEqualTo(scoreDto.getMyTeamScore()); + assertThat(enemyTeam.getScore()).isEqualTo(scoreDto.getEnemyTeamScore()); + } + + @ParameterizedTest + @EnumSource(value = StatusType.class, names = {"WAIT", "LIVE"}) + @DisplayName("InvalidParameterException") + void invalidParameterException(StatusType type) { + // given + setFieldWithReflection(game, "status", type); + given(gameFindService.findGameWithPessimisticLockById(scoreDto.getGameId())).willReturn(game); + given(teamUserRepository.findAllByGameId(game.getId())).willReturn(teams); + // when, then + assertThatThrownBy(() -> gameService.createRankResult(scoreDto, enemy.getId())) + .isInstanceOf(InvalidParameterException.class); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameStatusServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameStatusServiceTest.java index 383b15f97..f98085832 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameStatusServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameStatusServiceTest.java @@ -10,13 +10,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.manage.SlotManagement; -import gg.data.season.Season; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameStatusServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameStatusServiceUnitTest.java new file mode 100644 index 000000000..004fac987 --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/GameStatusServiceUnitTest.java @@ -0,0 +1,143 @@ +package gg.pingpong.api.user.game.service; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.BDDMockito.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +import gg.data.pingpong.game.Game; +import gg.data.pingpong.manage.SlotManagement; +import gg.pingpong.api.user.noti.service.NotiService; +import gg.pingpong.api.user.noti.service.SnsNotiService; +import gg.pingpong.api.user.user.service.UserService; +import gg.repo.game.GameRepository; +import gg.repo.game.out.GameUser; +import gg.repo.manage.SlotManagementRepository; +import gg.utils.annotation.UnitTest; +import gg.utils.exception.game.GameDataConsistencyException; +import gg.utils.exception.match.SlotNotFoundException; + +@UnitTest +class GameStatusServiceUnitTest { + @Mock + GameRepository gameRepository; + @Mock + SnsNotiService snsNotiService; + @Mock + NotiService notiService; + @Mock + UserService userService; + @Mock + SlotManagementRepository slotManagementRepository; + @InjectMocks + GameStatusService gameStatusService; + + List gameList; + List gameUserList; + + @BeforeEach + void beforeEach() { + gameList = new ArrayList<>(List.of(mock(Game.class), mock(Game.class), mock(Game.class))); + gameUserList = new ArrayList<>(); + } + + @Nested + @DisplayName("updateBeforeToLiveStatus ๋ฉ”์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class UpdateBeforeToLiveStatus { + @BeforeEach + void beforeEach() { + // given + given(gameRepository.findAllByStatusAndStartTimeLessThanEqual(any(), any())) + .willReturn(gameList); + } + + @Test + @DisplayName("success") + void success() { + // when, then + gameStatusService.updateBeforeToLiveStatus(); + verify(gameRepository, times(1)).findAllByStatusAndStartTimeLessThanEqual(any(), any()); + } + } + + @Nested + @DisplayName("updateLiveToWaitStatus ๋ฉ”์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class UpdateLiveToWaitStatus { + @BeforeEach + void beforeEach() { + // given + given(gameRepository.findAllByStatusAndEndTimeLessThanEqual(any(), any())) + .willReturn(gameList); + } + + @Test + @DisplayName("success") + void success() { + // when, then + gameStatusService.updateLiveToWaitStatus(); + verify(gameRepository, times(1)).findAllByStatusAndEndTimeLessThanEqual(any(), any()); + } + } + + @Nested + @MockitoSettings(strictness = Strictness.LENIENT) + @DisplayName("imminentGame ๋ฉ”์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class ImminentGame { + @BeforeEach + void beforeEach() { + // given + given(slotManagementRepository.findCurrent(any())).willReturn(Optional.of(mock(SlotManagement.class))); + given(gameRepository.findAllByStartTimeLessThanEqual(any())).willReturn(gameUserList); + } + + @ParameterizedTest + @ValueSource(ints = {0, 2}) + @DisplayName("success") + void success(int size) { + // given + for (int i = 0; i < size; i++) { + gameUserList.add(mock(GameUser.class)); + } + // when, then + gameStatusService.imminentGame(); + verify(slotManagementRepository, times(1)).findCurrent(any()); + verify(gameRepository, times(1)).findAllByStartTimeLessThanEqual(any()); + } + + @ParameterizedTest + @ValueSource(ints = {1, 3}) + @DisplayName("GameDataConsistencyException") + void gameDataConsistencyException(int size) { + // given + for (int i = 0; i < size; i++) { + gameUserList.add(mock(GameUser.class)); + } + // when, then + assertThatThrownBy(() -> gameStatusService.imminentGame()) + .isInstanceOf(GameDataConsistencyException.class); + } + + @Test + @DisplayName("SlotNotFoundException") + void slotNotFoundException() { + // given + given(slotManagementRepository.findCurrent(any())).willReturn(Optional.empty()); + // when, then + assertThatThrownBy(() -> gameStatusService.imminentGame()) + .isInstanceOf(SlotNotFoundException.class); + } + } +} diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/PChangeServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/PChangeServiceUnitTest.java new file mode 100644 index 000000000..32ce814bb --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/game/service/PChangeServiceUnitTest.java @@ -0,0 +1,100 @@ +package gg.pingpong.api.user.game.service; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.BDDMockito.*; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.PChange; +import gg.data.user.User; +import gg.repo.game.PChangeRepository; +import gg.utils.annotation.UnitTest; +import gg.utils.exception.pchange.PChangeNotExistException; + +@UnitTest +class PChangeServiceUnitTest { + @Mock + PChangeRepository pChangeRepository; + @InjectMocks + PChangeService pChangeService; + List pChangeList; + + @BeforeEach + void beforeEach() { + int size = 5; + pChangeList = new ArrayList<>(); + for (int i = 0; i < size; i++) { + pChangeList.add(mock(PChange.class)); + } + } + + @Nested + @DisplayName("addPChange ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class AddPChange { + @Test + @DisplayName("success") + void success() { + // given + given(pChangeRepository.save(any())).willReturn(mock(PChange.class)); + // when, then + pChangeService.addPChange(mock(Game.class), mock(User.class), 1, true); + } + } + + @Nested + @DisplayName("findExpChangeHistory ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class FindExpChangeHistory { + @Test + @DisplayName("success") + void success() { + // given + given(pChangeRepository.findExpHistory(any(), any())).willReturn(pChangeList); + // when, then + pChangeService.findExpChangeHistory(1L, 2L); + } + + @Test + @DisplayName("PChangeNotExistException") + void notExistException() { + // given + given(pChangeRepository.findExpHistory(any(), any())).willReturn(new ArrayList<>()); + // when, then + assertThatThrownBy(() -> pChangeService.findExpChangeHistory(1L, 2L)) + .isInstanceOf(PChangeNotExistException.class); + + } + } + + @Nested + @DisplayName("findPPPChangeHistory ๋งค์„œ๋“œ ์œ ๋‹› ํ…Œ์ŠคํŠธ") + class FindPPPChangeHistory { + @Test + @DisplayName("success") + void success() { + // given + given(pChangeRepository.findPPPHistory(any(), any(), any())).willReturn(pChangeList); + // when, then + pChangeService.findPPPChangeHistory(any(), any(), any()); + } + + @Test + @DisplayName("PChangeNotExistException") + void notExistException() { + // given + given(pChangeRepository.findPPPHistory(any(), any(), any())).willReturn(new ArrayList<>()); + // when, then + assertThatThrownBy(() -> pChangeService.findPPPChangeHistory(any(), any(), any())) + .isInstanceOf(PChangeNotExistException.class); + } + + } +} diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemGiftControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemGiftControllerTest.java index 822070f34..2b59b4d29 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemGiftControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemGiftControllerTest.java @@ -17,10 +17,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; +import gg.auth.UserDto; +import gg.auth.utils.AuthTokenProvider; import gg.pingpong.api.user.store.controller.request.ItemGiftRequestDto; import gg.pingpong.api.user.store.service.ItemService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemPurchaseControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemPurchaseControllerTest.java index c9f285c73..86eeb00f0 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemPurchaseControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemPurchaseControllerTest.java @@ -16,9 +16,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; +import gg.auth.UserDto; +import gg.auth.utils.AuthTokenProvider; import gg.pingpong.api.user.store.service.ItemService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; import lombok.RequiredArgsConstructor; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemStoreListControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemStoreListControllerTest.java index 48fc990f5..df5164a5b 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemStoreListControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/controller/ItemStoreListControllerTest.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.item.controller; -import static gg.data.store.type.ItemType.*; +import static gg.data.pingpong.store.type.ItemType.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; @@ -21,7 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; +import gg.auth.utils.AuthTokenProvider; import gg.pingpong.api.user.store.controller.response.ItemStoreListResponseDto; import gg.pingpong.api.user.store.controller.response.ItemStoreResponseDto; import gg.pingpong.api.user.store.service.ItemService; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/service/ItemServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/service/ItemServiceUnitTest.java index 45aeb4b29..6e2d148db 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/service/ItemServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/item/service/ItemServiceUnitTest.java @@ -20,10 +20,11 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; -import gg.data.store.Item; -import gg.data.store.Receipt; -import gg.data.store.type.ItemStatus; -import gg.data.store.type.ItemType; +import gg.auth.UserDto; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.type.ItemStatus; +import gg.data.pingpong.store.type.ItemType; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; @@ -31,7 +32,6 @@ import gg.pingpong.api.user.noti.service.NotiService; import gg.pingpong.api.user.store.service.ItemService; import gg.pingpong.api.user.store.service.UserCoinChangeService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.store.ItemRepository; import gg.repo.store.ReceiptRepository; import gg.repo.store.UserItemRepository; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/dto/MatchStatusDtoUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/dto/MatchStatusDtoUnitTest.java index b0e726e53..b008debab 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/dto/MatchStatusDtoUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/dto/MatchStatusDtoUnitTest.java @@ -11,9 +11,9 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.manage.SlotManagement; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.manage.SlotManagement; import gg.utils.annotation.UnitTest; @UnitTest diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchBothServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchBothServiceTest.java index 6cac860e4..59bb459fd 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchBothServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchBothServiceTest.java @@ -19,15 +19,15 @@ import org.springframework.transaction.annotation.Transactional; import gg.admin.repo.manage.PenaltyAdminRepository; -import gg.data.game.Game; -import gg.data.manage.SlotManagement; +import gg.auth.UserDto; import gg.data.manage.type.PenaltyKey; -import gg.data.match.type.Option; -import gg.data.season.Season; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.match.type.Option; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.pingpong.api.user.manage.redis.PenaltyUserRedisRepository; import gg.pingpong.api.user.match.utils.MatchIntegrationTestUtils; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.game.GameRepository; import gg.repo.manage.SlotManagementRepository; import gg.repo.match.RedisMatchTimeRepository; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchFindServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchFindServiceUnitTest.java index e84103f51..38d7504f4 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchFindServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchFindServiceUnitTest.java @@ -21,18 +21,18 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import gg.data.game.Game; -import gg.data.game.type.StatusType; -import gg.data.manage.SlotManagement; -import gg.data.match.RedisMatchTime; -import gg.data.match.type.Option; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; +import gg.auth.UserDto; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.match.RedisMatchTime; +import gg.data.pingpong.match.type.Option; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.pingpong.api.user.match.utils.SlotGenerator; import gg.pingpong.api.user.season.service.SeasonFindService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.game.GameRepository; import gg.repo.manage.SlotManagementRepository; import gg.repo.match.RedisMatchTimeRepository; @@ -46,6 +46,15 @@ @UnitTest @ExtendWith(MockitoExtension.class) public class MatchFindServiceUnitTest { + private static final SlotManagement slotManagement = SlotManagement.builder() + .pastSlotTime(0) + .futureSlotTime(12) + .openMinute(5) + .gameInterval(15) + .startTime(LocalDateTime.now()) + .build(); + private static final Season season = Season.builder().startTime(LocalDateTime.now()).startPpp(123).build(); + private static final Tier tier = new Tier(); @InjectMocks MatchFindService matchFindService; @Mock @@ -65,16 +74,6 @@ public class MatchFindServiceUnitTest { @Mock private TierRepository tierRepository; - private static final SlotManagement slotManagement = SlotManagement.builder() - .pastSlotTime(0) - .futureSlotTime(12) - .openMinute(5) - .gameInterval(15) - .startTime(LocalDateTime.now()) - .build(); - private static final Season season = Season.builder().startTime(LocalDateTime.now()).startPpp(123).build(); - private static final Tier tier = new Tier(); - @BeforeEach public void init() { setFieldWithReflection(slotManagement, "id", 1L); diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchServiceTest.java index e40f7f2dc..45aee4440 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchServiceTest.java @@ -23,22 +23,23 @@ import org.springframework.transaction.annotation.Transactional; import gg.admin.repo.manage.PenaltyAdminRepository; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.manage.SlotManagement; +import gg.auth.UserDto; import gg.data.manage.redis.RedisPenaltyUser; -import gg.data.match.RedisMatchUser; -import gg.data.match.type.MatchKey; -import gg.data.match.type.Option; -import gg.data.match.type.SlotStatus; import gg.data.noti.Noti; import gg.data.noti.type.NotiType; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; -import gg.data.tournament.Tournament; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.MatchKey; +import gg.data.pingpong.match.type.Option; +import gg.data.pingpong.match.type.SlotStatus; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; import gg.data.user.User; import gg.pingpong.api.user.manage.redis.PenaltyUserRedisRepository; import gg.pingpong.api.user.match.controller.response.MatchStatusResponseListDto; @@ -47,7 +48,6 @@ import gg.pingpong.api.user.match.dto.SlotStatusDto; import gg.pingpong.api.user.match.utils.MatchIntegrationTestUtils; import gg.pingpong.api.user.rank.redis.RedisUploadService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.game.GameRepository; import gg.repo.manage.SlotManagementRepository; import gg.repo.match.RedisMatchTimeRepository; @@ -377,7 +377,7 @@ void readMyTableAfterMakingGame() { SlotStatusResponseListDto slotStatusList = matchFindService.getAllMatchStatus(UserDto.from(users.get(0)), Option.NORMAL); for (int i = 0; i < 3; i++) { - System.out.println("slotTimes = " + String.valueOf(i) + slotTimes.get(i)); + System.out.println("slotTimes = " + i + slotTimes.get(i)); } for (List dtos : slotStatusList.getMatchBoards()) { for (SlotStatusDto dto : dtos) { diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchTournamentServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchTournamentServiceTest.java index 0b7aa2530..fbc0ea527 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchTournamentServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchTournamentServiceTest.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.match.service; -import static gg.data.tournament.type.RoundNumber.*; +import static gg.data.pingpong.tournament.type.RoundNumber.*; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -19,14 +19,14 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.game.type.StatusType; -import gg.data.match.type.TournamentMatchStatus; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.match.type.TournamentMatchStatus; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; import gg.data.user.User; import gg.pingpong.api.admin.noti.controller.request.SendNotiAdminRequestDto; import gg.pingpong.api.admin.noti.service.NotiAdminService; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchTournamentServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchTournamentServiceUnitTest.java index c0acdbb9e..6772ca250 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchTournamentServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/service/MatchTournamentServiceUnitTest.java @@ -1,6 +1,6 @@ package gg.pingpong.api.user.match.service; -import static gg.data.tournament.type.RoundNumber.*; +import static gg.data.pingpong.tournament.type.RoundNumber.*; import static gg.pingpong.api.user.match.utils.TournamentGameTestUtils.*; import static gg.pingpong.api.utils.ReflectionUtilsForUnitTest.*; import static org.assertj.core.api.Assertions.assertThat; @@ -23,18 +23,18 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.manage.SlotManagement; -import gg.data.match.type.TournamentMatchStatus; -import gg.data.season.Season; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.type.RoundNumber; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.match.type.TournamentMatchStatus; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.type.RoundNumber; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; import gg.data.user.User; import gg.pingpong.api.admin.noti.controller.request.SendNotiAdminRequestDto; import gg.pingpong.api.admin.noti.service.NotiAdminService; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/GameTestUtils.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/GameTestUtils.java index 1b6b44346..150877a9f 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/GameTestUtils.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/GameTestUtils.java @@ -2,12 +2,12 @@ import java.time.LocalDateTime; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.season.Season; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.season.Season; import gg.data.user.User; public class GameTestUtils { diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/MatchIntegrationTestUtils.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/MatchIntegrationTestUtils.java index 0bb2d3def..310b4dad1 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/MatchIntegrationTestUtils.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/MatchIntegrationTestUtils.java @@ -9,14 +9,14 @@ import org.springframework.stereotype.Component; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.manage.SlotManagement; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.type.TournamentRound; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.type.TournamentRound; import gg.data.user.User; import gg.repo.game.GameRepository; import gg.repo.manage.SlotManagementRepository; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/TournamentGameTestUtils.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/TournamentGameTestUtils.java index 2bbd24485..2918ee3af 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/TournamentGameTestUtils.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/TournamentGameTestUtils.java @@ -7,16 +7,16 @@ import java.util.Optional; import java.util.stream.Collectors; -import gg.data.game.Game; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.season.Season; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.type.RoundNumber; -import gg.data.tournament.type.TournamentRound; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.type.RoundNumber; +import gg.data.pingpong.tournament.type.TournamentRound; import gg.data.user.User; import gg.utils.exception.match.WinningTeamNotFoundException; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/TournamentTestUtils.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/TournamentTestUtils.java index b39ac3b02..bdec3d65f 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/TournamentTestUtils.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/match/utils/TournamentTestUtils.java @@ -2,12 +2,12 @@ import java.time.LocalDateTime; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; public class TournamentTestUtils { /** diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/megaphone/controller/MegaphoneControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/megaphone/controller/MegaphoneControllerTest.java index eb7ac45c5..d243ebfc3 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/megaphone/controller/MegaphoneControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/megaphone/controller/MegaphoneControllerTest.java @@ -17,17 +17,17 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.store.Item; -import gg.data.store.Megaphone; -import gg.data.store.Receipt; -import gg.data.store.type.ItemStatus; -import gg.data.store.type.ItemType; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.Megaphone; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.type.ItemStatus; +import gg.data.pingpong.store.type.ItemType; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; import gg.data.user.type.SnsType; import gg.pingpong.api.admin.store.controller.request.ItemUpdateRequestDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.store.controller.request.MegaphoneUseRequestDto; import gg.repo.store.MegaphoneRepository; import gg.repo.store.ReceiptRepository; @@ -42,24 +42,18 @@ class MegaphoneControllerTest { @Autowired TestDataUtils testDataUtils; - - @Autowired - private MockMvc mockMvc; - @Autowired ObjectMapper objectMapper; - @Autowired AuthTokenProvider tokenProvider; - @Autowired MegaphoneRepository megaphoneRepository; - @Autowired ReceiptRepository receiptRepository; - @Autowired ItemTestUtils itemTestUtils; + @Autowired + private MockMvc mockMvc; @Test @Transactional diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/megaphone/service/MegaphoneServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/megaphone/service/MegaphoneServiceUnitTest.java index 1dd4dce0d..7be892d2c 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/megaphone/service/MegaphoneServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/megaphone/service/MegaphoneServiceUnitTest.java @@ -22,11 +22,12 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import gg.data.store.Item; -import gg.data.store.Megaphone; -import gg.data.store.Receipt; -import gg.data.store.type.ItemStatus; -import gg.data.store.type.ItemType; +import gg.auth.UserDto; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.Megaphone; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.type.ItemStatus; +import gg.data.pingpong.store.type.ItemType; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; @@ -35,7 +36,6 @@ import gg.pingpong.api.user.store.redis.MegaphoneRedisRepository; import gg.pingpong.api.user.store.service.ItemService; import gg.pingpong.api.user.store.service.MegaphoneService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.store.MegaphoneRepository; import gg.repo.store.ReceiptRepository; import gg.repo.user.UserRepository; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/controller/NotiControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/controller/NotiControllerTest.java index b6f3c805a..0193eaca6 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/controller/NotiControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/controller/NotiControllerTest.java @@ -16,13 +16,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import gg.auth.UserDto; +import gg.auth.utils.AuthTokenProvider; import gg.data.noti.Noti; import gg.data.noti.type.NotiType; import gg.data.user.User; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.noti.controller.response.NotiListResponseDto; import gg.pingpong.api.user.noti.service.NotiService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.noti.NotiRepository; import gg.repo.user.UserRepository; import gg.utils.TestDataUtils; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/NotiServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/NotiServiceTest.java index 0a4fbbeb8..43d3bf657 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/NotiServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/NotiServiceTest.java @@ -11,11 +11,11 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import gg.auth.UserDto; +import gg.auth.utils.AuthTokenProvider; import gg.data.noti.Noti; import gg.data.noti.type.NotiType; import gg.data.user.User; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.noti.NotiRepository; import gg.repo.user.UserRepository; import gg.utils.TestDataUtils; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/NotiServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/NotiServiceUnitTest.java index c498b707f..314d88a62 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/NotiServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/NotiServiceUnitTest.java @@ -16,13 +16,13 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import gg.auth.UserDto; import gg.data.noti.Noti; import gg.data.noti.type.NotiType; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; import gg.data.user.type.SnsType; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.noti.NotiRepository; import gg.repo.user.UserRepository; import gg.utils.annotation.UnitTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/SnsNotiServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/SnsNotiServiceUnitTest.java index bb49f754d..b06af7597 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/SnsNotiServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/SnsNotiServiceUnitTest.java @@ -10,12 +10,12 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import gg.auth.UserDto; import gg.data.noti.Noti; import gg.data.user.type.SnsType; import gg.pingpong.api.user.noti.dto.UserNotiDto; import gg.pingpong.api.user.noti.service.sns.NotiMailSender; import gg.pingpong.api.user.noti.service.sns.SlackbotService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.game.out.GameUser; import gg.utils.annotation.UnitTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/sns/NotiMailSenderUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/sns/NotiMailSenderUnitTest.java index 4161564b2..8df09d2fc 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/sns/NotiMailSenderUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/noti/service/sns/NotiMailSenderUnitTest.java @@ -12,11 +12,11 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.mail.javamail.JavaMailSender; +import gg.auth.UserDto; import gg.data.noti.Noti; import gg.pingpong.api.global.utils.AsyncMailSender; import gg.pingpong.api.user.noti.dto.UserNotiDto; import gg.pingpong.api.user.noti.service.NotiService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.game.out.GameUser; import gg.utils.annotation.UnitTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/pchange/service/PChangeServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/pchange/service/PChangeServiceTest.java index b396d297e..cfa5cdcb9 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/pchange/service/PChangeServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/pchange/service/PChangeServiceTest.java @@ -14,8 +14,8 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import gg.data.game.Game; -import gg.data.game.PChange; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.PChange; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/controller/RankControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/controller/RankControllerTest.java index 99e9e8e6d..c439a99e7 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/controller/RankControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/controller/RankControllerTest.java @@ -19,9 +19,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.season.Season; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.season.Season; import gg.data.user.User; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.rank.controller.response.ExpRankPageResponseDto; import gg.pingpong.api.user.rank.controller.response.RankPageResponseDto; import gg.pingpong.api.user.rank.dto.RankDto; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/controller/RankV2ControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/controller/RankV2ControllerTest.java index 01f676b0a..114f4030d 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/controller/RankV2ControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/controller/RankV2ControllerTest.java @@ -19,16 +19,16 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; +import gg.auth.UserDto; +import gg.auth.utils.AuthTokenProvider; import gg.data.user.User; import gg.pingpong.api.global.config.WebConfig; import gg.pingpong.api.global.security.config.SecurityConfig; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.global.security.jwt.utils.TokenAuthenticationFilter; import gg.pingpong.api.global.utils.querytracker.LoggingInterceptor; import gg.pingpong.api.user.rank.controller.response.ExpRankPageResponseDto; import gg.pingpong.api.user.rank.controller.response.RankPageResponseDto; import gg.pingpong.api.user.rank.service.RankService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.user.UserRepository; @WebMvcTest(value = RankV2Controller.class, diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/redis/RankRedisRepositoryTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/redis/RankRedisRepositoryTest.java index c048a5f26..bf2079a51 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/redis/RankRedisRepositoryTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/redis/RankRedisRepositoryTest.java @@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import gg.data.rank.redis.RankRedis; +import gg.data.pingpong.rank.redis.RankRedis; import gg.repo.rank.redis.RankRedisRepository; import gg.utils.annotation.IntegrationTest; import gg.utils.exception.rank.RedisDataNotFoundException; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/service/RankServiceTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/service/RankServiceTest.java index 9e0afdb01..3edd4295d 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/service/RankServiceTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/rank/service/RankServiceTest.java @@ -17,12 +17,12 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; -import gg.data.season.Season; +import gg.auth.UserDto; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.pingpong.api.user.rank.controller.response.ExpRankPageResponseDto; import gg.pingpong.api.user.rank.controller.response.RankPageResponseDto; import gg.pingpong.api.user.season.service.SeasonFindService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.repo.rank.RankRepository; import gg.repo.rank.RankV2Dto; import gg.repo.rank.redis.RankRedisRepository; @@ -42,41 +42,6 @@ class RankServiceTest { @InjectMocks private RankService rankService; - @BeforeEach - void setUp() { - // ํ˜„์žฌ ์‹œ์ฆŒ ๊ฐ€์ ธ์˜ค๊ธฐ - given(seasonFindService.findCurrentSeason(any())) - .willReturn(Season.builder() - .seasonName("Test Season") - .build()); - } - - @AfterEach - void tearDown() { - } - - @Test - void getExpRankPage() { - PageRequest pageRequest = PageRequest.of(0, 10); - // exp ranking user list, total page size ์กฐํšŒ - given(userRepository.findAllByTotalExpGreaterThan(pageRequest, 0)) - .willReturn(new PageImpl<>(new ArrayList(), pageRequest, 1)); - - // exp ranking list ์กฐํšŒ - List expRankV2DtoList = expRankingSampleData(); - given(userRepository.findExpRank(pageRequest.getPageNumber(), pageRequest.getPageSize(), - null)) - .willReturn(expRankV2DtoList); - ExpRankPageResponseDto testRes = rankService.getExpRankPage(pageRequest, UserDto - .builder() - .intraId("TestUser") - .id(1L) - .totalExp(0) - .build()); - assertThat(testRes.getMyRank()).isEqualTo(-1); - assertThat(testRes.getRankList().get(0).getIntraId()).isEqualTo("Test User"); - } - private static List expRankingSampleData() { List expRankV2Dtos = new ArrayList<>(); expRankV2Dtos.add(new ExpRankV2Dto() { @@ -113,31 +78,6 @@ public Integer getRanking() { return expRankV2Dtos; } - @Test - void getRankPageV2() { - PageRequest pageRequest = PageRequest.of(0, 10); - // ํ˜„์žฌ ์‹œ์ฆŒ id ์— ํ•ด๋‹นํ•˜๋Š” ๋žญํฌ ์œ ์ € ๋ฆฌ์ŠคํŠธ์˜ ํŽ˜์ด์ง€ ์ˆ˜ - given(rankRepository.countRankUserBySeasonId(any())) - .willReturn(1); - // ํ˜„์žฌ ์œ ์ € ranking - given(rankRepository.findRankByUserIdAndSeasonId(any(), any())) - .willReturn(Optional.of(1)); - // sample data - List rankV2DtoList = pppRankingSampleData(); - given(rankRepository.findPppRankBySeasonId(anyInt(), anyInt(), any())) - .willReturn(rankV2DtoList); - RankPageResponseDto result = rankService.getRankPageV2(pageRequest, - UserDto - .builder() - .intraId("TestUser") - .id(1L) - .totalExp(0) - .build(), - any()); - assertThat(result.getCurrentPage()).isEqualTo(pageRequest.getPageNumber() + 1); - assertThat(result.getRankList().size()).isEqualTo(rankV2DtoList.size()); - } - private static List pppRankingSampleData() { List rankV2DtoList = new ArrayList<>(); rankV2DtoList.add(new RankV2Dto() { @@ -173,4 +113,64 @@ public Integer getRanking() { }); return rankV2DtoList; } + + @BeforeEach + void setUp() { + // ํ˜„์žฌ ์‹œ์ฆŒ ๊ฐ€์ ธ์˜ค๊ธฐ + given(seasonFindService.findCurrentSeason(any())) + .willReturn(Season.builder() + .seasonName("Test Season") + .build()); + } + + @AfterEach + void tearDown() { + } + + @Test + void getExpRankPage() { + PageRequest pageRequest = PageRequest.of(0, 10); + // exp ranking user list, total page size ์กฐํšŒ + given(userRepository.findAllByTotalExpGreaterThan(pageRequest, 0)) + .willReturn(new PageImpl<>(new ArrayList(), pageRequest, 1)); + + // exp ranking list ์กฐํšŒ + List expRankV2DtoList = expRankingSampleData(); + given(userRepository.findExpRank(pageRequest.getPageNumber(), pageRequest.getPageSize(), + null)) + .willReturn(expRankV2DtoList); + ExpRankPageResponseDto testRes = rankService.getExpRankPage(pageRequest, UserDto + .builder() + .intraId("TestUser") + .id(1L) + .totalExp(0) + .build()); + assertThat(testRes.getMyRank()).isEqualTo(-1); + assertThat(testRes.getRankList().get(0).getIntraId()).isEqualTo("Test User"); + } + + @Test + void getRankPageV2() { + PageRequest pageRequest = PageRequest.of(0, 10); + // ํ˜„์žฌ ์‹œ์ฆŒ id ์— ํ•ด๋‹นํ•˜๋Š” ๋žญํฌ ์œ ์ € ๋ฆฌ์ŠคํŠธ์˜ ํŽ˜์ด์ง€ ์ˆ˜ + given(rankRepository.countRankUserBySeasonId(any())) + .willReturn(1); + // ํ˜„์žฌ ์œ ์ € ranking + given(rankRepository.findRankByUserIdAndSeasonId(any(), any())) + .willReturn(Optional.of(1)); + // sample data + List rankV2DtoList = pppRankingSampleData(); + given(rankRepository.findPppRankBySeasonId(anyInt(), anyInt(), any())) + .willReturn(rankV2DtoList); + RankPageResponseDto result = rankService.getRankPageV2(pageRequest, + UserDto + .builder() + .intraId("TestUser") + .id(1L) + .totalExp(0) + .build(), + any()); + assertThat(result.getCurrentPage()).isEqualTo(pageRequest.getPageNumber() + 1); + assertThat(result.getRankList().size()).isEqualTo(rankV2DtoList.size()); + } } diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/SeasonTestController.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/SeasonTestController.java index 8b20a431e..9d6634787 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/SeasonTestController.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/SeasonTestController.java @@ -18,8 +18,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.season.Season; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.season.Season; import gg.pingpong.api.user.season.controller.response.SeasonListResDto; import gg.pingpong.api.user.season.controller.response.SeasonResDto; import gg.pingpong.api.user.season.service.SeasonService; @@ -36,14 +36,13 @@ public class SeasonTestController { @Autowired MockMvc mvc; @Autowired - private SeasonService seasonService; - @Autowired TestDataUtils testDataUtils; @Autowired AuthTokenProvider tokenProvider; @Autowired ObjectMapper objectMapper; - + @Autowired + private SeasonService seasonService; @Autowired private SeasonRepository seasonRepository; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/SeasonTriggerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/SeasonTriggerTest.java index 1728f970d..e059b8c16 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/SeasonTriggerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/SeasonTriggerTest.java @@ -16,9 +16,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.game.type.Mode; -import gg.data.season.Season; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.season.Season; import gg.repo.season.SeasonRepository; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/service/SeasonServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/service/SeasonServiceUnitTest.java index 0a8b083fa..d60d118dc 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/service/SeasonServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/season/service/SeasonServiceUnitTest.java @@ -14,7 +14,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import gg.data.season.Season; +import gg.data.pingpong.season.Season; import gg.repo.season.SeasonRepository; import gg.utils.annotation.UnitTest; import gg.utils.exception.season.SeasonNotFoundException; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tier/service/TierServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tier/service/TierServiceUnitTest.java index 46fa47aba..0d034c5f5 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tier/service/TierServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tier/service/TierServiceUnitTest.java @@ -22,9 +22,9 @@ import org.mockito.quality.Strictness; import org.springframework.data.domain.Sort; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.season.Season; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.season.Season; import gg.data.user.User; import gg.pingpong.api.user.rank.service.TierService; import gg.repo.rank.RankRepository; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentControllerMvcTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentControllerMvcTest.java index 33ffb76d7..511c34b33 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentControllerMvcTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentControllerMvcTest.java @@ -20,6 +20,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.web.servlet.MockMvc; +import gg.auth.UserDto; +import gg.auth.config.AuthWebConfig; import gg.pingpong.api.global.config.WebConfig; import gg.pingpong.api.global.security.config.SecurityConfig; import gg.pingpong.api.global.security.jwt.utils.TokenAuthenticationFilter; @@ -30,13 +32,13 @@ import gg.pingpong.api.user.tournament.controller.response.TournamentResponseDto; import gg.pingpong.api.user.tournament.controller.response.TournamentUserRegistrationResponseDto; import gg.pingpong.api.user.tournament.service.TournamentService; -import gg.pingpong.api.user.user.dto.UserDto; import gg.utils.annotation.UnitTest; @UnitTest @WebMvcTest(controllers = TournamentController.class, excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SecurityConfig.class), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = WebConfig.class), + @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = AuthWebConfig.class), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = TokenAuthenticationFilter.class), @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = LoggingInterceptor.class)}) class TournamentControllerMvcTest { diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentFindControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentFindControllerTest.java index aaade00a1..088da5551 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentFindControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentFindControllerTest.java @@ -20,15 +20,15 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; import gg.data.user.type.SnsType; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.tournament.controller.response.TournamentListResponseDto; import gg.pingpong.api.user.tournament.controller.response.TournamentResponseDto; import gg.repo.tournarment.TournamentUserRepository; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentGameControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentGameControllerTest.java index b98c27d0e..9e749bb8f 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentGameControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentGameControllerTest.java @@ -18,17 +18,17 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.game.type.Mode; -import gg.data.season.Season; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; import gg.data.user.type.SnsType; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.tournament.controller.response.TournamentGameListResponseDto; import gg.pingpong.api.user.tournament.controller.response.TournamentGameResDto; import gg.utils.TestDataUtils; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentSchedulerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentSchedulerTest.java index 7b8d45ccc..c47785f03 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentSchedulerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/controller/TournamentSchedulerTest.java @@ -15,10 +15,10 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; -import gg.data.manage.SlotManagement; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.type.TournamentStatus; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.type.TournamentStatus; import gg.pingpong.api.admin.noti.controller.request.SendNotiAdminRequestDto; import gg.pingpong.api.admin.noti.service.NotiAdminService; import gg.pingpong.api.user.tournament.service.TournamentService; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/service/TournamentServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/service/TournamentServiceUnitTest.java index f639df29f..9eda15bf6 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/service/TournamentServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/tournament/service/TournamentServiceUnitTest.java @@ -24,15 +24,16 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import gg.data.game.Game; -import gg.data.game.type.StatusType; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; -import gg.data.tournament.type.TournamentUserStatus; +import gg.auth.UserDto; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; +import gg.data.pingpong.tournament.type.TournamentUserStatus; import gg.data.user.User; import gg.data.user.type.RacketType; import gg.data.user.type.RoleType; @@ -43,7 +44,6 @@ import gg.pingpong.api.user.tournament.controller.response.TournamentGameListResponseDto; import gg.pingpong.api.user.tournament.controller.response.TournamentResponseDto; import gg.pingpong.api.user.tournament.controller.response.TournamentUserRegistrationResponseDto; -import gg.pingpong.api.user.user.dto.UserDto; import gg.pingpong.api.utils.ReflectionUtilsForUnitTest; import gg.repo.game.GameRepository; import gg.repo.game.out.GameTeamUser; @@ -76,6 +76,36 @@ class TournamentServiceUnitTest { @InjectMocks TournamentService tournamentService; + private Tournament createTournament(Long id, TournamentStatus status, LocalDateTime startTime, + LocalDateTime endTime) { + Tournament tournament = Tournament.builder() + .title(id + "st tournament") + .contents("") + .startTime(startTime) + .endTime(endTime) + .type(TournamentType.ROOKIE) + .status(status) + .build(); + ReflectionUtilsForUnitTest.setFieldWithReflection(tournament, "id", id); + return tournament; + } + + /** + * ์œ ์ € ์ƒ์„ฑ ๋งค์„œ๋“œ - intraId๋กœ๋งŒ ์ดˆ๊ธฐํ™” + * @param intraId + * @return + */ + private User createUser(String intraId) { + return User.builder() + .eMail("email") + .intraId(intraId) + .racketType(RacketType.PENHOLDER) + .snsNotiOpt(SnsType.NONE) + .roleType(RoleType.USER) + .totalExp(1000) + .build(); + } + @Nested @DisplayName("getAllTournamentList") class GetAllTournamentList { @@ -585,34 +615,4 @@ void tournamentGameAndGameExist() { verify(gameRepository, times(7)).findTeamsByGameId(any(Long.class)); } } - - private Tournament createTournament(Long id, TournamentStatus status, LocalDateTime startTime, - LocalDateTime endTime) { - Tournament tournament = Tournament.builder() - .title(id + "st tournament") - .contents("") - .startTime(startTime) - .endTime(endTime) - .type(TournamentType.ROOKIE) - .status(status) - .build(); - ReflectionUtilsForUnitTest.setFieldWithReflection(tournament, "id", id); - return tournament; - } - - /** - * ์œ ์ € ์ƒ์„ฑ ๋งค์„œ๋“œ - intraId๋กœ๋งŒ ์ดˆ๊ธฐํ™” - * @param intraId - * @return - */ - private User createUser(String intraId) { - return User.builder() - .eMail("email") - .intraId(intraId) - .racketType(RacketType.PENHOLDER) - .snsNotiOpt(SnsType.NONE) - .roleType(RoleType.USER) - .totalExp(1000) - .build(); - } } diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/controller/UserControllerTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/controller/UserControllerTest.java index 7553d1f94..38d9abf55 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/controller/UserControllerTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/controller/UserControllerTest.java @@ -27,17 +27,18 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; -import gg.data.store.Item; -import gg.data.store.Receipt; -import gg.data.store.type.ItemStatus; -import gg.data.store.type.ItemType; +import gg.auth.utils.AuthTokenProvider; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.type.ItemStatus; +import gg.data.pingpong.store.type.ItemType; import gg.data.user.User; import gg.data.user.type.BackgroundType; import gg.data.user.type.EdgeType; @@ -45,7 +46,6 @@ import gg.data.user.type.RoleType; import gg.data.user.type.SnsType; import gg.pingpong.api.admin.store.controller.request.ItemUpdateRequestDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.global.utils.UserImageHandler; import gg.pingpong.api.user.game.controller.request.RankResultReqDto; import gg.pingpong.api.user.game.service.GameService; @@ -87,46 +87,30 @@ class UserControllerTest { @Autowired TestDataUtils testDataUtils; - - @Autowired - private MockMvc mockMvc; - @Autowired ObjectMapper objectMapper; - @Autowired AuthTokenProvider tokenProvider; - @Autowired UserRepository userRepository; - @Autowired RankRedisRepository redisRepository; - @Autowired TierRepository tierRepository; - @Autowired RankRepository rankRepository; - @Autowired SeasonRepository seasonRepository; - @Autowired GameRepository gameRepository; - @Autowired GameService gameService; - @Autowired CoinPolicyRepository coinPolicyRepository; - @Autowired CoinHistoryRepository coinHistoryRepository; - @Autowired ReceiptRepository receiptRepository; - @Autowired CoinHistoryService coinHistoryService; @Autowired @@ -134,6 +118,8 @@ class UserControllerTest { @MockBean UserImageHandler userImageHandler; User admin; + @Autowired + private MockMvc mockMvc; @BeforeEach public void setUp() { diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/service/UserAuthenticationServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/service/UserAuthenticationServiceUnitTest.java index 7a24f2f2c..713c49a25 100644 --- a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/service/UserAuthenticationServiceUnitTest.java +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/service/UserAuthenticationServiceUnitTest.java @@ -11,8 +11,8 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import gg.auth.utils.AuthTokenProvider; import gg.pingpong.api.global.security.jwt.repository.JwtRedisRepository; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.utils.annotation.UnitTest; import gg.utils.exception.user.TokenNotValidException; diff --git a/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/service/UserTextColorCheckServiceUnitTest.java b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/service/UserTextColorCheckServiceUnitTest.java new file mode 100644 index 000000000..2366262bb --- /dev/null +++ b/gg-pingpong-api/src/test/java/gg/pingpong/api/user/user/service/UserTextColorCheckServiceUnitTest.java @@ -0,0 +1,81 @@ +package gg.pingpong.api.user.user.service; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import gg.utils.annotation.UnitTest; + +@UnitTest +class UserTextColorCheckServiceUnitTest { + + UserTextColorCheckService userTextColorCheckService = new UserTextColorCheckService(); + + @Nested + @DisplayName("check") + class Check { + @Test + @DisplayName("textColor๊ฐ€ null์ผ ๊ฒฝ์šฐ false ๋ฐ˜ํ™˜") + void nullCheck() { + //Arrange + String textColor = null; + + //Act + boolean check = userTextColorCheckService.check(textColor); + + //Assert + Assertions.assertThat(check).isFalse(); + } + + @ParameterizedTest + @DisplayName("7๊ธ€์ž๊ฐ€ ์•„๋‹๊ฒฝ์šฐ false ๋ฐ˜ํ™˜") + @ValueSource(strings = {"", "#", "#1", "#12", "#123", "#12345", "#1234567"}) + void lengthCheck(String textColor) { + //Arrange + //Act + boolean check = userTextColorCheckService.check(textColor); + + //Assert + Assertions.assertThat(check).isFalse(); + } + } + + @ParameterizedTest + @DisplayName("์ฒซ ๊ธ€์ž # ์•„๋‹๊ฒฝ์šฐ false ๋ฐ˜ํ™˜") + @ValueSource(strings = {"#,", "a#12345", "ใ„ฑ#12345", "1#12345", "Z#12345", " #12345"}) + void startCheck(String textColor) { + //Arrange + //Act + boolean check = userTextColorCheckService.check(textColor); + + //Assert + Assertions.assertThat(check).isFalse(); + } + + @ParameterizedTest + @DisplayName("์ •๊ทœ์‹ ์‹คํŒจํ• ๊ฒฝ์šฐ false ๋ฐ˜ํ™˜") + @ValueSource(strings = {"#12345G", "#gabcde", "#zABCDE", "#Ab3DEx"}) + void regexFail(String textColor) { + //Arrange + //Act + boolean check = userTextColorCheckService.check(textColor); + + //Assert + Assertions.assertThat(check).isFalse(); + } + + @ParameterizedTest + @DisplayName("๋ชจ๋“  ์กฐ๊ฑด์„ ํ†ต๊ณผํ• ๊ฒฝ์šฐ true ๋ฐ˜ํ™˜") + @ValueSource(strings = {"#023589", "#abcdef", "#ABCDEF", "#Ab3DeE"}) + void checkSuccess(String textColor) { + //Arrange + //Act + boolean check = userTextColorCheckService.check(textColor); + + //Assert + Assertions.assertThat(check).isTrue(); + } +} diff --git a/gg-recruit-api/build.gradle b/gg-recruit-api/build.gradle new file mode 100644 index 000000000..4f8e11d62 --- /dev/null +++ b/gg-recruit-api/build.gradle @@ -0,0 +1,29 @@ +plugins { + id 'java' +} + +group 'gg.api' +version '42gg' + +repositories { + mavenCentral() +} + +dependencies { + /* spring */ + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-mail' + annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' + + /* StringUtils */ + implementation 'org.apache.commons:commons-lang3:3.12.0' + + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' + testImplementation testFixtures(project(':gg-utils')) +} + +test { + useJUnitPlatform() +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/RecruitmentAdminController.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/RecruitmentAdminController.java new file mode 100644 index 000000000..e0f1d192a --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/RecruitmentAdminController.java @@ -0,0 +1,182 @@ +package gg.recruit.api.admin.controller; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import javax.validation.Valid; +import javax.validation.constraints.Positive; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import gg.data.recruit.application.Application; +import gg.data.recruit.recruitment.Recruitment; +import gg.recruit.api.admin.controller.request.InterviewRequestDto; +import gg.recruit.api.admin.controller.request.RecruitmentRequestDto; +import gg.recruit.api.admin.controller.request.SetFinalApplicationStatusResultReqDto; +import gg.recruit.api.admin.controller.request.UpdateStatusRequestDto; +import gg.recruit.api.admin.controller.response.CreatedRecruitmentResponse; +import gg.recruit.api.admin.controller.response.GetRecruitmentApplicationResponseDto; +import gg.recruit.api.admin.controller.response.RecruitmentAdminDetailResDto; +import gg.recruit.api.admin.controller.response.RecruitmentApplicantResultResponseDto; +import gg.recruit.api.admin.controller.response.RecruitmentApplicantResultsResponseDto; +import gg.recruit.api.admin.controller.response.RecruitmentsResponse; +import gg.recruit.api.admin.service.RecruitmentAdminService; +import gg.recruit.api.admin.service.param.GetRecruitmentApplicationsParam; +import gg.recruit.api.admin.service.param.UpdateApplicationStatusParam; +import gg.recruit.api.admin.service.param.UpdateRecruitStatusParam; +import gg.recruit.api.admin.service.result.AllRecruitmentsResult; +import gg.utils.dto.PageRequestDto; +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.BusinessException; +import lombok.RequiredArgsConstructor; + +@RestController +@Validated +@RequiredArgsConstructor +@RequestMapping("/admin/recruitments") +public class RecruitmentAdminController { + private final RecruitmentAdminService recruitmentAdminService; + + @PostMapping + public ResponseEntity createRecruitment( + @RequestBody @Valid RecruitmentRequestDto recruitmentDto) { + Recruitment recruitment = RecruitmentRequestDto.RecruitmentMapper.INSTANCE.dtoToEntity(recruitmentDto); + Long recruitmentId = recruitmentAdminService.createRecruitment(recruitment, recruitmentDto.getForms()).getId(); + CreatedRecruitmentResponse createdRecruitmentResponse = new CreatedRecruitmentResponse(recruitmentId); + + return ResponseEntity.status(HttpStatus.CREATED).body(createdRecruitmentResponse); + } + + @GetMapping("/{recruitId}") + public RecruitmentAdminDetailResDto findRecruitmentDetail(@PathVariable Long recruitId) { + RecruitmentAdminDetailResDto res = new RecruitmentAdminDetailResDto( + recruitmentAdminService.findRecruitmentDetail(recruitId)); + return res; + } + + @PatchMapping("/{recruitId}/status") + public ResponseEntity updateRecruitStatus(@PathVariable @Positive Long recruitId, + @RequestBody UpdateStatusRequestDto requestDto) { + + recruitmentAdminService.updateRecruitStatus( + new UpdateRecruitStatusParam(recruitId, requestDto.getFinish())); + return ResponseEntity.noContent().build(); + } + + @GetMapping + public ResponseEntity getRecruitments(@Valid PageRequestDto pageRequestDto) { + Pageable pageable = PageRequest.of(pageRequestDto.getPage() - 1, pageRequestDto.getSize()); + AllRecruitmentsResult allRecruitments = recruitmentAdminService.getAllRecruitments(pageable); + return ResponseEntity.ok( + new RecruitmentsResponse(allRecruitments.getAllRecruitments(), allRecruitments.getTotalPage())); + } + + /** + * ์ง€์›์„œ์˜ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ๋“ฑ๋ก + * @return ResponseEntity + */ + @PostMapping("/{recruitId}/result") + public ResponseEntity setFinalApplicationStatusResult( + @PathVariable @Positive Long recruitId, + @RequestParam("application") @Positive Long applicationId, + @RequestBody @Valid SetFinalApplicationStatusResultReqDto reqDto) { + UpdateApplicationStatusParam dto = new UpdateApplicationStatusParam(reqDto.getStatus(), applicationId, + recruitId); + recruitmentAdminService.updateFinalApplicationStatusAndNotification(dto); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @GetMapping("/{recruitId}/applications") + public ResponseEntity getRecruitmentApplications( + @PathVariable @Positive Long recruitId, + @RequestParam(value = "question", required = false) Long questionId, + @RequestParam(value = "checks", required = false) String checks, + @RequestParam(value = "search", required = false) String search, + @PageableDefault(sort = "id", page = 1) Pageable page + ) { + GetRecruitmentApplicationsParam dto; + + Pageable parsedPage = PageRequest.of(page.getPageNumber() - 1, Math.min(page.getPageSize(), 20)); + List checkListIds = parseChecks(checks); + dto = new GetRecruitmentApplicationsParam(recruitId, questionId, checkListIds, search, parsedPage); + Page applicationsPage = recruitmentAdminService.findApplicationsWithAnswersAndUserWithFilter(dto); + return ResponseEntity.ok(GetRecruitmentApplicationResponseDto.applicationsPageToDto(applicationsPage)); + } + + /** + * ์ „๋‹ฌ๋œ checkListId ๋ชฉ๋ก ํŒŒ์‹ฑ + * @param checks + * @return List + */ + private List parseChecks(String checks) { + try { + if (checks != null) { + return Arrays.stream(checks.split(",")).map(Long::parseLong).collect(Collectors.toList()); + } else { + return new ArrayList<>(); + } + } catch (Exception e) { + throw new BusinessException(ErrorCode.BAD_ARGU); + } + } + + @DeleteMapping("/{recruitId}") + public ResponseEntity deleteRecruitment(@PathVariable @Positive Long recruitId) { + recruitmentAdminService.deleteRecruitment(recruitId); + return ResponseEntity.noContent().build(); + } + + @PutMapping("/{recruitId}") + public ResponseEntity updateRecruitment(@PathVariable @Positive Long recruitId, + @RequestBody @Valid RecruitmentRequestDto recruitmentDto) { + Recruitment recruitment = RecruitmentRequestDto.RecruitmentMapper.INSTANCE.dtoToEntity(recruitmentDto); + recruitment = recruitmentAdminService.updateRecruitment(recruitId, recruitment, recruitmentDto.getForms()); + recruitmentAdminService.createRecruitment(recruitment, recruitmentDto.getForms()); + return ResponseEntity.noContent().build(); + } + + @PostMapping("/{recruitId}/interview") + public ResponseEntity setInterviewDate(@PathVariable @Positive Long recruitId, + @RequestParam("application") @Positive Long applicationId, + @RequestBody @Valid InterviewRequestDto reqDto) { + + recruitmentAdminService.updateDocumentScreening( + new UpdateApplicationStatusParam(reqDto.getStatus(), applicationId, recruitId, reqDto.getInterviewDate())); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + /** + * ๋ชจ์ง‘๊ธ€ ์ง€์›์„œ๋“ค์˜ ๊ฒฐ๊ณผ ์ •๋ณด ๋ชฉ๋ก ์กฐํšŒ + * @param recruitId + * @return + */ + @GetMapping("/{recruitId}/applicants") + public ResponseEntity getRecruitmentApplicantResults( + @PathVariable @Positive Long recruitId) { + List resultApplications = recruitmentAdminService.getRecruitmentApplicants(recruitId); + + List resultDto = resultApplications.stream() + .map(RecruitmentApplicantResultResponseDto.MapStruct.INSTANCE::entityToDto) + .collect(Collectors.toList()); + + return ResponseEntity.ok(new RecruitmentApplicantResultsResponseDto(resultDto)); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/RecruitmentResultMessageAdminController.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/RecruitmentResultMessageAdminController.java new file mode 100644 index 000000000..0bacc1b15 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/RecruitmentResultMessageAdminController.java @@ -0,0 +1,65 @@ +package gg.recruit.api.admin.controller; + +import java.util.List; +import java.util.stream.Collectors; + +import javax.validation.Valid; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.data.recruit.manage.ResultMessage; +import gg.recruit.api.admin.controller.request.GetRecruitmentResultMessagePreviewReqDto; +import gg.recruit.api.admin.controller.response.GetRecruitmentResultMessagePreviewResDto; +import gg.recruit.api.admin.controller.response.GetRecruitmentResultMessageResponseDto; +import gg.recruit.api.admin.controller.response.GetRecruitmentResultMessagesResponseDto; +import gg.recruit.api.admin.service.RecruitmentResultMessageAdminService; +import gg.recruit.api.admin.service.param.RecruitmentResultMessageParam; +import lombok.RequiredArgsConstructor; + +@Validated +@RestController +@RequiredArgsConstructor +@RequestMapping("/admin/recruitments/result/message") +public class RecruitmentResultMessageAdminController { + + private final RecruitmentResultMessageAdminService resultMessageAdminService; + + /** + * ์ง€์›์ž์—๊ฒŒ ๋ณด์—ฌ์งˆ ๊ฒฐ๊ณผ ๋ฉ”์‹œ์ง€ ๋“ฑ๋ก + * @param reqDto + * @return ResponseEntity + */ + @PostMapping + public ResponseEntity postResultMessage(@Valid @RequestBody RecruitmentResultMessageParam reqDto) { + resultMessageAdminService.postResultMessage(reqDto); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + /** + * ์ง€์›์ž์—๊ฒŒ ๋ณด์—ฌ์งˆ ๊ฒฐ๊ณผ ๋ฉ”์‹œ์ง€ ์ „์ฒด ๋ชฉ๋ก ์กฐํšŒ + * @return ResponseEntity + */ + @GetMapping + public ResponseEntity getResultMessages() { + List resultMessages = resultMessageAdminService.getResultMessages(); + + List resultDto = resultMessages.stream() + .map(GetRecruitmentResultMessageResponseDto.MapStruct.INSTANCE::entityToDto) + .collect(Collectors.toList()); + + return ResponseEntity.ok(new GetRecruitmentResultMessagesResponseDto(resultDto)); + } + + @GetMapping("/preview") + public GetRecruitmentResultMessagePreviewResDto getPreview(GetRecruitmentResultMessagePreviewReqDto reqDto) { + return new GetRecruitmentResultMessagePreviewResDto( + resultMessageAdminService.getResultMessagePreview(reqDto.getMessageType())); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/GetRecruitmentResultMessagePreviewReqDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/GetRecruitmentResultMessagePreviewReqDto.java new file mode 100644 index 000000000..8294143fe --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/GetRecruitmentResultMessagePreviewReqDto.java @@ -0,0 +1,14 @@ +package gg.recruit.api.admin.controller.request; + +import javax.validation.constraints.NotNull; + +import gg.data.recruit.manage.enums.MessageType; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class GetRecruitmentResultMessagePreviewReqDto { + @NotNull(message = "๋ฉ”์‹œ์ง€ ํƒ€์ž…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private MessageType messageType; +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/InterviewRequestDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/InterviewRequestDto.java new file mode 100644 index 000000000..ab0845af1 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/InterviewRequestDto.java @@ -0,0 +1,43 @@ +package gg.recruit.api.admin.controller.request; + +import java.time.LocalDateTime; + +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.FutureOrPresent; +import javax.validation.constraints.NotNull; + +import gg.data.recruit.application.enums.ApplicationStatus; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +@Getter +public class InterviewRequestDto { + public static final String MUST_DOCS_RESULT_STATUS = "PROGRESS_INTERVIEW or FAIL ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•ด์ฃผ์„ธ์š”."; + + @NotNull(message = MUST_DOCS_RESULT_STATUS) + private ApplicationStatus status; + + @NotNull + @FutureOrPresent(message = "๋ฉด์ ‘ ์ผ์ž๋Š” ํ˜„์žฌ ์ดํ›„์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + private LocalDateTime interviewDate; + + @AssertTrue(message = MUST_DOCS_RESULT_STATUS) + private boolean isValidDocsResultStatus() { + if (status == null) { + return false; + } + if (status != ApplicationStatus.PROGRESS_INTERVIEW && status != ApplicationStatus.INTERVIEW_FAIL) { + return false; + } + if (status == ApplicationStatus.PROGRESS_INTERVIEW) { + return interviewDate != null; + } + return true; + } + + public InterviewRequestDto(ApplicationStatus status, LocalDateTime interviewDate) { + this.status = status; + this.interviewDate = interviewDate; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/RecruitmentRequestDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/RecruitmentRequestDto.java new file mode 100644 index 000000000..f6728bd3c --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/RecruitmentRequestDto.java @@ -0,0 +1,69 @@ +package gg.recruit.api.admin.controller.request; + +import java.time.LocalDateTime; +import java.util.List; + +import javax.validation.Valid; +import javax.validation.constraints.FutureOrPresent; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +import gg.data.recruit.recruitment.Recruitment; +import gg.recruit.api.admin.service.param.FormParam; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class RecruitmentRequestDto { + @NotNull(message = "์‹œ์ž‘์ผ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + @FutureOrPresent(message = "์‹œ์ž‘์ผ์€ ํ˜„์žฌ ์‹œ๊ฐ„ ์ดํ›„์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + LocalDateTime startDate; + + @NotNull(message = "์ข…๋ฃŒ์ผ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + @FutureOrPresent(message = "์ข…๋ฃŒ์ผ์€ ํ˜„์žฌ ์‹œ๊ฐ„ ์ดํ›„์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.") + LocalDateTime endDate; + + @NotBlank(message = "์ œ๋ชฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + @Size(max = 255, message = "์ œ๋ชฉ์€ 255์ž ์ด๋‚ด๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + String title; + + @NotBlank(message = "๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + @Size(max = 3000, message = "๋‚ด์šฉ์€ 3000์ž ์ด๋‚ด๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + String contents; + + @NotBlank(message = "๋ชจ์ง‘ ๊ธฐ์ˆ˜๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + @Size(max = 50, message = "๋ชจ์ง‘ ์„ธ๋Œ€๋Š” 50์ž ์ด๋‚ด๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + String generation; + + @NotNull(message = "ํผ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + @Valid + List forms; + + @Builder + public RecruitmentRequestDto(LocalDateTime startDate, LocalDateTime endDate, String title, + String contents, + String generation, List form) { + this.startDate = startDate; + this.endDate = endDate; + this.title = title; + this.contents = contents; + this.generation = generation; + this.forms = form; + } + + @Mapper + public interface RecruitmentMapper { + RecruitmentMapper INSTANCE = Mappers.getMapper(RecruitmentMapper.class); + + @Mapping(source = "startDate", target = "startTime") + @Mapping(source = "endDate", target = "endTime") + Recruitment dtoToEntity(RecruitmentRequestDto dto); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/SetFinalApplicationStatusResultReqDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/SetFinalApplicationStatusResultReqDto.java new file mode 100644 index 000000000..69fbe1c5e --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/SetFinalApplicationStatusResultReqDto.java @@ -0,0 +1,25 @@ +package gg.recruit.api.admin.controller.request; + +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.NotNull; + +import gg.data.recruit.application.enums.ApplicationStatus; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@Getter +public class SetFinalApplicationStatusResultReqDto { + public static final String MUST_FINAL_STATUS = "์ตœ์ข… ๊ฒฐ๊ณผ๋Š” PASS ํ˜น์€ FAIL ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค!"; + + @NotNull + ApplicationStatus status; + + @AssertTrue(message = MUST_FINAL_STATUS) + private boolean isValidFinalStatus() { + return status != null && status.isFinal; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/UpdateStatusRequestDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/UpdateStatusRequestDto.java new file mode 100644 index 000000000..e772b644e --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/request/UpdateStatusRequestDto.java @@ -0,0 +1,12 @@ +package gg.recruit.api.admin.controller.request; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class UpdateStatusRequestDto { + private Boolean finish; +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/CheckItemAdminResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/CheckItemAdminResDto.java new file mode 100644 index 000000000..2b4a0d9b6 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/CheckItemAdminResDto.java @@ -0,0 +1,17 @@ +package gg.recruit.api.admin.controller.response; + +import gg.recruit.api.admin.service.result.CheckItemAdminSvcDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class CheckItemAdminResDto { + private Long id; + private String contents; + + public CheckItemAdminResDto(CheckItemAdminSvcDto dto) { + this.id = dto.getId(); + this.contents = dto.getContents(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/CreatedRecruitmentResponse.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/CreatedRecruitmentResponse.java new file mode 100644 index 000000000..f35abb785 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/CreatedRecruitmentResponse.java @@ -0,0 +1,14 @@ +package gg.recruit.api.admin.controller.response; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class CreatedRecruitmentResponse { + private Long id; + + public CreatedRecruitmentResponse(Long id) { + this.id = id; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/FormDetailAdminResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/FormDetailAdminResDto.java new file mode 100644 index 000000000..d05ed9fa7 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/FormDetailAdminResDto.java @@ -0,0 +1,26 @@ +package gg.recruit.api.admin.controller.response; + +import java.util.List; +import java.util.stream.Collectors; + +import gg.data.recruit.recruitment.enums.InputType; +import gg.recruit.api.admin.service.result.FormDetailAdminSvcDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class FormDetailAdminResDto { + private Long questionId; + private String question; + private InputType inputType; + private List checkList; + + public FormDetailAdminResDto(FormDetailAdminSvcDto dto) { + this.questionId = dto.getQuestionId(); + this.question = dto.getQuestion(); + this.inputType = dto.getInputType(); + this.checkList = dto.getCheckList().stream() + .map(CheckItemAdminResDto::new).collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentApplicationDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentApplicationDto.java new file mode 100644 index 000000000..d2e88851c --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentApplicationDto.java @@ -0,0 +1,121 @@ +package gg.recruit.api.admin.controller.response; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.mapstruct.AfterMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.ApplicationAnswer; +import gg.data.recruit.application.ApplicationAnswerCheckList; +import gg.data.recruit.application.ApplicationAnswerText; +import gg.data.recruit.application.enums.ApplicationStatus; +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.enums.InputType; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class GetRecruitmentApplicationDto { + private Long applicationId; + private String intraId; + private ApplicationStatus status; + private List
forms = new ArrayList<>(); + + public GetRecruitmentApplicationDto(Long applicationId, String intraId, ApplicationStatus status) { + this.applicationId = applicationId; + this.intraId = intraId; + this.status = status; + } + + @NoArgsConstructor(access = AccessLevel.PROTECTED) + @Getter + public static class Form { + private Long questionId; + private String question; + private InputType inputType; + private String answer; + private List checkedList = new ArrayList<>(); + + public Form(Long questionId, String question, InputType inputType) { + this.questionId = questionId; + this.question = question; + this.inputType = inputType; + } + + @Mapper + public interface MapStruct { + MapStruct INSTANCE = Mappers.getMapper(MapStruct.class); + + @Mapping(source = "id", target = "questionId") + Form entityToDto(Question question); + } + + @NoArgsConstructor(access = AccessLevel.PROTECTED) + @Getter + public static class CheckListForm { + private Long checkId; + private String contents; + + public CheckListForm(Long checkId, String content) { + this.checkId = checkId; + this.contents = content; + } + + @Mapper + public interface MapStruct { + MapStruct INSTANCE = Mappers.getMapper(MapStruct.class); + + @Mapping(source = "id", target = "checkId") + CheckListForm entityToDto(CheckList checkList); + } + } + } + + @Mapper + public interface MapStruct { + MapStruct INSTANCE = Mappers.getMapper(MapStruct.class); + + @Mapping(source = "id", target = "applicationId") + @Mapping(source = "user.intraId", target = "intraId") + GetRecruitmentApplicationDto entityToDto(Application application); + + @AfterMapping + default void fillForms(Application application, @MappingTarget GetRecruitmentApplicationDto dto) { + Set questionIdSet = new HashSet<>(); + HashSet formSet = new LinkedHashSet<>(); + HashMap formMap = new HashMap<>(); + for (ApplicationAnswer answer : application.getApplicationAnswers()) { + Long questionId = answer.getQuestionId(); + if (!questionIdSet.contains(questionId)) { + questionIdSet.add(questionId); + Form form = Form.MapStruct.INSTANCE.entityToDto(answer.getQuestion()); + formSet.add(form); + formMap.put(questionId, form); + } + Form form = formMap.get(questionId); + if (answer instanceof ApplicationAnswerCheckList) { + ApplicationAnswerCheckList applicationAnswerCheckList = (ApplicationAnswerCheckList)answer; + CheckList checkList = applicationAnswerCheckList.getCheckList(); + form.checkedList.add(Form.CheckListForm.MapStruct.INSTANCE.entityToDto(checkList)); + } else if (answer instanceof ApplicationAnswerText) { + ApplicationAnswerText applicationAnswerText = (ApplicationAnswerText)answer; + form.answer = applicationAnswerText.getAnswer(); + } + } + dto.forms = formSet.stream().collect(Collectors.toList()); + } + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentApplicationResponseDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentApplicationResponseDto.java new file mode 100644 index 000000000..ed1d7ca20 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentApplicationResponseDto.java @@ -0,0 +1,36 @@ +package gg.recruit.api.admin.controller.response; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.data.domain.Page; + +import gg.data.recruit.application.Application; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class GetRecruitmentApplicationResponseDto { + private int page; + private boolean isLast; + private List applicationResults; + + public GetRecruitmentApplicationResponseDto(int page, boolean isLast, + List applicationResults) { + this.page = page; + this.isLast = isLast; + this.applicationResults = applicationResults; + } + + public static GetRecruitmentApplicationResponseDto applicationsPageToDto(Page applicationsPage) { + int page = applicationsPage.getPageable().getPageNumber() + 1; + boolean isLast = applicationsPage.isLast(); + List dto = applicationsPage.getContent() + .stream() + .map(GetRecruitmentApplicationDto.MapStruct.INSTANCE::entityToDto) + .collect(Collectors.toList()); + return new GetRecruitmentApplicationResponseDto(page, isLast, dto); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentResultMessagePreviewResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentResultMessagePreviewResDto.java new file mode 100644 index 000000000..1ffc57da6 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentResultMessagePreviewResDto.java @@ -0,0 +1,12 @@ +package gg.recruit.api.admin.controller.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class GetRecruitmentResultMessagePreviewResDto { + private String content; +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentResultMessageResponseDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentResultMessageResponseDto.java new file mode 100644 index 000000000..3b90bc9ad --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentResultMessageResponseDto.java @@ -0,0 +1,32 @@ +package gg.recruit.api.admin.controller.response; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +import gg.data.recruit.manage.ResultMessage; +import gg.data.recruit.manage.enums.MessageType; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@Getter +public class GetRecruitmentResultMessageResponseDto { + private long messageId; + private MessageType messageType; + private Boolean isUse; + private String message; + + @Mapper + public interface MapStruct { + MapStruct INSTANCE = Mappers.getMapper(MapStruct.class); + + @Mapping(source = "id", target = "messageId") + @Mapping(source = "content", target = "message") + GetRecruitmentResultMessageResponseDto entityToDto(ResultMessage dto); + } + +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentResultMessagesResponseDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentResultMessagesResponseDto.java new file mode 100644 index 000000000..2ebe2483b --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/GetRecruitmentResultMessagesResponseDto.java @@ -0,0 +1,15 @@ +package gg.recruit.api.admin.controller.response; + +import java.util.List; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@Getter +public class GetRecruitmentResultMessagesResponseDto { + private List messages; +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentAdminDetailResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentAdminDetailResDto.java new file mode 100644 index 000000000..a7809205a --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentAdminDetailResDto.java @@ -0,0 +1,30 @@ +package gg.recruit.api.admin.controller.response; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +import gg.recruit.api.admin.service.result.RecruitmentDetailAdminSvcDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class RecruitmentAdminDetailResDto { + private LocalDateTime startDate; + private LocalDateTime endDate; + private String title; + private String contents; + private String generation; + private List forms; + + public RecruitmentAdminDetailResDto(RecruitmentDetailAdminSvcDto recruitmentDetail) { + this.startDate = recruitmentDetail.getStartDate(); + this.endDate = recruitmentDetail.getEndDate(); + this.title = recruitmentDetail.getTitle(); + this.contents = recruitmentDetail.getContents(); + this.generation = recruitmentDetail.getGeneration(); + this.forms = recruitmentDetail.getForms().stream() + .map(FormDetailAdminResDto::new).collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentApplicantResultResponseDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentApplicantResultResponseDto.java new file mode 100644 index 000000000..7fa6c154b --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentApplicantResultResponseDto.java @@ -0,0 +1,49 @@ +package gg.recruit.api.admin.controller.response; + +import java.time.LocalDateTime; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.enums.ApplicationStatus; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class RecruitmentApplicantResultResponseDto { + private Long applicationId; + private String intraId; + private LocalDateTime interviewDate; + private ApplicationStatus result; + + public RecruitmentApplicantResultResponseDto(Long applicationId, String intraId, LocalDateTime interviewDate, + ApplicationStatus result) { + this.applicationId = applicationId; + this.intraId = intraId; + this.interviewDate = interviewDate; + this.result = result; + } + + @Mapper + public interface MapStruct { + MapStruct INSTANCE = Mappers.getMapper(MapStruct.class); + + @Mapping(source = "id", target = "applicationId") + @Mapping(source = "user.intraId", target = "intraId") + @Mapping(target = "interviewDate", expression = "java(mapInterviewDate(dto))") + @Mapping(source = "status", target = "result") + RecruitmentApplicantResultResponseDto entityToDto(Application dto); + + default LocalDateTime mapInterviewDate(Application application) { + if (application.getRecruitStatus() != null) { + return application.getRecruitStatus().getInterviewDate(); + } else { + return null; + } + } + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentApplicantResultsResponseDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentApplicantResultsResponseDto.java new file mode 100644 index 000000000..45922028e --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentApplicantResultsResponseDto.java @@ -0,0 +1,17 @@ +package gg.recruit.api.admin.controller.response; + +import java.util.List; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class RecruitmentApplicantResultsResponseDto { + private List applicationResults; + + public RecruitmentApplicantResultsResponseDto(List applicationResults) { + this.applicationResults = applicationResults; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentDto.java new file mode 100644 index 000000000..3a74388f3 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentDto.java @@ -0,0 +1,42 @@ +package gg.recruit.api.admin.controller.response; + +import java.time.LocalDateTime; + +import gg.data.recruit.recruitment.Recruitment; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class RecruitmentDto { + private Long id; + private String title; + private Boolean isFinish; + private String generation; + private LocalDateTime startDate; + private LocalDateTime endDate; + + @Builder + public RecruitmentDto(Long id, String title, Boolean isFinish, String generation, LocalDateTime startDate, + LocalDateTime endDate) { + this.id = id; + this.title = title; + this.isFinish = isFinish; + this.generation = generation; + this.startDate = startDate; + this.endDate = endDate; + } + + public static RecruitmentDto toRecruitmentDto(Recruitment recruitment) { + return RecruitmentDto.builder() + .id(recruitment.getId()) + .title(recruitment.getTitle()) + .isFinish(recruitment.getIsFinsh()) + .generation(recruitment.getGeneration()) + .startDate(recruitment.getStartTime()) + .endDate(recruitment.getEndTime()) + .build(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentsResponse.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentsResponse.java new file mode 100644 index 000000000..4579bf392 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/controller/response/RecruitmentsResponse.java @@ -0,0 +1,23 @@ +package gg.recruit.api.admin.controller.response; + +import java.util.ArrayList; +import java.util.List; + +import gg.data.recruit.recruitment.Recruitment; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class RecruitmentsResponse { + private List recruitments = new ArrayList<>(); + private int totalPage; + + public RecruitmentsResponse(List recruitmentList, int totalPage) { + for (Recruitment recruitment : recruitmentList) { + this.recruitments.add(RecruitmentDto.toRecruitmentDto(recruitment)); + } + this.totalPage = totalPage; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/RecruitmentAdminService.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/RecruitmentAdminService.java new file mode 100644 index 000000000..e8c696ab9 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/RecruitmentAdminService.java @@ -0,0 +1,245 @@ +package gg.recruit.api.admin.service; + +import java.time.LocalDateTime; +import java.util.List; + +import javax.persistence.EntityManager; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.admin.repo.recruit.ApplicationAdminRepository; +import gg.admin.repo.recruit.RecruitmentAdminRepository; +import gg.admin.repo.recruit.recruitment.RecruitStatusAdminRepository; +import gg.data.recruit.application.Application; +import gg.data.recruit.application.RecruitStatus; +import gg.data.recruit.application.enums.ApplicationStatus; +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.recruit.recruitment.enums.InputType; +import gg.recruit.api.admin.service.param.CheckListContent; +import gg.recruit.api.admin.service.param.FormParam; +import gg.recruit.api.admin.service.param.GetRecruitmentApplicationsParam; +import gg.recruit.api.admin.service.param.UpdateApplicationStatusParam; +import gg.recruit.api.admin.service.param.UpdateRecruitStatusParam; +import gg.recruit.api.admin.service.result.AllRecruitmentsResult; +import gg.recruit.api.admin.service.result.RecruitmentDetailAdminSvcDto; +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.BusinessException; +import gg.utils.exception.custom.DuplicationException; +import gg.utils.exception.custom.ForbiddenException; +import gg.utils.exception.custom.NotExistException; +import gg.utils.exception.recruitment.InvalidCheckListException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class RecruitmentAdminService { + private final RecruitmentAdminRepository recruitmentAdminRepository; + private final ApplicationAdminRepository applicationAdminRepository; + private final EntityManager entityManager; + private final RecruitStatusAdminRepository recruitStatusAdminRepository; + + /** + * ์ฑ„์šฉ ๊ณต๊ณ ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. + * Recruitment, Question, CheckList์„ ์ €์žฅํ•œ๋‹ค. + * @param recruitment Recruitment + * @param forms Question, CheckList์ด ํฌํ•จ + * @return Recruitment ์ƒ์„ฑ๋œ ์ฑ„์šฉ ๊ณต๊ณ  + */ + @Transactional + public Recruitment createRecruitment(Recruitment recruitment, List forms) { + for (int i = 0; i < forms.size(); i++) { + FormParam form = forms.get(i); + Question question = form.toQuestion(recruitment, i + 1); + InputType inputType = question.getInputType(); + + if (inputType == InputType.SINGLE_CHECK || inputType == InputType.MULTI_CHECK) { + addCheckList(question, form.getCheckList()); + } + } + return recruitmentAdminRepository.save(recruitment); + } + + @Transactional + public void updateRecruitStatus(UpdateRecruitStatusParam updateRecruitStatusParam) { + Recruitment recruitments = recruitmentAdminRepository.findById(updateRecruitStatusParam.getRecruitId()) + .orElseThrow(() -> new NotExistException("Recruitment not found.")); + recruitments.setFinish(updateRecruitStatusParam.getFinish()); + } + + /** + * ๊ณต๊ณ  ์ข…๋ฃŒ ๋‚ ์งœ ๊ธฐ์ค€์œผ๋กœ ๋‚ด๋ฆผ์ฐจ์ˆœ(์ตœ๊ทผ์ˆœ) ์ •๋ ฌํ•˜์—ฌ ์ฑ„์šฉ ๊ณต๊ณ ๋ฅผ ์กฐํšŒํ•œ๋‹ค. + * @param pageable + * @return ์กฐํšŒ๋œ ์ฑ„์šฉ ๊ณต๊ณ  ๋ฆฌ์ŠคํŠธ + */ + @Transactional(readOnly = true) + public AllRecruitmentsResult getAllRecruitments(Pageable pageable) { + Page allByOrderByEndDateDesc = recruitmentAdminRepository.findAllByIsDeletedOrderByEndTimeDesc( + false, pageable); + return new AllRecruitmentsResult(allByOrderByEndDateDesc.getTotalPages(), allByOrderByEndDateDesc.getContent()); + } + + /** + * ๊ณต๊ณ  ์‚ญ์ œ + * @param recruitId ์‚ญ์ œํ•  ๊ณต๊ณ  id + */ + @Transactional + public void deleteRecruitment(Long recruitId) { + Recruitment recruitment = recruitmentAdminRepository.findById(recruitId) + .orElseThrow(() -> new NotExistException("Recruitment not found.")); + recruitment.del(); + } + + /** + * ์ฑ„์šฉ ๊ณต๊ณ ๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค. + * @param recruitId ์ฑ„์šฉ ๊ณต๊ณ  ID + * @param updatedRecruitment ์ˆ˜์ •ํ•  ์ฑ„์šฉ ๊ณต๊ณ  + * @param forms ์ˆ˜์ •ํ•  ์งˆ๋ฌธ๊ณผ ์„ ํƒ์ง€ + * @throws NotExistException ์ฑ„์šฉ ๊ณต๊ณ ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๋•Œ ๋ฐœ์ƒ + * @throws IllegalArgumentException ์ฑ„์šฉ ๊ณต๊ณ  ์‹œ์ž‘ ์‹œ๊ฐ„์ด ํ˜„์žฌ ์‹œ๊ฐ„๊ณผ ๊ฐ™๊ฑฐ๋‚˜ ์ดํ›„์ผ ๋•Œ ๋ฐœ์ƒ + */ + @Transactional + public Recruitment updateRecruitment(Long recruitId, Recruitment updatedRecruitment, List forms) { + Recruitment target = recruitmentAdminRepository.findById(recruitId) + .orElseThrow(() -> new NotExistException("๊ณต๊ณ ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")); + LocalDateTime now = LocalDateTime.now(); + if (target.getIsFinish() || target.getStartTime().isEqual(now) || target.getStartTime().isBefore(now)) { + throw new ForbiddenException("์ˆ˜์ • ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ณต๊ณ ์ž…๋‹ˆ๋‹ค."); + } + target.update(updatedRecruitment); + return target; + } + + /** + * @param question ์งˆ๋ฌธ + * @param checkLists ์„ ํƒ์ง€ + * @throws InvalidCheckListException ์„ ํƒ์ง€๊ฐ€ ํ•„์š”ํ•œ๋ฐ ๋น„์–ด์žˆ์„ ๋•Œ ๋ฐœ์ƒ + */ + private void addCheckList(Question question, List checkLists) { + if (checkLists == null || checkLists.isEmpty()) { + throw new InvalidCheckListException(); + } + for (CheckListContent checkList : checkLists) { + new CheckList(question, checkList.getContents()); + } + } + + /** + * ์ตœ์ข… ๊ฒฐ๊ณผ ๋“ฑ๋ก ํ›„ ์•Œ๋ฆผ + * @param dto + */ + @Transactional + public void updateFinalApplicationStatusAndNotification(UpdateApplicationStatusParam dto) { + Application application = applicationAdminRepository + .findByIdAndRecruitId(dto.getApplicationId(), dto.getRecruitId()) + .orElseThrow(() -> new NotExistException("Application not found.")); + finalApplicationStatusCheck(dto.getStatus()); + updateApplicationStatus(dto); + // TODO ์‚ฌ์ดํด๋กœ SNS Noti ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•ด ์•Œ๋ฆผ ๊ธฐ๋Šฅ ์ถ”ํ›„ ๊ตฌํ˜„ + } + + /** + * ์ตœ์ข… ๊ฒฐ๊ณผ์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์ธ์ง€ ๊ฒ€์ฆ + * @param status + */ + private void finalApplicationStatusCheck(ApplicationStatus status) { + if (!status.isFinal) { + throw new BusinessException(ErrorCode.BAD_ARGU); + } + } + + /** + * ์ง€์›์„œ ์ƒํƒœ ๋ณ€๊ฒฝ + * @param dto + */ + @Transactional + public void updateApplicationStatus(UpdateApplicationStatusParam dto) { + Application application = applicationAdminRepository + .findByIdAndRecruitId(dto.getApplicationId(), dto.getRecruitId()) + .orElseThrow(() -> new NotExistException("Application not found.")); + application.updateApplicationStatus(dto.getStatus()); + } + + /** + * ์„œ๋ฅ˜ ๊ฒฐ๊ณผ ๋“ฑ๋ก + * ํ•ฉ๊ฒฉ์ผ ๊ฒฝ์šฐ, ๋ฉด์ ‘ ์ผ์ž ๋“ฑ๋ก ๋ฐ ๋ณ€๊ฒฝ ํ›„ ์•Œ๋ฆผ ์ „์†ก + * @param dto UpdateApplicationStatusDto ์„œ๋ฅ˜ ๊ฒฐ๊ณผ ๋“ฑ๋ก ์ •๋ณด + * @throws NotExistException ์ง€์›์„œ ๋˜๋Š” ์ฑ„์šฉ ๊ณต๊ณ ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๋•Œ + * @throws ForbiddenException ์„œ๋ฅ˜์ „ํ˜• ์ง„ํ–‰์ค‘์ธ ์ง€์›์„œ๊ฐ€ ์•„๋‹ ๋•Œ + * + */ + @Transactional + public void updateDocumentScreening(UpdateApplicationStatusParam dto) { + Application application = applicationAdminRepository + .findByIdAndRecruitId(dto.getApplicationId(), dto.getRecruitId()) + .orElseThrow(() -> new NotExistException("Application not found.")); + if (application.getStatus() != ApplicationStatus.PROGRESS_DOCS) { + throw new ForbiddenException("์„œ๋ฅ˜์ „ํ˜• ์ง„ํ–‰์ค‘์ธ ์ง€์›์„œ๋งŒ ๋ฉด์ ‘ ์ผ์ž๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."); + } + if (dto.getStatus() == ApplicationStatus.PROGRESS_INTERVIEW) { + updateInterviewDate(application, dto.getRecruitId(), dto.getInterviewDate()); + } + application.updateApplicationStatus(dto.getStatus()); + // TODO ์‚ฌ์ดํด๋กœ SNS Noti ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•ด ์•Œ๋ฆผ ๊ธฐ๋Šฅ ์ถ”ํ›„ ๊ตฌํ˜„ + } + + /** + * ๋ฉด์ ‘ ์ผ์ž ๋“ฑ๋ก ๋ฐ ๋ณ€๊ฒฝ + * @param application ์ง€์›์„œ + * @param recruitId ์ฑ„์šฉ ๊ณต๊ณ  id + * @param interviewDate ๋ฉด์ ‘ ์ผ์ž + * @throws DuplicationException ๋ฉด์ ‘ ์‹œ๊ฐ„์ด ์ค‘๋ณต๋  ๋•Œ + */ + private void updateInterviewDate(Application application, long recruitId, LocalDateTime interviewDate) { + int minutes = 30; + boolean isDuplicated = recruitStatusAdminRepository.existsByRecruitmentIdAndInterviewDateBetween( + recruitId, interviewDate.minusMinutes(minutes), interviewDate.plusMinutes(minutes)); + if (isDuplicated) { + throw new DuplicationException("๋ฉด์ ‘ ์‹œ๊ฐ„์ด ์ค‘๋ณต๋ฉ๋‹ˆ๋‹ค."); + } + RecruitStatus recruitStatus = new RecruitStatus(application, interviewDate); + recruitStatusAdminRepository.save(recruitStatus); + } + + public List getRecruitmentApplicants(Long recruitId) { + return applicationAdminRepository + .findAllByRecruitmentIdWithUserAndRecruitStatusFetchJoinOrderByIdDesc(recruitId); + } + + /** + * ์ง€์›์„œ ๋ชฉ๋ก ์กฐํšŒ + * @param dto + * @return + * + * must query by questionId and checkListIds + * or questionId and search + */ + public Page findApplicationsWithAnswersAndUserWithFilter(GetRecruitmentApplicationsParam dto) { + Long recruitId = dto.getRecruitId(); + Long questionId = dto.getQuestionId(); + String search = dto.getSearch(); + Pageable pageable = dto.getPageable(); + List checkListIds = dto.getCheckListIds(); + + //question && checkList + if (questionId != null && !checkListIds.isEmpty() && search == null) { + return applicationAdminRepository.findAllByCheckList(recruitId, questionId, checkListIds, pageable); + //question && search + } else if (questionId != null && search != null && checkListIds.isEmpty()) { + return applicationAdminRepository.findAllByContainSearch(recruitId, questionId, search, pageable); + } else { + //not + return applicationAdminRepository.findByRecruitIdAndIsDeletedFalseOrderByIdDesc(recruitId, pageable); + } + } + + public RecruitmentDetailAdminSvcDto findRecruitmentDetail(Long recruitId) { + Recruitment recruitment = recruitmentAdminRepository.findNotDeletedRecruit(recruitId) + .orElseThrow(() -> new NotExistException("Recruitment not found.")); + return new RecruitmentDetailAdminSvcDto(recruitment); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/RecruitmentResultMessageAdminService.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/RecruitmentResultMessageAdminService.java new file mode 100644 index 000000000..afceba813 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/RecruitmentResultMessageAdminService.java @@ -0,0 +1,33 @@ +package gg.recruit.api.admin.service; + +import java.util.List; + +import gg.data.recruit.manage.ResultMessage; +import gg.data.recruit.manage.enums.MessageType; +import gg.recruit.api.admin.service.param.RecruitmentResultMessageParam; + +/** + * RecruitmentResultMessageAdminService. + * + *

+ * + *

+ * @see : + * @author : middlefitting + * @since : 2024/03/20 + */ +public interface RecruitmentResultMessageAdminService { + /** + * ์ง€์› ๊ฒฐ๊ณผ ๋ฉ”์‹œ์ง€ ๋“ฑ๋ก + * @param reqDto + */ + void postResultMessage(RecruitmentResultMessageParam reqDto); + + /** + * ์ง€์› ๊ฒฐ๊ณผ ๋ฉ”์‹œ์ง€ ๋ชฉ๋ก ์กฐํšŒ + * @return List + */ + List getResultMessages(); + + String getResultMessagePreview(MessageType messageType); +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/RecruitmentResultMessageAdminServiceImpl.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/RecruitmentResultMessageAdminServiceImpl.java new file mode 100644 index 000000000..7759656a9 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/RecruitmentResultMessageAdminServiceImpl.java @@ -0,0 +1,51 @@ +package gg.recruit.api.admin.service; + +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.admin.repo.recruit.manage.RecruitResultMessageRepository; +import gg.data.recruit.manage.ResultMessage; +import gg.data.recruit.manage.enums.MessageType; +import gg.recruit.api.admin.service.param.RecruitmentResultMessageDtoMapper; +import gg.recruit.api.admin.service.param.RecruitmentResultMessageParam; +import gg.utils.exception.custom.NotExistException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class RecruitmentResultMessageAdminServiceImpl implements RecruitmentResultMessageAdminService { + private final RecruitResultMessageRepository recruitResultMessageRepository; + + /** + * ๋™์ผ ํƒ€์ž…์˜ ์ด์ „ ๋ฉ”์‹œ์ง€๋ฅผ disable ํ•˜๊ณ  ํ˜„์žฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ €์žฅ. + * @param reqDto + */ + @Override + @Transactional + public void postResultMessage(RecruitmentResultMessageParam reqDto) { + recruitResultMessageRepository.disablePreviousResultMessages(reqDto.getMessageType()); + recruitResultMessageRepository.save(RecruitmentResultMessageDtoMapper.INSTANCE.dtoToEntity(reqDto)); + } + + /** + * ์ง€์› ๊ฒฐ๊ณผ ๋ฉ”์‹œ์ง€ ์–‘์‹ ์ „์ฒด ์กฐํšŒ + * @return List + */ + @Override + public List getResultMessages() { + return recruitResultMessageRepository.findAllOrderByIdDesc(); + } + + /** + * ์ง€์› ๊ฒฐ๊ณผ ๋ฉ”์‹œ์ง€ ์–‘์‹ ๋ฏธ๋ฆฌ๋ณด๊ธฐ + * @return String + */ + @Override + public String getResultMessagePreview(MessageType messageType) { + return recruitResultMessageRepository.findActiveResultMessageByMessageType(messageType) + .orElseThrow(() -> new NotExistException("์ง€์› ๊ฒฐ๊ณผ ๋ฉ”์‹œ์ง€๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.")) + .getContent(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/CheckListContent.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/CheckListContent.java new file mode 100644 index 000000000..4376c0fc7 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/CheckListContent.java @@ -0,0 +1,19 @@ +package gg.recruit.api.admin.service.param; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class CheckListContent { + @NotBlank(message = "๋ฌธํ•ญ ๋‚ด์šฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + @Size(min = 1, max = 100, message = "100์ž ์ด๋‚ด๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + String contents; + + public CheckListContent(String content) { + this.contents = content; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/FormParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/FormParam.java new file mode 100644 index 000000000..13ed745ed --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/FormParam.java @@ -0,0 +1,40 @@ +package gg.recruit.api.admin.service.param; + +import java.util.List; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.recruit.recruitment.enums.InputType; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class FormParam { + @NotBlank(message = "์งˆ๋ฌธ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + @Size(min = 1, max = 300, message = "์งˆ๋ฌธ์€ 300์ž ์ด๋‚ด๋กœ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + String question; + + @NotNull(message = "inputType์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + InputType inputType; + + @Valid + List checkList; + + @Builder + public FormParam(String question, InputType inputType, List checkList) { + this.question = question; + this.inputType = inputType; + this.checkList = checkList; + } + + public Question toQuestion(Recruitment recruitment, int sortNum) { + return new Question(recruitment, inputType, question, sortNum); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/GetRecruitmentApplicationsParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/GetRecruitmentApplicationsParam.java new file mode 100644 index 000000000..180f16003 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/GetRecruitmentApplicationsParam.java @@ -0,0 +1,27 @@ +package gg.recruit.api.admin.service.param; + +import java.util.List; + +import org.springframework.data.domain.Pageable; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class GetRecruitmentApplicationsParam { + private Long recruitId; + private Long questionId; + private List checkListIds; + private String search; + private Pageable pageable; + + public GetRecruitmentApplicationsParam(Long recruitId, Long questionId, List checkListIds, String search, + Pageable pageable) { + this.recruitId = recruitId; + this.questionId = questionId; + this.checkListIds = checkListIds; + this.search = search; + this.pageable = pageable; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/RecruitmentResultMessageDtoMapper.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/RecruitmentResultMessageDtoMapper.java new file mode 100644 index 000000000..1438dfaf7 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/RecruitmentResultMessageDtoMapper.java @@ -0,0 +1,13 @@ +package gg.recruit.api.admin.service.param; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import gg.data.recruit.manage.ResultMessage; + +@Mapper +public interface RecruitmentResultMessageDtoMapper { + RecruitmentResultMessageDtoMapper INSTANCE = Mappers.getMapper(RecruitmentResultMessageDtoMapper.class); + + ResultMessage dtoToEntity(RecruitmentResultMessageParam dto); +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/RecruitmentResultMessageParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/RecruitmentResultMessageParam.java new file mode 100644 index 000000000..bb57c4820 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/RecruitmentResultMessageParam.java @@ -0,0 +1,24 @@ +package gg.recruit.api.admin.service.param; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import gg.data.recruit.manage.ResultMessage; +import gg.data.recruit.manage.enums.MessageType; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class RecruitmentResultMessageParam { + @NotNull + private MessageType messageType; + + @NotEmpty + @Size(max = ResultMessage.contentLimit) + private String content; +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/UpdateApplicationStatusParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/UpdateApplicationStatusParam.java new file mode 100644 index 000000000..f6681b5cc --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/UpdateApplicationStatusParam.java @@ -0,0 +1,28 @@ +package gg.recruit.api.admin.service.param; + +import java.time.LocalDateTime; + +import gg.data.recruit.application.enums.ApplicationStatus; +import lombok.Getter; + +@Getter +public class UpdateApplicationStatusParam { + ApplicationStatus status; + Long applicationId; + Long recruitId; + LocalDateTime interviewDate; + + public UpdateApplicationStatusParam(ApplicationStatus status, Long applicationId, Long recruitId) { + this.status = status; + this.applicationId = applicationId; + this.recruitId = recruitId; + } + + public UpdateApplicationStatusParam(ApplicationStatus status, Long applicationId, Long recruitId, + LocalDateTime interviewDate) { + this.status = status; + this.applicationId = applicationId; + this.recruitId = recruitId; + this.interviewDate = interviewDate; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/UpdateRecruitStatusParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/UpdateRecruitStatusParam.java new file mode 100644 index 000000000..fa1075316 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/param/UpdateRecruitStatusParam.java @@ -0,0 +1,11 @@ +package gg.recruit.api.admin.service.param; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class UpdateRecruitStatusParam { + private Long recruitId; + private Boolean finish; +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/AllRecruitmentsResult.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/AllRecruitmentsResult.java new file mode 100644 index 000000000..b8c3fb3e1 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/AllRecruitmentsResult.java @@ -0,0 +1,20 @@ +package gg.recruit.api.admin.service.result; + +import java.util.List; + +import gg.data.recruit.recruitment.Recruitment; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class AllRecruitmentsResult { + private int totalPage; + private List allRecruitments; + + public AllRecruitmentsResult(int totalPage, List allRecruitments) { + this.totalPage = totalPage; + this.allRecruitments = allRecruitments; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/CheckItemAdminSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/CheckItemAdminSvcDto.java new file mode 100644 index 000000000..6446d75a4 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/CheckItemAdminSvcDto.java @@ -0,0 +1,15 @@ +package gg.recruit.api.admin.service.result; + +import gg.data.recruit.recruitment.CheckList; +import lombok.Getter; + +@Getter +public class CheckItemAdminSvcDto { + private Long id; + private String contents; + + public CheckItemAdminSvcDto(CheckList checkList) { + this.id = checkList.getId(); + this.contents = checkList.getContent(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/FormDetailAdminSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/FormDetailAdminSvcDto.java new file mode 100644 index 000000000..4a06b6fa0 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/FormDetailAdminSvcDto.java @@ -0,0 +1,24 @@ +package gg.recruit.api.admin.service.result; + +import java.util.List; +import java.util.stream.Collectors; + +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.enums.InputType; +import lombok.Getter; + +@Getter +public class FormDetailAdminSvcDto { + private Long questionId; + private String question; + private InputType inputType; + private List checkList; + + public FormDetailAdminSvcDto(Question question) { + this.questionId = question.getId(); + this.question = question.getQuestion(); + this.inputType = question.getInputType(); + this.checkList = question.getCheckLists().stream() + .map(CheckItemAdminSvcDto::new).collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/RecruitmentDetailAdminSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/RecruitmentDetailAdminSvcDto.java new file mode 100644 index 000000000..b3db2cf54 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/admin/service/result/RecruitmentDetailAdminSvcDto.java @@ -0,0 +1,28 @@ +package gg.recruit.api.admin.service.result; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +import gg.data.recruit.recruitment.Recruitment; +import lombok.Getter; + +@Getter +public class RecruitmentDetailAdminSvcDto { + private LocalDateTime startDate; + private LocalDateTime endDate; + private String title; + private String contents; + private String generation; + private List forms; + + public RecruitmentDetailAdminSvcDto(Recruitment recruit) { + this.startDate = recruit.getStartTime(); + this.endDate = recruit.getEndTime(); + this.title = recruit.getTitle(); + this.contents = recruit.getContents(); + this.generation = recruit.getGeneration(); + this.forms = recruit.getQuestions().stream() + .map(FormDetailAdminSvcDto::new).collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/ApplicationController.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/ApplicationController.java new file mode 100644 index 000000000..560b4d169 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/ApplicationController.java @@ -0,0 +1,93 @@ +package gg.recruit.api.user.controller; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; +import gg.recruit.api.user.controller.request.FormPatchRequestDto; +import gg.recruit.api.user.controller.request.RecruitApplyFormListReqDto; +import gg.recruit.api.user.controller.response.ApplicationResultResDto; +import gg.recruit.api.user.controller.response.MyApplicationDetailResDto; +import gg.recruit.api.user.controller.response.MyApplicationsResDto; +import gg.recruit.api.user.service.ApplicationService; +import gg.recruit.api.user.service.param.DelApplicationParam; +import gg.recruit.api.user.service.param.FindApplicationDetailParam; +import gg.recruit.api.user.service.param.FindApplicationResultParam; +import gg.recruit.api.user.service.param.FormPatchParam; +import gg.recruit.api.user.service.param.RecruitApplyFormParam; +import gg.recruit.api.user.service.param.RecruitApplyParam; +import gg.recruit.api.user.service.response.ApplicationListSvcDto; +import gg.recruit.api.user.service.response.ApplicationResultSvcDto; +import gg.recruit.api.user.service.response.ApplicationWithAnswerSvcDto; +import io.swagger.v3.oas.annotations.Parameter; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/recruitments") +public class ApplicationController { + + private final ApplicationService applicationService; + + @GetMapping("/applications") + public MyApplicationsResDto getMyApplications(@Login UserDto userDto) { + ApplicationListSvcDto res = applicationService.findMyApplications(userDto.getId()); + return new MyApplicationsResDto(res); + } + + @GetMapping("{recruitmentId}/applications/{applicationId}") + public MyApplicationDetailResDto getMyApplication(@Login @Parameter(hidden = true) UserDto userDto, + @PathVariable Long recruitmentId, @PathVariable Long applicationId) { + ApplicationWithAnswerSvcDto res = applicationService + .findMyApplicationDetail(new FindApplicationDetailParam(userDto.getId(), recruitmentId, applicationId)); + return new MyApplicationDetailResDto(res); + } + + @PostMapping("{recruitmentId}/applications") + public ResponseEntity apply(@Login @Parameter(hidden = true) UserDto userDto, + @PathVariable Long recruitmentId, @RequestBody RecruitApplyFormListReqDto reqDto) { + List forms = reqDto.getForms().stream() + .map(form -> new RecruitApplyFormParam(form.getQuestionId(), form.getInputType(), form.getCheckedList(), + form.getAnswer())) + .collect(Collectors.toList()); + Long applicationId = applicationService.recruitApply( + new RecruitApplyParam(userDto.getId(), recruitmentId, forms)); + return ResponseEntity.status(HttpStatus.CREATED).body(applicationId); + } + + @GetMapping("{recruitmentId}/applications/{applicationId}/result") + public ApplicationResultResDto getApplicationResult(@Login @Parameter(hidden = true) UserDto userDto, + @PathVariable Long recruitmentId, @PathVariable Long applicationId) { + ApplicationResultSvcDto res = applicationService.findApplicationResult( + new FindApplicationResultParam(userDto.getId(), + recruitmentId, applicationId)); + return new ApplicationResultResDto(res); + } + + @PatchMapping("{recruitmentId}/applications/{applicationId}") + public ResponseEntity updateApplication(@Login @Parameter(hidden = true) UserDto userDto, + @PathVariable Long recruitmentId, @PathVariable Long applicationId, @RequestBody FormPatchRequestDto reqDto) { + applicationService.updateApplication(new FormPatchParam(applicationId, recruitmentId, + userDto.getId(), reqDto.toFormParamList())); + return ResponseEntity.noContent().build(); + } + + @DeleteMapping("/{recruitmentId}/applications/{applicationId}") + public ResponseEntity cancelApplication(@Login @Parameter(hidden = true) UserDto userDto, + @PathVariable Long recruitmentId, @PathVariable Long applicationId) { + applicationService.deleteApplication(new DelApplicationParam(userDto.getId(), applicationId, recruitmentId)); + return ResponseEntity.noContent().build(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/RecruitmentController.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/RecruitmentController.java new file mode 100644 index 000000000..93cff3a99 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/RecruitmentController.java @@ -0,0 +1,41 @@ +package gg.recruit.api.user.controller; + +import javax.validation.Valid; + +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import gg.auth.UserDto; +import gg.auth.argumentresolver.Login; +import gg.recruit.api.user.controller.response.ActiveRecruitmentListResDto; +import gg.recruit.api.user.controller.response.RecruitmentDetailResDto; +import gg.recruit.api.user.service.ApplicationService; +import gg.recruit.api.user.service.RecruitmentService; +import gg.utils.dto.PageRequestDto; +import io.swagger.v3.oas.annotations.Parameter; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/recruitments") +public class RecruitmentController { + private final RecruitmentService recruitmentService; + private final ApplicationService applicationService; + + @GetMapping + public ActiveRecruitmentListResDto findActiveRecruitmentList(@Valid PageRequestDto requestDto) { + Pageable pageable = PageRequest.of(requestDto.getPage() - 1, requestDto.getSize()); + return new ActiveRecruitmentListResDto(recruitmentService.findActiveRecruitmentList(pageable)); + } + + @GetMapping("/{recruitmentId}") + public RecruitmentDetailResDto findRecruitmentDetail(@Parameter(hidden = true) @Login UserDto user, + @PathVariable Long recruitmentId) { + return new RecruitmentDetailResDto(recruitmentService.findRecruitmentDetail(recruitmentId), + applicationService.findApplicationByUserAndRecruit(user.getId(), recruitmentId)); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/CheckListFormRequest.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/CheckListFormRequest.java new file mode 100644 index 000000000..071d37c69 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/CheckListFormRequest.java @@ -0,0 +1,31 @@ +package gg.recruit.api.user.controller.request; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import gg.data.recruit.recruitment.enums.InputType; +import gg.recruit.api.user.service.param.CheckListFormParam; +import gg.recruit.api.user.service.param.FormParam; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Setter +@NoArgsConstructor +public class CheckListFormRequest extends FormRequest { + + @JsonProperty("checkedList") + private List checkedList; + + public CheckListFormRequest(Long questionId, InputType inputType, List checkedList) { + this.checkedList = checkedList; + this.questionId = questionId; + this.inputType = inputType; + } + + @Override + public FormParam toFormParam() { + return new CheckListFormParam(checkedList, questionId, inputType); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/FormPatchRequestDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/FormPatchRequestDto.java new file mode 100644 index 000000000..ddc43099d --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/FormPatchRequestDto.java @@ -0,0 +1,21 @@ +package gg.recruit.api.user.controller.request; + +import java.util.List; +import java.util.stream.Collectors; + +import gg.recruit.api.user.service.param.FormParam; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class FormPatchRequestDto { + List forms; + + public List toFormParamList() { + return forms.stream().map(FormRequest::toFormParam) + .collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/FormRequest.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/FormRequest.java new file mode 100644 index 000000000..50a5dfbfe --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/FormRequest.java @@ -0,0 +1,26 @@ +package gg.recruit.api.user.controller.request; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +import gg.data.recruit.recruitment.enums.InputType; +import gg.recruit.api.user.service.param.FormParam; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "inputType", visible = true) +@JsonSubTypes({ + @JsonSubTypes.Type(value = TextFormRequest.class, name = "TEXT"), + @JsonSubTypes.Type(value = CheckListFormRequest.class, name = "SINGLE_CHECK"), + @JsonSubTypes.Type(value = CheckListFormRequest.class, name = "MULTI_CHECK") +}) +@Setter +@Getter +@NoArgsConstructor +public abstract class FormRequest { + protected Long questionId; + protected InputType inputType; + + public abstract FormParam toFormParam(); +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/RecruitApplyFormListReqDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/RecruitApplyFormListReqDto.java new file mode 100644 index 000000000..b20843177 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/RecruitApplyFormListReqDto.java @@ -0,0 +1,21 @@ +package gg.recruit.api.user.controller.request; + +import java.util.List; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class RecruitApplyFormListReqDto { + @NotNull(message = "forms๋Š” null์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.") + @Valid + private List forms; + + public RecruitApplyFormListReqDto(List forms) { + this.forms = forms; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/RecruitApplyFormReqDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/RecruitApplyFormReqDto.java new file mode 100644 index 000000000..2589f32da --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/RecruitApplyFormReqDto.java @@ -0,0 +1,43 @@ +package gg.recruit.api.user.controller.request; + +import java.util.List; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +import gg.data.recruit.recruitment.enums.InputType; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class RecruitApplyFormReqDto { + @NotNull(message = "์งˆ๋ฌธ ID๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private Long questionId; + @NotNull(message = "์ž…๋ ฅ ํƒ€์ž…์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private InputType inputType; + @NotNull(message = "์ฒดํฌ๋œ ํ•ญ๋ชฉ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private List checkedList; + @NotBlank(message = "๋‹ต๋ณ€์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.") + private String answer; + + public RecruitApplyFormReqDto(Long questionId, String answer) { + this.questionId = questionId; + this.inputType = InputType.TEXT; + this.answer = answer; + } + + public RecruitApplyFormReqDto(Long questionId, List checkedList) { + this.questionId = questionId; + this.inputType = InputType.MULTI_CHECK; + this.checkedList = checkedList; + } + + public RecruitApplyFormReqDto(Long questionId, Long checkedList) { + this.questionId = questionId; + this.inputType = InputType.SINGLE_CHECK; + this.checkedList = List.of(checkedList); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/TextFormRequest.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/TextFormRequest.java new file mode 100644 index 000000000..b497b9b85 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/request/TextFormRequest.java @@ -0,0 +1,29 @@ +package gg.recruit.api.user.controller.request; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import gg.data.recruit.recruitment.enums.InputType; +import gg.recruit.api.user.service.param.FormParam; +import gg.recruit.api.user.service.param.TextFormParam; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Setter +@NoArgsConstructor +public class TextFormRequest extends FormRequest { + + @JsonProperty("answer") + private String answer; + + public TextFormRequest(Long questionId, InputType inputType, String answer) { + this.questionId = questionId; + this.inputType = inputType; + this.answer = answer; + } + + @Override + public FormParam toFormParam() { + return new TextFormParam(answer, questionId, inputType); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/ActiveRecruitmentListResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/ActiveRecruitmentListResDto.java new file mode 100644 index 000000000..c0429edb5 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/ActiveRecruitmentListResDto.java @@ -0,0 +1,20 @@ +package gg.recruit.api.user.controller.response; + +import java.util.List; +import java.util.stream.Collectors; + +import gg.recruit.api.user.service.response.RecruitmentListSvcDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ActiveRecruitmentListResDto { + private List recruitments; + private Integer totalPage; + + public ActiveRecruitmentListResDto(RecruitmentListSvcDto dto) { + this.recruitments = dto.getRecruitments().stream().map(RecruitmentDto::new).collect(Collectors.toList()); + this.totalPage = dto.getTotalPage(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/ApplicationResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/ApplicationResDto.java new file mode 100644 index 000000000..7a1f20401 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/ApplicationResDto.java @@ -0,0 +1,29 @@ +package gg.recruit.api.user.controller.response; + +import java.time.LocalDateTime; + +import gg.recruit.api.user.service.response.ApplicationSvcDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ApplicationResDto { + private Long recruitId; + private Long applicationId; + private LocalDateTime startDate; + private LocalDateTime endDate; + private String title; + private String generation; + private String status; + + public ApplicationResDto(ApplicationSvcDto applicationDto) { + this.recruitId = applicationDto.getRecruitId(); + this.applicationId = applicationDto.getApplicationId(); + this.startDate = applicationDto.getStartDate(); + this.endDate = applicationDto.getEndDate(); + this.title = applicationDto.getTitle(); + this.generation = applicationDto.getGeneration(); + this.status = applicationDto.getStatus(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/ApplicationResultResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/ApplicationResultResDto.java new file mode 100644 index 000000000..b31271b81 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/ApplicationResultResDto.java @@ -0,0 +1,25 @@ +package gg.recruit.api.user.controller.response; + +import java.time.LocalDateTime; + +import gg.data.recruit.application.enums.ApplicationStatus; +import gg.recruit.api.user.service.response.ApplicationResultSvcDto; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor +public class ApplicationResultResDto { + private String title; + private ApplicationStatus status; + private LocalDateTime interviewDate; + + public ApplicationResultResDto(ApplicationResultSvcDto applicationResult) { + this.title = applicationResult.getTitle(); + this.status = applicationResult.getStatus(); + this.interviewDate = applicationResult.getInterviewDate(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/CheckItemResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/CheckItemResDto.java new file mode 100644 index 000000000..5048c4bc3 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/CheckItemResDto.java @@ -0,0 +1,17 @@ +package gg.recruit.api.user.controller.response; + +import gg.recruit.api.user.service.response.CheckItemSvcDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class CheckItemResDto { + private Long id; + private String contents; + + public CheckItemResDto(CheckItemSvcDto dto) { + this.id = dto.getId(); + this.contents = dto.getContents(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/CheckListResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/CheckListResDto.java new file mode 100644 index 000000000..50d46f8f4 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/CheckListResDto.java @@ -0,0 +1,15 @@ +package gg.recruit.api.user.controller.response; + +import gg.recruit.api.user.service.response.CheckListSvcDto; +import lombok.Getter; + +@Getter +public class CheckListResDto { + private Long checkListId; + private String content; + + public CheckListResDto(CheckListSvcDto checkListSvcDto) { + this.checkListId = checkListSvcDto.getCheckListId(); + this.content = checkListSvcDto.getContent(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/FormDetailResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/FormDetailResDto.java new file mode 100644 index 000000000..0fa625c9e --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/FormDetailResDto.java @@ -0,0 +1,25 @@ +package gg.recruit.api.user.controller.response; + +import java.util.List; +import java.util.stream.Collectors; + +import gg.data.recruit.recruitment.enums.InputType; +import gg.recruit.api.user.service.response.FormDetailSvcDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class FormDetailResDto { + private Long questionId; + private String question; + private InputType inputType; + private List checkList; + + public FormDetailResDto(FormDetailSvcDto dto) { + this.questionId = dto.getQuestionId(); + this.question = dto.getQuestion(); + this.inputType = dto.getInputType(); + this.checkList = dto.getCheckList().stream().map(CheckItemResDto::new).collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/FormResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/FormResDto.java new file mode 100644 index 000000000..c7b8954e6 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/FormResDto.java @@ -0,0 +1,26 @@ +package gg.recruit.api.user.controller.response; + +import static java.util.stream.Collectors.*; + +import java.util.List; + +import gg.recruit.api.user.service.response.FormSvcDto; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class FormResDto { + private Long questionId; + private String inputType; + private List checkedList; + private String answer; + + public FormResDto(FormSvcDto formSvcDto) { + this.questionId = formSvcDto.getQuestionId(); + this.inputType = formSvcDto.getInputType(); + this.checkedList = formSvcDto.getCheckedList().stream() + .map(CheckListResDto::new).collect(toList()); + this.answer = formSvcDto.getAnswer(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/MyApplicationDetailResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/MyApplicationDetailResDto.java new file mode 100644 index 000000000..02efb7a29 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/MyApplicationDetailResDto.java @@ -0,0 +1,28 @@ +package gg.recruit.api.user.controller.response; + +import static java.util.stream.Collectors.*; + +import java.time.LocalDateTime; +import java.util.List; + +import gg.recruit.api.user.service.response.ApplicationWithAnswerSvcDto; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class MyApplicationDetailResDto { + private Long applicationId; + private LocalDateTime endTime; + private String title; + private List forms; + + public MyApplicationDetailResDto(ApplicationWithAnswerSvcDto applicationWithAnswerSvcDto) { + this.applicationId = applicationWithAnswerSvcDto.getApplicationId(); + this.endTime = applicationWithAnswerSvcDto.getEndTime(); + this.title = applicationWithAnswerSvcDto.getTitle(); + this.forms = applicationWithAnswerSvcDto.getForm().stream() + .map(FormResDto::new) + .collect(toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/MyApplicationsResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/MyApplicationsResDto.java new file mode 100644 index 000000000..434ba0e3c --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/MyApplicationsResDto.java @@ -0,0 +1,21 @@ +package gg.recruit.api.user.controller.response; + +import java.util.List; +import java.util.stream.Collectors; + +import gg.recruit.api.user.service.response.ApplicationListSvcDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class MyApplicationsResDto { + private List applications; + + public MyApplicationsResDto(ApplicationListSvcDto applicationListDto) { + applications = applicationListDto.getApplications() + .stream() + .map(ApplicationResDto::new) + .collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/RecruitmentDetailResDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/RecruitmentDetailResDto.java new file mode 100644 index 000000000..99629bc9b --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/RecruitmentDetailResDto.java @@ -0,0 +1,31 @@ +package gg.recruit.api.user.controller.response; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +import gg.recruit.api.user.service.response.RecruitmentDetailSvcDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Getter +public class RecruitmentDetailResDto { + private LocalDateTime startDate; + private LocalDateTime endDate; + private String title; + private String contents; + private String generation; + private List forms; + private Long applicationId; + + public RecruitmentDetailResDto(RecruitmentDetailSvcDto dto, Long applicationId) { + this.startDate = dto.getStartDate(); + this.endDate = dto.getEndDate(); + this.title = dto.getTitle(); + this.contents = dto.getContents(); + this.generation = dto.getGeneration(); + this.forms = dto.getForms().stream().map(FormDetailResDto::new).collect(Collectors.toList()); + this.applicationId = applicationId; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/RecruitmentDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/RecruitmentDto.java new file mode 100644 index 000000000..fe58eca14 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/RecruitmentDto.java @@ -0,0 +1,25 @@ +package gg.recruit.api.user.controller.response; + +import java.time.LocalDateTime; + +import gg.recruit.api.user.service.response.RecruitmentSvcDto; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class RecruitmentDto { + private Long id; + private LocalDateTime startDate; + private LocalDateTime endDate; + private String title; + private String generation; + + public RecruitmentDto(RecruitmentSvcDto dto) { + this.id = dto.getId(); + this.startDate = dto.getStartDate(); + this.endDate = dto.getEndDate(); + this.title = dto.getTitle(); + this.generation = dto.getGeneration(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/RecruitmentStatus.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/RecruitmentStatus.java new file mode 100644 index 000000000..70ddeb385 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/controller/response/RecruitmentStatus.java @@ -0,0 +1,9 @@ +package gg.recruit.api.user.controller.response; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum RecruitmentStatus { + BEFORE("๋ชจ์ง‘์ „"), PROGRESS("๋ชจ์ง‘์ค‘"), FINISHED("๋ชจ์ง‘์™„๋ฃŒ"); + private final String desc; +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/ApplicationService.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/ApplicationService.java new file mode 100644 index 000000000..c4c7ab2f2 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/ApplicationService.java @@ -0,0 +1,185 @@ +package gg.recruit.api.user.service; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.ApplicationAnswer; +import gg.data.recruit.application.ApplicationAnswerCheckList; +import gg.data.recruit.application.ApplicationAnswerText; +import gg.data.recruit.application.RecruitStatus; +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.recruit.recruitment.enums.InputType; +import gg.data.user.User; +import gg.data.user.type.SnsType; +import gg.recruit.api.user.service.param.DelApplicationParam; +import gg.recruit.api.user.service.param.FindApplicationDetailParam; +import gg.recruit.api.user.service.param.FindApplicationResultParam; +import gg.recruit.api.user.service.param.FormParam; +import gg.recruit.api.user.service.param.FormPatchParam; +import gg.recruit.api.user.service.param.RecruitApplyFormParam; +import gg.recruit.api.user.service.param.RecruitApplyParam; +import gg.recruit.api.user.service.response.ApplicationListSvcDto; +import gg.recruit.api.user.service.response.ApplicationResultSvcDto; +import gg.recruit.api.user.service.response.ApplicationWithAnswerSvcDto; +import gg.repo.recruit.application.ApplicationAnswerRepository; +import gg.repo.recruit.application.ApplicationRepository; +import gg.repo.recruit.application.RecruitStatusRepository; +import gg.repo.recruit.recruitment.CheckListRepository; +import gg.repo.recruit.recruitment.QuestionRepository; +import gg.repo.recruit.recruitment.RecruitmentRepository; +import gg.repo.user.UserRepository; +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.DuplicationException; +import gg.utils.exception.custom.ForbiddenException; +import gg.utils.exception.custom.NotExistException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class ApplicationService { + + private final ApplicationRepository applicationRepository; + private final ApplicationAnswerRepository applicationAnswerRepository; + private final UserRepository userRepository; + private final RecruitmentRepository recruitmentRepository; + private final QuestionRepository questionRepository; + private final CheckListRepository checkListRepository; + private final RecruitStatusRepository recruitStatusRepository; + + public ApplicationListSvcDto findMyApplications(Long userId) { + List res = applicationRepository.findAllByUserId(userId); + return new ApplicationListSvcDto(res); + } + + public ApplicationWithAnswerSvcDto findMyApplicationDetail(FindApplicationDetailParam param) { + List answers = applicationAnswerRepository + .findAllAnswers(param.getUserId(), param.getRecruitId(), param.getApplicationId()); + if (answers.size() == 0) { + throw new NotExistException("application not found", ErrorCode.BAD_REQUEST); + } + return new ApplicationWithAnswerSvcDto(answers); + } + + public Long findApplicationByUserAndRecruit(Long userId, Long recruitId) { + Optional application = applicationRepository.findByUserIdAndRecruitId(userId, recruitId); + return application.map(Application::getId).orElse(null); + } + + /** + * user ๊ฐ€ recruit ์— ์ง€์›ํ•œ๋‹ค. + * @param param + * @return + */ + public Long recruitApply(RecruitApplyParam param) { + // application ์— ๊ธฐ์กด ์ง€์›์„œ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธ isExist + Optional application = applicationRepository + .findByUserIdAndRecruitId(param.getUserId(), param.getRecruitId()); + if (application.isPresent()) { + throw new DuplicationException("์ด๋ฏธ ์ง€์›ํ•œ ๊ณต๊ณ ์ž…๋‹ˆ๋‹ค. applicationId = " + application.get().getId()); + } + // application ์ƒ์„ฑ + User user = userRepository.findById(param.getUserId()) + .orElseThrow(() -> new NotExistException("user not found")); + if (user.getSnsNotiOpt().equals(SnsType.NONE) || user.getSnsNotiOpt().equals(SnsType.EMAIL)) { + user.updateTypes(user.getRacketType(), SnsType.BOTH); + } + Recruitment recruitments = recruitmentRepository.getById(param.getRecruitId()); + // recruit๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ + if (recruitments.getEndTime().isBefore(LocalDateTime.now())) { + throw new ForbiddenException("๋งˆ๊ฐ๋œ ๊ณต๊ณ ์ž…๋‹ˆ๋‹ค."); + } + + Application newApplication = applicationRepository.save(new Application(user, recruitments)); + for (RecruitApplyFormParam form : + param.getForms()) { + if (form.getInputType().equals(InputType.TEXT)) { + applicationAnswerRepository.save( + new ApplicationAnswerText(newApplication, questionRepository.getById(form.getQuestionId()), + form.getAnswer())); + } else { + for (Long checkedId : form.getCheckedList()) { + applicationAnswerRepository.save( + new ApplicationAnswerCheckList(newApplication, questionRepository.getById(form.getQuestionId()), + checkListRepository.getById(checkedId))); + } + } + } + return newApplication.getId(); + } + + public ApplicationResultSvcDto findApplicationResult(FindApplicationResultParam param) { + Optional optionalApplication = applicationRepository + .findApplication(param.getApplicationId(), param.getUserId(), param.getRecruitmentId()); + ApplicationResultSvcDto result; + if (optionalApplication.isEmpty()) { + result = ApplicationResultSvcDto.nullResult(); + } else { + Application application = optionalApplication.get(); + Optional recruitStatusOptional = recruitStatusRepository.findByApplicationId( + param.getApplicationId()); + result = recruitStatusOptional.map( + recruitStatus -> ApplicationResultSvcDto.of(application.getRecruitTitle(), + application.getStatus(), recruitStatus.getInterviewDate())) + .orElseGet( + () -> ApplicationResultSvcDto.of(application.getRecruitTitle(), application.getStatus(), null)); + } + return result; + } + + @Transactional + public void updateApplication(FormPatchParam param) { + Application application = applicationRepository.findByUserIdAndRecruitId(param.getUserId(), + param.getRecruitmentId()).orElseThrow(() -> + new NotExistException("application not found")); + + //delete all existing answers + List questionIds = param.getQuestionIds(); + List res = applicationAnswerRepository.findAllByQuestionIds(param.getUserId(), + param.getApplicationId(), param.getRecruitmentId(), questionIds); + applicationAnswerRepository.deleteAll(res); + + Map questionMap = questionRepository.findAllById(questionIds) + .stream() + .collect(Collectors.toMap(Question::getId, q -> q)); + + Map checkListMap = checkListRepository.findAllByQuestionIds(questionIds) + .stream() + .collect(Collectors.toMap(CheckList::getId, q -> q)); + applicationAnswerRepository.saveAll( + toApplicationAnswer(application, questionMap, checkListMap, param.getForms())); + } + + private List toApplicationAnswer(Application application, Map questionMap, + Map checkListMap, List forms) { + List newAnswers = new ArrayList<>(); + forms.stream().forEach(form -> { + newAnswers.addAll(form.toApplicationAnswer(application, questionMap, checkListMap)); + }); + return newAnswers; + } + + @Transactional + public void deleteApplication(DelApplicationParam param) { + Application application = applicationRepository + .findByUserIdAndRecruitId(param.getUserId(), param.getRecruitmentId()) + .orElseThrow(() -> new NotExistException("application not found")); + if (!application.isUpdateAvailable()) { + throw new ForbiddenException("์ง€์›์„œ ์ˆ˜์ • ๊ธฐ๊ฐ„์ด ์ง€๋‚ฌ์Šต๋‹ˆ๋‹ค."); + } + if (application.getId().equals(param.getApplicationId())) { + application.delete(); + } else { + throw new NotExistException("application not found"); + } + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/QuestionService.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/QuestionService.java new file mode 100644 index 000000000..a555eb56d --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/QuestionService.java @@ -0,0 +1,19 @@ +package gg.recruit.api.user.service; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import gg.data.recruit.recruitment.Question; +import gg.repo.recruit.recruitment.QuestionRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class QuestionService { + private final QuestionRepository questionRepository; + + public List findQuestionsByRecruitId(Long recruitId) { + return questionRepository.findAllByRecruitId(recruitId); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/RecruitmentService.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/RecruitmentService.java new file mode 100644 index 000000000..d1437124b --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/RecruitmentService.java @@ -0,0 +1,35 @@ +package gg.recruit.api.user.service; + +import java.time.LocalDateTime; +import java.util.List; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import gg.recruit.api.user.service.response.RecruitmentDetailSvcDto; +import gg.recruit.api.user.service.response.RecruitmentListSvcDto; +import gg.repo.recruit.recruitment.RecruitmentRepository; +import gg.utils.exception.custom.NotExistException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class RecruitmentService { + private final RecruitmentRepository recruitmentRepository; + private final QuestionService questionService; + + public RecruitmentListSvcDto findActiveRecruitmentList(Pageable pageable) { + Page pages = recruitmentRepository.findActiveRecruitmentList(LocalDateTime.now(), pageable); + return new RecruitmentListSvcDto(pages.getContent(), pages.getTotalPages()); + } + + public RecruitmentDetailSvcDto findRecruitmentDetail(Long recruitmentId) { + Recruitment recruit = recruitmentRepository.findByActiveRecruit(recruitmentId, LocalDateTime.now()) + .orElseThrow(() -> new NotExistException("Recruitment id ๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.")); + List questions = questionService.findQuestionsByRecruitId(recruitmentId); + return new RecruitmentDetailSvcDto(recruit, questions); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/CheckListFormParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/CheckListFormParam.java new file mode 100644 index 000000000..1c068b023 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/CheckListFormParam.java @@ -0,0 +1,36 @@ +package gg.recruit.api.user.service.param; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.ApplicationAnswer; +import gg.data.recruit.application.ApplicationAnswerCheckList; +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.enums.InputType; + +public class CheckListFormParam extends FormParam { + private final List checkedList; + + public CheckListFormParam(List checkedList, Long questionId, InputType inputType) { + this.checkedList = checkedList; + this.questionId = questionId; + this.inputType = inputType; + } + + @Override + public List toApplicationAnswer(Application application, Map questionMap, + Map checkListMap) { + List res = new ArrayList<>(); + for (Long checkListId : checkedList) { + CheckList checkList = checkListMap.get(checkListId); + if (checkList == null) { + throw new IllegalArgumentException("checkListId must exist in checkListMap"); + } + res.add(new ApplicationAnswerCheckList(application, questionMap.get(questionId), checkList)); + } + return res; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/DelApplicationParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/DelApplicationParam.java new file mode 100644 index 000000000..bb19390e5 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/DelApplicationParam.java @@ -0,0 +1,16 @@ +package gg.recruit.api.user.service.param; + +import lombok.Getter; + +@Getter +public class DelApplicationParam { + private Long userId; + private Long applicationId; + private Long recruitmentId; + + public DelApplicationParam(Long userId, Long applicationId, Long recruitmentId) { + this.applicationId = applicationId; + this.recruitmentId = recruitmentId; + this.userId = userId; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FindApplicationDetailParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FindApplicationDetailParam.java new file mode 100644 index 000000000..8e19d0b94 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FindApplicationDetailParam.java @@ -0,0 +1,12 @@ +package gg.recruit.api.user.service.param; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class FindApplicationDetailParam { + private Long userId; + private Long recruitId; + private Long applicationId; +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FindApplicationResultParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FindApplicationResultParam.java new file mode 100644 index 000000000..5e6e6d723 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FindApplicationResultParam.java @@ -0,0 +1,15 @@ +package gg.recruit.api.user.service.param; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class FindApplicationResultParam { + + private Long userId; + private Long recruitmentId; + private Long applicationId; + +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FormParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FormParam.java new file mode 100644 index 000000000..ae91ce601 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FormParam.java @@ -0,0 +1,26 @@ +package gg.recruit.api.user.service.param; + +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.ApplicationAnswer; +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.enums.InputType; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +@Getter +public abstract class FormParam { + protected Long questionId; + + protected InputType inputType; + + public abstract List toApplicationAnswer(Application application, + Map questionMap, Map checkListMap); +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FormPatchParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FormPatchParam.java new file mode 100644 index 000000000..e29a0854e --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/FormPatchParam.java @@ -0,0 +1,23 @@ +package gg.recruit.api.user.service.param; + +import java.util.List; +import java.util.stream.Collectors; + +import gg.recruit.api.user.controller.request.FormRequest; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class FormPatchParam { + Long applicationId; + Long recruitmentId; + Long userId; + List forms; + + public List getQuestionIds() { + return forms.stream().map(FormParam::getQuestionId) + .collect(Collectors.toList()); + } + +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/RecruitApplyFormParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/RecruitApplyFormParam.java new file mode 100644 index 000000000..1519f20a8 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/RecruitApplyFormParam.java @@ -0,0 +1,21 @@ +package gg.recruit.api.user.service.param; + +import java.util.List; + +import gg.data.recruit.recruitment.enums.InputType; +import lombok.Getter; + +@Getter +public class RecruitApplyFormParam { + private Long questionId; + private InputType inputType; + private List checkedList; + private String answer; + + public RecruitApplyFormParam(Long questionId, InputType inputType, List checkedList, String answer) { + this.questionId = questionId; + this.inputType = inputType; + this.checkedList = checkedList; + this.answer = answer; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/RecruitApplyParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/RecruitApplyParam.java new file mode 100644 index 000000000..10d9333d5 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/RecruitApplyParam.java @@ -0,0 +1,19 @@ +package gg.recruit.api.user.service.param; + +import java.util.List; + +import lombok.Getter; + +@Getter +public class RecruitApplyParam { + private Long userId; + private Long recruitId; + private List forms; + + public RecruitApplyParam(Long userId, Long recruitId, List forms) { + this.userId = userId; + this.recruitId = recruitId; + this.forms = forms; + } + +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/TextFormParam.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/TextFormParam.java new file mode 100644 index 000000000..b5f760ddc --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/param/TextFormParam.java @@ -0,0 +1,32 @@ +package gg.recruit.api.user.service.param; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.ApplicationAnswer; +import gg.data.recruit.application.ApplicationAnswerText; +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.enums.InputType; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.Setter; + +public class TextFormParam extends FormParam { + private String answer; + + public TextFormParam(String answer, Long questionId, InputType inputType) { + this.answer = answer; + this.questionId = questionId; + this.inputType = inputType; + } + + @Override + public List toApplicationAnswer(Application application, Map questionMap, + Map checkListMap) { + return Collections.singletonList( + new ApplicationAnswerText(application, questionMap.get(questionId), answer)); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationListSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationListSvcDto.java new file mode 100644 index 000000000..3b824536e --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationListSvcDto.java @@ -0,0 +1,17 @@ +package gg.recruit.api.user.service.response; + +import java.util.List; +import java.util.stream.Collectors; + +import gg.data.recruit.application.Application; +import lombok.Getter; + +@Getter +public class ApplicationListSvcDto { + List applications; + + public ApplicationListSvcDto(List applications) { + this.applications = applications.stream().map(ApplicationSvcDto::new) + .collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationResultSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationResultSvcDto.java new file mode 100644 index 000000000..a0d565d62 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationResultSvcDto.java @@ -0,0 +1,25 @@ +package gg.recruit.api.user.service.response; + +import java.time.LocalDateTime; + +import gg.data.recruit.application.enums.ApplicationStatus; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Getter +public class ApplicationResultSvcDto { + private String title; + private ApplicationStatus status; + private LocalDateTime interviewDate; + + public static ApplicationResultSvcDto nullResult() { + return new ApplicationResultSvcDto(null, null, null); + } + + public static ApplicationResultSvcDto of(String title, ApplicationStatus status, LocalDateTime interviewDate) { + return new ApplicationResultSvcDto(title, status, interviewDate); + } + +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationSvcDto.java new file mode 100644 index 000000000..3473ad125 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationSvcDto.java @@ -0,0 +1,29 @@ +package gg.recruit.api.user.service.response; + +import java.time.LocalDateTime; + +import gg.data.recruit.application.Application; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ApplicationSvcDto { + private Long recruitId; + private Long applicationId; + private LocalDateTime startDate; + private LocalDateTime endDate; + private String title; + private String generation; + private String status; + + public ApplicationSvcDto(Application application) { + this.recruitId = application.getRecruit().getId(); + this.applicationId = application.getId(); + this.startDate = application.getRecruit().getStartTime(); + this.endDate = application.getRecruit().getEndTime(); + this.title = application.getRecruit().getTitle(); + this.generation = application.getRecruit().getGeneration(); + this.status = application.getStatus().name(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationWithAnswerSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationWithAnswerSvcDto.java new file mode 100644 index 000000000..862f6173d --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/ApplicationWithAnswerSvcDto.java @@ -0,0 +1,42 @@ +package gg.recruit.api.user.service.response; + +import static java.util.stream.Collectors.*; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +import gg.data.recruit.application.ApplicationAnswer; +import gg.data.recruit.application.ApplicationAnswerEntityDto; +import lombok.Getter; + +@Getter +public class ApplicationWithAnswerSvcDto { + private final Long applicationId; + private final LocalDateTime endTime; + private final String title; + private final String content; + private final List form; + + public ApplicationWithAnswerSvcDto(List answers) { + this.applicationId = answers.get(0).getApplication().getId(); + this.endTime = answers.get(0).getApplication().getRecruit().getEndTime(); + this.title = answers.get(0).getApplication().getRecruit().getTitle(); + this.content = answers.get(0).getApplication().getRecruit().getContents(); + + List entityDtos = answers.stream() + .map(ApplicationAnswer::toForm).collect(toList()); + + // groupping answers by questionId and inputType + Map> groupedAnswers = entityDtos.stream() + .collect(groupingBy(ApplicationAnswerEntityDto::getQuestionId)); + + // convert to FromSvcDto + this.form = groupedAnswers.entrySet().stream() + .map(entry -> { + Long questionId = entry.getKey(); + List answersByInputType = entry.getValue(); + return new FormSvcDto(questionId, answersByInputType); + }).collect(toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/CheckItemSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/CheckItemSvcDto.java new file mode 100644 index 000000000..d4f10dc1e --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/CheckItemSvcDto.java @@ -0,0 +1,15 @@ +package gg.recruit.api.user.service.response; + +import gg.data.recruit.recruitment.CheckList; +import lombok.Getter; + +@Getter +public class CheckItemSvcDto { + private Long id; + private String contents; + + public CheckItemSvcDto(CheckList checkList) { + this.id = checkList.getId(); + this.contents = checkList.getContent(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/CheckListSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/CheckListSvcDto.java new file mode 100644 index 000000000..99779bde9 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/CheckListSvcDto.java @@ -0,0 +1,15 @@ +package gg.recruit.api.user.service.response; + +import gg.data.recruit.application.CheckListEntityDto; +import lombok.Getter; + +@Getter +public class CheckListSvcDto { + private Long checkListId; + private String content; + + public CheckListSvcDto(CheckListEntityDto entityDto) { + this.checkListId = entityDto.getCheckListId(); + this.content = entityDto.getContent(); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/FormDetailSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/FormDetailSvcDto.java new file mode 100644 index 000000000..6c14f2a2b --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/FormDetailSvcDto.java @@ -0,0 +1,23 @@ +package gg.recruit.api.user.service.response; + +import java.util.List; +import java.util.stream.Collectors; + +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.enums.InputType; +import lombok.Getter; + +@Getter +public class FormDetailSvcDto { + private Long questionId; + private String question; + private InputType inputType; + private List checkList; + + public FormDetailSvcDto(Question question) { + this.questionId = question.getId(); + this.question = question.getQuestion(); + this.inputType = question.getInputType(); + this.checkList = question.getCheckLists().stream().map(CheckItemSvcDto::new).collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/FormSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/FormSvcDto.java new file mode 100644 index 000000000..68a03bfd2 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/FormSvcDto.java @@ -0,0 +1,25 @@ +package gg.recruit.api.user.service.response; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import gg.data.recruit.application.ApplicationAnswerEntityDto; +import lombok.Getter; + +@Getter +public class FormSvcDto { + private Long questionId; + private String inputType; + + private List checkedList; + private String answer; + + public FormSvcDto(Long questionId, List entityDtos) { + this.questionId = questionId; + this.inputType = entityDtos.get(0).getInputType().name(); + this.answer = entityDtos.get(0).getAnswer(); + this.checkedList = entityDtos.stream().map(ApplicationAnswerEntityDto::getCheckedList) + .filter(Objects::nonNull) + .map(CheckListSvcDto::new).collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/RecruitmentDetailSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/RecruitmentDetailSvcDto.java new file mode 100644 index 000000000..9eefbb2d9 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/RecruitmentDetailSvcDto.java @@ -0,0 +1,28 @@ +package gg.recruit.api.user.service.response; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import lombok.Getter; + +@Getter +public class RecruitmentDetailSvcDto { + private LocalDateTime startDate; + private LocalDateTime endDate; + private String title; + private String contents; + private String generation; + private List forms; + + public RecruitmentDetailSvcDto(Recruitment recruit, List questions) { + this.startDate = recruit.getStartTime(); + this.endDate = recruit.getEndTime(); + this.title = recruit.getTitle(); + this.contents = recruit.getContents(); + this.generation = recruit.getGeneration(); + this.forms = questions.stream().map(FormDetailSvcDto::new).collect(Collectors.toList()); + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/RecruitmentListSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/RecruitmentListSvcDto.java new file mode 100644 index 000000000..d502d3996 --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/RecruitmentListSvcDto.java @@ -0,0 +1,20 @@ +package gg.recruit.api.user.service.response; + +import java.util.List; +import java.util.stream.Collectors; + +import gg.data.recruit.recruitment.Recruitment; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class RecruitmentListSvcDto { + private List recruitments; + private Integer totalPage; + + public RecruitmentListSvcDto(List recruitments, Integer totalPage) { + this.recruitments = recruitments.stream().map(RecruitmentSvcDto::new).collect(Collectors.toList()); + this.totalPage = totalPage; + } +} diff --git a/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/RecruitmentSvcDto.java b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/RecruitmentSvcDto.java new file mode 100644 index 000000000..e38462aac --- /dev/null +++ b/gg-recruit-api/src/main/java/gg/recruit/api/user/service/response/RecruitmentSvcDto.java @@ -0,0 +1,25 @@ +package gg.recruit.api.user.service.response; + +import java.time.LocalDateTime; + +import gg.data.recruit.recruitment.Recruitment; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class RecruitmentSvcDto { + private Long id; + private LocalDateTime startDate; + private LocalDateTime endDate; + private String title; + private String generation; + + public RecruitmentSvcDto(Recruitment recruitments) { + this.id = recruitments.getId(); + this.startDate = recruitments.getStartTime(); + this.endDate = recruitments.getEndTime(); + this.title = recruitments.getTitle(); + this.generation = recruitments.getGeneration(); + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/RecruitMockData.java b/gg-recruit-api/src/test/java/gg/recruit/api/RecruitMockData.java new file mode 100644 index 000000000..1c19d4c9f --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/RecruitMockData.java @@ -0,0 +1,102 @@ +package gg.recruit.api; + +import java.time.LocalDateTime; +import java.util.List; + +import org.springframework.stereotype.Component; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.ApplicationAnswer; +import gg.data.recruit.application.ApplicationAnswerCheckList; +import gg.data.recruit.application.ApplicationAnswerText; +import gg.data.recruit.application.RecruitStatus; +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.recruit.recruitment.enums.InputType; +import gg.data.user.User; +import gg.repo.recruit.application.ApplicationAnswerRepository; +import gg.repo.recruit.application.ApplicationRepository; +import gg.repo.recruit.application.RecruitStatusRepository; +import gg.repo.recruit.recruitment.CheckListRepository; +import gg.repo.recruit.recruitment.QuestionRepository; +import gg.repo.recruit.recruitment.RecruitmentRepository; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class RecruitMockData { + private final RecruitmentRepository recruitmentRepository; + private final ApplicationRepository applicationRepository; + private final QuestionRepository questionRepository; + private final RecruitStatusRepository recruitStatusRepository; + private final CheckListRepository checkListRepository; + private final ApplicationAnswerRepository applicationAnswerRepository; + + public Recruitment createRecruitment() { + Recruitment recruitments = new Recruitment("title", "contents", "generation", + LocalDateTime.now(), LocalDateTime.now().plusDays(1)); + return recruitmentRepository.save(recruitments); + } + + public Recruitment createRecruitmentDel() { + Recruitment recruitments = new Recruitment("title", "contents", "generation", + LocalDateTime.now(), LocalDateTime.now().plusDays(1)); + recruitments.del(); + return recruitmentRepository.save(recruitments); + } + + public Recruitment createRecruitmentEnd() { + Recruitment recruitments = new Recruitment("title", "contents", "generation", + LocalDateTime.now().minusDays(2), LocalDateTime.now().minusDays(1)); + return recruitmentRepository.save(recruitments); + } + + public Recruitment createRecruitmentNotStarted() { + Recruitment recruitments = new Recruitment("title", "contents", "generation", + LocalDateTime.now().plusDays(1), LocalDateTime.now().plusDays(2)); + return recruitmentRepository.save(recruitments); + } + + public Application createApplication(User user, Recruitment recruitments) { + Application application = new Application(user, recruitments); + return applicationRepository.save(application); + } + + public Question createQuestion(Recruitment recruitments) { + Question question = new Question(recruitments, InputType.TEXT, "question", 1); + return questionRepository.save(question); + } + + public Question createQuestion(Recruitment recruitments, String question, + InputType inputType, String... checkList) { + Question questionEntity = new Question(recruitments, inputType, question, 1); + questionRepository.save(questionEntity); + for (String check : checkList) { + CheckList checkListEntity = new CheckList(questionEntity, check); + checkListRepository.save(checkListEntity); + } + return questionEntity; + } + + public RecruitStatus createRecruitStatus(Application application) { + RecruitStatus recruitStatus = new RecruitStatus(application); + return recruitStatusRepository.save(recruitStatus); + } + + public ApplicationAnswer makeAnswer(Application application, Question question, String content) { + ApplicationAnswer answer = new ApplicationAnswerText(application, question, content); + return applicationAnswerRepository.save(answer); + } + + public void makeAnswer(Application application, Question question, Long checkedId) { + CheckList checkList = checkListRepository.findById(checkedId) + .orElseThrow(() -> new IllegalArgumentException("์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ฒดํฌ๋ฆฌ์ŠคํŠธ")); + ApplicationAnswer answer = new ApplicationAnswerCheckList(application, question, checkList); + applicationAnswerRepository.save(answer); + } + + public List getAllAnswers(Long userId, Long recruitId, Long applicationId) { + return applicationAnswerRepository.findAllAnswers(userId, recruitId, applicationId); + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/TestSpringBootApplication.java b/gg-recruit-api/src/test/java/gg/recruit/api/TestSpringBootApplication.java new file mode 100644 index 000000000..dcc4eecb9 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/TestSpringBootApplication.java @@ -0,0 +1,8 @@ +package gg.recruit.api; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = {"gg.recruit.api", "gg.utils", "gg.data", "gg.repo", + "gg.admin.repo", "gg.auth", "gg.pingpong.api"}) +public class TestSpringBootApplication { +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/WebMvcTestApplicationContext.java b/gg-recruit-api/src/test/java/gg/recruit/api/WebMvcTestApplicationContext.java new file mode 100644 index 000000000..51c7a4b35 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/WebMvcTestApplicationContext.java @@ -0,0 +1,10 @@ +package gg.recruit.api; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Profile; + +@SpringBootApplication(scanBasePackages = {"gg.recruit.api"}) +@Profile("test-mvc") +public class WebMvcTestApplicationContext { + +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/AdminRecruitmentControllerTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/AdminRecruitmentControllerTest.java new file mode 100644 index 000000000..792bfc909 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/AdminRecruitmentControllerTest.java @@ -0,0 +1,63 @@ +package gg.recruit.api.admin.controller; + +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +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.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.data.recruit.recruitment.Recruitment; +import gg.data.user.User; +import gg.recruit.api.RecruitMockData; +import gg.recruit.api.admin.controller.request.UpdateStatusRequestDto; +import gg.repo.recruit.recruitment.RecruitmentRepository; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@Transactional +@AutoConfigureMockMvc +class AdminRecruitmentControllerTest { + @Autowired + private RecruitMockData recruitMockData; + + @Autowired + private TestDataUtils testDataUtils; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private RecruitmentRepository recruitmentRepository; + + @Test + @DisplayName("PATCH /admin/recruitments/{recruitId}/status -> 204 NO CONTENT TEST") + public void updateRecruitStatusTest() throws Exception { + //given + Recruitment recruitments = recruitMockData.createRecruitment(); + UpdateStatusRequestDto requestDto = new UpdateStatusRequestDto(true); + User adminUser = testDataUtils.createAdminUser(); + + //when + mockMvc.perform(patch("/admin/recruitments/{recruitId}/status", recruitments.getId()) + .header("Authorization", "Bearer " + testDataUtils.getLoginAccessTokenFromUser(adminUser)) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDto))) + .andExpect(status().isNoContent()); + + //then + Recruitment updatedRecruitments = recruitmentRepository.findById(recruitments.getId()).get(); + assertTrue(updatedRecruitments.getIsFinish()); + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/RecruitmentAdminControllerTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/RecruitmentAdminControllerTest.java new file mode 100644 index 000000000..eafab2ff6 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/RecruitmentAdminControllerTest.java @@ -0,0 +1,90 @@ +package gg.recruit.api.admin.controller; + +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDateTime; +import java.util.List; + +import javax.transaction.Transactional; + +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.testcontainers.shaded.com.google.common.net.HttpHeaders; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.data.recruit.recruitment.enums.InputType; +import gg.recruit.api.admin.controller.request.RecruitmentRequestDto; +import gg.recruit.api.admin.service.param.CheckListContent; +import gg.recruit.api.admin.service.param.FormParam; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@AutoConfigureMockMvc +@Transactional +public class RecruitmentAdminControllerTest { + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private TestDataUtils testDataUtils; + + @Nested + @DisplayName("๊ณต๊ณ  ์ƒ์„ฑ") + public class CreateRecruitmentTest { + @Test + @DisplayName("์„ฑ๊ณต") + public void testCreateRecruitment() throws Exception { + // given + String accessToken = testDataUtils.getAdminLoginAccessToken(); + List forms = List.of(FormParam.builder().question("์งˆ๋ฌธ").inputType(InputType.SINGLE_CHECK) + .checkList(List.of(new CheckListContent("์„ ํƒ์ง€1"), new CheckListContent("์„ ํƒ์ง€2"))).build(), + FormParam.builder().question("์งˆ๋ฌธ2").inputType(InputType.TEXT).build() + ); + RecruitmentRequestDto requestDto = new RecruitmentRequestDto(LocalDateTime.now().plusDays(1), + LocalDateTime.now().plusDays(2), + "์ œ๋ชฉ", "๋‚ด์šฉ", "๋ชจ์ง‘ ๊ธฐ์ˆ˜", forms); + + // when + ResultActions response = mockMvc.perform(post("/admin/recruitments") + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDto))) + .andExpect(status().isCreated()); + + // then + } + } + + @Test + @DisplayName("๊ณต๊ณ  ์ƒ์„ฑ ์‹คํŒจ - ์„ ํƒ์ง€ ๋ฏธ์ž…๋ ฅ") + public void testCreateRecruitmentWithEmptyCheckList() throws Exception { + // given + String accessToken = testDataUtils.getAdminLoginAccessToken(); + List forms = List.of(FormParam.builder().question("์งˆ๋ฌธ").inputType(InputType.SINGLE_CHECK).build()); + // .checkList(List.of()).build()); + RecruitmentRequestDto requestDto = new RecruitmentRequestDto(LocalDateTime.now().plusDays(1), + LocalDateTime.now().plusDays(2), + "์ œ๋ชฉ", "๋‚ด์šฉ", "๋ชจ์ง‘ ๊ธฐ์ˆ˜", forms); + + // when + ResultActions response = mockMvc.perform(post("/admin/recruitments") + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(requestDto))) + .andExpect(status().isBadRequest()); + + // then + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/RecruitmentAdminControllerUnitTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/RecruitmentAdminControllerUnitTest.java new file mode 100644 index 000000000..6e2c94286 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/RecruitmentAdminControllerUnitTest.java @@ -0,0 +1,186 @@ +package gg.recruit.api.admin.controller; + +import static org.mockito.ArgumentMatchers.*; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import javax.validation.ConstraintViolationException; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.PageRequest; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.RecruitStatus; +import gg.data.recruit.application.enums.ApplicationStatus; +import gg.data.user.User; +import gg.recruit.api.WebMvcTestApplicationContext; +import gg.recruit.api.admin.controller.request.SetFinalApplicationStatusResultReqDto; +import gg.recruit.api.admin.controller.response.RecruitmentApplicantResultResponseDto; +import gg.recruit.api.admin.controller.response.RecruitmentApplicantResultsResponseDto; +import gg.recruit.api.admin.service.RecruitmentAdminService; +import gg.utils.annotation.UnitTest; +import gg.utils.exception.custom.BusinessException; + +@UnitTest +@WebMvcTest(controllers = RecruitmentAdminController.class) +@ActiveProfiles("test-mvc") +@ContextConfiguration(classes = WebMvcTestApplicationContext.class) +class RecruitmentAdminControllerUnitTest { + + @MockBean + private RecruitmentAdminService recruitmentAdminService; + @Autowired + private RecruitmentAdminController recruitmentAdminController; + + @Nested + class SetFinalApplicationStatusResult { + @ParameterizedTest + @DisplayName("PASS, FAIL ํŒŒ๋ผ๋ฏธํ„ฐ ์ „๋‹ฌ ์‹œ ์ตœ์ข… ๊ฒฐ๊ณผ ๋“ฑ๋ก ์„ฑ๊ณต") + @EnumSource(value = ApplicationStatus.class, mode = EnumSource.Mode.INCLUDE, names = {"PASS", "INTERVIEW_FAIL"}) + void setResultSuccess(ApplicationStatus status) { + //Arrange + SetFinalApplicationStatusResultReqDto reqDto = new SetFinalApplicationStatusResultReqDto(status); + + //Act + ResponseEntity response = recruitmentAdminController.setFinalApplicationStatusResult(1L, 1L, reqDto); + + //Assert + Assertions.assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED); + } + + @ParameterizedTest + @DisplayName("PASS, FAIL๋ฅผ ์ œ์™ธํ•œ status๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค") + @EnumSource(value = ApplicationStatus.class, mode = EnumSource.Mode.EXCLUDE, names = {"PASS", "INTERVIEW_FAIL"}) + void invalidStatus(ApplicationStatus status) { + //Arrange + SetFinalApplicationStatusResultReqDto reqDto = new SetFinalApplicationStatusResultReqDto(status); + + //Act + //Assert + Assertions.assertThatThrownBy( + () -> recruitmentAdminController.setFinalApplicationStatusResult(1L, 1L, reqDto)) + .isInstanceOf(ConstraintViolationException.class) + .hasMessageContaining(SetFinalApplicationStatusResultReqDto.MUST_FINAL_STATUS); + } + + @Test + @DisplayName("status null์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค") + void invalidStatusNull() { + //Arrange + SetFinalApplicationStatusResultReqDto reqDto = new SetFinalApplicationStatusResultReqDto(null); + + //Act + //Assert + Assertions.assertThatThrownBy( + () -> recruitmentAdminController.setFinalApplicationStatusResult(1L, 1L, reqDto)) + .isInstanceOf(ConstraintViolationException.class) + .hasMessageContaining(SetFinalApplicationStatusResultReqDto.MUST_FINAL_STATUS); + } + + } + + @Nested + @DisplayName("getRecruitmentsApplicants") + class GetRecruitmentsApplicants { + @Test + @DisplayName("๋“ฑ๋ก๋œ ์ง€์›์„œ๊ฐ€ ์—†์–ด๋„ ์กฐํšŒ ๊ฒฐ๊ณผ๋Š” null ์ด์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค") + void successEmpty() { + //Arrange + ResponseEntity result; + + //Act + result = recruitmentAdminController.getRecruitmentApplicantResults(1L); + + //Assert + Assertions.assertThat(result).isNotNull(); + Assertions.assertThat(result.getBody()).isNotNull(); + Assertions.assertThat(result.getBody().getApplicationResults()).isNotNull(); + Assertions.assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); + } + } + + @Test + @DisplayName("๋ชจ๋“  ์ •๋ณด๊ฐ€ ์ž˜ ๋“ค์–ด๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค") + void successNotEmpty() { + //Arrange + Application application = Mockito.mock(Application.class); + User user = Mockito.mock(User.class); + RecruitStatus recruitStatus = Mockito.mock(RecruitStatus.class); + ApplicationStatus status = ApplicationStatus.INTERVIEW_FAIL; + + Long applicationId = 1L; + LocalDateTime interviewDate = LocalDateTime.now(); + String intraId = "dummy"; + + Mockito.when(application.getId()).thenReturn(applicationId); + Mockito.when(application.getUser()).thenReturn(user); + Mockito.when(application.getRecruitStatus()).thenReturn(recruitStatus); + Mockito.when(application.getStatus()).thenReturn(status); + + Mockito.when(user.getIntraId()).thenReturn(intraId); + + Mockito.when(recruitStatus.getInterviewDate()).thenReturn(interviewDate); + + List serviceResult = new ArrayList<>(); + serviceResult.add(application); + + Mockito.when(recruitmentAdminService.getRecruitmentApplicants(any(Long.class))).thenReturn(serviceResult); + + //Act + RecruitmentApplicantResultResponseDto result = recruitmentAdminController + .getRecruitmentApplicantResults(1L).getBody().getApplicationResults().get(0); + + //Assert + Assertions.assertThat(result.getResult()).isEqualTo(status); + Assertions.assertThat(result.getIntraId()).isEqualTo(intraId); + Assertions.assertThat(result.getApplicationId()).isEqualTo(applicationId); + Assertions.assertThat(result.getInterviewDate()).isEqualTo(interviewDate); + + } + + @Nested + @DisplayName("getRecruitmentApplications") + class GetRecruitmentApplications { + @Test + @DisplayName("long์œผ๋กœ ํŒŒ์‹ฑํ•  ์ˆ˜ ์—†๋Š” ์œ ํšจํ•˜์ง€ ์•Š์€ checks์˜ ๊ฒฝ์šฐ exceptions ๋ฐœ์ƒ") + void invalidChecks() { + //Arrange + //Act + //Assert + Assertions.assertThatThrownBy( + () -> recruitmentAdminController.getRecruitmentApplications(1L, null, "d,d,d", null, + PageRequest.of(1, 10))) + .isInstanceOf(BusinessException.class); + + } + + @Test + @DisplayName("์„ฑ๊ณต") + @Disabled + void success() { + //Arrange + //Act + recruitmentAdminController.getRecruitmentApplications(1L, null, "1,2,3", null, + PageRequest.of(1, 10)); + + //Assert + } + } +} + diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/RecruitmentResultMessageAdminControllerUnitTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/RecruitmentResultMessageAdminControllerUnitTest.java new file mode 100644 index 000000000..b31f1d5c7 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/RecruitmentResultMessageAdminControllerUnitTest.java @@ -0,0 +1,132 @@ +package gg.recruit.api.admin.controller; + +import java.util.ArrayList; +import java.util.List; + +import javax.validation.ConstraintViolationException; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.util.ReflectionTestUtils; + +import gg.data.recruit.manage.ResultMessage; +import gg.data.recruit.manage.enums.MessageType; +import gg.recruit.api.WebMvcTestApplicationContext; +import gg.recruit.api.admin.controller.response.GetRecruitmentResultMessagesResponseDto; +import gg.recruit.api.admin.service.RecruitmentResultMessageAdminService; +import gg.recruit.api.admin.service.param.RecruitmentResultMessageParam; +import gg.utils.annotation.UnitTest; + +@UnitTest +@WebMvcTest(controllers = RecruitmentResultMessageAdminController.class) +@ActiveProfiles("test-mvc") +@ContextConfiguration(classes = WebMvcTestApplicationContext.class) +class RecruitmentResultMessageAdminControllerUnitTest { + + @MockBean + private RecruitmentResultMessageAdminService resultMessageAdminService; + @Autowired + private RecruitmentResultMessageAdminController resultMessageAdminController; + + @Nested + @DisplayName("postResultMessage") + class PostResultMessage { + @Test + @DisplayName("resultMessage ๋“ฑ๋ก ์„ฑ๊ณต") + void postResultMessageSuccess() { + //Arrange + RecruitmentResultMessageParam dto = new RecruitmentResultMessageParam(MessageType.FAIL, "ํƒˆ๋ฝ"); + //Act + ResponseEntity response = resultMessageAdminController.postResultMessage(dto); + //Assert + Assertions.assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED); + } + + @Test + @DisplayName("์œ ํšจํ•˜์ง€ ์•Š์€ dto๋Š” ConstraintViolationException") + void invalidArgument() { + //Arrange + List listDto = new ArrayList<>(); + listDto.add(new RecruitmentResultMessageParam(MessageType.FAIL, null)); + listDto.add(new RecruitmentResultMessageParam(null, "fail")); + listDto.add( + new RecruitmentResultMessageParam(MessageType.FAIL, "f".repeat(ResultMessage.contentLimit + 1))); + //Act + //Assert + for (RecruitmentResultMessageParam dto : listDto) { + Assertions.assertThatExceptionOfType(ConstraintViolationException.class) + .isThrownBy( + () -> resultMessageAdminController.postResultMessage(dto)); + } + } + } + + @Nested + @DisplayName("getResultMessage") + class GetResultMessage { + + @Test + @DisplayName("๋“ฑ๋ก๋œ ๊ฒฐ๊ณผ๊ฐ€ ์—†์„๋•Œ ์กฐํšŒ ๊ฒฐ๊ณผ๋Š” null์ด์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค") + void successEmpty() { + //Arrange + ResponseEntity resultMessages; + + //Act + resultMessages = resultMessageAdminController.getResultMessages(); + + //Assert + Assertions.assertThat(resultMessages).isNotNull(); + Assertions.assertThat(resultMessages.getBody()).isNotNull(); + Assertions.assertThat(resultMessages.getBody().getMessages()).isNotNull(); + Assertions.assertThat(resultMessages.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + @DisplayName("๋“ฑ๋ก๋œ ๊ฒฐ๊ณผ๊ฐ€ ์žˆ์„๋•Œ ์กฐํšŒ ๊ฒฐ๊ณผ ๋ชจ๋“  ์š”์†Œ๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค") + void successNotEmpty() { + //Arrange + List listDto = makeSampleResultMessages(); + ResponseEntity resultMessages; + Mockito.when(resultMessageAdminService.getResultMessages()).thenReturn(listDto); + + //Act + resultMessages = resultMessageAdminController.getResultMessages(); + + //Assert + Assertions.assertThat(resultMessages.getBody().getMessages().size()).isEqualTo(listDto.size()); + for (int i = 0; i < listDto.size(); i++) { + Assertions.assertThat(resultMessages.getBody().getMessages().get(i).getMessageId()) + .isEqualTo(listDto.get(i).getId()); + Assertions.assertThat(resultMessages.getBody().getMessages().get(i).getMessage()) + .isEqualTo(listDto.get(i).getContent()); + Assertions.assertThat(resultMessages.getBody().getMessages().get(i).getMessageType()) + .isEqualTo(listDto.get(i).getMessageType()); + Assertions.assertThat(resultMessages.getBody().getMessages().get(i).getIsUse()) + .isEqualTo(listDto.get(i).getIsUse()); + } + + Assertions.assertThat(resultMessages.getStatusCode()).isEqualTo(HttpStatus.OK); + } + } + + List makeSampleResultMessages() { + List resultMessages = new ArrayList<>(); + MessageType[] messageTypes = {MessageType.FAIL, MessageType.PASS, MessageType.INTERVIEW}; + for (int i = 0; i < 3; i++) { + ResultMessage message = ResultMessage.builder().content("๋ฉ”์‹œ์ง€" + i).messageType(messageTypes[i]).build(); + ReflectionTestUtils.setField(message, "id", Long.valueOf(i)); + resultMessages.add(message); + } + return resultMessages; + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/response/GetRecruitmentApplicationDtoTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/response/GetRecruitmentApplicationDtoTest.java new file mode 100644 index 000000000..a4245013e --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/admin/controller/response/GetRecruitmentApplicationDtoTest.java @@ -0,0 +1,102 @@ +package gg.recruit.api.admin.controller.response; + +import javax.persistence.EntityManager; + +import org.assertj.core.api.Assertions; +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.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.transaction.annotation.Transactional; + +import gg.admin.repo.recruit.ApplicationAdminRepository; +import gg.data.recruit.application.Application; +import gg.data.recruit.application.enums.ApplicationStatus; +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.recruit.recruitment.enums.InputType; +import gg.data.user.User; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; +import gg.utils.annotation.UnitTest; + +@IntegrationTest +@UnitTest +@Transactional +class GetRecruitmentApplicationDtoTest { + @Autowired + EntityManager entityManager; + + @Autowired + ApplicationAdminRepository applicationAdminRepository; + + @Autowired + TestDataUtils testDataUtils; + + @Nested + @DisplayName("MapperTest") + class MapperTest { + + @Test + @DisplayName("mapper์— ์กฐ๊ฑด์— ๋งž๊ฒŒ ๋ชจ๋“  ์š”์†Œ๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค") + void success() { + String search = "hello world"; + + Recruitment recruitment = testDataUtils.createNewRecruitment(); + User user = testDataUtils.createNewUser(); + + Application application = testDataUtils.createApplication(user, recruitment); + Question question = testDataUtils.createNewQuestion(recruitment, InputType.MULTI_CHECK, "multi", 2); + CheckList checkList = testDataUtils.createNewCheckList(question, "dd"); + CheckList checkList2 = testDataUtils.createNewCheckList(question, "dd"); + testDataUtils.createNewApplicationAnswerCheckList(application, question, checkList); + testDataUtils.createNewApplicationAnswerCheckList(application, question, checkList2); + + Question question2 = testDataUtils.createNewQuestion(recruitment, InputType.SINGLE_CHECK, "single", 2); + testDataUtils.createNewApplicationAnswerCheckList(application, question2, checkList); + + Question question3 = testDataUtils.createNewQuestion(recruitment, InputType.TEXT, "text", 2); + testDataUtils.createNewApplicationAnswerText(application, question3, search); + + Long recruitmentId = recruitment.getId(); + Long applicationId = application.getId(); + String intraId = user.getIntraId(); + ApplicationStatus status = application.getStatus(); + + entityManager.flush(); + entityManager.clear(); + + //Arrange + Pageable pageable = PageRequest.of(0, 10); + Page all = applicationAdminRepository.findByRecruitIdAndIsDeletedFalseOrderByIdDesc( + recruitmentId, pageable); + Application applicationResult = all.getContent().get(0); + GetRecruitmentApplicationDto dto = GetRecruitmentApplicationDto.MapStruct.INSTANCE.entityToDto( + applicationResult); + + // Assert + Assertions.assertThat(dto.getApplicationId()).isEqualTo(applicationId); + Assertions.assertThat(dto.getIntraId()).isEqualTo(intraId); + Assertions.assertThat(dto.getStatus()).isEqualTo(status); + Assertions.assertThat(dto.getForms().size()).isEqualTo(3); + for (GetRecruitmentApplicationDto.Form form : dto.getForms()) { + if (form.getInputType().equals(InputType.TEXT)) { + Assertions.assertThat(form.getCheckedList().size()).isEqualTo(0); + Assertions.assertThat(form.getAnswer()).isEqualTo(search); + } + if (form.getInputType().equals(InputType.SINGLE_CHECK)) { + Assertions.assertThat(form.getCheckedList().size()).isEqualTo(1); + Assertions.assertThat(form.getAnswer()).isNull(); + } + if (form.getInputType().equals(InputType.MULTI_CHECK)) { + Assertions.assertThat(form.getCheckedList().size()).isEqualTo(2); + Assertions.assertThat(form.getAnswer()).isNull(); + } + } + } + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/admin/integration/RecruitmentAdminIntegrationTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/admin/integration/RecruitmentAdminIntegrationTest.java new file mode 100644 index 000000000..b0ca4d5ed --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/admin/integration/RecruitmentAdminIntegrationTest.java @@ -0,0 +1,274 @@ +package gg.recruit.api.admin.integration; + +import static org.assertj.core.api.AssertionsForClassTypes.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +import javax.persistence.EntityManager; +import javax.transaction.Transactional; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.testcontainers.shaded.com.google.common.net.HttpHeaders; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.admin.repo.recruit.ApplicationAdminRepository; +import gg.admin.repo.recruit.RecruitmentAdminRepository; +import gg.admin.repo.recruit.recruitment.QuestionAdminRepository; +import gg.data.recruit.application.Application; +import gg.data.recruit.application.enums.ApplicationStatus; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.recruit.recruitment.enums.InputType; +import gg.data.user.User; +import gg.recruit.api.RecruitMockData; +import gg.recruit.api.admin.controller.request.InterviewRequestDto; +import gg.recruit.api.admin.controller.request.RecruitmentRequestDto; +import gg.recruit.api.admin.controller.response.RecruitmentAdminDetailResDto; +import gg.recruit.api.admin.service.param.FormParam; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@Transactional +@AutoConfigureMockMvc +public class RecruitmentAdminIntegrationTest { + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private TestDataUtils testDataUtils; + + @Autowired + private RecruitMockData recruitMockData; + + @Autowired + private RecruitmentAdminRepository recruitmentAdminRepository; + + @Autowired + private QuestionAdminRepository questionAdminRepository; + + @Autowired + EntityManager em; + + @Autowired + private ApplicationAdminRepository applicationAdminRepository; + + @Nested + @DisplayName("๊ณต๊ณ  ์ƒ์„ธ ์กฐํšŒ ์‹œ - GET /admin/recruitments/{recruitmentId}") + class GetRecruitment { + + @DisplayName("์ง€์›Œ์ง„ ๊ณต๊ณ ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๊ณต๊ณ  ์ƒ์„ธ ์กฐํšŒ ์„ฑ๊ณต - 200 OK") + @Test + void getRecruitment() throws Exception { + // given + Recruitment recruitment = recruitMockData.createRecruitment(); + recruitMockData.createQuestion(recruitment); + recruitMockData.createQuestion(recruitment, "question2", + InputType.MULTI_CHECK, "check1", "check2"); + long recruitmentId = recruitment.getId(); + String url = String.format("/admin/recruitments/%d", recruitmentId); + String accessToken = testDataUtils.getAdminLoginAccessToken(); + + // when + String response = mockMvc.perform(get(url) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + RecruitmentAdminDetailResDto resDto = objectMapper.readValue(response, + RecruitmentAdminDetailResDto.class); + + assertThat(resDto.getForms().size()).isEqualTo(2); + } + + } + + @Nested + @DisplayName("๊ณต๊ณ  ์ „์ฒด ์กฐํšŒ ์‹œ - POST /admin/recruitments") + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + class PostRecruitment { + + @DisplayName("๊ณต๊ณ  ์ข…๋ฃŒ ๋‚ ์งœ ๊ธฐ์ค€ ์ตœ์‹ ์ˆœ์œผ๋กœ ์กฐํšŒ๋œ๋‹ค.") + @ParameterizedTest + @MethodSource("getRecruitments") + void getAllRecruitments(List recruitments) throws Exception { + // given + int page = 1; + int size = 10; + String url = String.format("/admin/recruitments?page=%d&size=%d", page, size); + String accessToken = testDataUtils.getAdminLoginAccessToken(); + recruitmentAdminRepository.saveAll(recruitments); + + // when + String response = mockMvc.perform(get(url) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + + System.out.println(response); + } + + /** + * parameterized test์— ์‚ฌ์šฉํ•  List๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์†Œ๋“œ + * @return ์ข…๋ฃŒ ๋‚ ์งœ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ 3๊ฐœ์˜ ๊ณต๊ณ  ๋ฆฌ์ŠคํŠธ, empty list + */ + private Stream> getRecruitments() { + LocalDateTime startDate = LocalDateTime.of(2021, 1, 1, 0, 0, 0); + return Stream.of(List.of( + new Recruitment("title", "contents", "generation", startDate, startDate.plusDays(1)), + new Recruitment("title", "contents", "generation", startDate, startDate.plusDays(2)), + new Recruitment("title", "contents", "generation", startDate, startDate.plusDays(3)) + ), + List.of()); + } + + } + + @Nested + @DisplayName("๊ณต๊ณ  ์‚ญ์ œ ์‹œ - DELETE /admin/recruitments/{recruitmentId}") + class DeleteRecruitment { + @Test + @DisplayName("๊ณต๊ณ ๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ ์‚ญ์ œ ์„ฑ๊ณต (isDeleted = true) - 204 No Content") + void deleteRecruitment() throws Exception { + // given + Recruitment recruitment = recruitMockData.createRecruitment(); + long recruitmentId = recruitment.getId(); + String url = String.format("/admin/recruitments/%d", recruitmentId); + String accessToken = testDataUtils.getAdminLoginAccessToken(); + + // when + mockMvc.perform(delete(url) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)) + .andExpect(status().isNoContent()); + + // then + assertThat(recruitmentAdminRepository.findById(recruitmentId).get().getIsDeleted()).isTrue(); + assertThat(recruitment.getIsDeleted()).isTrue(); + } + + @Test + @DisplayName("๊ณต๊ณ ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ NotExistException ๋ฐœ์ƒํ•˜๊ณ  ์‚ญ์ œ๋Š” ์‹คํŒจํ•œ๋‹ค. - 404 Not Found") + void deleteRecruitmentFail() throws Exception { + // given + long recruitmentId = 1L; + String url = String.format("/admin/recruitments/%d", recruitmentId); + String accessToken = testDataUtils.getAdminLoginAccessToken(); + + // when then + mockMvc.perform(delete(url) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken)) + .andExpect(status().isNotFound()); + } + } + + @Nested + @DisplayName("์„œ๋ฅ˜์ „ํ˜• ๊ฒฐ๊ณผ ๋“ฑ๋ก - POST /admin/recruitments/{recruitmentId}/applications/{applicationId}") + class PostResultDocumentScreening { + @Test + @DisplayName("์„œ๋ฅ˜์ „ํ˜• ํ•ฉ๊ฒฉ(PROGRESS_INTERVIEW) ๋“ฑ๋ก ์„ฑ๊ณต - 201 Created") + void postResultDocumentScreening() throws Exception { + // given + User user = testDataUtils.createAdminUser(); + Recruitment recruitment = recruitMockData.createRecruitment(); + Application application = recruitMockData.createApplication(user, recruitment); + InterviewRequestDto dto = new InterviewRequestDto(ApplicationStatus.PROGRESS_INTERVIEW, + LocalDateTime.now().plusDays(1)); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + String url = String.format("/admin/recruitments/%d/interview?application=%d", recruitment.getId(), + application.getId()); + + // when + mockMvc.perform(post(url) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(dto))) + .andExpect(status().isCreated()); + + // then + Optional after = applicationAdminRepository.findById(application.getId()); + assertThat(after.get().getStatus()).isEqualTo(ApplicationStatus.PROGRESS_INTERVIEW); + } + } + + @Nested + @DisplayName("๊ณต๊ณ  ์ˆ˜์ • ์‹œ - PUT /admin/recruitments/{recruitmentId}") + class PutRecruitment { + private final FormParam afterQuestion = new FormParam("updated question", InputType.TEXT, List.of()); + RecruitmentRequestDto afterRecruitment = RecruitmentRequestDto.builder() + .title("updated title") + .contents("updated contents") + .generation("updated generation") + .startDate(LocalDateTime.now().plusDays(1)) + .endDate(LocalDateTime.now().plusDays(2)) + .form(List.of(afterQuestion)) + .build(); + + @Test + @DisplayName("๊ณต๊ณ ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•„ ์ˆ˜์ • ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ NotExistException ๋ฐœ์ƒ - 404 Not Found") + void updateRecruitmentNotExist() throws Exception { + // given + long recruitmentId = 1L; + String url = String.format("/admin/recruitments/%d", recruitmentId); + String accessToken = testDataUtils.getAdminLoginAccessToken(); + String content = objectMapper.writeValueAsString(afterRecruitment); + + // when then + mockMvc.perform(put(url) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(content)) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("๊ณต๊ณ  ์ˆ˜์ • ์„ฑ๊ณต ํ›„ - 204 No Content") + void updateRecruitment() throws Exception { + // given + Recruitment beforeRecruitment = recruitMockData.createRecruitmentNotStarted(); + long recruitmentId = beforeRecruitment.getId(); + long beforeQuestionId = recruitMockData.createQuestion(beforeRecruitment).getId(); + String url = String.format("/admin/recruitments/%d", recruitmentId); + String accessToken = testDataUtils.getAdminLoginAccessToken(); + String content = objectMapper.writeValueAsString(afterRecruitment); + + // when + mockMvc.perform(put(url) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(content)) + .andExpect(status().isNoContent()); + + // flush + // recruitmentAdminRepository.flush(); + // questionAdminRepository.flush(); + em.flush(); + em.clear(); + + // then + Recruitment after = recruitmentAdminRepository.findById(recruitmentId).get(); + assertThat(after.getId()).isEqualTo(recruitmentId); + assertThat(after.getTitle()).isEqualTo(afterRecruitment.getTitle()); + assertThat(after.getContents()).isEqualTo(afterRecruitment.getContents()); + + // TODO ์‚ญ์ œ ํ™•์ธ -> ์—๋Ÿฌ.. ์ˆ˜์ • ํ•„์š” + // Optional deletedQuestion = questionAdminRepository.findById(beforeQuestionId); + // assertThat(deletedQuestion).isEmpty(); + } + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/admin/integration/RecruitmentResultMessageIntegrationTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/admin/integration/RecruitmentResultMessageIntegrationTest.java new file mode 100644 index 000000000..571916bf3 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/admin/integration/RecruitmentResultMessageIntegrationTest.java @@ -0,0 +1,174 @@ +package gg.recruit.api.admin.integration; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; + +import javax.persistence.EntityManager; + +import org.assertj.core.api.Assertions; +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.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.admin.repo.recruit.manage.RecruitResultMessageRepository; +import gg.data.recruit.manage.ResultMessage; +import gg.data.recruit.manage.enums.MessageType; +import gg.data.user.User; +import gg.recruit.api.admin.controller.request.GetRecruitmentResultMessagePreviewReqDto; +import gg.recruit.api.admin.controller.response.GetRecruitmentResultMessagePreviewResDto; +import gg.recruit.api.admin.service.param.RecruitmentResultMessageParam; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@Transactional +@AutoConfigureMockMvc +public class RecruitmentResultMessageIntegrationTest { + @Autowired + TestDataUtils testDataUtils; + @Autowired + ObjectMapper objectMapper; + @Autowired + RecruitResultMessageRepository recruitResultMessageRepository; + @Autowired + MockMvc mockMvc; + @Autowired + EntityManager em; + + @Nested + @DisplayName("POST /admin/recruitments/result/message") + class PostResultMessage { + @Test + @DisplayName("์ €์žฅ ์„ฑ๊ณต") + void saveSuccess() throws Exception { + //Arrange + MessageType targetType = MessageType.FAIL; + + User adminUser = testDataUtils.createAdminUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(adminUser); + ResultMessage resultMessage1 = makeResultMessage(targetType); + em.persist(resultMessage1); + em.flush(); + List all = recruitResultMessageRepository.findAll(); + HashSet previousId = all.stream() + .map(ResultMessage::getId) + .collect(Collectors.toCollection(HashSet::new)); + em.clear(); + + RecruitmentResultMessageParam req = new RecruitmentResultMessageParam(targetType, "bye"); + String content = objectMapper.writeValueAsString(req); + + //Act + mockMvc.perform(post(("/admin/recruitments/result/message")) + .header("Authorization", "Bearer " + accessToken) + .contentType("application/json") + .content(content)) + .andExpect(status().isCreated()); + + //Assert + all = recruitResultMessageRepository.findAll(); + for (ResultMessage resultMessage : all) { + if (previousId.contains(resultMessage.getId())) { + Assertions.assertThat(resultMessage.getIsUse()).isFalse(); + } else { + Assertions.assertThat(resultMessage.getIsUse()).isTrue(); + } + } + } + + @Test + @DisplayName("์ด์ „์— ์ €์žฅํ•œ ๊ฐ™์€ ํƒ€์ž…์˜ message๋Š” fail์—ฌ์•ผ ํ•œ๋‹ค") + void previousMessageStatusFalse() throws Exception { + //Arrange + MessageType targetType = MessageType.FAIL; + MessageType differentType = MessageType.PASS; + MessageType differentType2 = MessageType.INTERVIEW; + + User adminUser = testDataUtils.createAdminUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(adminUser); + ResultMessage sameResultMessage = makeResultMessage(targetType); + ResultMessage sameResultMessage2 = makeResultMessage(targetType); + ResultMessage differentResultMessage = makeResultMessage(differentType); + ResultMessage differentResultMessage2 = makeResultMessage(differentType2); + em.persist(sameResultMessage); + em.persist(sameResultMessage2); + em.persist(differentResultMessage); + em.persist(differentResultMessage2); + em.flush(); + List all = recruitResultMessageRepository.findAll(); + all.forEach((result) -> Assertions.assertThat(result.getIsUse()).isTrue()); + HashSet previousId = all.stream() + .map(ResultMessage::getId) + .collect(Collectors.toCollection(HashSet::new)); + em.clear(); + + RecruitmentResultMessageParam req = new RecruitmentResultMessageParam(targetType, "bye"); + String content = objectMapper.writeValueAsString(req); + + //Act + mockMvc.perform(post(("/admin/recruitments/result/message")) + .header("Authorization", "Bearer " + accessToken) + .contentType("application/json") + .content(content)) + .andExpect(status().isCreated()); + + //Assert + all = recruitResultMessageRepository.findAll(); + all = recruitResultMessageRepository.findAll(); + for (ResultMessage resultMessage : all) { + if (resultMessage.getMessageType().equals(targetType)) { + if (previousId.contains(resultMessage.getId())) { + Assertions.assertThat(resultMessage.getIsUse()).isFalse(); + } else { + Assertions.assertThat(resultMessage.getIsUse()).isTrue(); + } + } else { + Assertions.assertThat(resultMessage.getIsUse()).isTrue(); + } + } + } + } + + @Test + @DisplayName("GET getPreview -> 200 OK TEST") + void getPreviewOK() throws Exception { + //Arrange + MessageType targetType = MessageType.FAIL; + User adminUser = testDataUtils.createAdminUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(adminUser); + ResultMessage resultMessage = makeResultMessage(targetType); + recruitResultMessageRepository.save(resultMessage); + recruitResultMessageRepository.flush(); + GetRecruitmentResultMessagePreviewReqDto req = new GetRecruitmentResultMessagePreviewReqDto(targetType); + String content = objectMapper.writeValueAsString(req); + + //Act + String res = mockMvc.perform(get("/admin/recruitments/result/message/preview?messageType=FAIL") + .header("Authorization", "Bearer " + accessToken) + .contentType("application/json") + .content(content)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + + //Assert + GetRecruitmentResultMessagePreviewResDto resDto = objectMapper.readValue(res, + GetRecruitmentResultMessagePreviewResDto.class); + Assertions.assertThat(resDto.getContent()).isEqualTo(resultMessage.getContent()); + } + + private static ResultMessage makeResultMessage(MessageType targetType) { + return ResultMessage.builder() + .messageType(targetType) + .content("good bye") + .build(); + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/admin/service/RecruitmentAdminServiceTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/admin/service/RecruitmentAdminServiceTest.java new file mode 100644 index 000000000..bcbba3fd9 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/admin/service/RecruitmentAdminServiceTest.java @@ -0,0 +1,101 @@ +package gg.recruit.api.admin.service; + +import static org.mockito.ArgumentMatchers.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; + +import gg.admin.repo.recruit.ApplicationAdminRepository; +import gg.admin.repo.recruit.RecruitmentAdminRepository; +import gg.data.recruit.application.Application; +import gg.data.recruit.application.enums.ApplicationStatus; +import gg.recruit.api.admin.service.param.GetRecruitmentApplicationsParam; +import gg.recruit.api.admin.service.param.UpdateApplicationStatusParam; +import gg.utils.annotation.UnitTest; +import gg.utils.exception.custom.NotExistException; + +@UnitTest +class RecruitmentAdminServiceTest { + @Mock + RecruitmentAdminRepository recruitmentAdminRepository; + @Mock + ApplicationAdminRepository applicationAdminRepository; + @InjectMocks + RecruitmentAdminService recruitmentAdminService; + + @Nested + class UpdateFinalApplicationStatusAndNotification { + @Test + @DisplayName("์ตœ์ข… ๊ฒฐ๊ณผ๊ฐ€ ์•„๋‹Œ ApplicationStatus๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ์‹คํŒจํ•ด์•ผ ํ•œ๋‹ค") + void invalidApplicationStatus() { + //Arrange + List nonFinalStatuses = Arrays.stream(ApplicationStatus.values()) + .filter(status -> !status.isFinal) + .collect(Collectors.toList()); + List invalidDtoList = nonFinalStatuses.stream() + .map((status) -> new UpdateApplicationStatusParam(status, 1L, 1L)) + .collect(Collectors.toList()); + + //Act + //Assert + for (UpdateApplicationStatusParam invalidDto : invalidDtoList) { + Assertions.assertThatThrownBy( + () -> recruitmentAdminService.updateFinalApplicationStatusAndNotification(invalidDto)) + .isInstanceOf(NotExistException.class); + } + } + + @Test + @DisplayName("์ตœ์ข… ๊ฒฐ๊ณผ์ธ ApplicationStatus ๋ฐ ์ •์ƒ์ ์ธ dto ๋“ค์–ด์˜ค๋ฉด ์„ฑ๊ณต") + void validApplicationStatus() { + //Arrange + List finalStatuses = Arrays.stream(ApplicationStatus.values()) + .filter(status -> status.isFinal) + .collect(Collectors.toList()); + List validDtoList = finalStatuses.stream() + .map((status) -> new UpdateApplicationStatusParam(status, 1L, 1L)) + .collect(Collectors.toList()); + Application application = Mockito.mock(Application.class); + + //Act + //Assert + for (UpdateApplicationStatusParam validDto : validDtoList) { + Mockito.when(applicationAdminRepository.findByIdAndRecruitId(eq(validDto.getApplicationId()), + eq(validDto.getRecruitId()))).thenReturn(Optional.of(application)); + recruitmentAdminService.updateFinalApplicationStatusAndNotification(validDto); + } + } + } + + @Nested + @DisplayName("getRecruitmentApplicationsFetchApplicationAnswersWithFilter") + class GetRecruitmentApplicationsFetchApplicationAnswersWithFilter { + @Test + @DisplayName("์กฐํšŒ ์„ฑ๊ณต") + void success() { + //Arrange + Pageable pageable = PageRequest.of(1, 10, Sort.by(new Sort.Order(Sort.Direction.DESC, "id"))); + GetRecruitmentApplicationsParam dto = new GetRecruitmentApplicationsParam(1L, null, new ArrayList<>(), null, + pageable); + recruitmentAdminService.findApplicationsWithAnswersAndUserWithFilter(dto); + + //Act + + //Assert + } + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/admin/service/RecruitmentAdminServiceUnitTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/admin/service/RecruitmentAdminServiceUnitTest.java new file mode 100644 index 000000000..e701ae9ac --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/admin/service/RecruitmentAdminServiceUnitTest.java @@ -0,0 +1,266 @@ +package gg.recruit.api.admin.service; + +import static gg.data.recruit.application.enums.ApplicationStatus.*; +import static org.assertj.core.api.AssertionsForClassTypes.*; +import static org.mockito.BDDMockito.*; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import gg.admin.repo.recruit.ApplicationAdminRepository; +import gg.admin.repo.recruit.RecruitmentAdminRepository; +import gg.admin.repo.recruit.recruitment.RecruitStatusAdminRepository; +import gg.data.recruit.application.Application; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.recruit.recruitment.enums.InputType; +import gg.data.user.User; +import gg.recruit.api.admin.service.param.FormParam; +import gg.recruit.api.admin.service.param.UpdateApplicationStatusParam; +import gg.utils.annotation.UnitTest; +import gg.utils.exception.custom.DuplicationException; +import gg.utils.exception.custom.ForbiddenException; +import gg.utils.exception.custom.NotExistException; + +@UnitTest +class RecruitmentAdminServiceUnitTest { + @InjectMocks + private RecruitmentAdminService recruitmentAdminService; + + @Mock + private RecruitmentAdminRepository recruitmentAdminRepository; + + @Mock + private ApplicationAdminRepository applicationAdminRepository; + + @Mock + private RecruitStatusAdminRepository recruitStatusAdminRepository; + + @Test + @DisplayName("๊ณต๊ณ  ์กฐํšŒ") + void getAllRecruitments() { + // given + Page mock = mock(Page.class); + Pageable mockPageable = mock(Pageable.class); + given(recruitmentAdminRepository.findAllByIsDeletedOrderByEndTimeDesc(false, mockPageable)).willReturn(mock); + + // when + recruitmentAdminService.getAllRecruitments(mockPageable); + + // then + verify(recruitmentAdminRepository, times(1)).findAllByIsDeletedOrderByEndTimeDesc(false, mockPageable); + } + + @Nested + @DisplayName("๊ณต๊ณ  ์ˆ˜์ •") + class UpdateRecruitment { + LocalDateTime start = LocalDateTime.now().plusDays(1); + Long recruitId = 1L; + + @Test + @DisplayName("๊ณต๊ณ  ์ˆ˜์ • ์„ฑ๊ณต") + void updateRecruitment() { + // given + Recruitment target = Recruitment.builder() + .title("before-title") + .contents("before-contents") + .generation("before-5th") + .startTime(start.plusDays(1)) + .endTime(start.plusDays(2)) + .build(); + Recruitment recruitment = Recruitment.builder().title("after-title") + .contents("after-contents") + .generation("after-6th") + .startTime(start.plusDays(2)) + .endTime(start.plusDays(3)) + .build(); + List forms = List.of( + FormParam.builder().question("question").inputType(InputType.TEXT).checkList(List.of()).build()); + given(recruitmentAdminRepository.findById(recruitId)).willReturn(Optional.of(target)); + + // when + recruitmentAdminService.updateRecruitment(recruitId, recruitment, forms); + + // then + verify(recruitmentAdminRepository, times(1)).findById(recruitId); + assertThat(recruitment.getTitle()).isEqualTo(target.getTitle()); + assertThat(recruitment.getContents()).isEqualTo(target.getContents()); + assertThat(recruitment.getGeneration()).isEqualTo(target.getGeneration()); + assertThat(recruitment.getStartTime()).isEqualTo(target.getStartTime()); + assertThat(recruitment.getEndTime()).isEqualTo(target.getEndTime()); + List questions = recruitment.getQuestions(); + List questions1 = target.getQuestions(); + for (int i = 0; i < questions.size(); i++) { + assertThat(questions.get(i).getQuestion()).isEqualTo(questions1.get(i).getQuestion()); + assertThat(questions.get(i).getInputType()).isEqualTo(questions1.get(i).getInputType()); + } + } + + @Test + @DisplayName("๊ณต๊ณ ๊ฐ€ ์ด๋ฏธ ์‹œ์ž‘๋˜์–ด ์ˆ˜์ • ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ Forbidden Exception ๋ฐœ์ƒ") + void updateRecruitmentFail() { + // given + Recruitment pastRecruitment = Recruitment.builder() + .title("after-title") + .contents("after-contents") + .generation("after-5th") + .startTime(LocalDateTime.of(2021, 1, 1, 0, 0)) + .endTime(LocalDateTime.of(2021, 1, 2, 0, 0)) + .build(); + given(recruitmentAdminRepository.findById(recruitId)).willReturn(Optional.of(pastRecruitment)); + Recruitment recruitment = mock(Recruitment.class); + + // when + assertThatThrownBy( + () -> recruitmentAdminService.updateRecruitment(recruitId, recruitment, List.of())) + .isInstanceOf(ForbiddenException.class); + + // then + verify(recruitmentAdminRepository, times(1)).findById(recruitId); + } + + @Test + @DisplayName("๊ณต๊ณ ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•„ ์ˆ˜์ • ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ NotExistException ๋ฐœ์ƒ") + void updateRecruitmentNotExist() { + // given + given(recruitmentAdminRepository.findById(recruitId)).willReturn(Optional.empty()); + Recruitment recruitment = mock(Recruitment.class); + + // when + assertThatThrownBy( + () -> recruitmentAdminService.updateRecruitment(recruitId, recruitment, List.of())) + .isInstanceOf(NotExistException.class); + + // then + verify(recruitmentAdminRepository, times(1)).findById(recruitId); + } + } + + @Nested + @DisplayName("๊ณต๊ณ  ์‚ญ์ œ") + class DeleteRecruitment { + @Test + @DisplayName("๊ณต๊ณ ๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ ์‚ญ์ œ ์„ฑ๊ณต (isDeleted = true)") + void deleteRecruitment() { + // given + Long recruitmentId = 1L; + LocalDateTime date = LocalDateTime.of(2024, 1, 1, 0, 0, 0); + Recruitment recruitment = new Recruitment("title", "contents", "5th", date, date.plusDays(1)); + given(recruitmentAdminRepository.findById(recruitmentId)).willReturn(Optional.of(recruitment)); + + // when + recruitmentAdminService.deleteRecruitment(recruitmentId); + + // then + verify(recruitmentAdminRepository, times(1)).findById(recruitmentId); + assertThat(recruitment.getIsDeleted()).isTrue(); + } + + @Test + @DisplayName("๊ณต๊ณ ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ NotExistException ๋ฐœ์ƒํ•˜๊ณ  ์‚ญ์ œ๋Š” ์‹คํŒจํ•œ๋‹ค.") + void deleteRecruitmentFail() { + // given + Long recruitmentId = 1L; + given(recruitmentAdminRepository.findById(recruitmentId)).willReturn(Optional.empty()); + + // when then + assertThatThrownBy(() -> recruitmentAdminService.deleteRecruitment(recruitmentId)) + .isInstanceOf(NotExistException.class); + + // then + verify(recruitmentAdminRepository, times(1)).findById(recruitmentId); + } + } + + @Nested + @DisplayName("์„œ๋ฅ˜ ์ „ํ˜• ๊ฒฐ๊ณผ ๋“ฑ๋ก ํ…Œ์ŠคํŠธ") + class UpdateFinalApplicationStatusAndNotification { + @Test + @DisplayName("์„œ๋ฅ˜์ „ํ˜• ์ง„ํ–‰์ค‘์ธ ์ง€์›์„œ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ์‹คํŒจ - ForbiddenException") + void invalidApplicationStatus() { + // given + Application application = new Application(mock(User.class), mock(Recruitment.class)); + application.updateApplicationStatus(PROGRESS_INTERVIEW); + UpdateApplicationStatusParam dto = new UpdateApplicationStatusParam(INTERVIEW_FAIL, 1L, 1L); + given( + applicationAdminRepository.findByIdAndRecruitId(dto.getApplicationId(), dto.getRecruitId())) + .willReturn(Optional.of(application)); + + // when, then + assertThatThrownBy(() -> recruitmentAdminService.updateDocumentScreening(dto)) + .isInstanceOf(ForbiddenException.class); + } + + @Test + @DisplayName("์„œ๋ฅ˜์ „ํ˜• ํƒˆ๋ฝ ๋“ฑ๋ก ์„ฑ๊ณต") + void validApplicationStatus() { + // given + Application application = new Application(mock(User.class), mock(Recruitment.class)); + UpdateApplicationStatusParam dto = new UpdateApplicationStatusParam(INTERVIEW_FAIL, 1L, 1L); + given( + applicationAdminRepository.findByIdAndRecruitId(dto.getApplicationId(), dto.getRecruitId())) + .willReturn(Optional.of(application)); + + // when + recruitmentAdminService.updateDocumentScreening(dto); + + // then + verify(applicationAdminRepository, times(1)).findByIdAndRecruitId( + dto.getApplicationId(), dto.getRecruitId()); + assertThat(application.getStatus()).isEqualTo(INTERVIEW_FAIL); + } + + @Test + @DisplayName("๋ฉด์ ‘๋‚ ์งœ ๋“ฑ๋ก ์„ฑ๊ณต") + void validInterviewDate() { + // given + Application application = new Application(mock(User.class), mock(Recruitment.class)); + UpdateApplicationStatusParam dto = new UpdateApplicationStatusParam( + PROGRESS_INTERVIEW, 1L, 1L, LocalDateTime.of(2024, 1, 1, 0, 0, 0)); + given( + applicationAdminRepository.findByIdAndRecruitId(dto.getApplicationId(), dto.getRecruitId())) + .willReturn(Optional.of(application)); + given(recruitStatusAdminRepository.existsByRecruitmentIdAndInterviewDateBetween( + dto.getRecruitId(), dto.getInterviewDate().minusMinutes(30), dto.getInterviewDate().plusMinutes(30))) + .willReturn(false); + + // when + recruitmentAdminService.updateDocumentScreening(dto); + + // then + verify(recruitStatusAdminRepository, times(1)).existsByRecruitmentIdAndInterviewDateBetween( + dto.getRecruitId(), dto.getInterviewDate().minusMinutes(30), dto.getInterviewDate().plusMinutes(30)); + assertThat(application.getStatus()).isEqualTo(PROGRESS_INTERVIEW); + } + + @Test + @DisplayName("๋ฉด์ ‘ ์‹œ๊ฐ„ ์ค‘๋ณต์œผ๋กœ ๋“ฑ๋ก ์‹คํŒจ - DuplicationException") + void invalidInterviewDate() { + // given + Application application = new Application(mock(User.class), mock(Recruitment.class)); + UpdateApplicationStatusParam dto = new UpdateApplicationStatusParam( + PROGRESS_INTERVIEW, 1L, 1L, LocalDateTime.of(2024, 1, 1, 0, 0, 0)); + given( + applicationAdminRepository.findByIdAndRecruitId(dto.getApplicationId(), dto.getRecruitId())) + .willReturn(Optional.of(application)); + given(recruitStatusAdminRepository.existsByRecruitmentIdAndInterviewDateBetween( + dto.getRecruitId(), dto.getInterviewDate().minusMinutes(30), dto.getInterviewDate().plusMinutes(30))) + .willReturn(true); + + // when, then + assertThatThrownBy(() -> recruitmentAdminService.updateDocumentScreening(dto)) + .isInstanceOf(DuplicationException.class); + } + + } + +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/admin/service/RecruitmentResultMessageAdminServiceImplTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/admin/service/RecruitmentResultMessageAdminServiceImplTest.java new file mode 100644 index 000000000..c1beb88d6 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/admin/service/RecruitmentResultMessageAdminServiceImplTest.java @@ -0,0 +1,39 @@ +package gg.recruit.api.admin.service; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import gg.admin.repo.recruit.manage.RecruitResultMessageRepository; +import gg.data.recruit.manage.enums.MessageType; +import gg.recruit.api.admin.service.param.RecruitmentResultMessageParam; +import gg.utils.annotation.UnitTest; + +@UnitTest +class RecruitmentResultMessageAdminServiceImplTest { + @Mock + RecruitResultMessageRepository recruitResultMessageRepository; + + @InjectMocks + RecruitmentResultMessageAdminServiceImpl recruitmentResultMessageAdminService; + + RecruitmentResultMessageParam dto; + + @Nested + @DisplayName("postResultMessage") + class PostResultMessage { + @Test + @DisplayName("์„ฑ๊ณต") + void postResultMessageSuccess() { + //Arrange + dto = new RecruitmentResultMessageParam(MessageType.FAIL, "message"); + + //Act + //Assert + recruitmentResultMessageAdminService.postResultMessage(dto); + + } + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/user/controller/ApplicationControllerTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/user/controller/ApplicationControllerTest.java new file mode 100644 index 000000000..582977360 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/user/controller/ApplicationControllerTest.java @@ -0,0 +1,231 @@ +package gg.recruit.api.user.controller; + +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +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.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.data.recruit.application.Application; +import gg.data.recruit.application.ApplicationAnswer; +import gg.data.recruit.application.enums.ApplicationStatus; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.recruit.recruitment.enums.InputType; +import gg.data.user.User; +import gg.recruit.api.RecruitMockData; +import gg.recruit.api.user.controller.request.CheckListFormRequest; +import gg.recruit.api.user.controller.request.FormPatchRequestDto; +import gg.recruit.api.user.controller.request.FormRequest; +import gg.recruit.api.user.controller.request.RecruitApplyFormListReqDto; +import gg.recruit.api.user.controller.request.RecruitApplyFormReqDto; +import gg.recruit.api.user.controller.request.TextFormRequest; +import gg.recruit.api.user.controller.response.ApplicationResultResDto; +import gg.recruit.api.user.controller.response.MyApplicationsResDto; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@Transactional +@AutoConfigureMockMvc +class ApplicationControllerTest { + + @Autowired + private RecruitMockData recruitMockData; + @Autowired + private TestDataUtils testDataUtils; + @Autowired + private ObjectMapper objectMapper; + @Autowired + private MockMvc mockMvc; + + @Test + @DisplayName("GET /recruitments/applications -> 200 OK TEST") + public void getMyApplicationsTest() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + + Recruitment recruitment = recruitMockData.createRecruitment(); + Recruitment recruitment2 = recruitMockData.createRecruitment(); + Recruitment recruitment3 = recruitMockData.createRecruitment(); + + recruitMockData.createApplication(user, recruitment); + recruitMockData.createApplication(user, recruitment2); + recruitMockData.createApplication(user, recruitment3); + + //when + String res = mockMvc.perform(get(("/recruitments/applications")) + .header("Authorization", "Bearer " + accessToken)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + + //then + MyApplicationsResDto myApplicationsResDto = objectMapper.readValue(res, MyApplicationsResDto.class); + assertEquals(3, myApplicationsResDto.getApplications().size()); + } + + @Test + @DisplayName("POST /recruitments/{recruitmentId}/applications -> 201 CREATED TEST") + void saveApplicationTest() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + + Recruitment recruitment = recruitMockData.createRecruitment(); + Question q1 = recruitMockData.createQuestion(recruitment); + Question q2 = recruitMockData.createQuestion(recruitment); + Question q3 = recruitMockData.createQuestion(recruitment); + + List forms = List.of(new RecruitApplyFormReqDto(q1.getId(), "๋‹ต๋ณ€ 1"), + new RecruitApplyFormReqDto(q2.getId(), "๋‹ต๋ณ€ 2"), + new RecruitApplyFormReqDto(q3.getId(), "๋‹ต๋ณ€ 3")); + RecruitApplyFormListReqDto req = new RecruitApplyFormListReqDto(forms); + String content = objectMapper.writeValueAsString(req); + + //when + String res = mockMvc.perform(post(("/recruitments/" + recruitment.getId() + "/applications")) + .header("Authorization", "Bearer " + accessToken) + .contentType("application/json") + .content(content)) + .andExpect(status().isCreated()).andReturn().getResponse().getContentAsString(); + + //then + } + + @Test + @DisplayName("GET /recruitments/{recruitmentId}/applications/{applicationId}/result -> 200 OK TEST") + public void applicationResApiTest() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + Recruitment recruitment = recruitMockData.createRecruitment(); + Application application = recruitMockData.createApplication(user, recruitment); + recruitMockData.createRecruitStatus(application); + + //when + String url = "/recruitments/" + recruitment.getId() + + "/applications/" + application.getId() + "/result"; + + String res = mockMvc.perform(get(url) + .header("Authorization", "Bearer " + accessToken)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + + ApplicationResultResDto applicationResultResDto = objectMapper + .readValue(res, ApplicationResultResDto.class); + + assertEquals(recruitment.getTitle(), applicationResultResDto.getTitle()); + assertEquals(ApplicationStatus.PROGRESS_DOCS, applicationResultResDto.getStatus()); + } + + @Test + @DisplayName("DELETE /recruitments/{recruitmentId}/applications/{applicationId} -> 204 NO_CONTENT TEST") + void deleteApplicationTest() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + Recruitment recruitment = recruitMockData.createRecruitment(); + Application application = recruitMockData.createApplication(user, recruitment); + + //when + String url = "/recruitments/" + recruitment.getId() + + "/applications/" + application.getId(); + + mockMvc.perform(delete(url) + .header("Authorization", "Bearer " + accessToken)) + .andExpect(status().isNoContent()); + } + + @Test + @DisplayName("DELETE /recruitments/{recruitmentId}/applications/{applicationId} -> 403 FORBIDDEN TEST") + void deleteApplicationForbiddenTest() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + Recruitment recruitment = recruitMockData.createRecruitmentEnd(); + Application application = recruitMockData.createApplication(user, recruitment); + + //when, then + String url = "/recruitments/" + recruitment.getId() + + "/applications/" + application.getId(); + + mockMvc.perform(delete(url) + .header("Authorization", "Bearer " + accessToken)) + .andExpect(status().isForbidden()); + } + + @Test + @DisplayName("DELETE /recruitments/{recruitmentId}/applications/{applicationId} -> 404 NOT_FOUND TEST") + void deleteApplicationNotFoundTest() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + Recruitment recruitment = recruitMockData.createRecruitmentDel(); + Application application = recruitMockData.createApplication(user, recruitment); + + //when, then + String url = "/recruitments/" + recruitment.getId() + + "/applications/" + application.getId() + 1; + + mockMvc.perform(delete(url) + .header("Authorization", "Bearer " + accessToken)) + .andExpect(status().isNotFound()); + } + + @Test + @DisplayName("PATCH /recruitments/{recruitmentId}/applications/{applicationId} -> 204 NO_CONTENT TEST") + void patchApplicationTest() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + Recruitment recruitment = recruitMockData.createRecruitment(); + Question question1 = recruitMockData.createQuestion(recruitment, "์งˆ๋ฌธ 1", InputType.TEXT); + Question question2 = recruitMockData.createQuestion(recruitment, "์งˆ๋ฌธ 2", InputType.SINGLE_CHECK, + "์„ ํƒ์ง€ 1", "์„ ํƒ์ง€ 2"); + + Application application = recruitMockData.createApplication(user, recruitment); + recruitMockData.makeAnswer(application, question1, "๋‹ต๋ณ€ 1"); + recruitMockData.makeAnswer(application, question2, question2.getCheckLists().get(0).getId()); + + //when + List forms = new ArrayList<>(); + String newAnswerText = "์ƒˆ๋กœ์šด ๋‹ต๋ณ€"; + FormRequest newTextForm = new TextFormRequest(question1.getId(), InputType.TEXT, newAnswerText); + forms.add(newTextForm); + FormRequest newCheckListForm = new CheckListFormRequest(question2.getId(), InputType.SINGLE_CHECK, + Collections.singletonList(question2.getCheckLists().get(1).getId())); + forms.add(newCheckListForm); + FormPatchRequestDto requestDto = new FormPatchRequestDto(forms); + String content = objectMapper.writeValueAsString(requestDto); + + String url = "/recruitments/" + recruitment.getId() + + "/applications/" + application.getId(); + mockMvc.perform(patch(url) + .header("Authorization", "Bearer " + accessToken) + .contentType("application/json") + .content(content)) + .andExpect(status().isNoContent()); + + //then + List allAnswers = recruitMockData.getAllAnswers(user.getId(), + recruitment.getId(), application.getId()); + assertEquals(2, allAnswers.size()); + allAnswers.stream().forEach(answer -> { + if (answer.getQuestionId().equals(question1.getId())) { + assertEquals(newAnswerText, answer.getAnswer()); + } else if (answer.getQuestionId().equals(question2.getId())) { + assertEquals(question2.getCheckLists().get(1).getContent(), answer.getAnswer()); + } + }); + } +} diff --git a/gg-recruit-api/src/test/java/gg/recruit/api/user/controller/RecruitmentControllerTest.java b/gg-recruit-api/src/test/java/gg/recruit/api/user/controller/RecruitmentControllerTest.java new file mode 100644 index 000000000..1657a7787 --- /dev/null +++ b/gg-recruit-api/src/test/java/gg/recruit/api/user/controller/RecruitmentControllerTest.java @@ -0,0 +1,111 @@ +package gg.recruit.api.user.controller; + +import static org.assertj.core.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +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.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import gg.data.recruit.application.Application; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.user.User; +import gg.recruit.api.RecruitMockData; +import gg.recruit.api.user.controller.response.ActiveRecruitmentListResDto; +import gg.recruit.api.user.controller.response.RecruitmentDetailResDto; +import gg.utils.TestDataUtils; +import gg.utils.annotation.IntegrationTest; + +@IntegrationTest +@Transactional +@AutoConfigureMockMvc +class RecruitmentControllerTest { + @Autowired + private ObjectMapper objectMapper; + @Autowired + private MockMvc mockMvc; + @Autowired + private RecruitMockData recruitMockData; + @Autowired + private TestDataUtils testDataUtils; + + @Test + @DisplayName("GET /recruitments -> 200 OK TEST") + void findActiveRecruitmentList() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + + Recruitment recruitment = recruitMockData.createRecruitment(); + Recruitment recruitment2 = recruitMockData.createRecruitment(); + Recruitment recruitment3 = recruitMockData.createRecruitment(); + //when + String res = mockMvc.perform(get("/recruitments") + .param("page", "1") + .param("size", "10") + .header("Authorization", "Bearer " + accessToken)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + + //then + ActiveRecruitmentListResDto resDto = objectMapper.readValue(res, ActiveRecruitmentListResDto.class); + assertThat(resDto.getRecruitments().size()).isEqualTo(3); + assertThat(resDto.getTotalPage()).isEqualTo(1); + } + + @Test + @DisplayName("GET /recruitments/{recruitmentId} -> 200 OK TEST") + void findRecruitmentDetail() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + + Recruitment recruitment = recruitMockData.createRecruitment(); + //when + String res = mockMvc.perform(get("/recruitments/" + recruitment.getId()) + .header("Authorization", "Bearer " + accessToken)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + + //then + } + + @Test + @DisplayName("GET /recruitments/{recruitmentId} -> 404 NOT FOUND TEST") + void findRecruitmentDetailDel() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + + Recruitment recruitment = recruitMockData.createRecruitmentDel(); + //when + String res = mockMvc.perform(get("/recruitments/" + recruitment.getId()) + .header("Authorization", "Bearer " + accessToken)) + .andExpect(status().isNotFound()).andReturn().getResponse().getContentAsString(); + + //then + } + + @Test + @DisplayName("GET /recruitments/{recruitmentId} ์ง€์›์„œ id ์กฐํšŒ -> 200 OK TEST") + void findRecruitmentDetailAndApplicationId() throws Exception { + //given + User user = testDataUtils.createNewUser(); + String accessToken = testDataUtils.getLoginAccessTokenFromUser(user); + + Recruitment recruitment = recruitMockData.createRecruitment(); + Application application = recruitMockData.createApplication(user, recruitment); + //when + String result = mockMvc.perform(get("/recruitments/" + recruitment.getId()) + .header("Authorization", "Bearer " + accessToken)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + + //then + RecruitmentDetailResDto res = objectMapper.readValue(result, RecruitmentDetailResDto.class); + assertThat(res.getApplicationId()).isNotNull(); + } +} diff --git a/gg-recruit-api/src/test/resources/application.yml b/gg-recruit-api/src/test/resources/application.yml new file mode 100644 index 000000000..e01be0052 --- /dev/null +++ b/gg-recruit-api/src/test/resources/application.yml @@ -0,0 +1,201 @@ +spring: + application: + name: 42gg + + profiles: + active: testCode + + security: + oauth2.client: + authenticationScheme: header + registration: + 42: + redirect-uri: "{baseUrl}/{action}/oauth2/code/{registrationId}" + authorization-grant-type: authorization_code + scope: public + kakao: + redirect-uri: "{baseUrl}/{action}/oauth2/code/{registrationId}" + authorization-grant-type: authorization_code + scope: profile_nickname, profile_image, account_email + provider: + 42: + authorization-uri: "https://api.intra.42.fr/oauth/authorize" + token-uri: "https://api.intra.42.fr/oauth/token" + user-info-uri: "https://api.intra.42.fr/v2/me" + user-name-attribute: id + kakao: + authorization-uri: "https://kauth.kakao.com/oauth/authorize" + token-uri: "https://kauth.kakao.com/oauth/token" + user-info-uri: "https://kapi.kakao.com/v2/user/me" + user-name-attribute: id + + mvc: + hiddenmethod: + filter: + enabled: true + data: + web: + pageable: + default-page-size: 20 + one-indexed-parameters: false + + mail: + host: smtp.gmail.com + port: 587 + username: dummy + password: dummy + properties: + mail: + smtp: + starttls: + enable: true + required: true + auth: true + + # Message ์„ค์ • + messages: + basename: 'messages/validation' + encoding: UTF-8 + +springdoc: + swagger-ui: + path: /api-docs + default-consumes-media-type: application/json + default-produces-media-type: application/json + +app: + auth: + tokenSecret: authdummydummydummydummydummydummydummydummydummy + refreshTokenSecret: refreshdummydummydummydummydummydummydummydummydummy + +info: + image: + defaultUrl: 'https://42gg-public-test-image.s3.ap-northeast-2.amazonaws.com/images/small_default.jpeg' + itemNotFoundUrl: 'https://42gg-public-test-image.s3.ap-northeast-2.amazonaws.com/images/not_found.svg' + +constant: + allowedMinimalStartDays: 2 + tournamentSchedule: "0 0 0 * * *" + +# -- actuator + +management: + server: + port: 8081 + + info: + java: + enabled: true + os: + enabled: true + env: + enabled: true + + health: + show-details: always + + endpoints: + jmx: + exposure: + exclude: "*" + + web: + exposure: + include: "prometheus" + +server: + tomcat: + mbeanregistry: + enabled: true + +--- +spring.config.activate.on-profile: testCode + +# =========================== LOCAL =========================== +spring: + flyway: + enabled: true + baselineOnMigrate: true + locations: classpath:db/migration + user: root + password: 1234 + + jpa: + database-platform: org.hibernate.dialect.MySQL8Dialect + hibernate: + ddl-auto: validate + properties: + hibernate: + show_sql: true + format_sql: true + use_sql_comments: false + + security: + oauth2.client: + registration: + 42: + client-id: "dummy" + client-secret: "dummy" + kakao: + client-id: "dummy" + client-secret: "dummy" + client-authentication-method: POST + + # Redis ์„ค์ • + cache: + type: redis + +# cors ์„ค์ • +cors: + allowed-origins: 'http://localhost:8080,http://127.0.0.1:8081' + allowed-methods: GET,POST,PUT,DELETE,OPTIONS,PATCH + allowed-headers: '*' + allowed-Credentials: false + max-age: 3600 + +logging-level: + org.hibernate.SQL: debug + org.hibernate.type: trace + +slack: + xoxbToken: "dummy" + +info: + web: + frontUrl: 'http://localhost:8080' + domain: "localhost" + +cloud: + aws: + credentials: + accessKey: dummy + secretKey: dummy + s3: + bucket: 42gg-public-test-image + dir: images/ + region: + static: ap-northeast-2 + stack: + auto: false + +app: + auth: + refreshTokenExpiry: 604800000 + tokenExpiry: 604800000 + + + +--- +spring.config.activate.on-profile: test-mvc + +spring: + security: + oauth2.client: + registration: + 42: + client-id: "dummy" + client-secret: "dummy" + kakao: + client-id: "dummy" + client-secret: "dummy" + client-authentication-method: POST diff --git a/gg-repo/src/main/java/gg/repo/game/GameRepository.java b/gg-repo/src/main/java/gg/repo/game/GameRepository.java index f27d5bc27..c45dadcf7 100644 --- a/gg-repo/src/main/java/gg/repo/game/GameRepository.java +++ b/gg-repo/src/main/java/gg/repo/game/GameRepository.java @@ -14,9 +14,9 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.game.Game; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; import gg.repo.game.out.GameTeamUser; import gg.repo.game.out.GameTeamUserInfo; import gg.repo.game.out.GameUser; diff --git a/gg-repo/src/main/java/gg/repo/game/GameRepositoryCustom.java b/gg-repo/src/main/java/gg/repo/game/GameRepositoryCustom.java index 1b8b7b7dc..57012cb27 100644 --- a/gg-repo/src/main/java/gg/repo/game/GameRepositoryCustom.java +++ b/gg-repo/src/main/java/gg/repo/game/GameRepositoryCustom.java @@ -2,7 +2,7 @@ import java.util.Optional; -import gg.data.game.Game; +import gg.data.pingpong.game.Game; public interface GameRepositoryCustom { Optional getLatestGameByUser(Long userId); diff --git a/gg-repo/src/main/java/gg/repo/game/GameRepositoryImpl.java b/gg-repo/src/main/java/gg/repo/game/GameRepositoryImpl.java index d357d1600..9044556dc 100644 --- a/gg-repo/src/main/java/gg/repo/game/GameRepositoryImpl.java +++ b/gg-repo/src/main/java/gg/repo/game/GameRepositoryImpl.java @@ -5,8 +5,8 @@ import javax.persistence.EntityManager; import javax.persistence.NoResultException; -import gg.data.game.Game; -import gg.data.game.TeamUser; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.TeamUser; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor diff --git a/gg-repo/src/main/java/gg/repo/game/PChangeRepository.java b/gg-repo/src/main/java/gg/repo/game/PChangeRepository.java index a31b85364..ae0b5c434 100644 --- a/gg-repo/src/main/java/gg/repo/game/PChangeRepository.java +++ b/gg-repo/src/main/java/gg/repo/game/PChangeRepository.java @@ -7,8 +7,8 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.game.PChange; -import gg.data.game.type.Mode; +import gg.data.pingpong.game.PChange; +import gg.data.pingpong.game.type.Mode; public interface PChangeRepository extends JpaRepository, PChangeRepositoryCustom { diff --git a/gg-repo/src/main/java/gg/repo/game/PChangeRepositoryCustom.java b/gg-repo/src/main/java/gg/repo/game/PChangeRepositoryCustom.java index a6bb3b1f6..0e82b75a6 100644 --- a/gg-repo/src/main/java/gg/repo/game/PChangeRepositoryCustom.java +++ b/gg-repo/src/main/java/gg/repo/game/PChangeRepositoryCustom.java @@ -2,7 +2,7 @@ import java.util.List; -import gg.data.game.PChange; +import gg.data.pingpong.game.PChange; public interface PChangeRepositoryCustom { List findPChangesHistory(String intraId, Long seasonId); diff --git a/gg-repo/src/main/java/gg/repo/game/PChangeRepositoryImpl.java b/gg-repo/src/main/java/gg/repo/game/PChangeRepositoryImpl.java index 21275f7b3..8f208af67 100644 --- a/gg-repo/src/main/java/gg/repo/game/PChangeRepositoryImpl.java +++ b/gg-repo/src/main/java/gg/repo/game/PChangeRepositoryImpl.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Repository; -import gg.data.game.PChange; +import gg.data.pingpong.game.PChange; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/gg-repo/src/main/java/gg/repo/game/TeamRepository.java b/gg-repo/src/main/java/gg/repo/game/TeamRepository.java index 80e97a020..49a2a9d63 100644 --- a/gg-repo/src/main/java/gg/repo/game/TeamRepository.java +++ b/gg-repo/src/main/java/gg/repo/game/TeamRepository.java @@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.game.Team; +import gg.data.pingpong.game.Team; public interface TeamRepository extends JpaRepository { @Query("select t from Team t where t.game.id=:gameId") diff --git a/gg-repo/src/main/java/gg/repo/game/TeamUserRepository.java b/gg-repo/src/main/java/gg/repo/game/TeamUserRepository.java index ecb568782..bb279716b 100644 --- a/gg-repo/src/main/java/gg/repo/game/TeamUserRepository.java +++ b/gg-repo/src/main/java/gg/repo/game/TeamUserRepository.java @@ -7,7 +7,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.game.TeamUser; +import gg.data.pingpong.game.TeamUser; public interface TeamUserRepository extends JpaRepository { @Query(value = "select team_user.id, team_user.team_id, team_user.user_id from team, team_user " diff --git a/gg-repo/src/main/java/gg/repo/game/out/GameTeamUser.java b/gg-repo/src/main/java/gg/repo/game/out/GameTeamUser.java index 0d4f1a010..2ad5aa371 100644 --- a/gg-repo/src/main/java/gg/repo/game/out/GameTeamUser.java +++ b/gg-repo/src/main/java/gg/repo/game/out/GameTeamUser.java @@ -2,8 +2,8 @@ import java.time.LocalDateTime; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; public interface GameTeamUser { Long getGameId(); diff --git a/gg-repo/src/main/java/gg/repo/game/out/GameTeamUserInfo.java b/gg-repo/src/main/java/gg/repo/game/out/GameTeamUserInfo.java index f12ff0c05..01e59f707 100644 --- a/gg-repo/src/main/java/gg/repo/game/out/GameTeamUserInfo.java +++ b/gg-repo/src/main/java/gg/repo/game/out/GameTeamUserInfo.java @@ -2,8 +2,8 @@ import java.time.LocalDateTime; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; public interface GameTeamUserInfo { Long getGameId(); diff --git a/gg-repo/src/main/java/gg/repo/manage/SlotManagementRepository.java b/gg-repo/src/main/java/gg/repo/manage/SlotManagementRepository.java index 56c72ee9a..a4b016ac9 100644 --- a/gg-repo/src/main/java/gg/repo/manage/SlotManagementRepository.java +++ b/gg-repo/src/main/java/gg/repo/manage/SlotManagementRepository.java @@ -8,7 +8,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.manage.SlotManagement; +import gg.data.pingpong.manage.SlotManagement; public interface SlotManagementRepository extends JpaRepository { diff --git a/gg-repo/src/main/java/gg/repo/match/RedisMatchTimeRepository.java b/gg-repo/src/main/java/gg/repo/match/RedisMatchTimeRepository.java index 7a8d5d0e2..6a877fe14 100644 --- a/gg-repo/src/main/java/gg/repo/match/RedisMatchTimeRepository.java +++ b/gg-repo/src/main/java/gg/repo/match/RedisMatchTimeRepository.java @@ -11,8 +11,8 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Repository; -import gg.data.match.RedisMatchUser; -import gg.data.match.type.MatchKey; +import gg.data.pingpong.match.RedisMatchUser; +import gg.data.pingpong.match.type.MatchKey; import lombok.RequiredArgsConstructor; @Repository @@ -49,5 +49,4 @@ public Set getAllEnrolledStartTimes() { return keys.stream().map(str -> LocalDateTime.parse(str.substring(prefixIdx))) .collect(Collectors.toSet()); } - } diff --git a/gg-repo/src/main/java/gg/repo/match/RedisMatchUserRepository.java b/gg-repo/src/main/java/gg/repo/match/RedisMatchUserRepository.java index c877c6622..91cb50d06 100644 --- a/gg-repo/src/main/java/gg/repo/match/RedisMatchUserRepository.java +++ b/gg-repo/src/main/java/gg/repo/match/RedisMatchUserRepository.java @@ -10,9 +10,9 @@ import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Repository; -import gg.data.match.RedisMatchTime; -import gg.data.match.type.MatchKey; -import gg.data.match.type.Option; +import gg.data.pingpong.match.RedisMatchTime; +import gg.data.pingpong.match.type.MatchKey; +import gg.data.pingpong.match.type.Option; import gg.utils.exception.match.PastSlotException; import lombok.RequiredArgsConstructor; diff --git a/gg-repo/src/main/java/gg/repo/party/CategoryRepository.java b/gg-repo/src/main/java/gg/repo/party/CategoryRepository.java new file mode 100644 index 000000000..7898b50eb --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/party/CategoryRepository.java @@ -0,0 +1,11 @@ +package gg.repo.party; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +import gg.data.party.Category; + +public interface CategoryRepository extends JpaRepository { + Optional findByName(String name); +} diff --git a/gg-repo/src/main/java/gg/repo/party/CommentReportRepository.java b/gg-repo/src/main/java/gg/repo/party/CommentReportRepository.java new file mode 100644 index 000000000..1702f5d3b --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/party/CommentReportRepository.java @@ -0,0 +1,25 @@ +package gg.repo.party; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import gg.data.party.CommentReport; +import gg.data.user.User; + +public interface CommentReportRepository extends JpaRepository { + List findByCommentId(Long commentId); + + Optional findByReporterAndCommentId(User reporter, Long commentId); + + @Query(value = "SELECT cr FROM CommentReport cr " + + "JOIN FETCH cr.reporter " + + "JOIN FETCH cr.comment " + + "JOIN FETCH cr.room", + countQuery = "SELECT count(cr) FROM CommentReport cr") + Page findAllWithCommentReportFetchJoin(Pageable pageable); +} diff --git a/gg-repo/src/main/java/gg/repo/party/CommentRepository.java b/gg-repo/src/main/java/gg/repo/party/CommentRepository.java new file mode 100644 index 000000000..e4a50cb91 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/party/CommentRepository.java @@ -0,0 +1,22 @@ +package gg.repo.party; + +import java.util.List; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.party.Comment; + +public interface CommentRepository extends JpaRepository { + List findByRoomId(Long roomId); + + @Query("SELECT c FROM Comment c " + + "JOIN FETCH c.user " + + "JOIN FETCH c.userRoom " + + "JOIN FETCH c.room r " + + "WHERE r.id = :roomId") + List findAllWithCommentFetchJoin(@Param("roomId") Long roomId); +} diff --git a/gg-repo/src/main/java/gg/repo/party/PartyPenaltyRepository.java b/gg-repo/src/main/java/gg/repo/party/PartyPenaltyRepository.java new file mode 100644 index 000000000..08f0086e3 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/party/PartyPenaltyRepository.java @@ -0,0 +1,23 @@ +package gg.repo.party; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.party.PartyPenalty; + +public interface PartyPenaltyRepository extends JpaRepository { + Optional findTopByUserIdOrderByStartTimeDesc(@Param("userId") Long userId); + + List findAllByUserId(Long userId); + + @Query(value = "SELECT pp FROM PartyPenalty pp " + + "JOIN FETCH pp.user ", + countQuery = "SELECT count(pp) FROM PartyPenalty pp") + Page findUserFetchJoin(Pageable pageable); +} diff --git a/gg-repo/src/main/java/gg/repo/party/RoomReportRepository.java b/gg-repo/src/main/java/gg/repo/party/RoomReportRepository.java new file mode 100644 index 000000000..f6fc670dd --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/party/RoomReportRepository.java @@ -0,0 +1,25 @@ +package gg.repo.party; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import gg.data.party.RoomReport; +import gg.data.user.User; + +public interface RoomReportRepository extends JpaRepository { + List findByRoomId(Long roomId); + + Optional findByReporterAndRoomId(User reporter, Long roomId); + + @Query(value = "SELECT rr FROM RoomReport rr " + + "JOIN FETCH rr.reporter " + + "JOIN FETCH rr.reportee " + + "JOIN FETCH rr.room", + countQuery = "SELECT count(rr) FROM RoomReport rr") + Page findAllWithRoomReportFetchJoin(Pageable pageable); +} diff --git a/gg-repo/src/main/java/gg/repo/party/RoomRepository.java b/gg-repo/src/main/java/gg/repo/party/RoomRepository.java new file mode 100644 index 000000000..fc78636b0 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/party/RoomRepository.java @@ -0,0 +1,25 @@ +package gg.repo.party; + +import java.time.LocalDateTime; +import java.util.List; + +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.party.Room; +import gg.data.party.type.RoomType; + +public interface RoomRepository extends JpaRepository { + + List findByStatus(RoomType status, Sort sort); + + @Query("SELECT r FROM Room r WHERE r.status IN :statuses") + List findByStatusIn(@Param("statuses") List statuses); + + @Query("SELECT r FROM Room r WHERE r.status = :status AND r.startDate < :cutline") + List findByStatusAndStartDate(@Param("status") RoomType status, + @Param("cutline") LocalDateTime cutline); + +} diff --git a/gg-repo/src/main/java/gg/repo/party/TemplateRepository.java b/gg-repo/src/main/java/gg/repo/party/TemplateRepository.java new file mode 100644 index 000000000..3de6e1554 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/party/TemplateRepository.java @@ -0,0 +1,8 @@ +package gg.repo.party; + +import org.springframework.data.jpa.repository.JpaRepository; + +import gg.data.party.GameTemplate; + +public interface TemplateRepository extends JpaRepository { +} diff --git a/gg-repo/src/main/java/gg/repo/party/UserReportRepository.java b/gg-repo/src/main/java/gg/repo/party/UserReportRepository.java new file mode 100644 index 000000000..44606d8b7 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/party/UserReportRepository.java @@ -0,0 +1,29 @@ +package gg.repo.party; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.party.Room; +import gg.data.party.UserReport; +import gg.data.user.User; + +public interface UserReportRepository extends JpaRepository { + Optional findByReporterAndReporteeAndRoom(User reporter, User reportee, Room room); + + @Query("SELECT ur FROM UserReport ur JOIN FETCH ur.reportee " + + "JOIN FETCH ur.room WHERE ur.reportee = :reportee AND ur.room.id = :roomId") + List findByReporteeAndRoomId(@Param("reportee") User reportee, @Param("roomId") Long roomId); + + @Query(value = "SELECT ur FROM UserReport ur " + + "JOIN FETCH ur.reporter " + + "JOIN FETCH ur.reportee " + + "JOIN FETCH ur.room", + countQuery = "SELECT count(ur) FROM UserReport ur") + Page findAllWithUserReportFetchJoin(Pageable pageable); +} diff --git a/gg-repo/src/main/java/gg/repo/party/UserRoomRepository.java b/gg-repo/src/main/java/gg/repo/party/UserRoomRepository.java new file mode 100644 index 000000000..444eafb06 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/party/UserRoomRepository.java @@ -0,0 +1,42 @@ +package gg.repo.party; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.party.Room; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.data.user.User; + +public interface UserRoomRepository extends JpaRepository { + List findByRoomId(Long roomId); + + @Query("SELECT ur FROM UserRoom ur WHERE ur.user.id = :userId AND ur.isExist = true") + List findByUserIdAndIsExistTrue(Long userId); + + @Query("SELECT ur FROM UserRoom ur WHERE ur.room.id = :roomId AND ur.isExist = true") + List findByRoomIdAndIsExistTrue(@Param("roomId") Long roomId); + + @Query("SELECT ur.user FROM UserRoom ur WHERE ur.room.id = :roomId AND ur.isExist = true") + List findByIsExist(@Param("roomId") Long roomId); + + Optional findByUserAndRoom(User user, Room room); + + @Query("SELECT ur.room FROM UserRoom ur WHERE ur.user.id = :userId AND ur.isExist = true " + + "AND ur.room.status = :status") + List findByUserIdAndStatusAndIsExistTrue(@Param("userId") Long userId, @Param("status") RoomType status); + + @Query("SELECT ur.room FROM UserRoom ur WHERE ur.user.id = :userId " + + "AND ur.isExist = true AND ur.room.status = 'OPEN'") + List findOpenRoomsByUserId(@Param("userId") Long userId); + + boolean existsByRoomAndNickname(Room room, String nickname); + + @Query("SELECT ur FROM UserRoom ur JOIN FETCH ur.user " + + "JOIN FETCH ur.room WHERE ur.user.id = :userId AND ur.room.id = :roomId AND ur.isExist = true") + Optional findByUserIdAndRoomIdAndIsExistTrue(@Param("userId") Long userId, @Param("roomId") Long roomId); +} diff --git a/gg-repo/src/main/java/gg/repo/rank/RankRepository.java b/gg-repo/src/main/java/gg/repo/rank/RankRepository.java index 03861c4fa..f087072f6 100644 --- a/gg-repo/src/main/java/gg/repo/rank/RankRepository.java +++ b/gg-repo/src/main/java/gg/repo/rank/RankRepository.java @@ -10,7 +10,7 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import gg.data.rank.Rank; +import gg.data.pingpong.rank.Rank; @Repository public interface RankRepository extends JpaRepository { diff --git a/gg-repo/src/main/java/gg/repo/rank/TierRepository.java b/gg-repo/src/main/java/gg/repo/rank/TierRepository.java index 38ff04a7c..006e4c615 100644 --- a/gg-repo/src/main/java/gg/repo/rank/TierRepository.java +++ b/gg-repo/src/main/java/gg/repo/rank/TierRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import gg.data.rank.Tier; +import gg.data.pingpong.rank.Tier; public interface TierRepository extends JpaRepository { diff --git a/gg-repo/src/main/java/gg/repo/rank/redis/RankRedisRepository.java b/gg-repo/src/main/java/gg/repo/rank/redis/RankRedisRepository.java index 3ded2f8a9..692d7b303 100644 --- a/gg-repo/src/main/java/gg/repo/rank/redis/RankRedisRepository.java +++ b/gg-repo/src/main/java/gg/repo/rank/redis/RankRedisRepository.java @@ -10,7 +10,7 @@ import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Repository; -import gg.data.rank.redis.RankRedis; +import gg.data.pingpong.rank.redis.RankRedis; import gg.utils.exception.rank.RedisDataNotFoundException; @Repository diff --git a/gg-repo/src/main/java/gg/repo/recruit/application/ApplicationAnswerRepository.java b/gg-repo/src/main/java/gg/repo/recruit/application/ApplicationAnswerRepository.java new file mode 100644 index 000000000..07abdf504 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/recruit/application/ApplicationAnswerRepository.java @@ -0,0 +1,27 @@ +package gg.repo.recruit.application; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.recruit.application.ApplicationAnswer; + +public interface ApplicationAnswerRepository extends JpaRepository { + + @Query("SELECT a FROM ApplicationAnswer a JOIN FETCH a.question WHERE a.application.user.id = :userId " + + "AND a.application.recruit.id = :recruitId AND a.application.id = :applicationId order by a.question.sortNum") + List findAllAnswers(@Param("userId") Long userId, + @Param("recruitId") Long recruitId, @Param("applicationId") Long applicationId); + + @Query("SELECT a FROM ApplicationAnswer a WHERE a.application.user.id = :userId " + + "AND a.application.recruit.id = :recruitmentId " + + "AND a.application.id = :applicationId " + + "AND a.question.id IN :questionIds") + List findAllByQuestionIds( + @Param("userId") Long userId, + @Param("applicationId") Long applicationId, + @Param("recruitmentId") Long recruitmentId, + @Param("questionIds") List questionIds); +} diff --git a/gg-repo/src/main/java/gg/repo/recruit/application/ApplicationRepository.java b/gg-repo/src/main/java/gg/repo/recruit/application/ApplicationRepository.java new file mode 100644 index 000000000..ae7a4f1de --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/recruit/application/ApplicationRepository.java @@ -0,0 +1,30 @@ +package gg.repo.recruit.application; + +import java.util.List; +import java.util.Optional; + +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.recruit.application.Application; + +public interface ApplicationRepository extends JpaRepository { + + @EntityGraph(attributePaths = {"recruit"}) + @Query("SELECT a FROM Application a WHERE a.user.id = :userId and a.isDeleted = false") + List findAllByUserId(@Param("userId") Long userId); + + @Query("SELECT a FROM Application a " + + "JOIN FETCH a.recruit r " + + "WHERE a.user.id = :userId and r.id = :recruitId and a.isDeleted = false and r.isDeleted = false") + Optional findByUserIdAndRecruitId(@Param("userId") Long userId, @Param("recruitId") Long recruitId); + + @Query("SELECT a FROM Application a " + + "JOIN FETCH a.recruit r " + + "WHERE a.id = :applicationId and a.user.id = :userId " + + "and r.id = :recruitmentId and a.isDeleted = false and r.isDeleted = false") + Optional findApplication(@Param("applicationId") Long applicationId, @Param("userId") Long userId, + @Param("recruitmentId") Long recruitmentId); +} diff --git a/gg-repo/src/main/java/gg/repo/recruit/application/RecruitStatusRepository.java b/gg-repo/src/main/java/gg/repo/recruit/application/RecruitStatusRepository.java new file mode 100644 index 000000000..45eef7122 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/recruit/application/RecruitStatusRepository.java @@ -0,0 +1,15 @@ +package gg.repo.recruit.application; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.recruit.application.RecruitStatus; + +public interface RecruitStatusRepository extends JpaRepository { + + @Query("SELECT rs FROM RecruitStatus rs WHERE rs.application.id = :applicationId") + Optional findByApplicationId(@Param("applicationId") Long applicationId); +} diff --git a/gg-repo/src/main/java/gg/repo/recruit/recruitment/CheckListRepository.java b/gg-repo/src/main/java/gg/repo/recruit/recruitment/CheckListRepository.java new file mode 100644 index 000000000..8acd795d0 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/recruit/recruitment/CheckListRepository.java @@ -0,0 +1,14 @@ +package gg.repo.recruit.recruitment; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.recruit.recruitment.CheckList; + +public interface CheckListRepository extends JpaRepository { + @Query("SELECT c FROM CheckList c WHERE c.question.id IN :questionIds") + List findAllByQuestionIds(@Param("questionIds") List questionIds); +} diff --git a/gg-repo/src/main/java/gg/repo/recruit/recruitment/QuestionRepository.java b/gg-repo/src/main/java/gg/repo/recruit/recruitment/QuestionRepository.java new file mode 100644 index 000000000..dfdd29b5d --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/recruit/recruitment/QuestionRepository.java @@ -0,0 +1,16 @@ +package gg.repo.recruit.recruitment; + +import java.util.List; + +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.recruit.recruitment.Question; + +public interface QuestionRepository extends JpaRepository { + @EntityGraph(attributePaths = {"checkLists"}) + @Query("SELECT q FROM Question q WHERE q.recruit.id = :recruitId ORDER BY q.sortNum") + List findAllByRecruitId(@Param("recruitId") Long recruitId); +} diff --git a/gg-repo/src/main/java/gg/repo/recruit/recruitment/RecruitmentRepository.java b/gg-repo/src/main/java/gg/repo/recruit/recruitment/RecruitmentRepository.java new file mode 100644 index 000000000..d45f11bea --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/recruit/recruitment/RecruitmentRepository.java @@ -0,0 +1,23 @@ +package gg.repo.recruit.recruitment; + +import java.time.LocalDateTime; +import java.util.Optional; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import gg.data.recruit.recruitment.Recruitment; + +public interface RecruitmentRepository extends JpaRepository, RecruitmentRepositoryCustom { + @Query("SELECT r FROM Recruitment r " + + "WHERE r.isDeleted = false AND r.startTime <= :date AND r.isFinish = false " + + "ORDER BY r.startTime DESC") + Page findActiveRecruitmentList(@Param("date") LocalDateTime date, Pageable pageable); + + @Query("SELECT r FROM Recruitment r " + + "WHERE r.id = :recruitId AND r.startTime <= :date AND r.isDeleted = false AND r.isFinish = false") + Optional findByActiveRecruit(@Param("recruitId") Long recruitId, @Param("date") LocalDateTime date); +} diff --git a/gg-repo/src/main/java/gg/repo/recruit/recruitment/RecruitmentRepositoryCustom.java b/gg-repo/src/main/java/gg/repo/recruit/recruitment/RecruitmentRepositoryCustom.java new file mode 100644 index 000000000..6e0364f15 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/recruit/recruitment/RecruitmentRepositoryCustom.java @@ -0,0 +1,5 @@ +package gg.repo.recruit.recruitment; + +public interface RecruitmentRepositoryCustom { + +} diff --git a/gg-repo/src/main/java/gg/repo/recruit/recruitment/RecruitmentRepositoryCustomImpl.java b/gg-repo/src/main/java/gg/repo/recruit/recruitment/RecruitmentRepositoryCustomImpl.java new file mode 100644 index 000000000..062b41fe7 --- /dev/null +++ b/gg-repo/src/main/java/gg/repo/recruit/recruitment/RecruitmentRepositoryCustomImpl.java @@ -0,0 +1,12 @@ +package gg.repo.recruit.recruitment; + +import javax.persistence.EntityManager; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class RecruitmentRepositoryCustomImpl implements RecruitmentRepositoryCustom { + + private final EntityManager em; + +} diff --git a/gg-repo/src/main/java/gg/repo/season/SeasonRepository.java b/gg-repo/src/main/java/gg/repo/season/SeasonRepository.java index bae4dda42..7f00909e8 100644 --- a/gg-repo/src/main/java/gg/repo/season/SeasonRepository.java +++ b/gg-repo/src/main/java/gg/repo/season/SeasonRepository.java @@ -8,7 +8,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.season.Season; +import gg.data.pingpong.season.Season; public interface SeasonRepository extends JpaRepository { @Query("select s from Season s where s.startTime <= :now and s.endTime >= :now") diff --git a/gg-repo/src/main/java/gg/repo/store/CoinHistoryRepository.java b/gg-repo/src/main/java/gg/repo/store/CoinHistoryRepository.java index f287cf29e..5b0173cb2 100644 --- a/gg-repo/src/main/java/gg/repo/store/CoinHistoryRepository.java +++ b/gg-repo/src/main/java/gg/repo/store/CoinHistoryRepository.java @@ -10,7 +10,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.store.CoinHistory; +import gg.data.pingpong.store.CoinHistory; import gg.data.user.User; public interface CoinHistoryRepository extends JpaRepository { diff --git a/gg-repo/src/main/java/gg/repo/store/CoinPolicyRepository.java b/gg-repo/src/main/java/gg/repo/store/CoinPolicyRepository.java index 217852559..1a8e281d8 100644 --- a/gg-repo/src/main/java/gg/repo/store/CoinPolicyRepository.java +++ b/gg-repo/src/main/java/gg/repo/store/CoinPolicyRepository.java @@ -4,7 +4,7 @@ import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.store.CoinPolicy; +import gg.data.pingpong.store.CoinPolicy; public interface CoinPolicyRepository extends JpaRepository { Optional findTopByOrderByCreatedAtDesc(); diff --git a/gg-repo/src/main/java/gg/repo/store/ItemRepository.java b/gg-repo/src/main/java/gg/repo/store/ItemRepository.java index 74ace3772..2b2f764df 100644 --- a/gg-repo/src/main/java/gg/repo/store/ItemRepository.java +++ b/gg-repo/src/main/java/gg/repo/store/ItemRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import gg.data.store.Item; +import gg.data.pingpong.store.Item; public interface ItemRepository extends JpaRepository { @Query("SELECT i FROM Item i WHERE i.isVisible = true ORDER BY i.createdAt DESC") diff --git a/gg-repo/src/main/java/gg/repo/store/MegaphoneRepository.java b/gg-repo/src/main/java/gg/repo/store/MegaphoneRepository.java index d54128bcb..dfe6c60ae 100644 --- a/gg-repo/src/main/java/gg/repo/store/MegaphoneRepository.java +++ b/gg-repo/src/main/java/gg/repo/store/MegaphoneRepository.java @@ -6,9 +6,9 @@ import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.store.Megaphone; -import gg.data.store.Receipt; -import gg.data.store.type.ItemStatus; +import gg.data.pingpong.store.Megaphone; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.type.ItemStatus; public interface MegaphoneRepository extends JpaRepository { List findAllByUsedAtAndReceiptStatus(LocalDate date, ItemStatus itemStatus); diff --git a/gg-repo/src/main/java/gg/repo/store/ReceiptRepository.java b/gg-repo/src/main/java/gg/repo/store/ReceiptRepository.java index 87f43cd60..a3d757e77 100644 --- a/gg-repo/src/main/java/gg/repo/store/ReceiptRepository.java +++ b/gg-repo/src/main/java/gg/repo/store/ReceiptRepository.java @@ -2,7 +2,7 @@ import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.store.Receipt; +import gg.data.pingpong.store.Receipt; public interface ReceiptRepository extends JpaRepository { } diff --git a/gg-repo/src/main/java/gg/repo/store/UserItemRepository.java b/gg-repo/src/main/java/gg/repo/store/UserItemRepository.java index 2d5a9830b..4231ace5b 100644 --- a/gg-repo/src/main/java/gg/repo/store/UserItemRepository.java +++ b/gg-repo/src/main/java/gg/repo/store/UserItemRepository.java @@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.store.Receipt; +import gg.data.pingpong.store.Receipt; public interface UserItemRepository extends JpaRepository { diff --git a/gg-repo/src/main/java/gg/repo/tournarment/TournamentGameRepository.java b/gg-repo/src/main/java/gg/repo/tournarment/TournamentGameRepository.java index beb1da482..b45514e7d 100644 --- a/gg-repo/src/main/java/gg/repo/tournarment/TournamentGameRepository.java +++ b/gg-repo/src/main/java/gg/repo/tournarment/TournamentGameRepository.java @@ -5,8 +5,8 @@ import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.type.TournamentRound; public interface TournamentGameRepository extends JpaRepository { List findAllByTournamentId(Long tournamentId); diff --git a/gg-repo/src/main/java/gg/repo/tournarment/TournamentRepository.java b/gg-repo/src/main/java/gg/repo/tournarment/TournamentRepository.java index 852d3d1bd..10e7b8e4d 100644 --- a/gg-repo/src/main/java/gg/repo/tournarment/TournamentRepository.java +++ b/gg-repo/src/main/java/gg/repo/tournarment/TournamentRepository.java @@ -12,9 +12,9 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import gg.data.tournament.Tournament; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; public interface TournamentRepository extends JpaRepository { List findAllByStatusIsNot(TournamentStatus status); diff --git a/gg-repo/src/main/java/gg/repo/tournarment/TournamentUserRepository.java b/gg-repo/src/main/java/gg/repo/tournarment/TournamentUserRepository.java index 5482c2279..7fb166fe7 100644 --- a/gg-repo/src/main/java/gg/repo/tournarment/TournamentUserRepository.java +++ b/gg-repo/src/main/java/gg/repo/tournarment/TournamentUserRepository.java @@ -5,8 +5,8 @@ import org.springframework.data.jpa.repository.JpaRepository; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentUser; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentUser; import gg.data.user.User; public interface TournamentUserRepository extends JpaRepository { diff --git a/gg-utils/build.gradle b/gg-utils/build.gradle index 5f95eb653..3c6d27f6b 100644 --- a/gg-utils/build.gradle +++ b/gg-utils/build.gradle @@ -47,7 +47,8 @@ integrationTestCoverageReport { getClassDirectories().setFrom(files( [project(':gg-data'), project(':gg-admin-repo'), - project(':gg-repo'), project(':gg-pingpong-api')].collect { + project(':gg-repo'), project(':gg-pingpong-api'), + project(':gg-auth'), project(':gg-utils')].collect { it.fileTree(dir: "${it.buildDir}/classes/java/main", exclude: jacocoExcludes) } )) @@ -63,7 +64,8 @@ unitTestCoverageReport { getClassDirectories().setFrom(files( [project(':gg-data'), project(':gg-admin-repo'), - project(':gg-repo'), project(':gg-pingpong-api')].collect { + project(':gg-repo'), project(':gg-pingpong-api'), + project(':gg-auth'), project(':gg-utils')].collect { it.fileTree(dir: "${it.buildDir}/classes/java/main", exclude: jacocoExcludes) } )) @@ -88,14 +90,18 @@ dependencies { testFixturesAnnotationProcessor("org.projectlombok:lombok") testFixturesImplementation project(":gg-data") + testFixturesImplementation project(":gg-auth") testFixturesImplementation project(":gg-repo") testFixturesImplementation project(":gg-admin-repo") testFixturesImplementation project(":gg-pingpong-api") + testFixturesImplementation project(":gg-recruit-api") jacocoAggregation(project(':gg-data')) + jacocoAggregation(project(':gg-auth')) jacocoAggregation(project(':gg-repo')) jacocoAggregation(project(':gg-admin-repo')) jacocoAggregation(project(':gg-pingpong-api')) + jacocoAggregation(project(':gg-recruit-api')) } test { diff --git a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/dto/PageRequestDto.java b/gg-utils/src/main/java/gg/utils/dto/PageRequestDto.java similarity index 94% rename from gg-pingpong-api/src/main/java/gg/pingpong/api/global/dto/PageRequestDto.java rename to gg-utils/src/main/java/gg/utils/dto/PageRequestDto.java index 868992210..a39ec103b 100644 --- a/gg-pingpong-api/src/main/java/gg/pingpong/api/global/dto/PageRequestDto.java +++ b/gg-utils/src/main/java/gg/utils/dto/PageRequestDto.java @@ -1,4 +1,4 @@ -package gg.pingpong.api.global.dto; +package gg.utils.dto; import javax.validation.constraints.Max; import javax.validation.constraints.Min; @@ -10,7 +10,6 @@ @Getter @Setter public class PageRequestDto { - @Min(value = 1, message = "page must be greater than 0") @NotNull(message = "page ๋Š” ํ•„์ˆ˜ ๊ฐ’์ž…๋‹ˆ๋‹ค.") private Integer page; diff --git a/gg-utils/src/main/java/gg/utils/exception/ErrorCode.java b/gg-utils/src/main/java/gg/utils/exception/ErrorCode.java index 72b0fa6d3..5e10f5628 100644 --- a/gg-utils/src/main/java/gg/utils/exception/ErrorCode.java +++ b/gg-utils/src/main/java/gg/utils/exception/ErrorCode.java @@ -7,6 +7,7 @@ @Getter public enum ErrorCode { //common + BUSINESS_EXCEPTION(500, "CM100", "BUSINESS ERROR"), NULL_POINT(500, "G100", "NULL POINT EXCEPTION"), //user @@ -67,12 +68,16 @@ public enum ErrorCode { MEGAPHONE_TIME(400, "ME200", "MEGAPHONE TIME"), MEGAPHONE_CONTENT(400, "ME201", "MEGAPHONE CONTENT IS EMPTY"), - /** Penalty **/ + /** + * Penalty + **/ PENALTY_NOT_FOUND(404, "PE100", "PENALTY NOT FOUND"), REDIS_PENALTY_USER_NOT_FOUND(404, "PE101", "REDIS PENALTY USER NOT FOUND"), PENALTY_EXPIRED(400, "PE200", "PENALTY EXPIRED"), - /** team **/ + /** + * team + **/ TEAM_ID_NOT_MATCH(400, "TM201", "TEAM id ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."), TEAM_DUPLICATION(409, "TM202", "์ค‘๋ณต๋œ Team ์ด ํ•œ Game ์— ์กด์žฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."), TEAM_SIZE_EXCEED(500, "TM203", "๊ฒŒ์ž„ ์ตœ๋Œ€ Team ์˜ ์ˆ˜(2)๋ฅผ ์ดˆ๊ณผํ•˜์˜€์Šต๋‹ˆ๋‹ค."), @@ -87,7 +92,9 @@ public enum ErrorCode { TEAM_USER_EXCEED(500, "TU202", "TeamUser ์ตœ๋Œ€ ์ธ์›์˜ ์ˆ˜(2)๋ฅผ ์ดˆ๊ณผํ•˜์˜€์Šต๋‹ˆ๋‹ค."), TEAM_USER_NOT_FOUND(404, "TU203", "TeamUser๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค."), - /** game **/ + /** + * game + **/ GAME_DB_NOT_VALID(500, "GM201", "GAME DB NOT CONSISTENCY"), SCORE_NOT_MATCHED(400, "GM202", "score ์ž…๋ ฅ์ด ๊ธฐ์กด๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค."), GAME_NOT_FOUND(404, "GM101", "GAME ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."), @@ -98,7 +105,9 @@ public enum ErrorCode { SCORE_NOT_INVALID(400, "GM205", "score ์ž…๋ ฅ์ด ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."), GAME_NOT_TOURNAMENT(400, "GM206", "ํ† ๋„ˆ๋จผํŠธ ๊ฒŒ์ž„์ด ์•„๋‹™๋‹ˆ๋‹ค."), - /** match **/ + /** + * match + **/ SLOT_ENROLLED(400, "MA300", "SLOT ALREADY ENROLLED"), SLOT_COUNT_EXCEEDED(400, "MA301", "SLOT COUNT MORE THAN THREE"), SLOT_NOT_FOUND(404, "MA100", "SLOT NOT FOUND"), @@ -106,7 +115,9 @@ public enum ErrorCode { SLOT_PAST(400, "MA303", "PAST SLOT ENROLLED"), MODE_INVALID(400, "MA200", "MODE INVALID"), - /** Common **/ + /** + * Common + **/ INTERNAL_SERVER_ERR(500, "CM001", "INTERNAL SERVER ERROR"), NOT_FOUND(404, "CM002", "NOT FOUND"), BAD_REQUEST(400, "CM003", "BAD REQUEST"), @@ -116,6 +127,8 @@ public enum ErrorCode { VALID_FAILED(400, "CM007", "Valid Test Failed."), BAD_ARGU(400, "ARGUMENT-ERR-400", "์ž˜๋ชป๋œ argument ์ž…๋‹ˆ๋‹ค."), UNREADABLE_HTTP_MESSAGE(400, "CM008", "์œ ํšจํ•˜์ง€ ์•Š์€ HTTP ๋ฉ”์‹œ์ง€์ž…๋‹ˆ๋‹ค."), + CONFLICT(409, "CM009", "CONFLICT"), + FORBIDDEN(403, "CM010", "์ ‘๊ทผ์ด ๊ธˆ์ง€๋œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค."), //Feedback FEEDBACK_NOT_FOUND(404, "FB100", "FB NOT FOUND"), @@ -151,7 +164,32 @@ public enum ErrorCode { TOURNAMENT_GAME_DUPLICATION(409, "TN014", "์ค‘๋ณต๋œ ํ† ๋„ˆ๋จผํŠธ ๊ฒŒ์ž„์ž…๋‹ˆ๋‹ค!"), TOURNAMENT_USER_DUPLICATION(409, "TN015", "์ค‘๋ณต๋œ ํ† ๋„ˆ๋จผํŠธ ์œ ์ €์ž…๋‹ˆ๋‹ค!"), TOURNAMENT_GAME_EXCEED(500, "TN016", "ํ† ๋„ˆ๋จผํŠธ ๊ฒŒ์ž„ ์ตœ๋Œ€ ์‚ฌ์ด์ฆˆ๋ฅผ ์ดˆ๊ณผํ•˜์˜€์Šต๋‹ˆ๋‹ค!"), - TOURNAMENT_IS_BEFORE(403, "TN017", "before์ธ ํ† ๋„ˆ๋จผํŠธ์—์„œ ์ ์ˆ˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."); + TOURNAMENT_IS_BEFORE(403, "TN017", "before์ธ ํ† ๋„ˆ๋จผํŠธ์—์„œ ์ ์ˆ˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."), + + // Party + CATEGORY_NOT_FOUND(404, "PT101", "์œ ํšจํ•˜์ง€ ์•Š์€ ์นดํ…Œ๊ณ ๋ฆฌ ์ž…๋‹ˆ๋‹ค."), + ROOM_NOT_FOUND(404, "PT102", "์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ฐฉ ์ž…๋‹ˆ๋‹ค."), + ROOM_REPORTED_ERROR(404, "PT103", "์‹ ๊ณ  ์ƒํƒœ๋กœ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค."), + COMMENT_NOT_FOUND(404, "PT104", "์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋Œ“๊ธ€์ž…๋‹ˆ๋‹ค."), + ROOMSTAT_NOT_FOUND(404, "PT105", "์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ฐฉ status์ž…๋‹ˆ๋‹ค."), + TEMPLATE_NOT_FOUND(404, "PT106", "์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ…œํ”Œ๋ฆฟ ์ž…๋‹ˆ๋‹ค."), + PARTY_PENALTY_NOT_FOUND(404, "PT107", "์กด์žฌํ•˜์ง€ ์•Š๋Š” Party Penalty ์ž…๋‹ˆ๋‹ค."), + ROOM_NOT_ENOUGH_PEOPLE(400, "PT201", "์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ์ธ์›์ด ์•„๋‹™๋‹ˆ๋‹ค."), + DEFAULT_CATEGORY_NEED(400, "PT202", "๊ธฐ๋ณธ ์นดํ…Œ๊ณ ๋ฆฌ๊ฐ€ ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค."), + USER_NOT_HOST(400, "PT203", "๋ฐฉ์žฅ์ด ์•„๋‹™๋‹ˆ๋‹ค"), + ROOM_NOT_OPEN(400, "PT204", "๋ชจ์ง‘์ค‘์ธ ๋ฐฉ์ด ์•„๋‹™๋‹ˆ๋‹ค."), + ROOM_NOT_PARTICIPANT(400, "PT205", "์ฐธ์—ฌํ•˜์ง€ ์•Š์€ ๋ฐฉ ์ž…๋‹ˆ๋‹ค."), + ROOM_MIN_MAX_PEOPLE(400, "PT206", "์ตœ์†Œ์ธ์›์ด ์ตœ๋Œ€์ธ์›๋ณด๋‹ค ํฝ๋‹ˆ๋‹ค."), + SELF_REPORT(400, "PT207", "์ž์‹ ์„ ์‹ ๊ณ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."), + USER_ALREADY_IN_ROOM(409, "PT301", "์ด๋ฏธ ์ฐธ์—ฌํ•œ ๋ฐฉ ์ž…๋‹ˆ๋‹ค."), + ALREADY_REPORTED(409, "PT302", "์ด๋ฏธ ์‹ ๊ณ ํ•œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค."), + CATEGORY_DUPLICATE(409, "PT304", "์ค‘๋ณต๋œ ์นดํ…Œ๊ณ ๋ฆฌ ์ž…๋‹ˆ๋‹ค."), + CHANGE_SAME_STATUS(409, "PT305", "๋ฐ”๊พธ๋ ค๋Š” ํ•ญ๋ชฉ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค."), + ON_PENALTY(403, "PT501", "ํŒจ๋„ํ‹ฐ ์ƒํƒœ์ž…๋‹ˆ๋‹ค."), + + // recruitment + INVALID_CHECKLIST(400, "RE001", "์ž˜๋ชป๋œ ์š”์ฒญ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค."); + private final int status; private final String errCode; private String message; diff --git a/gg-utils/src/main/java/gg/utils/exception/custom/DuplicationException.java b/gg-utils/src/main/java/gg/utils/exception/custom/DuplicationException.java index 7d3591af2..0fc4c5861 100644 --- a/gg-utils/src/main/java/gg/utils/exception/custom/DuplicationException.java +++ b/gg-utils/src/main/java/gg/utils/exception/custom/DuplicationException.java @@ -6,4 +6,8 @@ public class DuplicationException extends CustomRuntimeException { public DuplicationException(String message, ErrorCode errorCode) { super(message, errorCode); } + + public DuplicationException(String message) { + super(message, ErrorCode.CONFLICT); + } } diff --git a/gg-utils/src/main/java/gg/utils/exception/custom/ForbiddenException.java b/gg-utils/src/main/java/gg/utils/exception/custom/ForbiddenException.java index b9ff7b742..f31592bd4 100644 --- a/gg-utils/src/main/java/gg/utils/exception/custom/ForbiddenException.java +++ b/gg-utils/src/main/java/gg/utils/exception/custom/ForbiddenException.java @@ -6,4 +6,8 @@ public class ForbiddenException extends CustomRuntimeException { public ForbiddenException(String message, ErrorCode errorCode) { super(message, errorCode); } + + public ForbiddenException(String message) { + super(message, ErrorCode.FORBIDDEN); + } } diff --git a/gg-utils/src/main/java/gg/utils/exception/custom/NotExistException.java b/gg-utils/src/main/java/gg/utils/exception/custom/NotExistException.java index efbf33b5e..8255e9873 100644 --- a/gg-utils/src/main/java/gg/utils/exception/custom/NotExistException.java +++ b/gg-utils/src/main/java/gg/utils/exception/custom/NotExistException.java @@ -8,4 +8,8 @@ public class NotExistException extends CustomRuntimeException { public NotExistException(String message, ErrorCode errorCode) { super(message, errorCode); } + + public NotExistException(String message) { + super(message, ErrorCode.NOT_FOUND); + } } diff --git a/gg-utils/src/main/java/gg/utils/exception/party/AlreadyReportedException.java b/gg-utils/src/main/java/gg/utils/exception/party/AlreadyReportedException.java new file mode 100644 index 000000000..493717beb --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/AlreadyReportedException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.DuplicationException; + +public class AlreadyReportedException extends DuplicationException { + public AlreadyReportedException() { + super(ErrorCode.ALREADY_REPORTED.getMessage(), ErrorCode.ALREADY_REPORTED); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/CategoryDuplicateException.java b/gg-utils/src/main/java/gg/utils/exception/party/CategoryDuplicateException.java new file mode 100644 index 000000000..a49264b20 --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/CategoryDuplicateException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.DuplicationException; + +public class CategoryDuplicateException extends DuplicationException { + public CategoryDuplicateException() { + super(ErrorCode.CATEGORY_DUPLICATE.getMessage(), ErrorCode.CATEGORY_DUPLICATE); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/CategoryNotFoundException.java b/gg-utils/src/main/java/gg/utils/exception/party/CategoryNotFoundException.java new file mode 100644 index 000000000..940b46399 --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/CategoryNotFoundException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.NotExistException; + +public class CategoryNotFoundException extends NotExistException { + public CategoryNotFoundException() { + super(ErrorCode.CATEGORY_NOT_FOUND.getMessage(), ErrorCode.CATEGORY_NOT_FOUND); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/ChangeSameStatusException.java b/gg-utils/src/main/java/gg/utils/exception/party/ChangeSameStatusException.java new file mode 100644 index 000000000..3c5a61a5c --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/ChangeSameStatusException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.DuplicationException; + +public class ChangeSameStatusException extends DuplicationException { + public ChangeSameStatusException() { + super(ErrorCode.CHANGE_SAME_STATUS.getMessage(), ErrorCode.CHANGE_SAME_STATUS); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/CommentNotFoundException.java b/gg-utils/src/main/java/gg/utils/exception/party/CommentNotFoundException.java new file mode 100644 index 000000000..12d2238a4 --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/CommentNotFoundException.java @@ -0,0 +1,11 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.NotExistException; + +public class CommentNotFoundException extends NotExistException { + public CommentNotFoundException() { + super(ErrorCode.COMMENT_NOT_FOUND.getMessage(), ErrorCode.COMMENT_NOT_FOUND); + } + +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/DefaultCategoryNeedException.java b/gg-utils/src/main/java/gg/utils/exception/party/DefaultCategoryNeedException.java new file mode 100644 index 000000000..fb7d17244 --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/DefaultCategoryNeedException.java @@ -0,0 +1,12 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.BusinessException; + +public class DefaultCategoryNeedException extends BusinessException { + public static final String DEFAULT_CATEGORY_NAME = "๊ธฐํƒ€"; + + public DefaultCategoryNeedException() { + super(ErrorCode.DEFAULT_CATEGORY_NEED.getMessage(), ErrorCode.DEFAULT_CATEGORY_NEED); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/OnPenaltyException.java b/gg-utils/src/main/java/gg/utils/exception/party/OnPenaltyException.java new file mode 100644 index 000000000..f2d92fa68 --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/OnPenaltyException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.ForbiddenException; + +public class OnPenaltyException extends ForbiddenException { + public OnPenaltyException() { + super(ErrorCode.ON_PENALTY.getMessage(), ErrorCode.ON_PENALTY); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/PartyPenaltyNotFoundException.java b/gg-utils/src/main/java/gg/utils/exception/party/PartyPenaltyNotFoundException.java new file mode 100644 index 000000000..dc5e424ff --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/PartyPenaltyNotFoundException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.NotExistException; + +public class PartyPenaltyNotFoundException extends NotExistException { + public PartyPenaltyNotFoundException() { + super(ErrorCode.PARTY_PENALTY_NOT_FOUND.getMessage(), ErrorCode.PARTY_PENALTY_NOT_FOUND); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/RoomMinMaxPeople.java b/gg-utils/src/main/java/gg/utils/exception/party/RoomMinMaxPeople.java new file mode 100644 index 000000000..1d7a6290b --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/RoomMinMaxPeople.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.InvalidParameterException; + +public class RoomMinMaxPeople extends InvalidParameterException { + public RoomMinMaxPeople(ErrorCode errorCode) { + super(ErrorCode.ROOM_MIN_MAX_PEOPLE.getMessage(), ErrorCode.ROOM_MIN_MAX_PEOPLE); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/RoomNotEnoughPeopleException.java b/gg-utils/src/main/java/gg/utils/exception/party/RoomNotEnoughPeopleException.java new file mode 100644 index 000000000..67dce4d6c --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/RoomNotEnoughPeopleException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.BusinessException; + +public class RoomNotEnoughPeopleException extends BusinessException { + public RoomNotEnoughPeopleException() { + super(ErrorCode.ROOM_NOT_ENOUGH_PEOPLE.getMessage(), ErrorCode.ROOM_NOT_ENOUGH_PEOPLE); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/RoomNotFoundException.java b/gg-utils/src/main/java/gg/utils/exception/party/RoomNotFoundException.java new file mode 100644 index 000000000..c5c5e52cc --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/RoomNotFoundException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.NotExistException; + +public class RoomNotFoundException extends NotExistException { + public RoomNotFoundException() { + super(ErrorCode.ROOM_NOT_FOUND.getMessage(), ErrorCode.ROOM_NOT_FOUND); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/RoomNotOpenException.java b/gg-utils/src/main/java/gg/utils/exception/party/RoomNotOpenException.java new file mode 100644 index 000000000..38f2e0ea6 --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/RoomNotOpenException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.BusinessException; + +public class RoomNotOpenException extends BusinessException { + public RoomNotOpenException() { + super(ErrorCode.ROOM_NOT_OPEN.getMessage(), ErrorCode.ROOM_NOT_OPEN); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/RoomNotParticipantException.java b/gg-utils/src/main/java/gg/utils/exception/party/RoomNotParticipantException.java new file mode 100644 index 000000000..636f7870b --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/RoomNotParticipantException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.BusinessException; + +public class RoomNotParticipantException extends BusinessException { + public RoomNotParticipantException() { + super(ErrorCode.ROOM_NOT_PARTICIPANT.getMessage(), ErrorCode.ROOM_NOT_PARTICIPANT); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/RoomReportedException.java b/gg-utils/src/main/java/gg/utils/exception/party/RoomReportedException.java new file mode 100644 index 000000000..c63635e5f --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/RoomReportedException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.NotExistException; + +public class RoomReportedException extends NotExistException { + public RoomReportedException() { + super(ErrorCode.ROOM_REPORTED_ERROR.getMessage(), ErrorCode.ROOM_REPORTED_ERROR); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/RoomStatNotFoundException.java b/gg-utils/src/main/java/gg/utils/exception/party/RoomStatNotFoundException.java new file mode 100644 index 000000000..76df7c7be --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/RoomStatNotFoundException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.NotExistException; + +public class RoomStatNotFoundException extends NotExistException { + public RoomStatNotFoundException() { + super(ErrorCode.ROOMSTAT_NOT_FOUND.getMessage(), ErrorCode.ROOMSTAT_NOT_FOUND); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/SelfReportException.java b/gg-utils/src/main/java/gg/utils/exception/party/SelfReportException.java new file mode 100644 index 000000000..2b1dbd68d --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/SelfReportException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.BusinessException; + +public class SelfReportException extends BusinessException { + public SelfReportException() { + super(ErrorCode.SELF_REPORT.getMessage(), ErrorCode.SELF_REPORT); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/TemplateNotFoundException.java b/gg-utils/src/main/java/gg/utils/exception/party/TemplateNotFoundException.java new file mode 100644 index 000000000..bb03289ad --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/TemplateNotFoundException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.NotExistException; + +public class TemplateNotFoundException extends NotExistException { + public TemplateNotFoundException() { + super(ErrorCode.TEMPLATE_NOT_FOUND.getMessage(), ErrorCode.TEMPLATE_NOT_FOUND); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/UserAlreadyInRoom.java b/gg-utils/src/main/java/gg/utils/exception/party/UserAlreadyInRoom.java new file mode 100644 index 000000000..9a8f514ab --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/UserAlreadyInRoom.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.DuplicationException; + +public class UserAlreadyInRoom extends DuplicationException { + public UserAlreadyInRoom(ErrorCode errorCode) { + super(ErrorCode.USER_ALREADY_IN_ROOM.getMessage(), ErrorCode.USER_ALREADY_IN_ROOM); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/party/UserNotHostException.java b/gg-utils/src/main/java/gg/utils/exception/party/UserNotHostException.java new file mode 100644 index 000000000..97a6cb8cc --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/party/UserNotHostException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.party; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.ForbiddenException; + +public class UserNotHostException extends ForbiddenException { + public UserNotHostException() { + super(ErrorCode.USER_NOT_HOST.getMessage(), ErrorCode.USER_NOT_HOST); + } +} diff --git a/gg-utils/src/main/java/gg/utils/exception/recruitment/InvalidCheckListException.java b/gg-utils/src/main/java/gg/utils/exception/recruitment/InvalidCheckListException.java new file mode 100644 index 000000000..0a4c8c116 --- /dev/null +++ b/gg-utils/src/main/java/gg/utils/exception/recruitment/InvalidCheckListException.java @@ -0,0 +1,10 @@ +package gg.utils.exception.recruitment; + +import gg.utils.exception.ErrorCode; +import gg.utils.exception.custom.CustomRuntimeException; + +public class InvalidCheckListException extends CustomRuntimeException { + public InvalidCheckListException() { + super(ErrorCode.INVALID_CHECKLIST.getMessage(), ErrorCode.INVALID_CHECKLIST); + } +} diff --git a/gg-utils/src/testFixtures/java/gg/utils/ItemTestUtils.java b/gg-utils/src/testFixtures/java/gg/utils/ItemTestUtils.java index 68ea7dc0f..915b1203a 100644 --- a/gg-utils/src/testFixtures/java/gg/utils/ItemTestUtils.java +++ b/gg-utils/src/testFixtures/java/gg/utils/ItemTestUtils.java @@ -5,10 +5,10 @@ import org.springframework.stereotype.Component; -import gg.data.store.Item; -import gg.data.store.Megaphone; -import gg.data.store.Receipt; -import gg.data.store.type.ItemStatus; +import gg.data.pingpong.store.Item; +import gg.data.pingpong.store.Megaphone; +import gg.data.pingpong.store.Receipt; +import gg.data.pingpong.store.type.ItemStatus; import gg.data.user.User; import gg.pingpong.api.admin.store.controller.request.ItemUpdateRequestDto; import gg.repo.store.ItemRepository; diff --git a/gg-utils/src/testFixtures/java/gg/utils/TestDataUtils.java b/gg-utils/src/testFixtures/java/gg/utils/TestDataUtils.java index 9de9768b6..cc6ae463a 100644 --- a/gg-utils/src/testFixtures/java/gg/utils/TestDataUtils.java +++ b/gg-utils/src/testFixtures/java/gg/utils/TestDataUtils.java @@ -1,5 +1,7 @@ package gg.utils; +import static java.lang.Boolean.*; + import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -7,29 +9,50 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import javax.persistence.EntityManager; + import org.springframework.stereotype.Component; -import gg.data.game.Game; -import gg.data.game.PChange; -import gg.data.game.Team; -import gg.data.game.TeamUser; -import gg.data.game.type.Mode; -import gg.data.game.type.StatusType; +import gg.auth.utils.AuthTokenProvider; import gg.data.manage.Announcement; -import gg.data.manage.SlotManagement; import gg.data.noti.Noti; import gg.data.noti.type.NotiType; -import gg.data.rank.Rank; -import gg.data.rank.Tier; -import gg.data.rank.redis.RankRedis; -import gg.data.season.Season; -import gg.data.store.CoinPolicy; -import gg.data.tournament.Tournament; -import gg.data.tournament.TournamentGame; -import gg.data.tournament.TournamentUser; -import gg.data.tournament.type.TournamentRound; -import gg.data.tournament.type.TournamentStatus; -import gg.data.tournament.type.TournamentType; +import gg.data.party.Category; +import gg.data.party.Comment; +import gg.data.party.CommentReport; +import gg.data.party.GameTemplate; +import gg.data.party.PartyPenalty; +import gg.data.party.Room; +import gg.data.party.RoomReport; +import gg.data.party.UserReport; +import gg.data.party.UserRoom; +import gg.data.party.type.RoomType; +import gg.data.pingpong.game.Game; +import gg.data.pingpong.game.PChange; +import gg.data.pingpong.game.Team; +import gg.data.pingpong.game.TeamUser; +import gg.data.pingpong.game.type.Mode; +import gg.data.pingpong.game.type.StatusType; +import gg.data.pingpong.manage.SlotManagement; +import gg.data.pingpong.rank.Rank; +import gg.data.pingpong.rank.Tier; +import gg.data.pingpong.rank.redis.RankRedis; +import gg.data.pingpong.season.Season; +import gg.data.pingpong.store.CoinPolicy; +import gg.data.pingpong.tournament.Tournament; +import gg.data.pingpong.tournament.TournamentGame; +import gg.data.pingpong.tournament.TournamentUser; +import gg.data.pingpong.tournament.type.TournamentRound; +import gg.data.pingpong.tournament.type.TournamentStatus; +import gg.data.pingpong.tournament.type.TournamentType; +import gg.data.recruit.application.Application; +import gg.data.recruit.application.ApplicationAnswerCheckList; +import gg.data.recruit.application.ApplicationAnswerText; +import gg.data.recruit.application.RecruitStatus; +import gg.data.recruit.recruitment.CheckList; +import gg.data.recruit.recruitment.Question; +import gg.data.recruit.recruitment.Recruitment; +import gg.data.recruit.recruitment.enums.InputType; import gg.data.user.User; import gg.data.user.UserImage; import gg.data.user.type.RacketType; @@ -37,7 +60,6 @@ import gg.data.user.type.SnsType; import gg.pingpong.api.admin.tournament.controller.request.TournamentAdminCreateRequestDto; import gg.pingpong.api.admin.tournament.controller.request.TournamentAdminUpdateRequestDto; -import gg.pingpong.api.global.security.jwt.utils.AuthTokenProvider; import gg.pingpong.api.user.tournament.controller.response.TournamentResponseDto; import gg.pingpong.api.user.user.dto.UserImageDto; import gg.repo.game.GameRepository; @@ -47,9 +69,21 @@ import gg.repo.manage.AnnouncementRepository; import gg.repo.manage.SlotManagementRepository; import gg.repo.noti.NotiRepository; +import gg.repo.party.CategoryRepository; +import gg.repo.party.CommentReportRepository; +import gg.repo.party.CommentRepository; +import gg.repo.party.PartyPenaltyRepository; +import gg.repo.party.RoomReportRepository; +import gg.repo.party.RoomRepository; +import gg.repo.party.TemplateRepository; +import gg.repo.party.UserReportRepository; +import gg.repo.party.UserRoomRepository; import gg.repo.rank.RankRepository; import gg.repo.rank.TierRepository; import gg.repo.rank.redis.RankRedisRepository; +import gg.repo.recruit.application.ApplicationRepository; +import gg.repo.recruit.application.RecruitStatusRepository; +import gg.repo.recruit.recruitment.RecruitmentRepository; import gg.repo.season.SeasonRepository; import gg.repo.store.CoinPolicyRepository; import gg.repo.tournarment.TournamentGameRepository; @@ -82,6 +116,19 @@ public class TestDataUtils { private final CoinPolicyRepository coinPolicyRepository; private final UserImageRepository userImageRepository; private final SlotManagementRepository slotManagementRepository; + private final RoomRepository roomRepository; + private final UserRoomRepository userRoomRepository; + private final CategoryRepository categoryRepository; + private final PartyPenaltyRepository partyPenaltyRepository; + private final TemplateRepository templateRepository; + private final CommentRepository commentRepository; + private final CommentReportRepository commentReportRepository; + private final RoomReportRepository roomReportRepository; + private final UserReportRepository userReportRepository; + private final RecruitmentRepository recruitmentRepository; + private final ApplicationRepository applicationRepository; + private final RecruitStatusRepository recruitStatusRepository; + private final EntityManager entityManager; public String getLoginAccessToken() { User user = User.builder() @@ -766,4 +813,161 @@ public SlotManagement createSlot(int gameInterval) { .build(); return slotManagementRepository.save(slotManagement); } + + /* + * number๋Š” ๋ฐฉ ์ˆœ์„œ์— ๋”ฐ๋ผ ์ œ๋ชฉ ๋‚ด์šฉ์„ ์ˆœ์„œ๋”ฐ๋ผ ํ‘œ๊ธฐํ•˜๊ธฐ ์œ„ํ•จ. + */ + public Room createNewRoom(User host, User creator, Category category, int number, Integer currentPeople, + Integer maxPeople, Integer minPeople, Integer dueDate, RoomType status) { + Room room = Room.builder() + .host(host) + .creator(creator) + .category(category) + .title("๋ฐฉ ์ œ๋ชฉ" + number) + .content("๋ฐฉ ๋‚ด์šฉ" + number) + .currentPeople(currentPeople) + .maxPeople(maxPeople) + .minPeople(minPeople) + .dueDate(LocalDateTime.now().plusMinutes(dueDate)) + .status(status) + .build(); + return roomRepository.save(room); + } + + public Category createNewCategory(String name) { + Category newCategory = new Category(name); + return categoryRepository.save(newCategory); + } + + public PartyPenalty createNewPenalty(User user, String type, String message, LocalDateTime startTime, + Integer penaltyTime) { + PartyPenalty penalty = new PartyPenalty(user, type, message, startTime, penaltyTime); + partyPenaltyRepository.save(penalty); + return penalty; + } + + public UserRoom createNewUserRoom(User user, Room room, String nickname, boolean isExist) { + UserRoom userRoom = new UserRoom(user, room, nickname, isExist); + return userRoomRepository.save(userRoom); + } + + public User createNewImageUser(String intraId, String email, RacketType racketType, + SnsType snsType, RoleType roleType, String userImage) { + User user = User.builder() + .eMail(email) + .intraId(intraId) + .racketType(racketType) + .snsNotiOpt(snsType) + .roleType(roleType) + .totalExp(0) + .imageUri(userImage) + .build(); + userRepository.save(user); + return user; + } + + public GameTemplate createNewTemplate(Category category, String gameName, Integer maxGamePeople, + Integer minGamePeople, Integer maxGameTime, Integer minGameTime, String genre, String difficulty, + String summary) { + GameTemplate gameTemplate = GameTemplate.builder() + .category(category) + .gameName(gameName) + .maxGamePeople(maxGamePeople) + .minGamePeople(minGamePeople) + .maxGameTime(maxGameTime) + .minGameTime(minGameTime) + .genre(genre) + .difficulty(difficulty) + .summary(summary) + .build(); + return templateRepository.save(gameTemplate); + } + + public Comment createComment(User user, UserRoom userRoom, Room room, String content) { + Comment comment = new Comment(user, userRoom, room, content); + commentRepository.save(comment); + return comment; + } + + public CommentReport createCommentReport(User user, Room room, Comment comment) { + CommentReport commentReport = new CommentReport(user, comment, room, "test"); + commentReportRepository.save(commentReport); + return commentReport; + } + + public RoomReport createRoomReport(User user, User targetUser, Room room) { + RoomReport roomReport = new RoomReport(user, targetUser, room, "test"); + roomReportRepository.save(roomReport); + return roomReport; + } + + public UserReport createUserReport(User user, User targetUser, Room room) { + UserReport userReport = new UserReport(user, targetUser, room, "test"); + userReportRepository.save(userReport); + return userReport; + } + + public Comment createReportComment(User user, UserRoom userRoom, Room room, String content) { + Comment comment = new Comment(user, userRoom, room, content); + comment.updateHidden(TRUE); + commentRepository.save(comment); + return comment; + } + + public Recruitment createNewRecruitment() { + Recruitment recruitment = Recruitment.builder() + .contents("contents") + .generation("generation") + .title("title") + .startTime(LocalDateTime.now()) + .endTime(LocalDateTime.now().plusDays(1)) + .build(); + recruitmentRepository.save(recruitment); + return recruitment; + } + + public Application createApplication(User user, Recruitment recruitment) { + Application application = new Application(user, recruitment); + applicationRepository.save(application); + return application; + } + + public RecruitStatus createRecruitStatus(Application application) { + RecruitStatus recruitStatus = new RecruitStatus(application); + recruitStatusRepository.save(recruitStatus); + return recruitStatus; + } + + public RecruitStatus createRecruitStatus(Application application, LocalDateTime interviewDate) { + RecruitStatus recruitStatus = new RecruitStatus(application, interviewDate); + recruitStatusRepository.save(recruitStatus); + return recruitStatus; + } + + public Question createNewQuestion(Recruitment recruitment, InputType inputType, String quest, int sortNum) { + Question question = new Question(recruitment, inputType, quest, sortNum); + entityManager.persist(question); + return question; + } + + public CheckList createNewCheckList(Question question, String content) { + CheckList checkList = new CheckList(question, content); + entityManager.persist(checkList); + return checkList; + } + + public ApplicationAnswerCheckList createNewApplicationAnswerCheckList(Application application, Question question, + CheckList checkList) { + ApplicationAnswerCheckList applicationAnswerCheckList = new ApplicationAnswerCheckList(application, + question, checkList); + entityManager.persist(applicationAnswerCheckList); + return applicationAnswerCheckList; + } + + public ApplicationAnswerText createNewApplicationAnswerText(Application application, Question question, + String search) { + ApplicationAnswerText answerText = new ApplicationAnswerText(application, question, search); + entityManager.persist(answerText); + return answerText; + } } diff --git a/settings.gradle b/settings.gradle index ae330bfed..9e311f424 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,4 +4,6 @@ include 'gg-admin-repo' include 'gg-repo' include 'gg-pingpong-api' include 'gg-utils' +include 'gg-auth' +include 'gg-recruit-api' diff --git a/update-main-yml.sh b/update-main-yml.sh index a01d254e2..64f6418f8 100755 --- a/update-main-yml.sh +++ b/update-main-yml.sh @@ -1,7 +1,7 @@ #!/bin/bash # yml ํŒŒ์ผ ๊ฒฝ๋กœ -YML_FILE="./src/main/resources/application.yml" +YML_FILE="./gg-pingpong-api/src/main/resources/application.yml" # ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ์„ ์ž„์‹œ ํŒŒ์ผ์— ์ €์žฅ ENCODED_APPLICATION_YML=$(mktemp)