From 100cde3e1167d48760bc9ec839c95c86ac349e15 Mon Sep 17 00:00:00 2001 From: livenow14 Date: Tue, 7 Sep 2021 01:27:22 +0900 Subject: [PATCH 01/17] =?UTF-8?q?feat:=20=EB=A9=80=ED=8B=B0=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EC=A0=81=EC=9A=A9=5F=EB=8B=A8=EC=88=9C=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/.gitignore | 2 +- backend/app-cvi-admin/build.gradle | 19 ++++++++++++++++++ .../src/main/java/com/cvi/empty.txt} | 0 .../src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../src/test/resources/empty.txt | 0 backend/app-cvi-api/build.gradle | 19 ++++++++++++++++++ .../src/main/java/com/cvi/empty.txt | 0 .../app-cvi-api/src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../app-cvi-api/src/test/resources/empty.txt | 0 .../ehcache-disk-store.data | Bin 16384 -> 0 bytes .../ehcache-disk-store.meta | 4 ---- backend/common-cvi/build.gradle | 19 ++++++++++++++++++ .../src/main/java/com/cvi/empty.txt | 0 .../common-cvi/src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../common-cvi/src/test/resources/empty.txt | 0 backend/cvi-oauth-parser/build.gradle | 19 ++++++++++++++++++ .../src/main/java/com/cvi/empty.txt | 0 .../src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../src/test/resources/empty.txt | 0 backend/cvi-publicdata-parser/build.gradle | 19 ++++++++++++++++++ .../src/main/java/com/cvi/empty.txt | 0 .../src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../src/test/resources/empty.txt | 0 backend/domain-cvi-oauth-service/build.gradle | 19 ++++++++++++++++++ .../src/main/java/com/cvi/empty.txt | 0 .../src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../src/test/resources/empty.txt | 0 .../build.gradle | 19 ++++++++++++++++++ .../src/main/java/com/cvi/empty.txt | 0 .../src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../src/test/resources/empty.txt | 0 backend/domain-cvi-scheduler/build.gradle | 19 ++++++++++++++++++ .../src/main/java/com/cvi/empty.txt | 0 .../src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../src/test/resources/empty.txt | 0 backend/domain-cvi-service/build.gradle | 19 ++++++++++++++++++ .../src/main/java/com/cvi/empty.txt | 0 .../src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../src/test/resources/empty.txt | 0 backend/domain-cvi/build.gradle | 19 ++++++++++++++++++ .../src/main/java/com/cvi/empty.txt | 0 .../domain-cvi/src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../domain-cvi/src/test/resources/empty.txt | 0 backend/settings.gradle | 11 +++++++++- 54 files changed, 201 insertions(+), 6 deletions(-) create mode 100644 backend/app-cvi-admin/build.gradle rename backend/{cache/data/.lock => app-cvi-admin/src/main/java/com/cvi/empty.txt} (100%) create mode 100644 backend/app-cvi-admin/src/main/resources/empty.txt create mode 100644 backend/app-cvi-admin/src/test/java/com/cvi/empty.txt create mode 100644 backend/app-cvi-admin/src/test/resources/empty.txt create mode 100644 backend/app-cvi-api/build.gradle create mode 100644 backend/app-cvi-api/src/main/java/com/cvi/empty.txt create mode 100644 backend/app-cvi-api/src/main/resources/empty.txt create mode 100644 backend/app-cvi-api/src/test/java/com/cvi/empty.txt create mode 100644 backend/app-cvi-api/src/test/resources/empty.txt delete mode 100644 backend/cache/data/file/cache%003a%003aworldVaccinationStatistics_1955f38c9d44fb897fbc39ca30b91156eeb9d5ed/offheap-disk-store/ehcache-disk-store.data delete mode 100644 backend/cache/data/file/cache%003a%003aworldVaccinationStatistics_1955f38c9d44fb897fbc39ca30b91156eeb9d5ed/offheap-disk-store/ehcache-disk-store.meta create mode 100644 backend/common-cvi/build.gradle create mode 100644 backend/common-cvi/src/main/java/com/cvi/empty.txt create mode 100644 backend/common-cvi/src/main/resources/empty.txt create mode 100644 backend/common-cvi/src/test/java/com/cvi/empty.txt create mode 100644 backend/common-cvi/src/test/resources/empty.txt create mode 100644 backend/cvi-oauth-parser/build.gradle create mode 100644 backend/cvi-oauth-parser/src/main/java/com/cvi/empty.txt create mode 100644 backend/cvi-oauth-parser/src/main/resources/empty.txt create mode 100644 backend/cvi-oauth-parser/src/test/java/com/cvi/empty.txt create mode 100644 backend/cvi-oauth-parser/src/test/resources/empty.txt create mode 100644 backend/cvi-publicdata-parser/build.gradle create mode 100644 backend/cvi-publicdata-parser/src/main/java/com/cvi/empty.txt create mode 100644 backend/cvi-publicdata-parser/src/main/resources/empty.txt create mode 100644 backend/cvi-publicdata-parser/src/test/java/com/cvi/empty.txt create mode 100644 backend/cvi-publicdata-parser/src/test/resources/empty.txt create mode 100644 backend/domain-cvi-oauth-service/build.gradle create mode 100644 backend/domain-cvi-oauth-service/src/main/java/com/cvi/empty.txt create mode 100644 backend/domain-cvi-oauth-service/src/main/resources/empty.txt create mode 100644 backend/domain-cvi-oauth-service/src/test/java/com/cvi/empty.txt create mode 100644 backend/domain-cvi-oauth-service/src/test/resources/empty.txt create mode 100644 backend/domain-cvi-publicdata-service/build.gradle create mode 100644 backend/domain-cvi-publicdata-service/src/main/java/com/cvi/empty.txt create mode 100644 backend/domain-cvi-publicdata-service/src/main/resources/empty.txt create mode 100644 backend/domain-cvi-publicdata-service/src/test/java/com/cvi/empty.txt create mode 100644 backend/domain-cvi-publicdata-service/src/test/resources/empty.txt create mode 100644 backend/domain-cvi-scheduler/build.gradle create mode 100644 backend/domain-cvi-scheduler/src/main/java/com/cvi/empty.txt create mode 100644 backend/domain-cvi-scheduler/src/main/resources/empty.txt create mode 100644 backend/domain-cvi-scheduler/src/test/java/com/cvi/empty.txt create mode 100644 backend/domain-cvi-scheduler/src/test/resources/empty.txt create mode 100644 backend/domain-cvi-service/build.gradle create mode 100644 backend/domain-cvi-service/src/main/java/com/cvi/empty.txt create mode 100644 backend/domain-cvi-service/src/main/resources/empty.txt create mode 100644 backend/domain-cvi-service/src/test/java/com/cvi/empty.txt create mode 100644 backend/domain-cvi-service/src/test/resources/empty.txt create mode 100644 backend/domain-cvi/build.gradle create mode 100644 backend/domain-cvi/src/main/java/com/cvi/empty.txt create mode 100644 backend/domain-cvi/src/main/resources/empty.txt create mode 100644 backend/domain-cvi/src/test/java/com/cvi/empty.txt create mode 100644 backend/domain-cvi/src/test/resources/empty.txt diff --git a/backend/.gitignore b/backend/.gitignore index a22715d1..1d0e8c1d 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -46,4 +46,4 @@ out/ /src/main/resources/application-jwt.yml # client-secret -/src/main/resources/application-client-secret.yml \ No newline at end of file +/src/main/resources/application-client-secret.yml diff --git a/backend/app-cvi-admin/build.gradle b/backend/app-cvi-admin/build.gradle new file mode 100644 index 00000000..25fb3aff --- /dev/null +++ b/backend/app-cvi-admin/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'com.backjoongwon' +version '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/backend/cache/data/.lock b/backend/app-cvi-admin/src/main/java/com/cvi/empty.txt similarity index 100% rename from backend/cache/data/.lock rename to backend/app-cvi-admin/src/main/java/com/cvi/empty.txt diff --git a/backend/app-cvi-admin/src/main/resources/empty.txt b/backend/app-cvi-admin/src/main/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/app-cvi-admin/src/test/java/com/cvi/empty.txt b/backend/app-cvi-admin/src/test/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/app-cvi-admin/src/test/resources/empty.txt b/backend/app-cvi-admin/src/test/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/app-cvi-api/build.gradle b/backend/app-cvi-api/build.gradle new file mode 100644 index 00000000..25fb3aff --- /dev/null +++ b/backend/app-cvi-api/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'com.backjoongwon' +version '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/backend/app-cvi-api/src/main/java/com/cvi/empty.txt b/backend/app-cvi-api/src/main/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/app-cvi-api/src/main/resources/empty.txt b/backend/app-cvi-api/src/main/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/app-cvi-api/src/test/java/com/cvi/empty.txt b/backend/app-cvi-api/src/test/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/app-cvi-api/src/test/resources/empty.txt b/backend/app-cvi-api/src/test/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/cache/data/file/cache%003a%003aworldVaccinationStatistics_1955f38c9d44fb897fbc39ca30b91156eeb9d5ed/offheap-disk-store/ehcache-disk-store.data b/backend/cache/data/file/cache%003a%003aworldVaccinationStatistics_1955f38c9d44fb897fbc39ca30b91156eeb9d5ed/offheap-disk-store/ehcache-disk-store.data deleted file mode 100644 index 294f4016d05bdd696670c4840f1f36a71f9239de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeIuF#!Mo0K%a4Pi+hzh(KY$fB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM q7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjMyaxtA00031 diff --git a/backend/cache/data/file/cache%003a%003aworldVaccinationStatistics_1955f38c9d44fb897fbc39ca30b91156eeb9d5ed/offheap-disk-store/ehcache-disk-store.meta b/backend/cache/data/file/cache%003a%003aworldVaccinationStatistics_1955f38c9d44fb897fbc39ca30b91156eeb9d5ed/offheap-disk-store/ehcache-disk-store.meta deleted file mode 100644 index f84eed96..00000000 --- a/backend/cache/data/file/cache%003a%003aworldVaccinationStatistics_1955f38c9d44fb897fbc39ca30b91156eeb9d5ed/offheap-disk-store/ehcache-disk-store.meta +++ /dev/null @@ -1,4 +0,0 @@ -#Key and value types -#Thu Aug 12 00:46:35 KST 2021 -valueType=java.util.ArrayList -keyType=java.lang.String diff --git a/backend/common-cvi/build.gradle b/backend/common-cvi/build.gradle new file mode 100644 index 00000000..25fb3aff --- /dev/null +++ b/backend/common-cvi/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'com.backjoongwon' +version '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/backend/common-cvi/src/main/java/com/cvi/empty.txt b/backend/common-cvi/src/main/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/common-cvi/src/main/resources/empty.txt b/backend/common-cvi/src/main/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/common-cvi/src/test/java/com/cvi/empty.txt b/backend/common-cvi/src/test/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/common-cvi/src/test/resources/empty.txt b/backend/common-cvi/src/test/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/cvi-oauth-parser/build.gradle b/backend/cvi-oauth-parser/build.gradle new file mode 100644 index 00000000..25fb3aff --- /dev/null +++ b/backend/cvi-oauth-parser/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'com.backjoongwon' +version '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/backend/cvi-oauth-parser/src/main/java/com/cvi/empty.txt b/backend/cvi-oauth-parser/src/main/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/cvi-oauth-parser/src/main/resources/empty.txt b/backend/cvi-oauth-parser/src/main/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/cvi-oauth-parser/src/test/java/com/cvi/empty.txt b/backend/cvi-oauth-parser/src/test/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/cvi-oauth-parser/src/test/resources/empty.txt b/backend/cvi-oauth-parser/src/test/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/cvi-publicdata-parser/build.gradle b/backend/cvi-publicdata-parser/build.gradle new file mode 100644 index 00000000..25fb3aff --- /dev/null +++ b/backend/cvi-publicdata-parser/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'com.backjoongwon' +version '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/backend/cvi-publicdata-parser/src/main/java/com/cvi/empty.txt b/backend/cvi-publicdata-parser/src/main/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/cvi-publicdata-parser/src/main/resources/empty.txt b/backend/cvi-publicdata-parser/src/main/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/cvi-publicdata-parser/src/test/java/com/cvi/empty.txt b/backend/cvi-publicdata-parser/src/test/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/cvi-publicdata-parser/src/test/resources/empty.txt b/backend/cvi-publicdata-parser/src/test/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-oauth-service/build.gradle b/backend/domain-cvi-oauth-service/build.gradle new file mode 100644 index 00000000..25fb3aff --- /dev/null +++ b/backend/domain-cvi-oauth-service/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'com.backjoongwon' +version '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/empty.txt b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-oauth-service/src/main/resources/empty.txt b/backend/domain-cvi-oauth-service/src/main/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-oauth-service/src/test/java/com/cvi/empty.txt b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-oauth-service/src/test/resources/empty.txt b/backend/domain-cvi-oauth-service/src/test/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-publicdata-service/build.gradle b/backend/domain-cvi-publicdata-service/build.gradle new file mode 100644 index 00000000..25fb3aff --- /dev/null +++ b/backend/domain-cvi-publicdata-service/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'com.backjoongwon' +version '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/empty.txt b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-publicdata-service/src/main/resources/empty.txt b/backend/domain-cvi-publicdata-service/src/main/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/empty.txt b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-publicdata-service/src/test/resources/empty.txt b/backend/domain-cvi-publicdata-service/src/test/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-scheduler/build.gradle b/backend/domain-cvi-scheduler/build.gradle new file mode 100644 index 00000000..25fb3aff --- /dev/null +++ b/backend/domain-cvi-scheduler/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'com.backjoongwon' +version '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/backend/domain-cvi-scheduler/src/main/java/com/cvi/empty.txt b/backend/domain-cvi-scheduler/src/main/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-scheduler/src/main/resources/empty.txt b/backend/domain-cvi-scheduler/src/main/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-scheduler/src/test/java/com/cvi/empty.txt b/backend/domain-cvi-scheduler/src/test/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-scheduler/src/test/resources/empty.txt b/backend/domain-cvi-scheduler/src/test/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-service/build.gradle b/backend/domain-cvi-service/build.gradle new file mode 100644 index 00000000..25fb3aff --- /dev/null +++ b/backend/domain-cvi-service/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'com.backjoongwon' +version '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/backend/domain-cvi-service/src/main/java/com/cvi/empty.txt b/backend/domain-cvi-service/src/main/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-service/src/main/resources/empty.txt b/backend/domain-cvi-service/src/main/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-service/src/test/java/com/cvi/empty.txt b/backend/domain-cvi-service/src/test/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi-service/src/test/resources/empty.txt b/backend/domain-cvi-service/src/test/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi/build.gradle b/backend/domain-cvi/build.gradle new file mode 100644 index 00000000..25fb3aff --- /dev/null +++ b/backend/domain-cvi/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'com.backjoongwon' +version '0.0.1-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/backend/domain-cvi/src/main/java/com/cvi/empty.txt b/backend/domain-cvi/src/main/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi/src/main/resources/empty.txt b/backend/domain-cvi/src/main/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi/src/test/java/com/cvi/empty.txt b/backend/domain-cvi/src/test/java/com/cvi/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/domain-cvi/src/test/resources/empty.txt b/backend/domain-cvi/src/test/resources/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/backend/settings.gradle b/backend/settings.gradle index 270ba5aa..2a29ae75 100644 --- a/backend/settings.gradle +++ b/backend/settings.gradle @@ -1,3 +1,12 @@ rootProject.name = 'cvi' include 'cvi-vaccine-stats-parser' - +include 'cvi-publicdata-parser' +include 'cvi-oauth-parser' +include 'common-cvi' +include 'domain-cvi' +include 'domain-cvi-service' +include 'domain-cvi-oauth-service' +include 'domain-cvi-publicdata-service' +include 'domain-cvi-scheduler' +include 'app-cvi-api' +include 'app-cvi-admin' From e256746dbd8a57280878e6945b2fd29041c0de60 Mon Sep 17 00:00:00 2001 From: livenow14 Date: Tue, 7 Sep 2021 19:42:03 +0900 Subject: [PATCH 02/17] =?UTF-8?q?feat:=20=EB=A9=80=ED=8B=B0=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EC=A0=81=EC=9A=A9=5F=EA=B8=B0=EB=8A=A5=20=EB=8B=A8?= =?UTF-8?q?=EC=88=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 구현 코드만 변경한 후, 실행되는지 확인하엿음. --- backend/app-cvi-admin/build.gradle | 19 +- backend/app-cvi-api/build.gradle | 59 +- .../docs/asciidoc/index.adoc | 0 ...tralVaccinationInformationApplication.java | 12 + .../src/main/java/com/cvi/DataLoader.java | 126 + .../src/main/java/com/cvi/DummyData.java | 40 + .../java/com}/cvi/config/CacheConfig.java | 2 +- .../java/com}/cvi/config/WebMvcConfig.java | 6 +- .../com/cvi}/controller/AuthController.java | 8 +- .../cvi}/controller/CommentController.java | 12 +- .../com/cvi}/controller/LikeController.java | 10 +- .../com/cvi}/controller/PostController.java | 16 +- .../cvi/controller}/ProfileController.java | 4 +- .../cvi}/controller/PublicDataController.java | 6 +- .../com/cvi}/controller/UserController.java | 18 +- .../CVIControllerAdvice.java | 6 +- .../java/com/cvi}/dto/AgeRangeResponse.java | 4 +- .../java/com/cvi}/dto/CommentRequest.java | 4 +- .../java/com/cvi}/dto/CommentResponse.java | 5 +- .../main/java/com/cvi}/dto/LikeResponse.java | 2 +- .../main/java/com/cvi}/dto/PostRequest.java | 7 +- .../main/java/com/cvi}/dto/PostResponse.java | 9 +- .../com/cvi}/dto/PostWithCommentResponse.java | 14 +- .../main/java/com/cvi}/dto/UserRequest.java | 8 +- .../main/java/com/cvi}/dto/UserResponse.java | 6 +- .../java/com/cvi}/service/AuthService.java | 16 +- .../com/cvi/service}/CacheEventLogger.java | 2 +- .../java/com/cvi}/service/CommentService.java | 20 +- .../java/com/cvi}/service/LikeService.java | 20 +- .../java/com/cvi}/service/PostService.java | 30 +- .../java/com/cvi}/service/UserService.java | 20 +- .../src/main/resources/application.yml | 30 + .../src/main/resources/console-appender.xml | 7 + .../src/main/resources/ehcache.xml | 49 + .../main/resources/file-error-appender.xml | 18 + .../resources/file-error-aws-appender.xml | 18 + .../src/main/resources/file-info-appender.xml | 18 + .../main/resources/file-info-aws-appender.xml | 18 + .../src/main/resources/file-warn-appender.xml | 18 + .../main/resources/file-warn-aws-appender.xml | 18 + .../src/main/resources/logback-spring.xml | 44 + backend/build.gradle | 239 +- backend/common-cvi/build.gradle | 19 +- .../src/main/java/com/cvi/empty.txt | 0 .../com/cvi}/exception/CommonException.java | 2 +- .../cvi}/exception/DuplicateException.java | 2 +- .../com/cvi}/exception/ExceptionMessage.java | 2 +- .../cvi}/exception/InvalidInputException.java | 2 +- .../exception/InvalidOperationException.java | 2 +- .../exception/MappingFailureException.java | 2 +- .../com/cvi}/exception/NotFoundException.java | 2 +- .../cvi}/exception/UnAuthorizedException.java | 2 +- backend/cvi-oauth-parser/build.gradle | 19 - .../src/main/java/com/cvi/empty.txt | 0 .../src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../src/test/resources/empty.txt | 0 backend/cvi-publicdata-parser/build.gradle | 58 +- .../cvi/dto/KoreaRegionVaccinationData.java | 2 +- .../cvi/dto/KoreaVaccineParserResponse.java | 2 +- .../com}/cvi/dto/WorldVaccinationData.java | 2 +- .../dto/WorldVaccinationParserResponse.java | 2 +- .../src/main/java/com/cvi/empty.txt | 0 .../cvi/parser/ParameterStringBuilder.java | 2 +- .../src/main/java/com}/cvi/parser/Parser.java | 2 +- .../main/java/com}/cvi/parser/URLWrapper.java | 2 +- .../com}/cvi/parser/VaccinationParser.java | 10 +- .../java/com}/cvi/util/DateConverter.java | 2 +- .../main/java/com}/cvi/util/JsonMapper.java | 4 +- .../src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../parser/ParameterStringBuilderTest.java | 2 +- .../java/com}/cvi/parser/URLWrapperTest.java | 2 +- .../com}/cvi/parser/VaccineParserTest.java | 14 +- .../java/com}/cvi/util/DateConverterTest.java | 2 +- .../java/com}/cvi/util/JsonMapperTest.java | 6 +- .../src/test/resources/empty.txt | 0 backend/cvi-vaccine-stats-parser/build.gradle | 76 - .../gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 - backend/cvi-vaccine-stats-parser/gradlew | 185 - backend/cvi-vaccine-stats-parser/gradlew.bat | 89 - backend/domain-cvi-oauth-service/build.gradle | 50 +- .../cvi}/auth/AuthenticationPrincipal.java | 2 +- ...thenticationPrincipalArgumentResolver.java | 20 +- .../com/cvi}/auth/AuthorizationExtractor.java | 2 +- .../java/com/cvi/auth}/JwtTokenProvider.java | 2 +- .../java/com/cvi}/auth/SigninInterceptor.java | 3 +- .../java/com/cvi/config/WebMvcConfig.java | 35 + .../main/java/com/cvi}/dto/AuthRequest.java | 4 +- .../java/com/cvi/dto/UserInformation.java | 25 + .../cvi}/dto/oauthtoken/KakaoOAuthToken.java | 2 +- .../cvi}/dto/oauthtoken/NaverOAuthToken.java | 2 +- .../com/cvi}/dto/oauthtoken/OAuthToken.java | 2 +- .../com/cvi}/dto/profile/KakaoProfile.java | 2 +- .../com/cvi}/dto/profile/NaverProfile.java | 2 +- .../com/cvi}/dto/profile/SocialProfile.java | 2 +- .../com/cvi}/dto/profile/UserInformation.java | 2 +- .../src/main/java/com/cvi/empty.txt | 0 .../java/com/cvi/parser}/Authorization.java | 8 +- .../com/cvi/parser}/AuthorizationManager.java | 7 +- .../com/cvi/parser}/KakaoAuthorization.java | 15 +- .../com/cvi/parser}/NaverAuthorization.java | 14 +- .../application-domain-cvi-oauth.yml | 9 + .../src/main/resources/empty.txt | 0 .../build.gradle | 20 +- .../com}/cvi/config/VaccinationConfig.java | 9 +- .../dto/RegionVaccinationDataFactory.java | 7 +- .../dto/VaccinationStatisticResponse.java | 10 +- .../cvi}/dto/WorldVaccinationDataFactory.java | 7 +- .../src/main/java/com/cvi/empty.txt | 0 .../cvi/properties}/PublicDataProperties.java | 2 +- .../com/cvi}/service/PublicDataService.java | 16 +- .../application-domain-cvi-publicdata.yml | 4 + .../src/main/resources/empty.txt | 0 backend/domain-cvi-scheduler/build.gradle | 48 +- .../java/com/cvi/config/SchedulerConfig.java} | 4 +- .../src/main/java/com/cvi/empty.txt | 0 .../com/cvi}/service/PublicDataScheduler.java | 2 +- backend/domain-cvi-service/build.gradle | 19 - .../src/main/java/com/cvi/empty.txt | 0 .../src/main/resources/empty.txt | 0 .../src/test/java/com/cvi/empty.txt | 0 .../src/test/resources/empty.txt | 0 backend/domain-cvi/build.gradle | 58 +- .../cvi/comment/domain/model}/Comment.java | 19 +- .../domain/repository}/CommentQueryDsl.java | 4 +- .../domain/repository}/CommentRepository.java | 3 +- .../repository}/CommentRepositoryImpl.java | 7 +- .../com/cvi/config}/JpaConfiguration.java | 2 +- .../com/cvi/config}/entity/BaseEntity.java | 2 +- .../src/main/java/com/cvi/empty.txt | 0 .../java/com/cvi/like/domain/model}/Like.java | 12 +- .../like/domain/repository}/LikeQueryDsl.java | 4 +- .../domain/repository}/LikeRepository.java | 3 +- .../repository}/LikeRepositoryImpl.java | 7 +- .../com/cvi/post/domain/model}/Comments.java | 10 +- .../com/cvi/post/domain/model}/Filter.java | 2 +- .../com/cvi/post/domain/model}/Likes.java | 13 +- .../java/com/cvi/post/domain/model}/Post.java | 17 +- .../java/com/cvi/post/domain/model}/Sort.java | 6 +- .../post/domain/model}/VaccinationType.java | 2 +- .../post/domain/repository}/PostQueryDsl.java | 4 +- .../domain/repository}/PostRepository.java | 3 +- .../repository}/PostRepositoryImpl.java | 13 +- .../publicdata/domain/model}/PublicData.java | 4 +- .../domain/model}/RegionPopulation.java | 2 +- .../domain/model}/VaccinationStatistic.java | 2 +- .../domain/model}/VaccinationStatistics.java | 2 +- .../repository}/PublicDataRepository.java | 3 +- .../VaccinationStatisticRepository.java | 4 +- .../com/cvi/user/domain/model}/AgeRange.java | 2 +- .../user/domain/model}/SocialProvider.java | 2 +- .../java/com/cvi/user/domain/model}/User.java | 9 +- .../domain/repository}/UserRepository.java | 5 +- .../main/resources/application-domain-cvi.yml | 43 + .../db/migration/V20210809__Create_init.sql | 92 + .../domain-cvi/src/main/resources/empty.txt | 0 backend/settings.gradle | 6 +- backend/src/docs/asciidoc/index.html | 4243 ----------------- .../com/backjoongwon/cvi/CviApplication.java | 2 + .../java/com/backjoongwon/cvi/DataLoader.java | 3 +- .../java/com/backjoongwon/cvi/DummyData.java | 2 + .../backjoongwon/cvi/common/EnvSecret.java | 23 - .../auth/controller/AuthControllerTest.java | 2 - .../AuthorizationManagerTest.java | 6 +- .../authorization/KakaoAuthorizationTest.java | 4 +- .../authorization/NaverAuthorizationTest.java | 4 +- .../cvi/auth/service/AuthServiceTest.java | 5 +- .../cvi/comment/domain/CommentTest.java | 1 - .../comment/service/CommentServiceTest.java | 1 - .../cvi/like/domain/LikeTest.java | 1 - .../cvi/like/service/LikeServiceTest.java | 1 - .../PreprocessPostControllerTest.java | 1 - .../cvi/post/domain/PostTest.java | 1 - .../cvi/post/service/PostFindServiceTest.java | 1 - .../post/service/PostMyPageServiceTest.java | 1 - .../cvi/post/service/PostServiceTest.java | 1 - .../user/controller/UserControllerTest.java | 1 - .../cvi/user/domain/UserTest.java | 1 - .../cvi/user/service/UserServiceTest.java | 1 - 181 files changed, 1298 insertions(+), 5244 deletions(-) rename backend/{src => app-cvi-api}/docs/asciidoc/index.adoc (100%) create mode 100644 backend/app-cvi-api/src/main/java/com/cvi/CentralVaccinationInformationApplication.java create mode 100644 backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java create mode 100644 backend/app-cvi-api/src/main/java/com/cvi/DummyData.java rename backend/{src/main/java/com/backjoongwon => app-cvi-api/src/main/java/com}/cvi/config/CacheConfig.java (83%) rename backend/{src/main/java/com/backjoongwon => app-cvi-api/src/main/java/com}/cvi/config/WebMvcConfig.java (89%) rename backend/{src/main/java/com/backjoongwon/cvi/auth => app-cvi-api/src/main/java/com/cvi}/controller/AuthController.java (78%) rename backend/{src/main/java/com/backjoongwon/cvi/comment => app-cvi-api/src/main/java/com/cvi}/controller/CommentController.java (88%) rename backend/{src/main/java/com/backjoongwon/cvi/like => app-cvi-api/src/main/java/com/cvi}/controller/LikeController.java (78%) rename backend/{src/main/java/com/backjoongwon/cvi/post => app-cvi-api/src/main/java/com/cvi}/controller/PostController.java (86%) rename backend/{src/main/java/com/backjoongwon/cvi/deploy => app-cvi-api/src/main/java/com/cvi/controller}/ProfileController.java (88%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata => app-cvi-api/src/main/java/com/cvi}/controller/PublicDataController.java (92%) rename backend/{src/main/java/com/backjoongwon/cvi/user => app-cvi-api/src/main/java/com/cvi}/controller/UserController.java (83%) rename backend/{src/main/java/com/backjoongwon/cvi/common/handler => app-cvi-api/src/main/java/com/cvi/controller/exceptionhandler}/CVIControllerAdvice.java (93%) rename backend/{src/main/java/com/backjoongwon/cvi/user => app-cvi-api/src/main/java/com/cvi}/dto/AgeRangeResponse.java (83%) rename backend/{src/main/java/com/backjoongwon/cvi/comment => app-cvi-api/src/main/java/com/cvi}/dto/CommentRequest.java (86%) rename backend/{src/main/java/com/backjoongwon/cvi/comment => app-cvi-api/src/main/java/com/cvi}/dto/CommentResponse.java (86%) rename backend/{src/main/java/com/backjoongwon/cvi/post => app-cvi-api/src/main/java/com/cvi}/dto/LikeResponse.java (89%) rename backend/{src/main/java/com/backjoongwon/cvi/post => app-cvi-api/src/main/java/com/cvi}/dto/PostRequest.java (83%) rename backend/{src/main/java/com/backjoongwon/cvi/post => app-cvi-api/src/main/java/com/cvi}/dto/PostResponse.java (87%) rename backend/{src/main/java/com/backjoongwon/cvi/post => app-cvi-api/src/main/java/com/cvi}/dto/PostWithCommentResponse.java (85%) rename backend/{src/main/java/com/backjoongwon/cvi/user => app-cvi-api/src/main/java/com/cvi}/dto/UserRequest.java (90%) rename backend/{src/main/java/com/backjoongwon/cvi/user => app-cvi-api/src/main/java/com/cvi}/dto/UserResponse.java (91%) rename backend/{src/main/java/com/backjoongwon/cvi/auth => app-cvi-api/src/main/java/com/cvi}/service/AuthService.java (75%) rename backend/{src/main/java/com/backjoongwon/cvi/common/cache => app-cvi-api/src/main/java/com/cvi/service}/CacheEventLogger.java (90%) rename backend/{src/main/java/com/backjoongwon/cvi/comment => app-cvi-api/src/main/java/com/cvi}/service/CommentService.java (84%) rename backend/{src/main/java/com/backjoongwon/cvi/like => app-cvi-api/src/main/java/com/cvi}/service/LikeService.java (79%) rename backend/{src/main/java/com/backjoongwon/cvi/post => app-cvi-api/src/main/java/com/cvi}/service/PostService.java (89%) rename backend/{src/main/java/com/backjoongwon/cvi/user => app-cvi-api/src/main/java/com/cvi}/service/UserService.java (83%) create mode 100644 backend/app-cvi-api/src/main/resources/application.yml create mode 100644 backend/app-cvi-api/src/main/resources/console-appender.xml create mode 100644 backend/app-cvi-api/src/main/resources/ehcache.xml create mode 100644 backend/app-cvi-api/src/main/resources/file-error-appender.xml create mode 100644 backend/app-cvi-api/src/main/resources/file-error-aws-appender.xml create mode 100644 backend/app-cvi-api/src/main/resources/file-info-appender.xml create mode 100644 backend/app-cvi-api/src/main/resources/file-info-aws-appender.xml create mode 100644 backend/app-cvi-api/src/main/resources/file-warn-appender.xml create mode 100644 backend/app-cvi-api/src/main/resources/file-warn-aws-appender.xml create mode 100644 backend/app-cvi-api/src/main/resources/logback-spring.xml delete mode 100644 backend/common-cvi/src/main/java/com/cvi/empty.txt rename backend/{src/main/java/com/backjoongwon/cvi/common => common-cvi/src/main/java/com/cvi}/exception/CommonException.java (74%) rename backend/{src/main/java/com/backjoongwon/cvi/common => common-cvi/src/main/java/com/cvi}/exception/DuplicateException.java (74%) rename backend/{src/main/java/com/backjoongwon/cvi/common => common-cvi/src/main/java/com/cvi}/exception/ExceptionMessage.java (79%) rename backend/{src/main/java/com/backjoongwon/cvi/common => common-cvi/src/main/java/com/cvi}/exception/InvalidInputException.java (75%) rename backend/{src/main/java/com/backjoongwon/cvi/common => common-cvi/src/main/java/com/cvi}/exception/InvalidOperationException.java (76%) rename backend/{src/main/java/com/backjoongwon/cvi/common => common-cvi/src/main/java/com/cvi}/exception/MappingFailureException.java (76%) rename backend/{src/main/java/com/backjoongwon/cvi/common => common-cvi/src/main/java/com/cvi}/exception/NotFoundException.java (74%) rename backend/{src/main/java/com/backjoongwon/cvi/common => common-cvi/src/main/java/com/cvi}/exception/UnAuthorizedException.java (75%) delete mode 100644 backend/cvi-oauth-parser/build.gradle delete mode 100644 backend/cvi-oauth-parser/src/main/java/com/cvi/empty.txt delete mode 100644 backend/cvi-oauth-parser/src/main/resources/empty.txt delete mode 100644 backend/cvi-oauth-parser/src/test/java/com/cvi/empty.txt delete mode 100644 backend/cvi-oauth-parser/src/test/resources/empty.txt rename backend/{cvi-vaccine-stats-parser/src/main/java/com/backjoongwon => cvi-publicdata-parser/src/main/java/com}/cvi/dto/KoreaRegionVaccinationData.java (97%) rename backend/{cvi-vaccine-stats-parser/src/main/java/com/backjoongwon => cvi-publicdata-parser/src/main/java/com}/cvi/dto/KoreaVaccineParserResponse.java (97%) rename backend/{cvi-vaccine-stats-parser/src/main/java/com/backjoongwon => cvi-publicdata-parser/src/main/java/com}/cvi/dto/WorldVaccinationData.java (98%) rename backend/{cvi-vaccine-stats-parser/src/main/java/com/backjoongwon => cvi-publicdata-parser/src/main/java/com}/cvi/dto/WorldVaccinationParserResponse.java (96%) delete mode 100644 backend/cvi-publicdata-parser/src/main/java/com/cvi/empty.txt rename backend/{cvi-vaccine-stats-parser/src/main/java/com/backjoongwon => cvi-publicdata-parser/src/main/java/com}/cvi/parser/ParameterStringBuilder.java (97%) rename backend/{cvi-vaccine-stats-parser/src/main/java/com/backjoongwon => cvi-publicdata-parser/src/main/java/com}/cvi/parser/Parser.java (97%) rename backend/{cvi-vaccine-stats-parser/src/main/java/com/backjoongwon => cvi-publicdata-parser/src/main/java/com}/cvi/parser/URLWrapper.java (96%) rename backend/{cvi-vaccine-stats-parser/src/main/java/com/backjoongwon => cvi-publicdata-parser/src/main/java/com}/cvi/parser/VaccinationParser.java (90%) rename backend/{cvi-vaccine-stats-parser/src/main/java/com/backjoongwon => cvi-publicdata-parser/src/main/java/com}/cvi/util/DateConverter.java (95%) rename backend/{cvi-vaccine-stats-parser/src/main/java/com/backjoongwon => cvi-publicdata-parser/src/main/java/com}/cvi/util/JsonMapper.java (93%) delete mode 100644 backend/cvi-publicdata-parser/src/main/resources/empty.txt delete mode 100644 backend/cvi-publicdata-parser/src/test/java/com/cvi/empty.txt rename backend/{cvi-vaccine-stats-parser/src/test/java/com/backjoongwon => cvi-publicdata-parser/src/test/java/com}/cvi/parser/ParameterStringBuilderTest.java (95%) rename backend/{cvi-vaccine-stats-parser/src/test/java/com/backjoongwon => cvi-publicdata-parser/src/test/java/com}/cvi/parser/URLWrapperTest.java (96%) rename backend/{cvi-vaccine-stats-parser/src/test/java/com/backjoongwon => cvi-publicdata-parser/src/test/java/com}/cvi/parser/VaccineParserTest.java (96%) rename backend/{cvi-vaccine-stats-parser/src/test/java/com/backjoongwon => cvi-publicdata-parser/src/test/java/com}/cvi/util/DateConverterTest.java (97%) rename backend/{cvi-vaccine-stats-parser/src/test/java/com/backjoongwon => cvi-publicdata-parser/src/test/java/com}/cvi/util/JsonMapperTest.java (97%) delete mode 100644 backend/cvi-publicdata-parser/src/test/resources/empty.txt delete mode 100644 backend/cvi-vaccine-stats-parser/build.gradle delete mode 100644 backend/cvi-vaccine-stats-parser/gradle/wrapper/gradle-wrapper.jar delete mode 100644 backend/cvi-vaccine-stats-parser/gradle/wrapper/gradle-wrapper.properties delete mode 100755 backend/cvi-vaccine-stats-parser/gradlew delete mode 100644 backend/cvi-vaccine-stats-parser/gradlew.bat rename backend/{src/main/java/com/backjoongwon/cvi/user => domain-cvi-oauth-service/src/main/java/com/cvi}/auth/AuthenticationPrincipal.java (87%) rename backend/{src/main/java/com/backjoongwon/cvi/user => domain-cvi-oauth-service/src/main/java/com/cvi}/auth/AuthenticationPrincipalArgumentResolver.java (69%) rename backend/{src/main/java/com/backjoongwon/cvi/user => domain-cvi-oauth-service/src/main/java/com/cvi}/auth/AuthorizationExtractor.java (96%) rename backend/{src/main/java/com/backjoongwon/cvi/user/domain => domain-cvi-oauth-service/src/main/java/com/cvi/auth}/JwtTokenProvider.java (96%) rename backend/{src/main/java/com/backjoongwon/cvi/user => domain-cvi-oauth-service/src/main/java/com/cvi}/auth/SigninInterceptor.java (91%) create mode 100644 backend/domain-cvi-oauth-service/src/main/java/com/cvi/config/WebMvcConfig.java rename backend/{src/main/java/com/backjoongwon/cvi/auth => domain-cvi-oauth-service/src/main/java/com/cvi}/dto/AuthRequest.java (86%) create mode 100644 backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/UserInformation.java rename backend/{src/main/java/com/backjoongwon/cvi/auth => domain-cvi-oauth-service/src/main/java/com/cvi}/dto/oauthtoken/KakaoOAuthToken.java (75%) rename backend/{src/main/java/com/backjoongwon/cvi/auth => domain-cvi-oauth-service/src/main/java/com/cvi}/dto/oauthtoken/NaverOAuthToken.java (51%) rename backend/{src/main/java/com/backjoongwon/cvi/auth => domain-cvi-oauth-service/src/main/java/com/cvi}/dto/oauthtoken/OAuthToken.java (79%) rename backend/{src/main/java/com/backjoongwon/cvi/auth => domain-cvi-oauth-service/src/main/java/com/cvi}/dto/profile/KakaoProfile.java (96%) rename backend/{src/main/java/com/backjoongwon/cvi/auth => domain-cvi-oauth-service/src/main/java/com/cvi}/dto/profile/NaverProfile.java (91%) rename backend/{src/main/java/com/backjoongwon/cvi/auth => domain-cvi-oauth-service/src/main/java/com/cvi}/dto/profile/SocialProfile.java (68%) rename backend/{src/main/java/com/backjoongwon/cvi/auth => domain-cvi-oauth-service/src/main/java/com/cvi}/dto/profile/UserInformation.java (93%) delete mode 100644 backend/domain-cvi-oauth-service/src/main/java/com/cvi/empty.txt rename backend/{src/main/java/com/backjoongwon/cvi/auth/domain/authorization => domain-cvi-oauth-service/src/main/java/com/cvi/parser}/Authorization.java (76%) rename backend/{src/main/java/com/backjoongwon/cvi/auth/domain/authorization => domain-cvi-oauth-service/src/main/java/com/cvi/parser}/AuthorizationManager.java (88%) rename backend/{src/main/java/com/backjoongwon/cvi/auth/domain/authorization => domain-cvi-oauth-service/src/main/java/com/cvi/parser}/KakaoAuthorization.java (90%) rename backend/{src/main/java/com/backjoongwon/cvi/auth/domain/authorization => domain-cvi-oauth-service/src/main/java/com/cvi/parser}/NaverAuthorization.java (90%) create mode 100644 backend/domain-cvi-oauth-service/src/main/resources/application-domain-cvi-oauth.yml delete mode 100644 backend/domain-cvi-oauth-service/src/main/resources/empty.txt rename backend/{src/main/java/com/backjoongwon => domain-cvi-publicdata-service/src/main/java/com}/cvi/config/VaccinationConfig.java (62%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata => domain-cvi-publicdata-service/src/main/java/com/cvi}/dto/RegionVaccinationDataFactory.java (76%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata => domain-cvi-publicdata-service/src/main/java/com/cvi}/dto/VaccinationStatisticResponse.java (91%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata => domain-cvi-publicdata-service/src/main/java/com/cvi}/dto/WorldVaccinationDataFactory.java (76%) delete mode 100644 backend/domain-cvi-publicdata-service/src/main/java/com/cvi/empty.txt rename backend/{src/main/java/com/backjoongwon/cvi/publicdata/domain => domain-cvi-publicdata-service/src/main/java/com/cvi/properties}/PublicDataProperties.java (87%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata => domain-cvi-publicdata-service/src/main/java/com/cvi}/service/PublicDataService.java (89%) create mode 100644 backend/domain-cvi-publicdata-service/src/main/resources/application-domain-cvi-publicdata.yml delete mode 100644 backend/domain-cvi-publicdata-service/src/main/resources/empty.txt rename backend/{src/main/java/com/backjoongwon/cvi/config/ScheduleConfig.java => domain-cvi-scheduler/src/main/java/com/cvi/config/SchedulerConfig.java} (71%) delete mode 100644 backend/domain-cvi-scheduler/src/main/java/com/cvi/empty.txt rename backend/{src/main/java/com/backjoongwon/cvi/publicdata => domain-cvi-scheduler/src/main/java/com/cvi}/service/PublicDataScheduler.java (96%) delete mode 100644 backend/domain-cvi-service/build.gradle delete mode 100644 backend/domain-cvi-service/src/main/java/com/cvi/empty.txt delete mode 100644 backend/domain-cvi-service/src/main/resources/empty.txt delete mode 100644 backend/domain-cvi-service/src/test/java/com/cvi/empty.txt delete mode 100644 backend/domain-cvi-service/src/test/resources/empty.txt rename backend/{src/main/java/com/backjoongwon/cvi/comment/domain => domain-cvi/src/main/java/com/cvi/comment/domain/model}/Comment.java (87%) rename backend/{src/main/java/com/backjoongwon/cvi/comment/domain => domain-cvi/src/main/java/com/cvi/comment/domain/repository}/CommentQueryDsl.java (66%) rename backend/{src/main/java/com/backjoongwon/cvi/comment/domain => domain-cvi/src/main/java/com/cvi/comment/domain/repository}/CommentRepository.java (64%) rename backend/{src/main/java/com/backjoongwon/cvi/comment/domain => domain-cvi/src/main/java/com/cvi/comment/domain/repository}/CommentRepositoryImpl.java (86%) rename backend/{src/main/java/com/backjoongwon/cvi/common/domain => domain-cvi/src/main/java/com/cvi/config}/JpaConfiguration.java (82%) rename backend/{src/main/java/com/backjoongwon/cvi/common/domain => domain-cvi/src/main/java/com/cvi/config}/entity/BaseEntity.java (95%) delete mode 100644 backend/domain-cvi/src/main/java/com/cvi/empty.txt rename backend/{src/main/java/com/backjoongwon/cvi/like/domain => domain-cvi/src/main/java/com/cvi/like/domain/model}/Like.java (83%) rename backend/{src/main/java/com/backjoongwon/cvi/like/domain => domain-cvi/src/main/java/com/cvi/like/domain/repository}/LikeQueryDsl.java (67%) rename backend/{src/main/java/com/backjoongwon/cvi/like/domain => domain-cvi/src/main/java/com/cvi/like/domain/repository}/LikeRepository.java (65%) rename backend/{src/main/java/com/backjoongwon/cvi/like/domain => domain-cvi/src/main/java/com/cvi/like/domain/repository}/LikeRepositoryImpl.java (87%) rename backend/{src/main/java/com/backjoongwon/cvi/post/domain => domain-cvi/src/main/java/com/cvi/post/domain/model}/Comments.java (86%) rename backend/{src/main/java/com/backjoongwon/cvi/post/domain => domain-cvi/src/main/java/com/cvi/post/domain/model}/Filter.java (54%) rename backend/{src/main/java/com/backjoongwon/cvi/post/domain => domain-cvi/src/main/java/com/cvi/post/domain/model}/Likes.java (84%) rename backend/{src/main/java/com/backjoongwon/cvi/post/domain => domain-cvi/src/main/java/com/cvi/post/domain/model}/Post.java (90%) rename backend/{src/main/java/com/backjoongwon/cvi/post/domain => domain-cvi/src/main/java/com/cvi/post/domain/model}/Sort.java (86%) rename backend/{src/main/java/com/backjoongwon/cvi/post/domain => domain-cvi/src/main/java/com/cvi/post/domain/model}/VaccinationType.java (65%) rename backend/{src/main/java/com/backjoongwon/cvi/post/domain => domain-cvi/src/main/java/com/cvi/post/domain/repository}/PostQueryDsl.java (80%) rename backend/{src/main/java/com/backjoongwon/cvi/post/domain => domain-cvi/src/main/java/com/cvi/post/domain/repository}/PostRepository.java (70%) rename backend/{src/main/java/com/backjoongwon/cvi/post/domain => domain-cvi/src/main/java/com/cvi/post/domain/repository}/PostRepositoryImpl.java (89%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata/domain => domain-cvi/src/main/java/com/cvi/publicdata/domain/model}/PublicData.java (89%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata/domain => domain-cvi/src/main/java/com/cvi/publicdata/domain/model}/RegionPopulation.java (97%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata/domain => domain-cvi/src/main/java/com/cvi/publicdata/domain/model}/VaccinationStatistic.java (98%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata/domain => domain-cvi/src/main/java/com/cvi/publicdata/domain/model}/VaccinationStatistics.java (98%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata/domain => domain-cvi/src/main/java/com/cvi/publicdata/domain/repository}/PublicDataRepository.java (60%) rename backend/{src/main/java/com/backjoongwon/cvi/publicdata/domain => domain-cvi/src/main/java/com/cvi/publicdata/domain/repository}/VaccinationStatisticRepository.java (69%) rename backend/{src/main/java/com/backjoongwon/cvi/user/domain => domain-cvi/src/main/java/com/cvi/user/domain/model}/AgeRange.java (92%) rename backend/{src/main/java/com/backjoongwon/cvi/auth/domain/authorization => domain-cvi/src/main/java/com/cvi/user/domain/model}/SocialProvider.java (84%) rename backend/{src/main/java/com/backjoongwon/cvi/user/domain => domain-cvi/src/main/java/com/cvi/user/domain/model}/User.java (90%) rename backend/{src/main/java/com/backjoongwon/cvi/user/domain => domain-cvi/src/main/java/com/cvi/user/domain/repository}/UserRepository.java (70%) create mode 100644 backend/domain-cvi/src/main/resources/application-domain-cvi.yml create mode 100644 backend/domain-cvi/src/main/resources/db/migration/V20210809__Create_init.sql delete mode 100644 backend/domain-cvi/src/main/resources/empty.txt delete mode 100644 backend/src/docs/asciidoc/index.html delete mode 100644 backend/src/main/java/com/backjoongwon/cvi/common/EnvSecret.java diff --git a/backend/app-cvi-admin/build.gradle b/backend/app-cvi-admin/build.gradle index 25fb3aff..430a7b98 100644 --- a/backend/app-cvi-admin/build.gradle +++ b/backend/app-cvi-admin/build.gradle @@ -1,19 +1,6 @@ -plugins { - id 'java' -} - -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' - -repositories { - mavenCentral() -} +bootJar { enabled = false } +jar { enabled = true } dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' -} -test { - useJUnitPlatform() -} \ No newline at end of file +} diff --git a/backend/app-cvi-api/build.gradle b/backend/app-cvi-api/build.gradle index 25fb3aff..788aa054 100644 --- a/backend/app-cvi-api/build.gradle +++ b/backend/app-cvi-api/build.gradle @@ -1,19 +1,54 @@ -plugins { - id 'java' -} +version = '0.0.1' + +dependencies { + implementation project(path:':common-cvi', configuration: 'default') + implementation project(path:':domain-cvi', configuration: 'default') + implementation project(path:':domain-cvi-oauth-service', configuration: 'default') + implementation project(path:':domain-cvi-scheduler', configuration: 'default') + implementation project(path:':domain-cvi-publicdata-service', configuration: 'default') -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-validation' + + //cache + implementation 'org.springframework.boot:spring-boot-starter-cache' + implementation 'javax.cache:cache-api:1.1.1' + implementation 'org.ehcache:ehcache:3.9.4' -repositories { - mavenCentral() } -dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 + def Qdomains = [] + + for (qPattern in "*.QA".."*.QZ") { + Qdomains.add(qPattern + "*") + } + + violationRules { // 위반 규칙 + rule { + enabled = true + element = 'BUNDLE' + + limit { + counter = 'INSTRUCTION' + value = 'COVEREDRATIO' + minimum = 0.80 + } + + excludes = [ + // 커버리지 제외할 클래스 + '*.DataLoader*', + '*.CviApplication*', + '*.DummyData*', + '*.KakaoProfile*', + '*.NaverProfile*' + ] + Qdomains + } + } } -test { - useJUnitPlatform() +sonarqube { + properties { + property "sonar.exclusions", "**/*Test*.*, **/Q*.java, **/*Doc*.java" + } } \ No newline at end of file diff --git a/backend/src/docs/asciidoc/index.adoc b/backend/app-cvi-api/docs/asciidoc/index.adoc similarity index 100% rename from backend/src/docs/asciidoc/index.adoc rename to backend/app-cvi-api/docs/asciidoc/index.adoc diff --git a/backend/app-cvi-api/src/main/java/com/cvi/CentralVaccinationInformationApplication.java b/backend/app-cvi-api/src/main/java/com/cvi/CentralVaccinationInformationApplication.java new file mode 100644 index 00000000..5f0da41f --- /dev/null +++ b/backend/app-cvi-api/src/main/java/com/cvi/CentralVaccinationInformationApplication.java @@ -0,0 +1,12 @@ +package com.cvi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CentralVaccinationInformationApplication { + + public static void main(String[] args) { + SpringApplication.run(CentralVaccinationInformationApplication.class, args); + } +} \ No newline at end of file diff --git a/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java b/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java new file mode 100644 index 00000000..003acfc8 --- /dev/null +++ b/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java @@ -0,0 +1,126 @@ +package com.cvi; + +import com.cvi.comment.domain.model.Comment; +import com.cvi.like.domain.model.Like; +import com.cvi.like.domain.repository.LikeRepository; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import javax.persistence.Query; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.*; + +@Component +@RequiredArgsConstructor +@Profile("!local&!test") +public class DataLoader implements CommandLineRunner { + + private static final int USER_COUNT = 50; + private static final int POST_COUNT = 300; + private final UserRepository userRepository; + private final PostRepository postRepository; + private final LikeRepository likeRepository; + private final Random random = new Random(); + + @Autowired + private final EntityManager em; + + @Override + @Transactional + public void run(String... args) { + if (userRepository.findAll().isEmpty()) { + List users = new ArrayList<>(); + for (int i = 0; i < USER_COUNT; i++) { + User user = User.builder().nickname(String.valueOf(i)).socialId("socialId").socialProvider(SocialProvider.KAKAO).profileUrl("pictureUrl").ageRange(AgeRange.FIFTIES).build(); + users.add(user); + + User updateUser = User.builder().nickname(user.getNickname()).socialId("socialId").socialProvider(SocialProvider.NAVER).profileUrl("pictureUrl").ageRange(AgeRange.FORTIES).shotVerified(true).build(); + user.update(updateUser); + } + userRepository.saveAll(users); + + List posts = new ArrayList<>(); + List allComments = new ArrayList<>(); + for (int i = 0; i < POST_COUNT; i++) { + int randomInt = random.nextInt(USER_COUNT); + User user = users.get(i % USER_COUNT); + if (randomInt % 4 == 0) { + Post post = Post.builder().content("글" + (i + 1)).vaccinationType(VaccinationType.PFIZER).user(user).build(); + List comments = putLikeAndCommentRandomly(users, USER_COUNT, post, random); + allComments.addAll(comments); + posts.add(post); + } + if (randomInt % 4 == 1) { + Post post = Post.builder().content("글" + (i + 1)).vaccinationType(VaccinationType.ASTRAZENECA).user(user).build(); + posts.add(post); + } + if (randomInt % 4 == 2) { + Post post = Post.builder().content("글" + (i + 1)).vaccinationType(VaccinationType.JANSSEN).user(user).build(); + posts.add(post); + } + if (randomInt % 4 == 3) { + Post post = Post.builder().content("글" + (i + 1)).vaccinationType(VaccinationType.MODERNA).user(user).build(); + posts.add(post); + } + } + postRepository.saveAll(posts); + + for (Post post : posts) { + Long id = post.getId(); + Query q = em.createNativeQuery("UPDATE post SET created_at=:created_at WHERE post_id=:post_id"); + q.setParameter("created_at", generateRandomLocalDateTime()); + q.setParameter("post_id", id); + q.executeUpdate(); + } + + for (Comment comment : allComments) { + Long id = comment.getId(); + Query q = em.createNativeQuery("UPDATE comment SET created_at=:created_at WHERE comment_id=:comment_id"); + q.setParameter("created_at", generateRandomLocalDateTime()); + q.setParameter("comment_id", id); + q.executeUpdate(); + } + } + } + + private List putLikeAndCommentRandomly(List users, int userCount, Post post, Random random) { + Set userSet = new HashSet<>(); + List comments = new ArrayList<>(); + + for (int j = 0; j < random.nextInt(30); j++) { + int randomUser = random.nextInt(userCount); + userSet.add(users.get(randomUser)); + } + + for (User user : userSet) { + Like like = Like.builder().user(user).build(); + post.assignLike(like); + Comment comment = Comment.builder().content("Id:" + user.getId() + " 유저의 댓글").user(user).build(); + comments.add(comment); + post.assignComment(comment); + likeRepository.save(like); + } + return comments; + } + + private Timestamp generateRandomLocalDateTime() { + int randomHour = random.nextInt(24); + int randomMins = random.nextInt(60); + int randomDays = random.nextInt(20); + LocalDateTime localDateTime = LocalDateTime.now().minusHours(randomHour).minusMinutes(randomMins).minusDays(randomDays); + return Timestamp.valueOf(localDateTime); + } +} diff --git a/backend/app-cvi-api/src/main/java/com/cvi/DummyData.java b/backend/app-cvi-api/src/main/java/com/cvi/DummyData.java new file mode 100644 index 00000000..6948132d --- /dev/null +++ b/backend/app-cvi-api/src/main/java/com/cvi/DummyData.java @@ -0,0 +1,40 @@ +package com.cvi; + +public class DummyData { + public static final String DUMMY_DATA_10000 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean odio orci, venenatis sed vulputate quis, ultricies non massa. Nulla commodo justo at metus consequat hendrerit. Sed nec mauris urna. Nunc turpis est, pulvinar vitae tellus non, sollicitudin commodo ligula. Nullam est ante, faucibus id leo malesuada, elementum hendrerit tortor. Sed id metus eu leo aliquet faucibus et ac felis. Aliquam nec laoreet est, interdum tempor mauris. Etiam feugiat, ante sed ullamcorper euismod, ligula lorem ultricies nisi, nec bibendum est dui eget metus. Nam ac congue libero.\n" + + "\n" + + "Pellentesque blandit risus quis consequat maximus. Donec ullamcorper facilisis ante, non luctus ex condimentum quis. Quisque pulvinar sagittis nulla at pulvinar. Nam mi urna, rutrum non erat id, dapibus ultricies tortor. Aliquam malesuada metus eu erat imperdiet pulvinar. In eget iaculis metus. Suspendisse nec orci auctor, egestas elit ut, ultrices sapien. Suspendisse tincidunt iaculis tellus id scelerisque. In non congue orci. Aliquam erat volutpat. Sed iaculis diam at justo porttitor, pulvinar tristique mauris finibus. Sed lobortis venenatis nunc sit amet cursus. Aenean mattis enim lectus, sit amet ullamcorper arcu sodales id.\n" + + "\n" + + "Quisque ornare tincidunt enim. Maecenas quis laoreet mi, in hendrerit lacus. Praesent id turpis in sapien euismod accumsan. Cras euismod sollicitudin sem nec aliquet. Aenean magna ex, luctus ut nulla id, consectetur sodales risus. Curabitur interdum elit et consectetur aliquet. Morbi non fringilla nisl.\n" + + "\n" + + "Donec neque elit, dapibus in malesuada at, convallis in dui. Donec consectetur dignissim magna, et ultrices felis finibus id. Etiam a urna lectus. Proin neque metus, iaculis eget mauris ac, congue vulputate nisl. Pellentesque sodales felis eu diam scelerisque molestie. Pellentesque commodo tempus vestibulum. Proin non quam egestas, pulvinar augue eu, hendrerit lorem. Aenean vel mollis nisi, sit amet scelerisque dolor. Vestibulum feugiat eleifend tellus, ac auctor ex ultricies ut. Aenean volutpat vulputate risus a euismod. Nulla tincidunt massa pulvinar dapibus pharetra. Curabitur a blandit lectus, vel posuere purus. Ut erat diam, bibendum vitae luctus quis, sollicitudin eget magna. Phasellus dignissim in odio feugiat blandit. Etiam porta sollicitudin massa sit amet auctor. Suspendisse rutrum pellentesque fermentum.\n" + + "\n" + + "Maecenas non faucibus lorem, eget tempor sapien. Pellentesque ac augue id justo malesuada blandit. In auctor varius scelerisque. Nunc cursus id elit et facilisis. Aenean in egestas erat. Nullam eleifend vitae diam at vehicula. Suspendisse ut diam at elit mollis accumsan. Nulla facilisi.\n" + + "\n" + + "Etiam vel elit a lorem efficitur ullamcorper id laoreet neque. Pellentesque nec imperdiet urna. Vestibulum sodales ante ac justo rutrum, id tempus nulla tincidunt. Aenean accumsan posuere enim eu vestibulum. Donec ex metus, molestie ac enim a, ultrices dapibus ipsum. Pellentesque neque quam, lobortis a lacus sed, molestie finibus urna. Curabitur a dolor quis ante malesuada blandit.\n" + + "\n" + + "Aliquam in massa ac odio mollis malesuada vel et diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam placerat feugiat elit eget iaculis. Cras arcu arcu, suscipit ac mi eu, pharetra pulvinar diam. Praesent tincidunt, lorem id auctor mollis, mi ipsum rhoncus mauris, vel placerat elit massa quis leo. Curabitur et mi fringilla quam blandit pulvinar. Nunc enim sem, maximus vitae sem at, posuere euismod risus. Duis euismod ullamcorper sem eget semper. Curabitur et neque vitae neque euismod pharetra. Curabitur vel mi accumsan, facilisis neque nec, consequat lectus. Mauris tristique velit vitae congue consequat. Donec sit amet tortor sed ante congue bibendum a cursus libero.\n" + + "\n" + + "Praesent tristique eget neque quis bibendum. Donec quis ante sed orci varius maximus. Praesent gravida in massa nec tincidunt. Nulla facilisi. Praesent magna enim, placerat eu libero id, hendrerit malesuada diam. Fusce vestibulum nulla ut erat elementum iaculis. Fusce eu posuere purus. Quisque efficitur rutrum metus quis vestibulum.\n" + + "\n" + + "Fusce vitae semper orci. Quisque eu urna lobortis, auctor magna quis, pellentesque sem. Etiam vitae vehicula dolor, sit amet pretium nulla. Ut efficitur pretium augue in luctus. Vestibulum in odio a diam tristique efficitur. Nulla egestas quis risus at imperdiet. Maecenas eget bibendum nisi, eu faucibus odio.\n" + + "\n" + + "Vestibulum porttitor a nulla a varius. Pellentesque nec lacinia nunc, nec elementum est. Vivamus commodo tortor et velit euismod blandit. Maecenas luctus pharetra velit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque vulputate leo at nisi rutrum mattis. Pellentesque luctus malesuada turpis. Duis non erat quis eros hendrerit accumsan.\n" + + "\n" + + "Vivamus placerat, mi vitae fermentum pulvinar, massa lacus commodo tellus, in elementum neque purus elementum odio. Donec auctor volutpat finibus. Cras feugiat eu ipsum eu tincidunt. Sed non tortor ultrices, cursus sapien in, euismod nibh. Nunc interdum viverra dignissim. Nunc finibus finibus fermentum. Proin faucibus blandit lorem, nec pretium quam fermentum nec. In id euismod nisi, eu euismod tellus. Nulla interdum, arcu id vehicula viverra, lacus velit pellentesque sapien, sit amet sollicitudin erat metus in augue. Proin in congue dui. Aenean pharetra odio nec ornare suscipit. Nunc et libero magna. In ut quam ante.\n" + + "\n" + + "Fusce dignissim scelerisque neque ut tincidunt. Quisque ut lacinia metus, ut luctus lacus. Vivamus et dictum metus, et cursus libero. Phasellus turpis libero, hendrerit a mollis ac, semper feugiat urna. Nullam id sagittis quam, eu facilisis enim. Maecenas in tortor lacinia, aliquet felis non, congue leo. Proin enim massa, malesuada interdum tempus eget, venenatis id tellus. Etiam ultricies, lacus quis egestas pulvinar, ipsum nibh luctus nisl, sed interdum felis leo eu leo. Mauris faucibus semper nisi at rhoncus. Quisque vel venenatis nisi. Ut consectetur mauris nec magna lacinia fringilla. Nullam luctus fermentum odio. Donec ultricies augue sed dui elementum, sed euismod nibh laoreet. Maecenas condimentum sapien at faucibus mattis. Pellentesque porttitor sed tortor et faucibus. Aliquam sed quam eget lacus aliquam molestie sit amet at urna.\n" + + "\n" + + "Curabitur eget metus interdum diam volutpat efficitur. Maecenas viverra massa in est volutpat, eu convallis nisi eleifend. Sed molestie sagittis mauris. Quisque id arcu vitae lorem tristique pretium. Mauris cursus ex dolor, nec malesuada urna iaculis sit amet. Mauris pharetra magna eget sapien varius aliquet. Maecenas pulvinar orci non condimentum dictum. Maecenas faucibus rutrum arcu, nec aliquet elit dignissim ut. Integer ullamcorper massa eu lectus malesuada rutrum. Vestibulum maximus euismod ante, a euismod augue dapibus non. Praesent tellus orci, tempus quis dignissim id, ultricies porta felis. Maecenas ut ipsum dolor.\n" + + "\n" + + "Mauris pulvinar nisi et lorem elementum tristique. Vestibulum tempus, nunc id dictum condimentum, felis nisl dapibus sem, sit amet commodo metus tortor ut dui. Suspendisse viverra urna efficitur massa pellentesque mattis. Sed posuere, urna mollis bibendum ornare, felis dui congue nibh, sed placerat velit tellus vitae tellus. Cras maximus blandit diam nec feugiat. Nunc bibendum erat vitae libero lobortis pulvinar. In ut aliquam orci. Donec feugiat, ex congue pretium dictum, justo enim feugiat risus, malesuada ornare purus diam quis turpis. Phasellus vitae est id turpis consectetur semper. Quisque vel euismod justo, molestie vestibulum leo. Donec nibh nunc, rutrum ut diam ut, tincidunt bibendum est. Donec tristique dolor et interdum mollis. Aliquam a mi nulla.\n" + + "\n" + + "Morbi hendrerit sagittis nulla quis porta. Phasellus vitae vehicula sem, non mollis lorem. Donec mollis vestibulum nunc, vitae laoreet neque consectetur eget. Sed varius urna et urna porttitor, eu imperdiet velit sollicitudin. Nulla dolor dui, imperdiet at facilisis eget, scelerisque sed nisi. Integer maximus congue viverra. Ut mattis faucibus fermentum. Donec malesuada mattis sollicitudin. Maecenas vel est fringilla, elementum lectus et, rutrum mauris. Sed non viverra purus, ut finibus felis. Nunc ac fermentum tortor, non faucibus mauris.\n" + + "\n" + + "Aliquam erat volutpat. Etiam nulla erat, pretium id enim quis, hendrerit congue ligula. Sed vitae accumsan sem. Praesent ligula turpis, bibendum vitae nulla ut, efficitur commodo erat. Vestibulum odio nibh, convallis id ligula eget, pretium condimentum erat. Nam molestie tortor nec nibh ornare, at ultricies massa molestie. Aenean sodales dolor risus, sed fringilla purus interdum accumsan. In hac habitasse platea dictumst. In sit amet nisl nec leo sagittis tincidunt. Pellentesque at ligula at sapien suscipit facilisis. Sed nec feugiat neque. Sed eu neque lectus. Nullam sed magna ac mi pretium tristique. Integer at velit erat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris efficitur nisl eget metus porta, ut tincidunt felis ultricies.\n" + + "\n" + + "Nullam sit amet maximus lacus. Suspendisse elit erat, vestibulum vel magna mollis, iaculis hendrerit eros. Praesent quis eros sed lorem faucibus feugiat vitae non sapien. Aliquam non mi sed dolor accumsan finibus id in odio. Nunc a placerat mauris. In hac habitasse platea dictumst. Curabitur quis diam facilisis, vulputate ligula nec, auctor mauris. Suspendisse potenti. Duis tempor neque diam, vel ornare metus fringilla quis. Proin a odio non nisi egestas blandit. Vestibulum sit amet leo odio. Nulla quis quam vel mauris eleifend dapibus et sed sapien. Suspendisse cursus porta augue, sed scelerisque libero faucibus quis. Vestibulum ipsum sem, pulvinar id tellus a, tincidunt cursus velit. Pellentesque tristique interdum est, nec sollicitudin justo efficitur quis.\n" + + "\n" + + "Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed tellus nulla, fringilla ut tortor ut, pellentesque faucibus dui. Donec posuere risus ut enim fermentum tristique. Nullam a erat nec massa rutrum bibendum. Duis rutrum porttitor massa nunc."; +} + diff --git a/backend/src/main/java/com/backjoongwon/cvi/config/CacheConfig.java b/backend/app-cvi-api/src/main/java/com/cvi/config/CacheConfig.java similarity index 83% rename from backend/src/main/java/com/backjoongwon/cvi/config/CacheConfig.java rename to backend/app-cvi-api/src/main/java/com/cvi/config/CacheConfig.java index a9e402a1..1d59089b 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/config/CacheConfig.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/config/CacheConfig.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.config; +package com.cvi.config; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Configuration; diff --git a/backend/src/main/java/com/backjoongwon/cvi/config/WebMvcConfig.java b/backend/app-cvi-api/src/main/java/com/cvi/config/WebMvcConfig.java similarity index 89% rename from backend/src/main/java/com/backjoongwon/cvi/config/WebMvcConfig.java rename to backend/app-cvi-api/src/main/java/com/cvi/config/WebMvcConfig.java index 12221726..498708f8 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/config/WebMvcConfig.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/config/WebMvcConfig.java @@ -1,7 +1,7 @@ -package com.backjoongwon.cvi.config; +package com.cvi.config; -import com.backjoongwon.cvi.user.auth.AuthenticationPrincipalArgumentResolver; -import com.backjoongwon.cvi.user.auth.SigninInterceptor; +import com.cvi.auth.AuthenticationPrincipalArgumentResolver; +import com.cvi.auth.SigninInterceptor; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/controller/AuthController.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/AuthController.java similarity index 78% rename from backend/src/main/java/com/backjoongwon/cvi/auth/controller/AuthController.java rename to backend/app-cvi-api/src/main/java/com/cvi/controller/AuthController.java index 802cbb7b..11525fde 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/controller/AuthController.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/AuthController.java @@ -1,8 +1,8 @@ -package com.backjoongwon.cvi.auth.controller; +package com.cvi.controller; -import com.backjoongwon.cvi.auth.dto.AuthRequest; -import com.backjoongwon.cvi.auth.service.AuthService; -import com.backjoongwon.cvi.user.dto.UserResponse; +import com.cvi.dto.AuthRequest; +import com.cvi.dto.UserResponse; +import com.cvi.service.AuthService; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; diff --git a/backend/src/main/java/com/backjoongwon/cvi/comment/controller/CommentController.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/CommentController.java similarity index 88% rename from backend/src/main/java/com/backjoongwon/cvi/comment/controller/CommentController.java rename to backend/app-cvi-api/src/main/java/com/cvi/controller/CommentController.java index dc412758..41e36309 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/comment/controller/CommentController.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/CommentController.java @@ -1,10 +1,10 @@ -package com.backjoongwon.cvi.comment.controller; +package com.cvi.controller; -import com.backjoongwon.cvi.comment.service.CommentService; -import com.backjoongwon.cvi.comment.dto.CommentRequest; -import com.backjoongwon.cvi.comment.dto.CommentResponse; -import com.backjoongwon.cvi.user.auth.AuthenticationPrincipal; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.auth.AuthenticationPrincipal; +import com.cvi.dto.CommentRequest; +import com.cvi.dto.CommentResponse; +import com.cvi.service.CommentService; +import com.cvi.user.domain.model.User; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; diff --git a/backend/src/main/java/com/backjoongwon/cvi/like/controller/LikeController.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/LikeController.java similarity index 78% rename from backend/src/main/java/com/backjoongwon/cvi/like/controller/LikeController.java rename to backend/app-cvi-api/src/main/java/com/cvi/controller/LikeController.java index fa79407c..a78cdec2 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/like/controller/LikeController.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/LikeController.java @@ -1,9 +1,9 @@ -package com.backjoongwon.cvi.like.controller; +package com.cvi.controller; -import com.backjoongwon.cvi.like.service.LikeService; -import com.backjoongwon.cvi.post.dto.LikeResponse; -import com.backjoongwon.cvi.user.auth.AuthenticationPrincipal; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.auth.AuthenticationPrincipal; +import com.cvi.dto.LikeResponse; +import com.cvi.service.LikeService; +import com.cvi.user.domain.model.User; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/controller/PostController.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/PostController.java similarity index 86% rename from backend/src/main/java/com/backjoongwon/cvi/post/controller/PostController.java rename to backend/app-cvi-api/src/main/java/com/cvi/controller/PostController.java index b845813f..87ed5ed6 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/controller/PostController.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/PostController.java @@ -1,12 +1,12 @@ -package com.backjoongwon.cvi.post.controller; +package com.cvi.controller; -import com.backjoongwon.cvi.post.service.PostService; -import com.backjoongwon.cvi.post.domain.Sort; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.post.dto.PostRequest; -import com.backjoongwon.cvi.post.dto.PostResponse; -import com.backjoongwon.cvi.user.auth.AuthenticationPrincipal; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.auth.AuthenticationPrincipal; +import com.cvi.dto.PostRequest; +import com.cvi.dto.PostResponse; +import com.cvi.post.domain.model.Sort; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.service.PostService; +import com.cvi.user.domain.model.User; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; diff --git a/backend/src/main/java/com/backjoongwon/cvi/deploy/ProfileController.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/ProfileController.java similarity index 88% rename from backend/src/main/java/com/backjoongwon/cvi/deploy/ProfileController.java rename to backend/app-cvi-api/src/main/java/com/cvi/controller/ProfileController.java index 9f9750d4..4ace8383 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/deploy/ProfileController.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/ProfileController.java @@ -1,6 +1,6 @@ -package com.backjoongwon.cvi.deploy; +package com.cvi.controller; -import com.backjoongwon.cvi.common.exception.InvalidOperationException; +import com.cvi.exception.InvalidOperationException; import lombok.RequiredArgsConstructor; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.GetMapping; diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/controller/PublicDataController.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/PublicDataController.java similarity index 92% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/controller/PublicDataController.java rename to backend/app-cvi-api/src/main/java/com/cvi/controller/PublicDataController.java index f30a35bd..c7619549 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/controller/PublicDataController.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/PublicDataController.java @@ -1,7 +1,7 @@ -package com.backjoongwon.cvi.publicdata.controller; +package com.cvi.controller; -import com.backjoongwon.cvi.publicdata.service.PublicDataService; -import com.backjoongwon.cvi.publicdata.dto.VaccinationStatisticResponse; +import com.cvi.dto.VaccinationStatisticResponse; +import com.cvi.service.PublicDataService; import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/controller/UserController.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/UserController.java similarity index 83% rename from backend/src/main/java/com/backjoongwon/cvi/user/controller/UserController.java rename to backend/app-cvi-api/src/main/java/com/cvi/controller/UserController.java index 37358113..4a7103c3 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/controller/UserController.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/UserController.java @@ -1,13 +1,13 @@ -package com.backjoongwon.cvi.user.controller; +package com.cvi.controller; -import com.backjoongwon.cvi.post.service.PostService; -import com.backjoongwon.cvi.post.domain.Filter; -import com.backjoongwon.cvi.post.dto.PostWithCommentResponse; -import com.backjoongwon.cvi.user.service.UserService; -import com.backjoongwon.cvi.user.auth.AuthenticationPrincipal; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.dto.UserRequest; -import com.backjoongwon.cvi.user.dto.UserResponse; +import com.cvi.auth.AuthenticationPrincipal; +import com.cvi.dto.PostWithCommentResponse; +import com.cvi.dto.UserRequest; +import com.cvi.dto.UserResponse; +import com.cvi.post.domain.model.Filter; +import com.cvi.service.PostService; +import com.cvi.service.UserService; +import com.cvi.user.domain.model.User; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/handler/CVIControllerAdvice.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/exceptionhandler/CVIControllerAdvice.java similarity index 93% rename from backend/src/main/java/com/backjoongwon/cvi/common/handler/CVIControllerAdvice.java rename to backend/app-cvi-api/src/main/java/com/cvi/controller/exceptionhandler/CVIControllerAdvice.java index 977ccb1e..ada989ee 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/handler/CVIControllerAdvice.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/exceptionhandler/CVIControllerAdvice.java @@ -1,9 +1,7 @@ -package com.backjoongwon.cvi.common.handler; +package com.cvi.controller.exceptionhandler; -import com.backjoongwon.cvi.common.exception.*; +import com.cvi.exception.*; import lombok.extern.slf4j.Slf4j; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/dto/AgeRangeResponse.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/AgeRangeResponse.java similarity index 83% rename from backend/src/main/java/com/backjoongwon/cvi/user/dto/AgeRangeResponse.java rename to backend/app-cvi-api/src/main/java/com/cvi/dto/AgeRangeResponse.java index 8eb44330..b325aba9 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/dto/AgeRangeResponse.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/AgeRangeResponse.java @@ -1,6 +1,6 @@ -package com.backjoongwon.cvi.user.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.user.domain.AgeRange; +import com.cvi.user.domain.model.AgeRange; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/com/backjoongwon/cvi/comment/dto/CommentRequest.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/CommentRequest.java similarity index 86% rename from backend/src/main/java/com/backjoongwon/cvi/comment/dto/CommentRequest.java rename to backend/app-cvi-api/src/main/java/com/cvi/dto/CommentRequest.java index 6fc0eca3..20f7182c 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/comment/dto/CommentRequest.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/CommentRequest.java @@ -1,6 +1,6 @@ -package com.backjoongwon.cvi.comment.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.comment.domain.Comment; +import com.cvi.comment.domain.model.Comment; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/com/backjoongwon/cvi/comment/dto/CommentResponse.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/CommentResponse.java similarity index 86% rename from backend/src/main/java/com/backjoongwon/cvi/comment/dto/CommentResponse.java rename to backend/app-cvi-api/src/main/java/com/cvi/dto/CommentResponse.java index 79d5b061..ed2defbf 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/comment/dto/CommentResponse.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/CommentResponse.java @@ -1,7 +1,6 @@ -package com.backjoongwon.cvi.comment.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.user.dto.UserResponse; +import com.cvi.comment.domain.model.Comment; import lombok.Getter; import java.time.LocalDateTime; diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/dto/LikeResponse.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/LikeResponse.java similarity index 89% rename from backend/src/main/java/com/backjoongwon/cvi/post/dto/LikeResponse.java rename to backend/app-cvi-api/src/main/java/com/cvi/dto/LikeResponse.java index c415022b..bd8ea3a1 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/dto/LikeResponse.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/LikeResponse.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.post.dto; +package com.cvi.dto; import lombok.AccessLevel; import lombok.Getter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/dto/PostRequest.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostRequest.java similarity index 83% rename from backend/src/main/java/com/backjoongwon/cvi/post/dto/PostRequest.java rename to backend/app-cvi-api/src/main/java/com/cvi/dto/PostRequest.java index 3ef5e5d7..e9e6e78c 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/dto/PostRequest.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostRequest.java @@ -1,14 +1,13 @@ -package com.backjoongwon.cvi.post.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.VaccinationType; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; - @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class PostRequest { diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/dto/PostResponse.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostResponse.java similarity index 87% rename from backend/src/main/java/com/backjoongwon/cvi/post/dto/PostResponse.java rename to backend/app-cvi-api/src/main/java/com/cvi/dto/PostResponse.java index 79f54f66..6607657a 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/dto/PostResponse.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostResponse.java @@ -1,9 +1,8 @@ -package com.backjoongwon.cvi.post.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.dto.UserResponse; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.user.domain.model.User; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/dto/PostWithCommentResponse.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostWithCommentResponse.java similarity index 85% rename from backend/src/main/java/com/backjoongwon/cvi/post/dto/PostWithCommentResponse.java rename to backend/app-cvi-api/src/main/java/com/cvi/dto/PostWithCommentResponse.java index 9772e2b4..5b8779d3 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/dto/PostWithCommentResponse.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostWithCommentResponse.java @@ -1,11 +1,9 @@ -package com.backjoongwon.cvi.post.dto; - -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.comment.dto.CommentResponse; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.dto.UserResponse; +package com.cvi.dto; + +import com.cvi.comment.domain.model.Comment; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.user.domain.model.User; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/dto/UserRequest.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/UserRequest.java similarity index 90% rename from backend/src/main/java/com/backjoongwon/cvi/user/dto/UserRequest.java rename to backend/app-cvi-api/src/main/java/com/cvi/dto/UserRequest.java index 41af5418..86dee0a7 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/dto/UserRequest.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/UserRequest.java @@ -1,8 +1,8 @@ -package com.backjoongwon.cvi.user.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/dto/UserResponse.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/UserResponse.java similarity index 91% rename from backend/src/main/java/com/backjoongwon/cvi/user/dto/UserResponse.java rename to backend/app-cvi-api/src/main/java/com/cvi/dto/UserResponse.java index 5efad0c9..e596f6e8 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/dto/UserResponse.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/UserResponse.java @@ -1,7 +1,7 @@ -package com.backjoongwon.cvi.user.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/service/AuthService.java b/backend/app-cvi-api/src/main/java/com/cvi/service/AuthService.java similarity index 75% rename from backend/src/main/java/com/backjoongwon/cvi/auth/service/AuthService.java rename to backend/app-cvi-api/src/main/java/com/cvi/service/AuthService.java index 8cab58b4..715a98fb 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/service/AuthService.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/AuthService.java @@ -1,12 +1,12 @@ -package com.backjoongwon.cvi.auth.service; +package com.cvi.service; -import com.backjoongwon.cvi.auth.domain.authorization.AuthorizationManager; -import com.backjoongwon.cvi.auth.dto.AuthRequest; -import com.backjoongwon.cvi.auth.dto.profile.UserInformation; -import com.backjoongwon.cvi.user.domain.JwtTokenProvider; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.domain.UserRepository; -import com.backjoongwon.cvi.user.dto.UserResponse; +import com.cvi.auth.JwtTokenProvider; +import com.cvi.dto.AuthRequest; +import com.cvi.dto.UserResponse; +import com.cvi.dto.profile.UserInformation; +import com.cvi.parser.AuthorizationManager; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/cache/CacheEventLogger.java b/backend/app-cvi-api/src/main/java/com/cvi/service/CacheEventLogger.java similarity index 90% rename from backend/src/main/java/com/backjoongwon/cvi/common/cache/CacheEventLogger.java rename to backend/app-cvi-api/src/main/java/com/cvi/service/CacheEventLogger.java index a1a61479..f0867d94 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/cache/CacheEventLogger.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/CacheEventLogger.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.cache; +package com.cvi.service; import lombok.extern.slf4j.Slf4j; import org.ehcache.event.CacheEvent; diff --git a/backend/src/main/java/com/backjoongwon/cvi/comment/service/CommentService.java b/backend/app-cvi-api/src/main/java/com/cvi/service/CommentService.java similarity index 84% rename from backend/src/main/java/com/backjoongwon/cvi/comment/service/CommentService.java rename to backend/app-cvi-api/src/main/java/com/cvi/service/CommentService.java index f28b7f76..12521340 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/comment/service/CommentService.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/CommentService.java @@ -1,14 +1,14 @@ -package com.backjoongwon.cvi.comment.service; +package com.cvi.service; -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.comment.domain.CommentRepository; -import com.backjoongwon.cvi.comment.dto.CommentRequest; -import com.backjoongwon.cvi.comment.dto.CommentResponse; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.PostRepository; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.comment.domain.model.Comment; +import com.cvi.comment.domain.repository.CommentRepository; +import com.cvi.dto.CommentRequest; +import com.cvi.dto.CommentResponse; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.User; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; diff --git a/backend/src/main/java/com/backjoongwon/cvi/like/service/LikeService.java b/backend/app-cvi-api/src/main/java/com/cvi/service/LikeService.java similarity index 79% rename from backend/src/main/java/com/backjoongwon/cvi/like/service/LikeService.java rename to backend/app-cvi-api/src/main/java/com/cvi/service/LikeService.java index b2f19351..baec4e45 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/like/service/LikeService.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/LikeService.java @@ -1,13 +1,13 @@ -package com.backjoongwon.cvi.like.service; - -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.like.domain.Like; -import com.backjoongwon.cvi.like.domain.LikeRepository; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.PostRepository; -import com.backjoongwon.cvi.post.dto.LikeResponse; -import com.backjoongwon.cvi.user.domain.User; +package com.cvi.service; + +import com.cvi.dto.LikeResponse; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.like.domain.model.Like; +import com.cvi.like.domain.repository.LikeRepository; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.User; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/service/PostService.java b/backend/app-cvi-api/src/main/java/com/cvi/service/PostService.java similarity index 89% rename from backend/src/main/java/com/backjoongwon/cvi/post/service/PostService.java rename to backend/app-cvi-api/src/main/java/com/cvi/service/PostService.java index a97c51ed..8bb8228a 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/service/PostService.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/PostService.java @@ -1,16 +1,20 @@ -package com.backjoongwon.cvi.post.service; - -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.comment.domain.CommentRepository; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.like.domain.Like; -import com.backjoongwon.cvi.like.domain.LikeRepository; -import com.backjoongwon.cvi.post.domain.*; -import com.backjoongwon.cvi.post.dto.PostRequest; -import com.backjoongwon.cvi.post.dto.PostResponse; -import com.backjoongwon.cvi.post.dto.PostWithCommentResponse; -import com.backjoongwon.cvi.user.domain.User; +package com.cvi.service; + +import com.cvi.comment.domain.model.Comment; +import com.cvi.comment.domain.repository.CommentRepository; +import com.cvi.dto.PostRequest; +import com.cvi.dto.PostResponse; +import com.cvi.dto.PostWithCommentResponse; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.like.domain.model.Like; +import com.cvi.like.domain.repository.LikeRepository; +import com.cvi.post.domain.model.Filter; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.Sort; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.User; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/service/UserService.java b/backend/app-cvi-api/src/main/java/com/cvi/service/UserService.java similarity index 83% rename from backend/src/main/java/com/backjoongwon/cvi/user/service/UserService.java rename to backend/app-cvi-api/src/main/java/com/cvi/service/UserService.java index d2eb66a4..157dd2ca 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/service/UserService.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/UserService.java @@ -1,14 +1,14 @@ -package com.backjoongwon.cvi.user.service; +package com.cvi.service; -import com.backjoongwon.cvi.common.exception.DuplicateException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.post.domain.PostRepository; -import com.backjoongwon.cvi.user.domain.JwtTokenProvider; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.domain.UserRepository; -import com.backjoongwon.cvi.user.dto.UserRequest; -import com.backjoongwon.cvi.user.dto.UserResponse; +import com.cvi.auth.JwtTokenProvider; +import com.cvi.dto.UserRequest; +import com.cvi.dto.UserResponse; +import com.cvi.exception.DuplicateException; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; diff --git a/backend/app-cvi-api/src/main/resources/application.yml b/backend/app-cvi-api/src/main/resources/application.yml new file mode 100644 index 00000000..1462a41e --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/application.yml @@ -0,0 +1,30 @@ +spring: + profiles: + include: + - domain-cvi + - domain-cvi-oauth + - domain-cvi-publicdata + + cache: + jcache: + config: classpath:ehcache.xml + +server: + shutdown: graceful + +--- +spring: + config: + activate: + on-profile: deploy1 + +server: + port: 8081 +--- +spring: + config: + activate: + on-profile: deploy2 + +server: + port: 8082 diff --git a/backend/app-cvi-api/src/main/resources/console-appender.xml b/backend/app-cvi-api/src/main/resources/console-appender.xml new file mode 100644 index 00000000..48ec4fcb --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/console-appender.xml @@ -0,0 +1,7 @@ + + + + ${LOG_PATTERN} + + + diff --git a/backend/app-cvi-api/src/main/resources/ehcache.xml b/backend/app-cvi-api/src/main/resources/ehcache.xml new file mode 100644 index 00000000..c43a4ca7 --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/ehcache.xml @@ -0,0 +1,49 @@ + + + + + + + com.cvi.service.CacheEventLogger + ASYNCHRONOUS + UNORDERED + CREATED + EVICTED + REMOVED + UPDATED + EXPIRED + + + + + + java.lang.String + java.util.ArrayList + + + 1 + + + + 100 + + + + + java.lang.String + java.util.ArrayList + + + 1 + + + + 100 + + + diff --git a/backend/app-cvi-api/src/main/resources/file-error-appender.xml b/backend/app-cvi-api/src/main/resources/file-error-appender.xml new file mode 100644 index 00000000..e29b5b53 --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/file-error-appender.xml @@ -0,0 +1,18 @@ + + + ${LOG_LOCATION}/${ERROR_LOCATION}/error-${BY_DATE}.log + + ERROR + ACCEPT + DENY + + + ${LOG_PATTERN} + + + ${BACKUP_LOCATION}/${ERROR_LOCATION}/error-%d{yyyy-MM-dd}.%i.log + ${MAX_FILE_SIZE} + ${MAX_HISTORY} + + + \ No newline at end of file diff --git a/backend/app-cvi-api/src/main/resources/file-error-aws-appender.xml b/backend/app-cvi-api/src/main/resources/file-error-aws-appender.xml new file mode 100644 index 00000000..565df06d --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/file-error-aws-appender.xml @@ -0,0 +1,18 @@ + + + ${LOG_LOCATION}/${AWS_LOCATION}/${ERROR_LOCATION}/error-${BY_DATE}.log + + ERROR + ACCEPT + DENY + + + ${LOG_PATTERN_AWS} + + + ${BACKUP_LOCATION}/${AWS_LOCATION}/${ERROR_LOCATION}/error-%d{yyyy-MM-dd}.%i.log + ${MAX_FILE_SIZE} + ${MAX_HISTORY} + + + diff --git a/backend/app-cvi-api/src/main/resources/file-info-appender.xml b/backend/app-cvi-api/src/main/resources/file-info-appender.xml new file mode 100644 index 00000000..0bbd3c78 --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/file-info-appender.xml @@ -0,0 +1,18 @@ + + + ${LOG_LOCATION}/${INFO_LOCATION}/info-${BY_DATE}.log + + INFO + ACCEPT + DENY + + + ${LOG_PATTERN} + + + ${BACKUP_LOCATION}/${INFO_LOCATION}/info-%d{yyyy-MM-dd}.%i.log + ${MAX_FILE_SIZE} + ${MAX_HISTORY} + + + \ No newline at end of file diff --git a/backend/app-cvi-api/src/main/resources/file-info-aws-appender.xml b/backend/app-cvi-api/src/main/resources/file-info-aws-appender.xml new file mode 100644 index 00000000..59a82d09 --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/file-info-aws-appender.xml @@ -0,0 +1,18 @@ + + + ${LOG_LOCATION}/${AWS_LOCATION}/${INFO_LOCATION}/info-${BY_DATE}.log + + INFO + ACCEPT + DENY + + + ${LOG_PATTERN_AWS} + + + ${BACKUP_LOCATION}/${AWS_LOCATION}/${INFO_LOCATION}/info-%d{yyyy-MM-dd}.%i.log + ${MAX_FILE_SIZE} + ${MAX_HISTORY} + + + diff --git a/backend/app-cvi-api/src/main/resources/file-warn-appender.xml b/backend/app-cvi-api/src/main/resources/file-warn-appender.xml new file mode 100644 index 00000000..2e2e8763 --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/file-warn-appender.xml @@ -0,0 +1,18 @@ + + + ${LOG_LOCATION}/${WARN_LOCATION}/warn-${BY_DATE}.log + + WARN + ACCEPT + DENY + + + ${LOG_PATTERN} + + + ${BACKUP_LOCATION}/${WARN_LOCATION}/warn-%d{yyyy-MM-dd}.%i.log + ${MAX_FILE_SIZE} + ${MAX_HISTORY} + + + diff --git a/backend/app-cvi-api/src/main/resources/file-warn-aws-appender.xml b/backend/app-cvi-api/src/main/resources/file-warn-aws-appender.xml new file mode 100644 index 00000000..05f6fea7 --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/file-warn-aws-appender.xml @@ -0,0 +1,18 @@ + + + ${LOG_LOCATION}/${AWS_LOCATION}/${WARN_LOCATION}/warn-${BY_DATE}.log + + WARN + ACCEPT + DENY + + + ${LOG_PATTERN_AWS} + + + ${BACKUP_LOCATION}/${AWS_LOCATION}/${WARN_LOCATION}/warn-%d{yyyy-MM-dd}.%i.log + ${MAX_FILE_SIZE} + ${MAX_HISTORY} + + + diff --git a/backend/app-cvi-api/src/main/resources/logback-spring.xml b/backend/app-cvi-api/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..5f02a2de --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/logback-spring.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/build.gradle b/backend/build.gradle index 37344cad..3d18e818 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -2,173 +2,142 @@ plugins { id 'org.springframework.boot' version '2.5.2' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' - id 'org.asciidoctor.convert' version '1.5.8' id 'jacoco' id 'org.sonarqube' version '3.0' + id 'org.asciidoctor.convert' version '1.5.8' } -group = 'com.backjoongwon' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' -configurations { - compileOnly { - extendsFrom annotationProcessor - } -} +subprojects { + group = 'com.backjoongwon' + version = '0.0.1-SNAPSHOT' + sourceCompatibility = '1.8' -repositories { - mavenCentral() -} + apply plugin: 'java' + apply plugin: 'org.springframework.boot' + apply plugin: 'io.spring.dependency-management' + apply plugin: 'jacoco' + apply plugin: 'org.sonarqube' -dependencies { - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' - implementation 'org.springframework.boot:spring-boot-starter-validation' - implementation 'org.springframework.boot:spring-boot-starter-web' + dependencies { + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testImplementation('org.springframework.boot:spring-boot-starter-test') { + exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' + } + } - // jwt - implementation 'io.jsonwebtoken:jjwt:0.9.1' + configurations { + compileOnly { + extendsFrom annotationProcessor + } + } - asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor:2.0.5.RELEASE' - testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc:2.0.5.RELEASE' + repositories { + mavenCentral() + } - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' + /** + * jacoco 관련 설정 + */ + jacoco { + toolVersion = '0.8.7' + } - runtimeOnly 'com.h2database:h2' - runtimeOnly 'mysql:mysql-connector-java' - testImplementation 'org.springframework.boot:spring-boot-starter-test' + test { + useJUnitPlatform() + finalizedBy 'jacocoTestReport' // 테스트가 먼저 실행되고 리포트가 작동된다. + } - implementation 'com.querydsl:querydsl-jpa' - implementation 'com.querydsl:querydsl-core' - annotationProcessor("com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa") // querydsl JPAAnnotationProcessor 사용 지정 - annotationProcessor("jakarta.persistence:jakarta.persistence-api") // java.lang.NoClassDefFoundError(javax.annotation.Entity) 발생 대응 - annotationProcessor("jakarta.annotation:jakarta.annotation-api") // java.lang.NoClassDefFoundError (javax.annotation.Generated) 발생 대응 + jacocoTestReport { + dependsOn test // 리포트가 만들어지기 전 테스트 실행되어야 한다. + reports { + html.enabled true + xml.enabled true + csv.enabled false + } - //migration - implementation 'org.flywaydb:flyway-core:7.11.2' + def Qdomains = [] + for (qPattern in "**/QA".."**/QZ") { + Qdomains.add(qPattern + "*") + } - //cache - implementation 'org.springframework.boot:spring-boot-starter-cache' - implementation 'javax.cache:cache-api:1.1.1' - implementation 'org.ehcache:ehcache:3.9.4' + afterEvaluate { + classDirectories.setFrom(files(classDirectories.files.collect { + fileTree(dir: it, // 리포트 결과에 제외시킬 디렉토리 + exclude: ['**/DataLoader*', + '**/CviApplication*', + '**/DummyData*', + '**/KakaoProfile*', + '**/NaverProfile*'] + Qdomains) + })) + } + finalizedBy 'jacocoTestCoverageVerification' + } - //module - implementation project(':cvi-vaccine-stats-parser') -} + /** + * Sonar 관련 설정 + */ + sonarqube { + properties { + property "sonar.sources", "src/main/java" + property "sonar.tests", "src/test/java" + } + } -/** - * 인텔리제이 Annotation processor 에 생성되는 'src/main/generated' 디렉터리 삭제 - */ -task cleanGeneatedDir(type: Delete) { // 인텔리제이 annotation processor 가 생성한 Q클래스가 clean 태스크로 삭제되는 게 불편하다면 둘 중에 하나를 선택 - delete file('src/main/generated') +/* tasks.named('sonarqube').configure { + dependsOn jacocoTestCoverageVerification + }*/ } -sonarqube { - properties { - property "sonar.sources", "src/main/java" - property "sonar.tests", "src/test/java" +def queryDslProjects = [project(':domain-cvi')] +configure(queryDslProjects){ + dependencies { + implementation 'com.querydsl:querydsl-jpa' + implementation 'com.querydsl:querydsl-core' + annotationProcessor("com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa") // querydsl JPAAnnotationProcessor 사용 지정 + annotationProcessor("jakarta.persistence:jakarta.persistence-api") // java.lang.NoClassDefFoundError(javax.annotation.Entity) 발생 대응 + annotationProcessor("jakarta.annotation:jakarta.annotation-api") // java.lang.NoClassDefFoundError (javax.annotation.Generated) 발생 대응 } -} -tasks.named('sonarqube').configure { - dependsOn jacocoTestCoverageVerification + /** + * 인텔리제이 Annotation processor 에 생성되는 'src/main/generated' 디렉터리 삭제 + */ + task cleanGeneatedDir(type: Delete) { // 인텔리제이 annotation processor 가 생성한 Q클래스가 clean 태스크로 삭제되는 게 불편하다면 둘 중에 하나를 선택 + delete file('src/main/generated') + } } -/** -* jacoco 관련 설정 -*/ -jacoco { - toolVersion = '0.8.7' -} -jacocoTestReport { - dependsOn test // 리포트가 만들어지기 전 테스트 실행되어야 한다. - reports { - html.enabled true - xml.enabled true - csv.enabled false - } +def asciidoctorConfigureProjects = [project(':app-cvi-api')] +configure(asciidoctorConfigureProjects){ + apply plugin: "org.asciidoctor.convert" - def Qdomains = [] - for(qPattern in "**/QA" .. "**/QZ") { - Qdomains.add(qPattern+"*") + dependencies { + asciidoctor 'org.springframework.restdocs:spring-restdocs-asciidoctor:2.0.5.RELEASE' + testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc:2.0.5.RELEASE' } - afterEvaluate { - classDirectories.setFrom(files(classDirectories.files.collect { - fileTree(dir: it, // 리포트 결과에 제외시킬 디렉토리 - exclude: ['**/DataLoader*', - '**/CviApplication*', - '**/DummyData*', - '**/KakaoProfile*', - '**/NaverProfile*'] + Qdomains) - })) + ext { + snippetsDir = file('build/generated-snippets') } - finalizedBy 'jacocoTestCoverageVerification' -} - -jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 - def Qdomains = [] - - for (qPattern in "*.QA".."*.QZ") { - Qdomains.add(qPattern + "*") + test { + outputs.dir snippetsDir + useJUnitPlatform() } - violationRules { // 위반 규칙 - rule { - limit { - counter = 'METHOD' - value = 'COVEREDRATIO' - minimum = 0.80 - } - - excludes = [ - // 커버리지 제외할 클래스 - '*.DataLoader*', - '*.CviApplication*', - '*.DummyData*', - '*.KakaoProfile*', - '*.NaverProfile*' - ] + Qdomains - } + asciidoctor { + inputs.dir snippetsDir + dependsOn test } -} - -task testCoverage(type: Test) { - group 'verification' - description 'Runs the unit tests with coverage' - - dependsOn(':test', - ':jacocoTestReport', - ':jacocoTestCoverageVerification') - tasks['jacocoTestReport'].mustRunAfter(tasks['test']) - tasks['jacocoTestCoverageVerification'].mustRunAfter(tasks['jacocoTestReport']) -} - -// spring rest docs 관련 설정 부분 -ext { - snippetsDir = file('build/generated-snippets') -} - -asciidoctor { - inputs.dir snippetsDir - dependsOn test -} - -bootJar { - dependsOn asciidoctor - from("${asciidoctor.outputDir}/html5") { - into 'static/docs' + bootJar { + dependsOn asciidoctor + from ("${asciidoctor.outputDir}/html5") { + into 'static/docs' + } } } -test { - outputs.dir snippetsDir - useJUnitPlatform() - - finalizedBy 'jacocoTestReport' // 테스트가 먼저 실행되고 리포트가 작동된다. -} +project(':domain-cvi-scheduler') \ No newline at end of file diff --git a/backend/common-cvi/build.gradle b/backend/common-cvi/build.gradle index 25fb3aff..430a7b98 100644 --- a/backend/common-cvi/build.gradle +++ b/backend/common-cvi/build.gradle @@ -1,19 +1,6 @@ -plugins { - id 'java' -} - -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' - -repositories { - mavenCentral() -} +bootJar { enabled = false } +jar { enabled = true } dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' -} -test { - useJUnitPlatform() -} \ No newline at end of file +} diff --git a/backend/common-cvi/src/main/java/com/cvi/empty.txt b/backend/common-cvi/src/main/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/exception/CommonException.java b/backend/common-cvi/src/main/java/com/cvi/exception/CommonException.java similarity index 74% rename from backend/src/main/java/com/backjoongwon/cvi/common/exception/CommonException.java rename to backend/common-cvi/src/main/java/com/cvi/exception/CommonException.java index 60fc09d2..bb0ee2bd 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/exception/CommonException.java +++ b/backend/common-cvi/src/main/java/com/cvi/exception/CommonException.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.exception; +package com.cvi.exception; public class CommonException extends RuntimeException { diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/exception/DuplicateException.java b/backend/common-cvi/src/main/java/com/cvi/exception/DuplicateException.java similarity index 74% rename from backend/src/main/java/com/backjoongwon/cvi/common/exception/DuplicateException.java rename to backend/common-cvi/src/main/java/com/cvi/exception/DuplicateException.java index a5d20697..df9fb709 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/exception/DuplicateException.java +++ b/backend/common-cvi/src/main/java/com/cvi/exception/DuplicateException.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.exception; +package com.cvi.exception; public class DuplicateException extends CommonException { diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/exception/ExceptionMessage.java b/backend/common-cvi/src/main/java/com/cvi/exception/ExceptionMessage.java similarity index 79% rename from backend/src/main/java/com/backjoongwon/cvi/common/exception/ExceptionMessage.java rename to backend/common-cvi/src/main/java/com/cvi/exception/ExceptionMessage.java index 0fd11a0a..72e24020 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/exception/ExceptionMessage.java +++ b/backend/common-cvi/src/main/java/com/cvi/exception/ExceptionMessage.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.exception; +package com.cvi.exception; import lombok.Getter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/exception/InvalidInputException.java b/backend/common-cvi/src/main/java/com/cvi/exception/InvalidInputException.java similarity index 75% rename from backend/src/main/java/com/backjoongwon/cvi/common/exception/InvalidInputException.java rename to backend/common-cvi/src/main/java/com/cvi/exception/InvalidInputException.java index e359c996..732a6eeb 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/exception/InvalidInputException.java +++ b/backend/common-cvi/src/main/java/com/cvi/exception/InvalidInputException.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.exception; +package com.cvi.exception; public class InvalidInputException extends CommonException { diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/exception/InvalidOperationException.java b/backend/common-cvi/src/main/java/com/cvi/exception/InvalidOperationException.java similarity index 76% rename from backend/src/main/java/com/backjoongwon/cvi/common/exception/InvalidOperationException.java rename to backend/common-cvi/src/main/java/com/cvi/exception/InvalidOperationException.java index e357747e..973999bf 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/exception/InvalidOperationException.java +++ b/backend/common-cvi/src/main/java/com/cvi/exception/InvalidOperationException.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.exception; +package com.cvi.exception; public class InvalidOperationException extends CommonException { diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/exception/MappingFailureException.java b/backend/common-cvi/src/main/java/com/cvi/exception/MappingFailureException.java similarity index 76% rename from backend/src/main/java/com/backjoongwon/cvi/common/exception/MappingFailureException.java rename to backend/common-cvi/src/main/java/com/cvi/exception/MappingFailureException.java index 507874e0..743092d8 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/exception/MappingFailureException.java +++ b/backend/common-cvi/src/main/java/com/cvi/exception/MappingFailureException.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.exception; +package com.cvi.exception; public class MappingFailureException extends CommonException { diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/exception/NotFoundException.java b/backend/common-cvi/src/main/java/com/cvi/exception/NotFoundException.java similarity index 74% rename from backend/src/main/java/com/backjoongwon/cvi/common/exception/NotFoundException.java rename to backend/common-cvi/src/main/java/com/cvi/exception/NotFoundException.java index 136cd221..276f93ee 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/exception/NotFoundException.java +++ b/backend/common-cvi/src/main/java/com/cvi/exception/NotFoundException.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.exception; +package com.cvi.exception; public class NotFoundException extends CommonException { diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/exception/UnAuthorizedException.java b/backend/common-cvi/src/main/java/com/cvi/exception/UnAuthorizedException.java similarity index 75% rename from backend/src/main/java/com/backjoongwon/cvi/common/exception/UnAuthorizedException.java rename to backend/common-cvi/src/main/java/com/cvi/exception/UnAuthorizedException.java index df8b85a3..3c8293be 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/exception/UnAuthorizedException.java +++ b/backend/common-cvi/src/main/java/com/cvi/exception/UnAuthorizedException.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.exception; +package com.cvi.exception; public class UnAuthorizedException extends CommonException { diff --git a/backend/cvi-oauth-parser/build.gradle b/backend/cvi-oauth-parser/build.gradle deleted file mode 100644 index 25fb3aff..00000000 --- a/backend/cvi-oauth-parser/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -plugins { - id 'java' -} - -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' - -repositories { - mavenCentral() -} - -dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' -} - -test { - useJUnitPlatform() -} \ No newline at end of file diff --git a/backend/cvi-oauth-parser/src/main/java/com/cvi/empty.txt b/backend/cvi-oauth-parser/src/main/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/cvi-oauth-parser/src/main/resources/empty.txt b/backend/cvi-oauth-parser/src/main/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/cvi-oauth-parser/src/test/java/com/cvi/empty.txt b/backend/cvi-oauth-parser/src/test/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/cvi-oauth-parser/src/test/resources/empty.txt b/backend/cvi-oauth-parser/src/test/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/cvi-publicdata-parser/build.gradle b/backend/cvi-publicdata-parser/build.gradle index 25fb3aff..34317ddc 100644 --- a/backend/cvi-publicdata-parser/build.gradle +++ b/backend/cvi-publicdata-parser/build.gradle @@ -1,19 +1,53 @@ -plugins { - id 'java' -} +bootJar { enabled = false } +jar { enabled = true } -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' +dependencies { + testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.20.2' + testImplementation(group: 'org.junit.jupiter', name: 'junit-jupiter', version: '5.7.2') + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.4' -repositories { - mavenCentral() + implementation 'org.slf4j:slf4j-api:1.7.30' + implementation 'ch.qos.logback:logback-core:1.2.3' + implementation('ch.qos.logback:logback-classic:1.2.3') { + exclude group: 'org.slf4j', module: 'slf4j-api' + exclude group: 'ch.qos.logback', module: 'logback-core' + } + testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.11.2' + testImplementation 'org.mockito:mockito-inline:3.11.2' } -dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 + def Qdomains = [] + + for (qPattern in "*.QA".."*.QZ") { + Qdomains.add(qPattern + "*") + } + + violationRules { // 위반 규칙 + rule { + enabled = true + element = 'BUNDLE' + + limit { + counter = 'INSTRUCTION' + value = 'COVEREDRATIO' + minimum = 0.80 + } + + excludes = [ + // 커버리지 제외할 클래스 + '*.DataLoader*', + '*.CviApplication*', + '*.DummyData*', + '*.KakaoProfile*', + '*.NaverProfile*' + ] + Qdomains + } + } } -test { - useJUnitPlatform() +sonarqube { + properties { + property "sonar.exclusions", "**/*Test*.*, **/Q*.java, **/*Doc*.java" + } } \ No newline at end of file diff --git a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/KoreaRegionVaccinationData.java b/backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/KoreaRegionVaccinationData.java similarity index 97% rename from backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/KoreaRegionVaccinationData.java rename to backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/KoreaRegionVaccinationData.java index 7f7daa63..df5a4fb5 100644 --- a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/KoreaRegionVaccinationData.java +++ b/backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/KoreaRegionVaccinationData.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.dto; +package com.cvi.dto; public class KoreaRegionVaccinationData { diff --git a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/KoreaVaccineParserResponse.java b/backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/KoreaVaccineParserResponse.java similarity index 97% rename from backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/KoreaVaccineParserResponse.java rename to backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/KoreaVaccineParserResponse.java index f98ef9c5..99b238d9 100644 --- a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/KoreaVaccineParserResponse.java +++ b/backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/KoreaVaccineParserResponse.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.dto; +package com.cvi.dto; import java.util.Collections; import java.util.List; diff --git a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/WorldVaccinationData.java b/backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/WorldVaccinationData.java similarity index 98% rename from backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/WorldVaccinationData.java rename to backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/WorldVaccinationData.java index a4be1020..f9e5136c 100644 --- a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/WorldVaccinationData.java +++ b/backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/WorldVaccinationData.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.dto; +package com.cvi.dto; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/WorldVaccinationParserResponse.java b/backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/WorldVaccinationParserResponse.java similarity index 96% rename from backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/WorldVaccinationParserResponse.java rename to backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/WorldVaccinationParserResponse.java index a439abdf..b6657516 100644 --- a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/dto/WorldVaccinationParserResponse.java +++ b/backend/cvi-publicdata-parser/src/main/java/com/cvi/dto/WorldVaccinationParserResponse.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.dto; +package com.cvi.dto; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/backend/cvi-publicdata-parser/src/main/java/com/cvi/empty.txt b/backend/cvi-publicdata-parser/src/main/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/ParameterStringBuilder.java b/backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/ParameterStringBuilder.java similarity index 97% rename from backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/ParameterStringBuilder.java rename to backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/ParameterStringBuilder.java index dc3caf8d..01405d85 100644 --- a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/ParameterStringBuilder.java +++ b/backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/ParameterStringBuilder.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.parser; +package com.cvi.parser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/Parser.java b/backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/Parser.java similarity index 97% rename from backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/Parser.java rename to backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/Parser.java index d8b542a8..6923ce7c 100644 --- a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/Parser.java +++ b/backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/Parser.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.parser; +package com.cvi.parser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/URLWrapper.java b/backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/URLWrapper.java similarity index 96% rename from backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/URLWrapper.java rename to backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/URLWrapper.java index e7d82a84..8ad01e74 100644 --- a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/URLWrapper.java +++ b/backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/URLWrapper.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.parser; +package com.cvi.parser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/VaccinationParser.java b/backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/VaccinationParser.java similarity index 90% rename from backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/VaccinationParser.java rename to backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/VaccinationParser.java index dc4683c4..6292abee 100644 --- a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/parser/VaccinationParser.java +++ b/backend/cvi-publicdata-parser/src/main/java/com/cvi/parser/VaccinationParser.java @@ -1,9 +1,9 @@ -package com.backjoongwon.cvi.parser; +package com.cvi.parser; -import com.backjoongwon.cvi.dto.KoreaVaccineParserResponse; -import com.backjoongwon.cvi.dto.WorldVaccinationParserResponse; -import com.backjoongwon.cvi.util.DateConverter; -import com.backjoongwon.cvi.util.JsonMapper; +import com.cvi.dto.KoreaVaccineParserResponse; +import com.cvi.dto.WorldVaccinationParserResponse; +import com.cvi.util.DateConverter; +import com.cvi.util.JsonMapper; import java.time.LocalDate; import java.util.Collections; diff --git a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/util/DateConverter.java b/backend/cvi-publicdata-parser/src/main/java/com/cvi/util/DateConverter.java similarity index 95% rename from backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/util/DateConverter.java rename to backend/cvi-publicdata-parser/src/main/java/com/cvi/util/DateConverter.java index 3efca811..e0fb0c23 100644 --- a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/util/DateConverter.java +++ b/backend/cvi-publicdata-parser/src/main/java/com/cvi/util/DateConverter.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.util; +package com.cvi.util; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/util/JsonMapper.java b/backend/cvi-publicdata-parser/src/main/java/com/cvi/util/JsonMapper.java similarity index 93% rename from backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/util/JsonMapper.java rename to backend/cvi-publicdata-parser/src/main/java/com/cvi/util/JsonMapper.java index c5f6e257..97ba367d 100644 --- a/backend/cvi-vaccine-stats-parser/src/main/java/com/backjoongwon/cvi/util/JsonMapper.java +++ b/backend/cvi-publicdata-parser/src/main/java/com/cvi/util/JsonMapper.java @@ -1,6 +1,6 @@ -package com.backjoongwon.cvi.util; +package com.cvi.util; -import com.backjoongwon.cvi.dto.WorldVaccinationParserResponse; +import com.cvi.dto.WorldVaccinationParserResponse; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/backend/cvi-publicdata-parser/src/main/resources/empty.txt b/backend/cvi-publicdata-parser/src/main/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/cvi-publicdata-parser/src/test/java/com/cvi/empty.txt b/backend/cvi-publicdata-parser/src/test/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/parser/ParameterStringBuilderTest.java b/backend/cvi-publicdata-parser/src/test/java/com/cvi/parser/ParameterStringBuilderTest.java similarity index 95% rename from backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/parser/ParameterStringBuilderTest.java rename to backend/cvi-publicdata-parser/src/test/java/com/cvi/parser/ParameterStringBuilderTest.java index db40c53d..75fecab4 100644 --- a/backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/parser/ParameterStringBuilderTest.java +++ b/backend/cvi-publicdata-parser/src/test/java/com/cvi/parser/ParameterStringBuilderTest.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.parser; +package com.cvi.parser; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/parser/URLWrapperTest.java b/backend/cvi-publicdata-parser/src/test/java/com/cvi/parser/URLWrapperTest.java similarity index 96% rename from backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/parser/URLWrapperTest.java rename to backend/cvi-publicdata-parser/src/test/java/com/cvi/parser/URLWrapperTest.java index 5ca0fe9b..ab35c398 100644 --- a/backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/parser/URLWrapperTest.java +++ b/backend/cvi-publicdata-parser/src/test/java/com/cvi/parser/URLWrapperTest.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.parser; +package com.cvi.parser; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/parser/VaccineParserTest.java b/backend/cvi-publicdata-parser/src/test/java/com/cvi/parser/VaccineParserTest.java similarity index 96% rename from backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/parser/VaccineParserTest.java rename to backend/cvi-publicdata-parser/src/test/java/com/cvi/parser/VaccineParserTest.java index 91c0a101..b620ec93 100644 --- a/backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/parser/VaccineParserTest.java +++ b/backend/cvi-publicdata-parser/src/test/java/com/cvi/parser/VaccineParserTest.java @@ -1,11 +1,11 @@ -package com.backjoongwon.cvi.parser; +package com.cvi.parser; -import com.backjoongwon.cvi.dto.KoreaRegionVaccinationData; -import com.backjoongwon.cvi.dto.KoreaVaccineParserResponse; -import com.backjoongwon.cvi.dto.WorldVaccinationData; -import com.backjoongwon.cvi.dto.WorldVaccinationParserResponse; -import com.backjoongwon.cvi.util.DateConverter; -import com.backjoongwon.cvi.util.JsonMapper; +import com.cvi.dto.KoreaRegionVaccinationData; +import com.cvi.dto.KoreaVaccineParserResponse; +import com.cvi.dto.WorldVaccinationData; +import com.cvi.dto.WorldVaccinationParserResponse; +import com.cvi.util.DateConverter; +import com.cvi.util.JsonMapper; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; diff --git a/backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/util/DateConverterTest.java b/backend/cvi-publicdata-parser/src/test/java/com/cvi/util/DateConverterTest.java similarity index 97% rename from backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/util/DateConverterTest.java rename to backend/cvi-publicdata-parser/src/test/java/com/cvi/util/DateConverterTest.java index f0dd3376..88ddeb0a 100644 --- a/backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/util/DateConverterTest.java +++ b/backend/cvi-publicdata-parser/src/test/java/com/cvi/util/DateConverterTest.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.util; +package com.cvi.util; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/util/JsonMapperTest.java b/backend/cvi-publicdata-parser/src/test/java/com/cvi/util/JsonMapperTest.java similarity index 97% rename from backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/util/JsonMapperTest.java rename to backend/cvi-publicdata-parser/src/test/java/com/cvi/util/JsonMapperTest.java index 33b71490..4a715eec 100644 --- a/backend/cvi-vaccine-stats-parser/src/test/java/com/backjoongwon/cvi/util/JsonMapperTest.java +++ b/backend/cvi-publicdata-parser/src/test/java/com/cvi/util/JsonMapperTest.java @@ -1,7 +1,7 @@ -package com.backjoongwon.cvi.util; +package com.cvi.util; -import com.backjoongwon.cvi.dto.KoreaVaccineParserResponse; -import com.backjoongwon.cvi.dto.WorldVaccinationParserResponse; +import com.cvi.dto.KoreaVaccineParserResponse; +import com.cvi.dto.WorldVaccinationParserResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/cvi-publicdata-parser/src/test/resources/empty.txt b/backend/cvi-publicdata-parser/src/test/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/cvi-vaccine-stats-parser/build.gradle b/backend/cvi-vaccine-stats-parser/build.gradle deleted file mode 100644 index 54c1b015..00000000 --- a/backend/cvi-vaccine-stats-parser/build.gradle +++ /dev/null @@ -1,76 +0,0 @@ -plugins { - id 'java' - id 'jacoco' - id 'org.sonarqube' -} - -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' - -task wrapper(type: Wrapper) { - gradleVersion = '6.8.3' -} - -repositories { - mavenCentral() -} - -dependencies { - testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.20.2' - testImplementation(group: 'org.junit.jupiter', name: 'junit-jupiter', version: '5.7.2') - implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.4' - - implementation 'org.slf4j:slf4j-api:1.7.30' - implementation 'ch.qos.logback:logback-core:1.2.3' - implementation('ch.qos.logback:logback-classic:1.2.3') { - exclude group: 'org.slf4j', module: 'slf4j-api' - exclude group: 'ch.qos.logback', module: 'logback-core' - } - testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.11.2' - testImplementation 'org.mockito:mockito-inline:3.11.2' -} - -sonarqube { - properties { - property "sonar.sources", "src/main/java" - property "sonar.tests", "src/test/java" - } -} - -jacoco { - toolVersion = '0.8.7' -} - -jacocoTestReport { - dependsOn test // 리포트가 만들어지기 전 테스트 실행되어야 한다. - reports { - html.enabled true - xml.enabled true - csv.enabled false - } - - finalizedBy 'jacocoTestCoverageVerification' -} - -jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 - - violationRules { // 위반 규칙 - rule { - limit { - counter = 'METHOD' - value = 'COVEREDRATIO' - minimum = 0.80 - } - - excludes = [// 커버리지 제외할 클래스 - ] - } - } -} - -test { - useJUnitPlatform() - - finalizedBy 'jacocoTestReport' -} diff --git a/backend/cvi-vaccine-stats-parser/gradle/wrapper/gradle-wrapper.jar b/backend/cvi-vaccine-stats-parser/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59203 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

K7UpUK$>l@ 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 E2O(~oYXATM diff --git a/backend/cvi-vaccine-stats-parser/gradle/wrapper/gradle-wrapper.properties b/backend/cvi-vaccine-stats-parser/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 442d9132..00000000 --- a/backend/cvi-vaccine-stats-parser/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/backend/cvi-vaccine-stats-parser/gradlew b/backend/cvi-vaccine-stats-parser/gradlew deleted file mode 100755 index 4f906e0c..00000000 --- a/backend/cvi-vaccine-stats-parser/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/backend/cvi-vaccine-stats-parser/gradlew.bat b/backend/cvi-vaccine-stats-parser/gradlew.bat deleted file mode 100644 index ac1b06f9..00000000 --- a/backend/cvi-vaccine-stats-parser/gradlew.bat +++ /dev/null @@ -1,89 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/backend/domain-cvi-oauth-service/build.gradle b/backend/domain-cvi-oauth-service/build.gradle index 25fb3aff..b261ce01 100644 --- a/backend/domain-cvi-oauth-service/build.gradle +++ b/backend/domain-cvi-oauth-service/build.gradle @@ -1,19 +1,45 @@ -plugins { - id 'java' +bootJar { enabled = false } +jar { enabled = true } + +dependencies { + implementation project(path:':domain-cvi', configuration: 'default') + implementation 'org.springframework.boot:spring-boot-starter-web' + // jwt + implementation 'io.jsonwebtoken:jjwt:0.9.1' } -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' +jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 + def Qdomains = [] -repositories { - mavenCentral() -} + for (qPattern in "*.QA".."*.QZ") { + Qdomains.add(qPattern + "*") + } -dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' + violationRules { // 위반 규칙 + rule { + enabled = true + element = 'CLASS' + + limit { + counter = 'INSTRUCTION' + value = 'COVEREDRATIO' + minimum = 0.80 + } + + excludes = [ + // 커버리지 제외할 클래스 + '*.DataLoader*', + '*.CviApplication*', + '*.DummyData*', + '*.KakaoProfile*', + '*.NaverProfile*' + ] + Qdomains + } + } } -test { - useJUnitPlatform() +sonarqube { + properties { + property "sonar.exclusions", "**/*Test*.*, **/Q*.java, **/*Doc*.java" + } } \ No newline at end of file diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/auth/AuthenticationPrincipal.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthenticationPrincipal.java similarity index 87% rename from backend/src/main/java/com/backjoongwon/cvi/user/auth/AuthenticationPrincipal.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthenticationPrincipal.java index e07ed28b..342b0fb6 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/auth/AuthenticationPrincipal.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthenticationPrincipal.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.user.auth; +package com.cvi.auth; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/auth/AuthenticationPrincipalArgumentResolver.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java similarity index 69% rename from backend/src/main/java/com/backjoongwon/cvi/user/auth/AuthenticationPrincipalArgumentResolver.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java index cb784a83..2986ec15 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/auth/AuthenticationPrincipalArgumentResolver.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java @@ -1,9 +1,10 @@ -package com.backjoongwon.cvi.user.auth; +package com.cvi.auth; -import com.backjoongwon.cvi.user.service.UserService; -import com.backjoongwon.cvi.user.domain.JwtTokenProvider; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.exception.NotFoundException; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; import org.springframework.web.bind.support.WebDataBinderFactory; @@ -15,12 +16,13 @@ import java.util.Objects; import java.util.Optional; +@Slf4j @Component @RequiredArgsConstructor public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArgumentResolver { private final JwtTokenProvider jwtTokenProvider; - private final UserService userService; + private final UserRepository userRepository; @Override public boolean supportsParameter(MethodParameter parameter) { @@ -32,8 +34,12 @@ public Optional resolveArgument(MethodParameter parameter, ModelAndViewCon String accessToken = AuthorizationExtractor.extract(Objects.requireNonNull(webRequest.getNativeRequest(HttpServletRequest.class))); if (jwtTokenProvider.isValidToken(accessToken)) { String id = jwtTokenProvider.getPayload(accessToken); - User user = userService.findUserById(Long.valueOf(id)); - return Optional.of(user); + final Optional user = userRepository.findById(Long.valueOf(id)); + if (user.isPresent()) { + return user; + } + log.info("해당 id의 사용자가 없습니다. 입력값: {}", id); + throw new NotFoundException(String.format("해당 id의 사용자가 없습니다. 입력값: %s", id)); } return Optional.empty(); } diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/auth/AuthorizationExtractor.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthorizationExtractor.java similarity index 96% rename from backend/src/main/java/com/backjoongwon/cvi/user/auth/AuthorizationExtractor.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthorizationExtractor.java index 443aa444..1e6efa7b 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/auth/AuthorizationExtractor.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthorizationExtractor.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.user.auth; +package com.cvi.auth; import javax.servlet.http.HttpServletRequest; import java.util.Enumeration; diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/domain/JwtTokenProvider.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/JwtTokenProvider.java similarity index 96% rename from backend/src/main/java/com/backjoongwon/cvi/user/domain/JwtTokenProvider.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/JwtTokenProvider.java index 3f917e9f..11f2d10f 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/domain/JwtTokenProvider.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/JwtTokenProvider.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.user.domain; +package com.cvi.auth; import io.jsonwebtoken.*; import org.springframework.beans.factory.annotation.Value; diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/auth/SigninInterceptor.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/SigninInterceptor.java similarity index 91% rename from backend/src/main/java/com/backjoongwon/cvi/user/auth/SigninInterceptor.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/SigninInterceptor.java index a054d35c..c6512691 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/auth/SigninInterceptor.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/SigninInterceptor.java @@ -1,6 +1,5 @@ -package com.backjoongwon.cvi.user.auth; +package com.cvi.auth; -import com.backjoongwon.cvi.user.domain.JwtTokenProvider; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Component; diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/config/WebMvcConfig.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/config/WebMvcConfig.java new file mode 100644 index 00000000..99821170 --- /dev/null +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/config/WebMvcConfig.java @@ -0,0 +1,35 @@ +package com.cvi.config; + +import com.cvi.auth.AuthenticationPrincipalArgumentResolver; +import com.cvi.auth.SigninInterceptor; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +@RequiredArgsConstructor +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + private final SigninInterceptor signinInterceptor; + private final AuthenticationPrincipalArgumentResolver resolver; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(signinInterceptor) + .addPathPatterns("/**") + .excludePathPatterns("/api/v1/users/signup") + .excludePathPatterns("/api/v1/users/auth") + .excludePathPatterns("/api/v1/publicdata/vaccinations"); + } + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(resolver); + } +} diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/AuthRequest.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/AuthRequest.java similarity index 86% rename from backend/src/main/java/com/backjoongwon/cvi/auth/dto/AuthRequest.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/AuthRequest.java index 5965dcc9..59826c56 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/AuthRequest.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/AuthRequest.java @@ -1,6 +1,6 @@ -package com.backjoongwon.cvi.auth.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; +import com.cvi.user.domain.model.SocialProvider; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/UserInformation.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/UserInformation.java new file mode 100644 index 00000000..67ce5ae6 --- /dev/null +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/UserInformation.java @@ -0,0 +1,25 @@ +package com.cvi.dto; + +import com.cvi.dto.profile.SocialProfile; +import lombok.Getter; + +import javax.validation.constraints.NotBlank; + +@Getter +public class UserInformation { + + @NotBlank(message = "socialId(OAuth 고유의 id)는 null, '', ' ' 일 수 없습니다.") + private final String socialId; + + @NotBlank(message = "socialProfileUrl(OAuth profile url)은 null일 수 없습니다.") + private final String socialProfileUrl; + + private UserInformation(String socialId, String socialProfileUrl) { + this.socialId = socialId; + this.socialProfileUrl = socialProfileUrl; + } + + public static UserInformation of(SocialProfile socialProfile) { + return new UserInformation(socialProfile.extractSocialId(), socialProfile.extractProfileUrl()); + } +} diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/oauthtoken/KakaoOAuthToken.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/oauthtoken/KakaoOAuthToken.java similarity index 75% rename from backend/src/main/java/com/backjoongwon/cvi/auth/dto/oauthtoken/KakaoOAuthToken.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/oauthtoken/KakaoOAuthToken.java index 71830b36..2e2caa86 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/oauthtoken/KakaoOAuthToken.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/oauthtoken/KakaoOAuthToken.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.auth.dto.oauthtoken; +package com.cvi.dto.oauthtoken; import lombok.Getter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/oauthtoken/NaverOAuthToken.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/oauthtoken/NaverOAuthToken.java similarity index 51% rename from backend/src/main/java/com/backjoongwon/cvi/auth/dto/oauthtoken/NaverOAuthToken.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/oauthtoken/NaverOAuthToken.java index 8a523580..a1d47c41 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/oauthtoken/NaverOAuthToken.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/oauthtoken/NaverOAuthToken.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.auth.dto.oauthtoken; +package com.cvi.dto.oauthtoken; public class NaverOAuthToken extends OAuthToken { } diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/oauthtoken/OAuthToken.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/oauthtoken/OAuthToken.java similarity index 79% rename from backend/src/main/java/com/backjoongwon/cvi/auth/dto/oauthtoken/OAuthToken.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/oauthtoken/OAuthToken.java index baedddc8..73d2d015 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/oauthtoken/OAuthToken.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/oauthtoken/OAuthToken.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.auth.dto.oauthtoken; +package com.cvi.dto.oauthtoken; import lombok.Getter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/KakaoProfile.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/KakaoProfile.java similarity index 96% rename from backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/KakaoProfile.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/KakaoProfile.java index 4a9b62a0..4df3a9f0 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/KakaoProfile.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/KakaoProfile.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.auth.dto.profile; +package com.cvi.dto.profile; import lombok.Getter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/NaverProfile.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/NaverProfile.java similarity index 91% rename from backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/NaverProfile.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/NaverProfile.java index 49815f17..dfb4e661 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/NaverProfile.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/NaverProfile.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.auth.dto.profile; +package com.cvi.dto.profile; import lombok.Getter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/SocialProfile.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/SocialProfile.java similarity index 68% rename from backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/SocialProfile.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/SocialProfile.java index 5f379ca5..f925bff4 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/SocialProfile.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/SocialProfile.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.auth.dto.profile; +package com.cvi.dto.profile; public interface SocialProfile { diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/UserInformation.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/UserInformation.java similarity index 93% rename from backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/UserInformation.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/UserInformation.java index 74f55388..0296df6b 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/dto/profile/UserInformation.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/dto/profile/UserInformation.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.auth.dto.profile; +package com.cvi.dto.profile; import lombok.Getter; diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/empty.txt b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/Authorization.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/Authorization.java similarity index 76% rename from backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/Authorization.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/Authorization.java index 547e817f..2a6b4723 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/Authorization.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/Authorization.java @@ -1,8 +1,8 @@ -package com.backjoongwon.cvi.auth.domain.authorization; +package com.cvi.parser; -import com.backjoongwon.cvi.auth.dto.oauthtoken.OAuthToken; -import com.backjoongwon.cvi.auth.dto.profile.SocialProfile; -import com.backjoongwon.cvi.auth.dto.profile.UserInformation; +import com.cvi.dto.oauthtoken.OAuthToken; +import com.cvi.dto.profile.SocialProfile; +import com.cvi.dto.profile.UserInformation; import org.springframework.http.HttpEntity; import org.springframework.http.ResponseEntity; import org.springframework.util.MultiValueMap; diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/AuthorizationManager.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/AuthorizationManager.java similarity index 88% rename from backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/AuthorizationManager.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/AuthorizationManager.java index 752f1030..b5e5996f 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/AuthorizationManager.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/AuthorizationManager.java @@ -1,7 +1,8 @@ -package com.backjoongwon.cvi.auth.domain.authorization; +package com.cvi.parser; -import com.backjoongwon.cvi.auth.dto.profile.UserInformation; -import com.backjoongwon.cvi.common.exception.InvalidOperationException; +import com.cvi.dto.profile.UserInformation; +import com.cvi.exception.InvalidOperationException; +import com.cvi.user.domain.model.SocialProvider; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/KakaoAuthorization.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/KakaoAuthorization.java similarity index 90% rename from backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/KakaoAuthorization.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/KakaoAuthorization.java index 7249b617..00694c39 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/KakaoAuthorization.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/KakaoAuthorization.java @@ -1,11 +1,11 @@ -package com.backjoongwon.cvi.auth.domain.authorization; +package com.cvi.parser; -import com.backjoongwon.cvi.auth.dto.oauthtoken.KakaoOAuthToken; -import com.backjoongwon.cvi.auth.dto.oauthtoken.OAuthToken; -import com.backjoongwon.cvi.auth.dto.profile.KakaoProfile; -import com.backjoongwon.cvi.auth.dto.profile.SocialProfile; -import com.backjoongwon.cvi.auth.dto.profile.UserInformation; -import com.backjoongwon.cvi.common.exception.MappingFailureException; +import com.cvi.dto.oauthtoken.KakaoOAuthToken; +import com.cvi.dto.oauthtoken.OAuthToken; +import com.cvi.dto.profile.KakaoProfile; +import com.cvi.dto.profile.SocialProfile; +import com.cvi.dto.profile.UserInformation; +import com.cvi.exception.MappingFailureException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; @@ -25,6 +25,7 @@ public class KakaoAuthorization implements Authorization { private static final String PROFILE_REQUEST_URL = "https://kapi.kakao.com/v2/user/me"; private static final String TOKEN_REQUEST_URL = "https://kauth.kakao.com/oauth/token"; private static final String REDIRECT_URL = "https://vaccine-review.com/auth/kakao/callback"; + //private static final String REDIRECT_URL = "https://localhost:9000/auth/kakao/callback"; private final RestTemplate restTemplate = new RestTemplate(); private final ObjectMapper objectMapper = new ObjectMapper(); diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/NaverAuthorization.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/NaverAuthorization.java similarity index 90% rename from backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/NaverAuthorization.java rename to backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/NaverAuthorization.java index 8e67b042..46b20fe2 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/NaverAuthorization.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/NaverAuthorization.java @@ -1,11 +1,11 @@ -package com.backjoongwon.cvi.auth.domain.authorization; +package com.cvi.parser; -import com.backjoongwon.cvi.auth.dto.oauthtoken.NaverOAuthToken; -import com.backjoongwon.cvi.auth.dto.oauthtoken.OAuthToken; -import com.backjoongwon.cvi.auth.dto.profile.NaverProfile; -import com.backjoongwon.cvi.auth.dto.profile.SocialProfile; -import com.backjoongwon.cvi.auth.dto.profile.UserInformation; -import com.backjoongwon.cvi.common.exception.MappingFailureException; +import com.cvi.dto.oauthtoken.NaverOAuthToken; +import com.cvi.dto.oauthtoken.OAuthToken; +import com.cvi.dto.profile.NaverProfile; +import com.cvi.dto.profile.SocialProfile; +import com.cvi.dto.profile.UserInformation; +import com.cvi.exception.MappingFailureException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; diff --git a/backend/domain-cvi-oauth-service/src/main/resources/application-domain-cvi-oauth.yml b/backend/domain-cvi-oauth-service/src/main/resources/application-domain-cvi-oauth.yml new file mode 100644 index 00000000..85efc169 --- /dev/null +++ b/backend/domain-cvi-oauth-service/src/main/resources/application-domain-cvi-oauth.yml @@ -0,0 +1,9 @@ +security: + jwt: + token: + secret-key: cvi_secret_key + expire-length: 3600000 + + auth: + naver: + client-secret: client-secret \ No newline at end of file diff --git a/backend/domain-cvi-oauth-service/src/main/resources/empty.txt b/backend/domain-cvi-oauth-service/src/main/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/domain-cvi-publicdata-service/build.gradle b/backend/domain-cvi-publicdata-service/build.gradle index 25fb3aff..fb82a1af 100644 --- a/backend/domain-cvi-publicdata-service/build.gradle +++ b/backend/domain-cvi-publicdata-service/build.gradle @@ -1,19 +1,7 @@ -plugins { - id 'java' -} - -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' - -repositories { - mavenCentral() -} +bootJar { enabled = false } +jar { enabled = true } dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' + implementation project(path:':domain-cvi', configuration: 'default') + implementation project(path:':cvi-publicdata-parser', configuration: 'default') } - -test { - useJUnitPlatform() -} \ No newline at end of file diff --git a/backend/src/main/java/com/backjoongwon/cvi/config/VaccinationConfig.java b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/config/VaccinationConfig.java similarity index 62% rename from backend/src/main/java/com/backjoongwon/cvi/config/VaccinationConfig.java rename to backend/domain-cvi-publicdata-service/src/main/java/com/cvi/config/VaccinationConfig.java index 4c14d7c3..7913c9e4 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/config/VaccinationConfig.java +++ b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/config/VaccinationConfig.java @@ -1,8 +1,8 @@ -package com.backjoongwon.cvi.config; +package com.cvi.config; -import com.backjoongwon.cvi.parser.Parser; -import com.backjoongwon.cvi.parser.VaccinationParser; -import com.backjoongwon.cvi.util.JsonMapper; +import com.cvi.parser.Parser; +import com.cvi.parser.VaccinationParser; +import com.cvi.util.JsonMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -14,3 +14,4 @@ public VaccinationParser vaccineParser() { return new VaccinationParser(new Parser(), new JsonMapper()); } } + diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/dto/RegionVaccinationDataFactory.java b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/RegionVaccinationDataFactory.java similarity index 76% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/dto/RegionVaccinationDataFactory.java rename to backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/RegionVaccinationDataFactory.java index f0132ace..3e159444 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/dto/RegionVaccinationDataFactory.java +++ b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/RegionVaccinationDataFactory.java @@ -1,8 +1,7 @@ -package com.backjoongwon.cvi.publicdata.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.dto.KoreaRegionVaccinationData; -import com.backjoongwon.cvi.publicdata.domain.VaccinationStatistic; -import com.backjoongwon.cvi.publicdata.domain.VaccinationStatistics; +import com.cvi.publicdata.domain.model.VaccinationStatistic; +import com.cvi.publicdata.domain.model.VaccinationStatistics; import java.util.ArrayList; import java.util.List; diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/dto/VaccinationStatisticResponse.java b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/VaccinationStatisticResponse.java similarity index 91% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/dto/VaccinationStatisticResponse.java rename to backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/VaccinationStatisticResponse.java index 838f7239..faaf5024 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/dto/VaccinationStatisticResponse.java +++ b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/VaccinationStatisticResponse.java @@ -1,10 +1,8 @@ -package com.backjoongwon.cvi.publicdata.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.dto.KoreaRegionVaccinationData; -import com.backjoongwon.cvi.dto.WorldVaccinationData; -import com.backjoongwon.cvi.publicdata.domain.RegionPopulation; -import com.backjoongwon.cvi.publicdata.domain.VaccinationStatistic; -import com.backjoongwon.cvi.util.DateConverter; +import com.cvi.publicdata.domain.model.RegionPopulation; +import com.cvi.publicdata.domain.model.VaccinationStatistic; +import com.cvi.util.DateConverter; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/dto/WorldVaccinationDataFactory.java b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/WorldVaccinationDataFactory.java similarity index 76% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/dto/WorldVaccinationDataFactory.java rename to backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/WorldVaccinationDataFactory.java index 4bb45604..4726645a 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/dto/WorldVaccinationDataFactory.java +++ b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/WorldVaccinationDataFactory.java @@ -1,8 +1,7 @@ -package com.backjoongwon.cvi.publicdata.dto; +package com.cvi.dto; -import com.backjoongwon.cvi.dto.WorldVaccinationData; -import com.backjoongwon.cvi.publicdata.domain.VaccinationStatistic; -import com.backjoongwon.cvi.publicdata.domain.VaccinationStatistics; +import com.cvi.publicdata.domain.model.VaccinationStatistic; +import com.cvi.publicdata.domain.model.VaccinationStatistics; import java.util.ArrayList; import java.util.List; diff --git a/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/empty.txt b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/PublicDataProperties.java b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/properties/PublicDataProperties.java similarity index 87% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/PublicDataProperties.java rename to backend/domain-cvi-publicdata-service/src/main/java/com/cvi/properties/PublicDataProperties.java index 7508e947..3e2285e6 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/PublicDataProperties.java +++ b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/properties/PublicDataProperties.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.publicdata.domain; +package com.cvi.properties; import lombok.Getter; import lombok.Setter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/service/PublicDataService.java b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/service/PublicDataService.java similarity index 89% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/service/PublicDataService.java rename to backend/domain-cvi-publicdata-service/src/main/java/com/cvi/service/PublicDataService.java index b567b7c1..aa204948 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/service/PublicDataService.java +++ b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/service/PublicDataService.java @@ -1,12 +1,12 @@ -package com.backjoongwon.cvi.publicdata.service; +package com.cvi.service; -import com.backjoongwon.cvi.dto.KoreaVaccineParserResponse; -import com.backjoongwon.cvi.dto.WorldVaccinationParserResponse; -import com.backjoongwon.cvi.parser.VaccinationParser; -import com.backjoongwon.cvi.publicdata.domain.*; -import com.backjoongwon.cvi.publicdata.dto.RegionVaccinationDataFactory; -import com.backjoongwon.cvi.publicdata.dto.VaccinationStatisticResponse; -import com.backjoongwon.cvi.publicdata.dto.WorldVaccinationDataFactory; +import com.cvi.dto.*; +import com.cvi.parser.VaccinationParser; +import com.cvi.properties.PublicDataProperties; +import com.cvi.publicdata.domain.model.RegionPopulation; +import com.cvi.publicdata.domain.model.VaccinationStatistic; +import com.cvi.publicdata.domain.model.VaccinationStatistics; +import com.cvi.publicdata.domain.repository.VaccinationStatisticRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.annotation.CacheEvict; diff --git a/backend/domain-cvi-publicdata-service/src/main/resources/application-domain-cvi-publicdata.yml b/backend/domain-cvi-publicdata-service/src/main/resources/application-domain-cvi-publicdata.yml new file mode 100644 index 00000000..ee19ff04 --- /dev/null +++ b/backend/domain-cvi-publicdata-service/src/main/resources/application-domain-cvi-publicdata.yml @@ -0,0 +1,4 @@ +security: + public: + data: + vaccination: publicdata-secret \ No newline at end of file diff --git a/backend/domain-cvi-publicdata-service/src/main/resources/empty.txt b/backend/domain-cvi-publicdata-service/src/main/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/domain-cvi-scheduler/build.gradle b/backend/domain-cvi-scheduler/build.gradle index 25fb3aff..431d787e 100644 --- a/backend/domain-cvi-scheduler/build.gradle +++ b/backend/domain-cvi-scheduler/build.gradle @@ -1,19 +1,43 @@ -plugins { - id 'java' -} +bootJar { enabled = false } +jar { enabled = true } -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' +dependencies { + implementation project(path:':domain-cvi-publicdata-service' , configuration: 'default') -repositories { - mavenCentral() } -dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 + def Qdomains = [] + + for (qPattern in "*.QA".."*.QZ") { + Qdomains.add(qPattern + "*") + } + + violationRules { // 위반 규칙 + rule { + enabled = true + element = 'BUNDLE' + + limit { + counter = 'INSTRUCTION' + value = 'COVEREDRATIO' + minimum = 0.80 + } + + excludes = [ + // 커버리지 제외할 클래스 + '*.DataLoader*', + '*.CviApplication*', + '*.DummyData*', + '*.KakaoProfile*', + '*.NaverProfile*' + ] + Qdomains + } + } } -test { - useJUnitPlatform() +sonarqube { + properties { + property "sonar.exclusions", "**/*Test*.*, **/Q*.java, **/*Doc*.java" + } } \ No newline at end of file diff --git a/backend/src/main/java/com/backjoongwon/cvi/config/ScheduleConfig.java b/backend/domain-cvi-scheduler/src/main/java/com/cvi/config/SchedulerConfig.java similarity index 71% rename from backend/src/main/java/com/backjoongwon/cvi/config/ScheduleConfig.java rename to backend/domain-cvi-scheduler/src/main/java/com/cvi/config/SchedulerConfig.java index 8edfb5cd..96ddb2f3 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/config/ScheduleConfig.java +++ b/backend/domain-cvi-scheduler/src/main/java/com/cvi/config/SchedulerConfig.java @@ -1,9 +1,9 @@ -package com.backjoongwon.cvi.config; +package com.cvi.config; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; @Configuration @EnableScheduling -public class ScheduleConfig { +public class SchedulerConfig { } diff --git a/backend/domain-cvi-scheduler/src/main/java/com/cvi/empty.txt b/backend/domain-cvi-scheduler/src/main/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/service/PublicDataScheduler.java b/backend/domain-cvi-scheduler/src/main/java/com/cvi/service/PublicDataScheduler.java similarity index 96% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/service/PublicDataScheduler.java rename to backend/domain-cvi-scheduler/src/main/java/com/cvi/service/PublicDataScheduler.java index ebc11b50..cc7c7fa3 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/service/PublicDataScheduler.java +++ b/backend/domain-cvi-scheduler/src/main/java/com/cvi/service/PublicDataScheduler.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.publicdata.service; +package com.cvi.service; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/backend/domain-cvi-service/build.gradle b/backend/domain-cvi-service/build.gradle deleted file mode 100644 index 25fb3aff..00000000 --- a/backend/domain-cvi-service/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -plugins { - id 'java' -} - -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' - -repositories { - mavenCentral() -} - -dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' -} - -test { - useJUnitPlatform() -} \ No newline at end of file diff --git a/backend/domain-cvi-service/src/main/java/com/cvi/empty.txt b/backend/domain-cvi-service/src/main/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/domain-cvi-service/src/main/resources/empty.txt b/backend/domain-cvi-service/src/main/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/domain-cvi-service/src/test/java/com/cvi/empty.txt b/backend/domain-cvi-service/src/test/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/domain-cvi-service/src/test/resources/empty.txt b/backend/domain-cvi-service/src/test/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/domain-cvi/build.gradle b/backend/domain-cvi/build.gradle index 25fb3aff..7e88e389 100644 --- a/backend/domain-cvi/build.gradle +++ b/backend/domain-cvi/build.gradle @@ -1,19 +1,51 @@ -plugins { - id 'java' -} +bootJar { enabled = false } +jar { enabled = true } + +dependencies { + implementation project(path:':common-cvi', configuration: 'default') + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + runtimeOnly 'com.h2database:h2' + runtimeOnly 'mysql:mysql-connector-java' + implementation 'org.hibernate.validator:hibernate-validator:6.2.0.Final' -group 'com.backjoongwon' -version '0.0.1-SNAPSHOT' + //migration + implementation 'org.flywaydb:flyway-core:7.11.2' -repositories { - mavenCentral() } -dependencies { - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' +jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 + def Qdomains = [] + + for (qPattern in "*.QA".."*.QZ") { + Qdomains.add(qPattern + "*") + } + + violationRules { // 위반 규칙 + rule { + enabled = true + element = 'CLASS' + + limit { + counter = 'INSTRUCTION' + value = 'COVEREDRATIO' + minimum = 0.80 + } + + excludes = [ + // 커버리지 제외할 클래스 + '*.DataLoader*', + '*.CviApplication*', + '*.DummyData*', + '*.KakaoProfile*', + '*.NaverProfile*' + ] + Qdomains + } + } } -test { - useJUnitPlatform() -} \ No newline at end of file + +sonarqube { + properties { + property "sonar.exclusions", "**/*Test*.*, **/Q*.java, **/*Doc*.java" + } +} diff --git a/backend/src/main/java/com/backjoongwon/cvi/comment/domain/Comment.java b/backend/domain-cvi/src/main/java/com/cvi/comment/domain/model/Comment.java similarity index 87% rename from backend/src/main/java/com/backjoongwon/cvi/comment/domain/Comment.java rename to backend/domain-cvi/src/main/java/com/cvi/comment/domain/model/Comment.java index 6317037c..6bcadfaa 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/comment/domain/Comment.java +++ b/backend/domain-cvi/src/main/java/com/cvi/comment/domain/model/Comment.java @@ -1,12 +1,15 @@ -package com.backjoongwon.cvi.comment.domain; +package com.cvi.comment.domain.model; -import com.backjoongwon.cvi.common.domain.entity.BaseEntity; -import com.backjoongwon.cvi.common.exception.InvalidOperationException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.user.domain.User; -import lombok.*; +import com.cvi.config.entity.BaseEntity; +import com.cvi.exception.InvalidOperationException; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.post.domain.model.Post; +import com.cvi.user.domain.model.User; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.hibernate.validator.constraints.Length; diff --git a/backend/src/main/java/com/backjoongwon/cvi/comment/domain/CommentQueryDsl.java b/backend/domain-cvi/src/main/java/com/cvi/comment/domain/repository/CommentQueryDsl.java similarity index 66% rename from backend/src/main/java/com/backjoongwon/cvi/comment/domain/CommentQueryDsl.java rename to backend/domain-cvi/src/main/java/com/cvi/comment/domain/repository/CommentQueryDsl.java index baa0c461..865c20a2 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/comment/domain/CommentQueryDsl.java +++ b/backend/domain-cvi/src/main/java/com/cvi/comment/domain/repository/CommentQueryDsl.java @@ -1,4 +1,6 @@ -package com.backjoongwon.cvi.comment.domain; +package com.cvi.comment.domain.repository; + +import com.cvi.comment.domain.model.Comment; import java.util.List; diff --git a/backend/src/main/java/com/backjoongwon/cvi/comment/domain/CommentRepository.java b/backend/domain-cvi/src/main/java/com/cvi/comment/domain/repository/CommentRepository.java similarity index 64% rename from backend/src/main/java/com/backjoongwon/cvi/comment/domain/CommentRepository.java rename to backend/domain-cvi/src/main/java/com/cvi/comment/domain/repository/CommentRepository.java index 6a9d46b6..4c7e32e6 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/comment/domain/CommentRepository.java +++ b/backend/domain-cvi/src/main/java/com/cvi/comment/domain/repository/CommentRepository.java @@ -1,5 +1,6 @@ -package com.backjoongwon.cvi.comment.domain; +package com.cvi.comment.domain.repository; +import com.cvi.comment.domain.model.Comment; import org.springframework.data.jpa.repository.JpaRepository; public interface CommentRepository extends JpaRepository, CommentQueryDsl { diff --git a/backend/src/main/java/com/backjoongwon/cvi/comment/domain/CommentRepositoryImpl.java b/backend/domain-cvi/src/main/java/com/cvi/comment/domain/repository/CommentRepositoryImpl.java similarity index 86% rename from backend/src/main/java/com/backjoongwon/cvi/comment/domain/CommentRepositoryImpl.java rename to backend/domain-cvi/src/main/java/com/cvi/comment/domain/repository/CommentRepositoryImpl.java index a2a6b0d8..318ee350 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/comment/domain/CommentRepositoryImpl.java +++ b/backend/domain-cvi/src/main/java/com/cvi/comment/domain/repository/CommentRepositoryImpl.java @@ -1,5 +1,6 @@ -package com.backjoongwon.cvi.comment.domain; +package com.cvi.comment.domain.repository; +import com.cvi.comment.domain.model.Comment; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.JPQLQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -8,8 +9,8 @@ import java.util.List; import java.util.Objects; -import static com.backjoongwon.cvi.comment.domain.QComment.comment; -import static com.backjoongwon.cvi.user.domain.QUser.user; +import static com.cvi.comment.domain.model.QComment.comment; +import static com.cvi.user.domain.model.QUser.user; public class CommentRepositoryImpl implements CommentQueryDsl { diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/domain/JpaConfiguration.java b/backend/domain-cvi/src/main/java/com/cvi/config/JpaConfiguration.java similarity index 82% rename from backend/src/main/java/com/backjoongwon/cvi/common/domain/JpaConfiguration.java rename to backend/domain-cvi/src/main/java/com/cvi/config/JpaConfiguration.java index b2a4827d..c7ef6fd5 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/domain/JpaConfiguration.java +++ b/backend/domain-cvi/src/main/java/com/cvi/config/JpaConfiguration.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.domain; +package com.cvi.config; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/domain/entity/BaseEntity.java b/backend/domain-cvi/src/main/java/com/cvi/config/entity/BaseEntity.java similarity index 95% rename from backend/src/main/java/com/backjoongwon/cvi/common/domain/entity/BaseEntity.java rename to backend/domain-cvi/src/main/java/com/cvi/config/entity/BaseEntity.java index ec0be58d..482fc2f5 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/common/domain/entity/BaseEntity.java +++ b/backend/domain-cvi/src/main/java/com/cvi/config/entity/BaseEntity.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.common.domain.entity; +package com.cvi.config.entity; import lombok.AccessLevel; import lombok.EqualsAndHashCode; diff --git a/backend/domain-cvi/src/main/java/com/cvi/empty.txt b/backend/domain-cvi/src/main/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/src/main/java/com/backjoongwon/cvi/like/domain/Like.java b/backend/domain-cvi/src/main/java/com/cvi/like/domain/model/Like.java similarity index 83% rename from backend/src/main/java/com/backjoongwon/cvi/like/domain/Like.java rename to backend/domain-cvi/src/main/java/com/cvi/like/domain/model/Like.java index 483c1db8..ee51865e 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/like/domain/Like.java +++ b/backend/domain-cvi/src/main/java/com/cvi/like/domain/model/Like.java @@ -1,10 +1,10 @@ -package com.backjoongwon.cvi.like.domain; +package com.cvi.like.domain.model; -import com.backjoongwon.cvi.common.domain.entity.BaseEntity; -import com.backjoongwon.cvi.common.exception.InvalidOperationException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.config.entity.BaseEntity; +import com.cvi.exception.InvalidOperationException; +import com.cvi.exception.NotFoundException; +import com.cvi.post.domain.model.Post; +import com.cvi.user.domain.model.User; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/like/domain/LikeQueryDsl.java b/backend/domain-cvi/src/main/java/com/cvi/like/domain/repository/LikeQueryDsl.java similarity index 67% rename from backend/src/main/java/com/backjoongwon/cvi/like/domain/LikeQueryDsl.java rename to backend/domain-cvi/src/main/java/com/cvi/like/domain/repository/LikeQueryDsl.java index 58e15f34..3682369d 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/like/domain/LikeQueryDsl.java +++ b/backend/domain-cvi/src/main/java/com/cvi/like/domain/repository/LikeQueryDsl.java @@ -1,4 +1,6 @@ -package com.backjoongwon.cvi.like.domain; +package com.cvi.like.domain.repository; + +import com.cvi.like.domain.model.Like; import java.util.List; diff --git a/backend/src/main/java/com/backjoongwon/cvi/like/domain/LikeRepository.java b/backend/domain-cvi/src/main/java/com/cvi/like/domain/repository/LikeRepository.java similarity index 65% rename from backend/src/main/java/com/backjoongwon/cvi/like/domain/LikeRepository.java rename to backend/domain-cvi/src/main/java/com/cvi/like/domain/repository/LikeRepository.java index ee15ed12..af3ed2cb 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/like/domain/LikeRepository.java +++ b/backend/domain-cvi/src/main/java/com/cvi/like/domain/repository/LikeRepository.java @@ -1,5 +1,6 @@ -package com.backjoongwon.cvi.like.domain; +package com.cvi.like.domain.repository; +import com.cvi.like.domain.model.Like; import org.springframework.data.jpa.repository.JpaRepository; public interface LikeRepository extends JpaRepository, LikeQueryDsl { diff --git a/backend/src/main/java/com/backjoongwon/cvi/like/domain/LikeRepositoryImpl.java b/backend/domain-cvi/src/main/java/com/cvi/like/domain/repository/LikeRepositoryImpl.java similarity index 87% rename from backend/src/main/java/com/backjoongwon/cvi/like/domain/LikeRepositoryImpl.java rename to backend/domain-cvi/src/main/java/com/cvi/like/domain/repository/LikeRepositoryImpl.java index 25990edc..c3253449 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/like/domain/LikeRepositoryImpl.java +++ b/backend/domain-cvi/src/main/java/com/cvi/like/domain/repository/LikeRepositoryImpl.java @@ -1,5 +1,6 @@ -package com.backjoongwon.cvi.like.domain; +package com.cvi.like.domain.repository; +import com.cvi.like.domain.model.Like; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -7,8 +8,8 @@ import java.util.List; import java.util.Objects; -import static com.backjoongwon.cvi.like.domain.QLike.like; -import static com.backjoongwon.cvi.user.domain.QUser.user; +import static com.cvi.like.domain.model.QLike.like; +import static com.cvi.user.domain.model.QUser.user; public class LikeRepositoryImpl implements LikeQueryDsl { diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/domain/Comments.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Comments.java similarity index 86% rename from backend/src/main/java/com/backjoongwon/cvi/post/domain/Comments.java rename to backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Comments.java index 7f8955e4..52696297 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/domain/Comments.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Comments.java @@ -1,9 +1,9 @@ -package com.backjoongwon.cvi.post.domain; +package com.cvi.post.domain.model; -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.comment.domain.model.Comment; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.user.domain.model.User; import lombok.AccessLevel; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/domain/Filter.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Filter.java similarity index 54% rename from backend/src/main/java/com/backjoongwon/cvi/post/domain/Filter.java rename to backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Filter.java index 9f98e12a..f04e5ed3 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/domain/Filter.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Filter.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.post.domain; +package com.cvi.post.domain.model; public enum Filter { diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/domain/Likes.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Likes.java similarity index 84% rename from backend/src/main/java/com/backjoongwon/cvi/post/domain/Likes.java rename to backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Likes.java index e9883d15..3def5e99 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/domain/Likes.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Likes.java @@ -1,11 +1,10 @@ -package com.backjoongwon.cvi.post.domain; +package com.cvi.post.domain.model; - -import com.backjoongwon.cvi.common.exception.InvalidOperationException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.like.domain.Like; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.exception.InvalidOperationException; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.like.domain.model.Like; +import com.cvi.user.domain.model.User; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/domain/Post.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Post.java similarity index 90% rename from backend/src/main/java/com/backjoongwon/cvi/post/domain/Post.java rename to backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Post.java index a43c0ea9..8f271ea0 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/domain/Post.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Post.java @@ -1,17 +1,16 @@ -package com.backjoongwon.cvi.post.domain; - -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.common.domain.entity.BaseEntity; -import com.backjoongwon.cvi.common.exception.InvalidOperationException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.like.domain.Like; -import com.backjoongwon.cvi.user.domain.User; +package com.cvi.post.domain.model; + +import com.cvi.comment.domain.model.Comment; +import com.cvi.config.entity.BaseEntity; +import com.cvi.exception.InvalidOperationException; +import com.cvi.exception.NotFoundException; +import com.cvi.like.domain.model.Like; +import com.cvi.user.domain.model.User; import lombok.*; import javax.persistence.*; import javax.validation.constraints.NotBlank; import java.time.LocalDateTime; -import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Objects; diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/domain/Sort.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Sort.java similarity index 86% rename from backend/src/main/java/com/backjoongwon/cvi/post/domain/Sort.java rename to backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Sort.java index 5ba5b2d5..9c33e4fc 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/domain/Sort.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Sort.java @@ -1,12 +1,12 @@ -package com.backjoongwon.cvi.post.domain; +package com.cvi.post.domain.model; -import com.backjoongwon.cvi.common.exception.InvalidInputException; +import com.cvi.exception.InvalidInputException; import com.querydsl.core.types.OrderSpecifier; import lombok.Getter; import java.util.Arrays; -import static com.backjoongwon.cvi.post.domain.QPost.post; +import static com.cvi.post.domain.model.QPost.post; @Getter public enum Sort { diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/domain/VaccinationType.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/VaccinationType.java similarity index 65% rename from backend/src/main/java/com/backjoongwon/cvi/post/domain/VaccinationType.java rename to backend/domain-cvi/src/main/java/com/cvi/post/domain/model/VaccinationType.java index 9c0d286c..64657ebd 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/domain/VaccinationType.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/VaccinationType.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.post.domain; +package com.cvi.post.domain.model; public enum VaccinationType { diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/domain/PostQueryDsl.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostQueryDsl.java similarity index 80% rename from backend/src/main/java/com/backjoongwon/cvi/post/domain/PostQueryDsl.java rename to backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostQueryDsl.java index 36fee71e..28a1d50a 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/domain/PostQueryDsl.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostQueryDsl.java @@ -1,5 +1,7 @@ -package com.backjoongwon.cvi.post.domain; +package com.cvi.post.domain.repository; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; import com.querydsl.core.types.OrderSpecifier; import java.util.List; diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/domain/PostRepository.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostRepository.java similarity index 70% rename from backend/src/main/java/com/backjoongwon/cvi/post/domain/PostRepository.java rename to backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostRepository.java index f0920062..d749e8b7 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/domain/PostRepository.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostRepository.java @@ -1,5 +1,6 @@ -package com.backjoongwon.cvi.post.domain; +package com.cvi.post.domain.repository; +import com.cvi.post.domain.model.Post; import org.springframework.data.jpa.repository.JpaRepository; public interface PostRepository extends JpaRepository, PostQueryDsl { diff --git a/backend/src/main/java/com/backjoongwon/cvi/post/domain/PostRepositoryImpl.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostRepositoryImpl.java similarity index 89% rename from backend/src/main/java/com/backjoongwon/cvi/post/domain/PostRepositoryImpl.java rename to backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostRepositoryImpl.java index ccd6c837..aeca53c9 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/post/domain/PostRepositoryImpl.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostRepositoryImpl.java @@ -1,5 +1,8 @@ -package com.backjoongwon.cvi.post.domain; +package com.cvi.post.domain.repository; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.QPost; +import com.cvi.post.domain.model.VaccinationType; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.JPQLQueryFactory; @@ -11,10 +14,10 @@ import java.util.Objects; import java.util.Optional; -import static com.backjoongwon.cvi.comment.domain.QComment.comment; -import static com.backjoongwon.cvi.like.domain.QLike.like; -import static com.backjoongwon.cvi.post.domain.QPost.post; -import static com.backjoongwon.cvi.user.domain.QUser.user; +import static com.cvi.comment.domain.model.QComment.comment; +import static com.cvi.like.domain.model.QLike.like; +import static com.cvi.post.domain.model.QPost.post; +import static com.cvi.user.domain.model.QUser.user; public class PostRepositoryImpl implements PostQueryDsl { diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/PublicData.java b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/PublicData.java similarity index 89% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/PublicData.java rename to backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/PublicData.java index 83dae7bd..c5f56704 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/PublicData.java +++ b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/PublicData.java @@ -1,6 +1,6 @@ -package com.backjoongwon.cvi.publicdata.domain; +package com.cvi.publicdata.domain.model; -import com.backjoongwon.cvi.common.domain.entity.BaseEntity; +import com.cvi.config.entity.BaseEntity; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/RegionPopulation.java b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/RegionPopulation.java similarity index 97% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/RegionPopulation.java rename to backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/RegionPopulation.java index 2a9ffd3c..83670361 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/RegionPopulation.java +++ b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/RegionPopulation.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.publicdata.domain; +package com.cvi.publicdata.domain.model; import lombok.Getter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatistic.java b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistic.java similarity index 98% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatistic.java rename to backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistic.java index 3601d490..0af03397 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatistic.java +++ b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistic.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.publicdata.domain; +package com.cvi.publicdata.domain.model; import lombok.AccessLevel; import lombok.Builder; diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatistics.java b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistics.java similarity index 98% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatistics.java rename to backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistics.java index 2aca3e9f..0f71a4af 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatistics.java +++ b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistics.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.publicdata.domain; +package com.cvi.publicdata.domain.model; import java.time.LocalDate; import java.util.ArrayList; diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/PublicDataRepository.java b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/repository/PublicDataRepository.java similarity index 60% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/PublicDataRepository.java rename to backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/repository/PublicDataRepository.java index d12cfc3c..97006e12 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/PublicDataRepository.java +++ b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/repository/PublicDataRepository.java @@ -1,5 +1,6 @@ -package com.backjoongwon.cvi.publicdata.domain; +package com.cvi.publicdata.domain.repository; +import com.cvi.publicdata.domain.model.PublicData; import org.springframework.data.jpa.repository.JpaRepository; public interface PublicDataRepository extends JpaRepository { diff --git a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatisticRepository.java b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/repository/VaccinationStatisticRepository.java similarity index 69% rename from backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatisticRepository.java rename to backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/repository/VaccinationStatisticRepository.java index 15e4b670..c3b24378 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatisticRepository.java +++ b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/repository/VaccinationStatisticRepository.java @@ -1,5 +1,7 @@ -package com.backjoongwon.cvi.publicdata.domain; +package com.cvi.publicdata.domain.repository; +import com.cvi.publicdata.domain.model.RegionPopulation; +import com.cvi.publicdata.domain.model.VaccinationStatistic; import org.springframework.data.jpa.repository.JpaRepository; import java.time.LocalDate; diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/domain/AgeRange.java b/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/AgeRange.java similarity index 92% rename from backend/src/main/java/com/backjoongwon/cvi/user/domain/AgeRange.java rename to backend/domain-cvi/src/main/java/com/cvi/user/domain/model/AgeRange.java index ce149445..15529ce1 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/domain/AgeRange.java +++ b/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/AgeRange.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.user.domain; +package com.cvi.user.domain.model; import lombok.Getter; diff --git a/backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/SocialProvider.java b/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/SocialProvider.java similarity index 84% rename from backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/SocialProvider.java rename to backend/domain-cvi/src/main/java/com/cvi/user/domain/model/SocialProvider.java index cce2b9db..171edfb2 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/auth/domain/authorization/SocialProvider.java +++ b/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/SocialProvider.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.auth.domain.authorization; +package com.cvi.user.domain.model; public enum SocialProvider { NAVER("naverAuthorization"), diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/domain/User.java b/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java similarity index 90% rename from backend/src/main/java/com/backjoongwon/cvi/user/domain/User.java rename to backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java index 5fd2a33b..ec1b13a8 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/domain/User.java +++ b/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java @@ -1,12 +1,11 @@ -package com.backjoongwon.cvi.user.domain; +package com.cvi.user.domain.model; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; -import com.backjoongwon.cvi.common.domain.entity.BaseEntity; -import com.backjoongwon.cvi.common.exception.InvalidInputException; +import com.cvi.config.entity.BaseEntity; +import com.cvi.exception.InvalidInputException; import lombok.*; import lombok.extern.slf4j.Slf4j; import org.hibernate.validator.constraints.Length; -import org.thymeleaf.util.StringUtils; +import org.springframework.util.StringUtils; import javax.persistence.*; import javax.validation.constraints.NotBlank; diff --git a/backend/src/main/java/com/backjoongwon/cvi/user/domain/UserRepository.java b/backend/domain-cvi/src/main/java/com/cvi/user/domain/repository/UserRepository.java similarity index 70% rename from backend/src/main/java/com/backjoongwon/cvi/user/domain/UserRepository.java rename to backend/domain-cvi/src/main/java/com/cvi/user/domain/repository/UserRepository.java index 4331ab74..d5db415d 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/user/domain/UserRepository.java +++ b/backend/domain-cvi/src/main/java/com/cvi/user/domain/repository/UserRepository.java @@ -1,6 +1,7 @@ -package com.backjoongwon.cvi.user.domain; +package com.cvi.user.domain.repository; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; diff --git a/backend/domain-cvi/src/main/resources/application-domain-cvi.yml b/backend/domain-cvi/src/main/resources/application-domain-cvi.yml new file mode 100644 index 00000000..7b360071 --- /dev/null +++ b/backend/domain-cvi/src/main/resources/application-domain-cvi.yml @@ -0,0 +1,43 @@ +spring: + jpa: + properties: + hibernate.default_batch_fetch_size: 500 + h2: + console: + enabled: false + flyway: + enabled: false + +logging: + level: + org.hibernate.SQL: info +--- +spring: + config: + activate: + on-profile: local + + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE; + username: sa + password: + + h2: + console: + enabled: true + + jpa: + hibernate: + ddl-auto: create-drop + properties: + hibernate: + format_sql: true + generate-ddl: true + + flyway: + enabled: false + +logging: + level: + org.hibernate.SQL: debug diff --git a/backend/domain-cvi/src/main/resources/db/migration/V20210809__Create_init.sql b/backend/domain-cvi/src/main/resources/db/migration/V20210809__Create_init.sql new file mode 100644 index 00000000..85fb995d --- /dev/null +++ b/backend/domain-cvi/src/main/resources/db/migration/V20210809__Create_init.sql @@ -0,0 +1,92 @@ +drop table if exists comment CASCADE; +drop table if exists likes CASCADE; +drop table if exists post CASCADE; +drop table if exists user CASCADE; +drop table if exists vaccination_statistic; +drop table if exists public_data; + +create table comment +( + comment_id bigint auto_increment not null, + created_at timestamp default CURRENT_TIMESTAMP, + last_modified_at timestamp default CURRENT_TIMESTAMP, + post_id bigint, + user_id bigint, + content text, + primary key (comment_id) +); + +create table likes +( + likes_id bigint auto_increment not null, + created_at timestamp default CURRENT_TIMESTAMP, + last_modified_at timestamp default CURRENT_TIMESTAMP, + post_id bigint, + user_id bigint, + primary key (likes_id) +); + +create table user +( + user_id bigint auto_increment not null, + created_at timestamp default CURRENT_TIMESTAMP, + last_modified_at timestamp default CURRENT_TIMESTAMP, + nickname varchar(255), + age_range varchar(255), + shot_verified boolean not null default false, + social_provider varchar(255), + social_id varchar(255), + profile_url varchar(255), + primary key (user_id), + unique (nickname) +); + +create table post +( + post_id bigint auto_increment not null, + created_at timestamp default CURRENT_TIMESTAMP, + last_modified_at timestamp default CURRENT_TIMESTAMP, + user_id bigint, + content text, + view_count integer not null default 0, + vaccination_type varchar(255), + primary key (post_id) +); + +create table public_data +( + public_data_type varchar(31) not null, + public_data_id bigint auto_increment not null, + created_at timestamp default CURRENT_TIMESTAMP, + last_modified_at timestamp default CURRENT_TIMESTAMP, + region_population varchar(255), + primary key (public_data_id) +); + +create table vaccination_statistic +( + accumulated_first_cnt bigint, + accumulated_second_cnt bigint, + base_date date, + first_cnt bigint, + second_cnt bigint, + total_first_cnt bigint, + total_first_rate decimal(19, 1), + total_second_cnt bigint, + total_second_rate decimal(19, 1), + vaccination_statistic_id bigint not null, + primary key (vaccination_statistic_id) +); + +alter table comment + add constraint fk_comment_post foreign key (post_id) references post (post_id) on delete cascade; +alter table comment + add constraint fk_comment_user foreign key (user_id) references user (user_id) on delete cascade; +alter table likes + add constraint fk_likes_post foreign key (post_id) references post (post_id) on delete cascade; +alter table likes + add constraint fk_likes_user foreign key (user_id) references user (user_id) on delete cascade; +alter table post + add constraint fk_post_user foreign key (user_id) references user (user_id) on delete cascade; +alter table vaccination_statistic + add constraint fk_vaccination_statistic_public_data foreign key (vaccination_statistic_id) references public_data (public_data_id); diff --git a/backend/domain-cvi/src/main/resources/empty.txt b/backend/domain-cvi/src/main/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/settings.gradle b/backend/settings.gradle index 2a29ae75..35560e81 100644 --- a/backend/settings.gradle +++ b/backend/settings.gradle @@ -1,12 +1,10 @@ rootProject.name = 'cvi' -include 'cvi-vaccine-stats-parser' +include 'app-cvi-admin' include 'cvi-publicdata-parser' -include 'cvi-oauth-parser' include 'common-cvi' include 'domain-cvi' -include 'domain-cvi-service' include 'domain-cvi-oauth-service' include 'domain-cvi-publicdata-service' include 'domain-cvi-scheduler' include 'app-cvi-api' -include 'app-cvi-admin' + diff --git a/backend/src/docs/asciidoc/index.html b/backend/src/docs/asciidoc/index.html deleted file mode 100644 index d445110a..00000000 --- a/backend/src/docs/asciidoc/index.html +++ /dev/null @@ -1,4243 +0,0 @@ - - - - - - - - -Team CVI Api Specification - - - - - - -

-
-
-

Common Responses

-
-
-

Common Status Codes

-
-
-
# 생성
-## status code: 201
-## Headers: Location
-
-# 조회
-## status code: 200
-
-# 업데이트
-## status code: 204
-
-# 삭제
-## status code: 204
-
-
-
-
-

Common Exceptions

-
-
-
# 클라이언트 입력 예외
-## status code: 400
-
-# 인증 예외
-## status code: 401
-
-# NotFound 예외
-## status code: 404
-
-# 서버 내부 예외
-## status code: 500
-
-
-
-
-
-
-

PublicData (공공데이터)

-
-
-

공통 체크사항

-
-
-
시간을 Parameter로 넘기지 않을 때, defaultValue = LocalDateTime
-
-
-
-
-
 오전 10시전 당일 데이터 요청시, 전날 데이터 저장/출력
- ex) 현재 날짜 2021-08-05 09:59:59 요청시 2021-08-04 데이터 저장/출력
-
-
-
-
-

백신 접종률 저장

-
-

성공

-
-
Request
-
-
-
POST /api/v1/publicdata/vaccinations HTTP/1.1
-Host: localhost
-Content-Type: application/x-www-form-urlencoded
-
-targetDate=2021-08-09
-
-
-
-
-
Response
-
-
-
HTTP/1.1 201 Created
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 5173
-
-[ {
-  "accumulatedFirstCnt" : 19473657,
-  "accumulatedSecondCnt" : 7146602,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 473850,
-  "secondCnt" : 35955,
-  "sido" : "전국",
-  "totalFirstCnt" : 19947507,
-  "totalSecondCnt" : 7182557,
-  "totalFirstRate" : 39.2,
-  "totalSecondRate" : 14.3
-}, {
-  "accumulatedFirstCnt" : 3646765,
-  "accumulatedSecondCnt" : 1329982,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 77877,
-  "secondCnt" : 7123,
-  "sido" : "서울특별시",
-  "totalFirstCnt" : 3724642,
-  "totalSecondCnt" : 1337105,
-  "totalFirstRate" : 39.5,
-  "totalSecondRate" : 14.4
-}, {
-  "accumulatedFirstCnt" : 1352394,
-  "accumulatedSecondCnt" : 477845,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 31252,
-  "secondCnt" : 2628,
-  "sido" : "부산광역시",
-  "totalFirstCnt" : 1383646,
-  "totalSecondCnt" : 480473,
-  "totalFirstRate" : 41.8,
-  "totalSecondRate" : 14.6
-}, {
-  "accumulatedFirstCnt" : 848397,
-  "accumulatedSecondCnt" : 309317,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 22726,
-  "secondCnt" : 2688,
-  "sido" : "대구광역시",
-  "totalFirstCnt" : 871123,
-  "totalSecondCnt" : 312005,
-  "totalFirstRate" : 37.0,
-  "totalSecondRate" : 13.4
-}, {
-  "accumulatedFirstCnt" : 1032052,
-  "accumulatedSecondCnt" : 360923,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 27394,
-  "secondCnt" : 1760,
-  "sido" : "인천광역시",
-  "totalFirstCnt" : 1059446,
-  "totalSecondCnt" : 362683,
-  "totalFirstRate" : 39.8,
-  "totalSecondRate" : 14.7
-}, {
-  "accumulatedFirstCnt" : 549706,
-  "accumulatedSecondCnt" : 204415,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 13700,
-  "secondCnt" : 830,
-  "sido" : "광주광역시",
-  "totalFirstCnt" : 563406,
-  "totalSecondCnt" : 205245,
-  "totalFirstRate" : 37.6,
-  "totalSecondRate" : 14.7
-}, {
-  "accumulatedFirstCnt" : 396793,
-  "accumulatedSecondCnt" : 124839,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 11275,
-  "secondCnt" : 471,
-  "sido" : "울산광역시",
-  "totalFirstCnt" : 408068,
-  "totalSecondCnt" : 125310,
-  "totalFirstRate" : 37.6,
-  "totalSecondRate" : 14.0
-}, {
-  "accumulatedFirstCnt" : 523814,
-  "accumulatedSecondCnt" : 197608,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 12990,
-  "secondCnt" : 959,
-  "sido" : "대전광역시",
-  "totalFirstCnt" : 536804,
-  "totalSecondCnt" : 198567,
-  "totalFirstRate" : 36.8,
-  "totalSecondRate" : 12.7
-}, {
-  "accumulatedFirstCnt" : 4636237,
-  "accumulatedSecondCnt" : 1636357,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 118717,
-  "secondCnt" : 7895,
-  "sido" : "경기도",
-  "totalFirstCnt" : 4754954,
-  "totalSecondCnt" : 1644252,
-  "totalFirstRate" : 31.6,
-  "totalSecondRate" : 10.9
-}, {
-  "accumulatedFirstCnt" : 668422,
-  "accumulatedSecondCnt" : 273253,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 14908,
-  "secondCnt" : 1010,
-  "sido" : "강원도",
-  "totalFirstCnt" : 683330,
-  "totalSecondCnt" : 274263,
-  "totalFirstRate" : 36.9,
-  "totalSecondRate" : 11.5
-}, {
-  "accumulatedFirstCnt" : 109202,
-  "accumulatedSecondCnt" : 37624,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 3028,
-  "secondCnt" : 179,
-  "sido" : "세종특별자치시",
-  "totalFirstCnt" : 112230,
-  "totalSecondCnt" : 37803,
-  "totalFirstRate" : 42.7,
-  "totalSecondRate" : 15.8
-}, {
-  "accumulatedFirstCnt" : 639514,
-  "accumulatedSecondCnt" : 240704,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 15886,
-  "secondCnt" : 1324,
-  "sido" : "충청북도",
-  "totalFirstCnt" : 655400,
-  "totalSecondCnt" : 242028,
-  "totalFirstRate" : 42.1,
-  "totalSecondRate" : 16.1
-}, {
-  "accumulatedFirstCnt" : 849914,
-  "accumulatedSecondCnt" : 330591,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 22167,
-  "secondCnt" : 2054,
-  "sido" : "충청남도",
-  "totalFirstCnt" : 872081,
-  "totalSecondCnt" : 332645,
-  "totalFirstRate" : 45.6,
-  "totalSecondRate" : 17.8
-}, {
-  "accumulatedFirstCnt" : 789017,
-  "accumulatedSecondCnt" : 311961,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 17331,
-  "secondCnt" : 1270,
-  "sido" : "전라북도",
-  "totalFirstCnt" : 806348,
-  "totalSecondCnt" : 313231,
-  "totalFirstRate" : 48.4,
-  "totalSecondRate" : 19.1
-}, {
-  "accumulatedFirstCnt" : 859228,
-  "accumulatedSecondCnt" : 344275,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 19083,
-  "secondCnt" : 1378,
-  "sido" : "전라남도",
-  "totalFirstCnt" : 878311,
-  "totalSecondCnt" : 345653,
-  "totalFirstRate" : 42.7,
-  "totalSecondRate" : 16.0
-}, {
-  "accumulatedFirstCnt" : 1070878,
-  "accumulatedSecondCnt" : 409752,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 27263,
-  "secondCnt" : 2016,
-  "sido" : "경상북도",
-  "totalFirstCnt" : 1098141,
-  "totalSecondCnt" : 411768,
-  "totalFirstRate" : 40.4,
-  "totalSecondRate" : 14.8
-}, {
-  "accumulatedFirstCnt" : 1249910,
-  "accumulatedSecondCnt" : 464110,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 31098,
-  "secondCnt" : 1943,
-  "sido" : "경상남도",
-  "totalFirstCnt" : 1281008,
-  "totalSecondCnt" : 466053,
-  "totalFirstRate" : 39.2,
-  "totalSecondRate" : 14.3
-}, {
-  "accumulatedFirstCnt" : 251414,
-  "accumulatedSecondCnt" : 93046,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 7155,
-  "secondCnt" : 427,
-  "sido" : "제주특별자치도",
-  "totalFirstCnt" : 258569,
-  "totalSecondCnt" : 93473,
-  "totalFirstRate" : 42.7,
-  "totalSecondRate" : 17.8
-} ]
-
-
-
-
-
-
-

백신 접종률 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/publicdata/vaccinations?targetDate=2021-08-09 HTTP/1.1
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 5173
-
-[ {
-  "accumulatedFirstCnt" : 19473657,
-  "accumulatedSecondCnt" : 7146602,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 473850,
-  "secondCnt" : 35955,
-  "sido" : "전국",
-  "totalFirstCnt" : 19947507,
-  "totalSecondCnt" : 7182557,
-  "totalFirstRate" : 39.2,
-  "totalSecondRate" : 14.3
-}, {
-  "accumulatedFirstCnt" : 3646765,
-  "accumulatedSecondCnt" : 1329982,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 77877,
-  "secondCnt" : 7123,
-  "sido" : "서울특별시",
-  "totalFirstCnt" : 3724642,
-  "totalSecondCnt" : 1337105,
-  "totalFirstRate" : 39.5,
-  "totalSecondRate" : 14.4
-}, {
-  "accumulatedFirstCnt" : 1352394,
-  "accumulatedSecondCnt" : 477845,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 31252,
-  "secondCnt" : 2628,
-  "sido" : "부산광역시",
-  "totalFirstCnt" : 1383646,
-  "totalSecondCnt" : 480473,
-  "totalFirstRate" : 41.8,
-  "totalSecondRate" : 14.6
-}, {
-  "accumulatedFirstCnt" : 848397,
-  "accumulatedSecondCnt" : 309317,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 22726,
-  "secondCnt" : 2688,
-  "sido" : "대구광역시",
-  "totalFirstCnt" : 871123,
-  "totalSecondCnt" : 312005,
-  "totalFirstRate" : 37.0,
-  "totalSecondRate" : 13.4
-}, {
-  "accumulatedFirstCnt" : 1032052,
-  "accumulatedSecondCnt" : 360923,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 27394,
-  "secondCnt" : 1760,
-  "sido" : "인천광역시",
-  "totalFirstCnt" : 1059446,
-  "totalSecondCnt" : 362683,
-  "totalFirstRate" : 39.8,
-  "totalSecondRate" : 14.7
-}, {
-  "accumulatedFirstCnt" : 549706,
-  "accumulatedSecondCnt" : 204415,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 13700,
-  "secondCnt" : 830,
-  "sido" : "광주광역시",
-  "totalFirstCnt" : 563406,
-  "totalSecondCnt" : 205245,
-  "totalFirstRate" : 37.6,
-  "totalSecondRate" : 14.7
-}, {
-  "accumulatedFirstCnt" : 396793,
-  "accumulatedSecondCnt" : 124839,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 11275,
-  "secondCnt" : 471,
-  "sido" : "울산광역시",
-  "totalFirstCnt" : 408068,
-  "totalSecondCnt" : 125310,
-  "totalFirstRate" : 37.6,
-  "totalSecondRate" : 14.0
-}, {
-  "accumulatedFirstCnt" : 523814,
-  "accumulatedSecondCnt" : 197608,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 12990,
-  "secondCnt" : 959,
-  "sido" : "대전광역시",
-  "totalFirstCnt" : 536804,
-  "totalSecondCnt" : 198567,
-  "totalFirstRate" : 36.8,
-  "totalSecondRate" : 12.7
-}, {
-  "accumulatedFirstCnt" : 4636237,
-  "accumulatedSecondCnt" : 1636357,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 118717,
-  "secondCnt" : 7895,
-  "sido" : "경기도",
-  "totalFirstCnt" : 4754954,
-  "totalSecondCnt" : 1644252,
-  "totalFirstRate" : 31.6,
-  "totalSecondRate" : 10.9
-}, {
-  "accumulatedFirstCnt" : 668422,
-  "accumulatedSecondCnt" : 273253,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 14908,
-  "secondCnt" : 1010,
-  "sido" : "강원도",
-  "totalFirstCnt" : 683330,
-  "totalSecondCnt" : 274263,
-  "totalFirstRate" : 36.9,
-  "totalSecondRate" : 11.5
-}, {
-  "accumulatedFirstCnt" : 109202,
-  "accumulatedSecondCnt" : 37624,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 3028,
-  "secondCnt" : 179,
-  "sido" : "세종특별자치시",
-  "totalFirstCnt" : 112230,
-  "totalSecondCnt" : 37803,
-  "totalFirstRate" : 42.7,
-  "totalSecondRate" : 15.8
-}, {
-  "accumulatedFirstCnt" : 639514,
-  "accumulatedSecondCnt" : 240704,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 15886,
-  "secondCnt" : 1324,
-  "sido" : "충청북도",
-  "totalFirstCnt" : 655400,
-  "totalSecondCnt" : 242028,
-  "totalFirstRate" : 42.1,
-  "totalSecondRate" : 16.1
-}, {
-  "accumulatedFirstCnt" : 849914,
-  "accumulatedSecondCnt" : 330591,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 22167,
-  "secondCnt" : 2054,
-  "sido" : "충청남도",
-  "totalFirstCnt" : 872081,
-  "totalSecondCnt" : 332645,
-  "totalFirstRate" : 45.6,
-  "totalSecondRate" : 17.8
-}, {
-  "accumulatedFirstCnt" : 789017,
-  "accumulatedSecondCnt" : 311961,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 17331,
-  "secondCnt" : 1270,
-  "sido" : "전라북도",
-  "totalFirstCnt" : 806348,
-  "totalSecondCnt" : 313231,
-  "totalFirstRate" : 48.4,
-  "totalSecondRate" : 19.1
-}, {
-  "accumulatedFirstCnt" : 859228,
-  "accumulatedSecondCnt" : 344275,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 19083,
-  "secondCnt" : 1378,
-  "sido" : "전라남도",
-  "totalFirstCnt" : 878311,
-  "totalSecondCnt" : 345653,
-  "totalFirstRate" : 42.7,
-  "totalSecondRate" : 16.0
-}, {
-  "accumulatedFirstCnt" : 1070878,
-  "accumulatedSecondCnt" : 409752,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 27263,
-  "secondCnt" : 2016,
-  "sido" : "경상북도",
-  "totalFirstCnt" : 1098141,
-  "totalSecondCnt" : 411768,
-  "totalFirstRate" : 40.4,
-  "totalSecondRate" : 14.8
-}, {
-  "accumulatedFirstCnt" : 1249910,
-  "accumulatedSecondCnt" : 464110,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 31098,
-  "secondCnt" : 1943,
-  "sido" : "경상남도",
-  "totalFirstCnt" : 1281008,
-  "totalSecondCnt" : 466053,
-  "totalFirstRate" : 39.2,
-  "totalSecondRate" : 14.3
-}, {
-  "accumulatedFirstCnt" : 251414,
-  "accumulatedSecondCnt" : 93046,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 7155,
-  "secondCnt" : 427,
-  "sido" : "제주특별자치도",
-  "totalFirstCnt" : 258569,
-  "totalSecondCnt" : 93473,
-  "totalFirstRate" : 42.7,
-  "totalSecondRate" : 17.8
-} ]
-
-
-
-
-
-

성공 - 요청 후 api 데이터가 없을 때

-
-
Request
-
-
-
GET /api/v1/publicdata/vaccinations?targetDate=2021-08-10 HTTP/1.1
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 3
-
-[ ]
-
-
-
-
-
-
-

세계 백신 접종률 저장

-
-

성공

-
-
Request
-
-
-
POST /api/v1/publicdata/vaccinations/world HTTP/1.1
-Host: localhost
-Content-Type: application/x-www-form-urlencoded
-
-targetDate=2021-08-09
-
-
-
-
-
Response
-
-
-
HTTP/1.1 201 Created
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 540
-
-[ {
-  "accumulatedFirstCnt" : 0,
-  "accumulatedSecondCnt" : 0,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 0,
-  "secondCnt" : 0,
-  "sido" : "World",
-  "totalFirstCnt" : 2303769251,
-  "totalSecondCnt" : 1191535085,
-  "totalFirstRate" : 29.3,
-  "totalSecondRate" : 15.0
-}, {
-  "accumulatedFirstCnt" : 0,
-  "accumulatedSecondCnt" : 0,
-  "baseDate" : "2021-08-08",
-  "firstCnt" : 0,
-  "secondCnt" : 0,
-  "sido" : "World",
-  "totalFirstCnt" : 2293196690,
-  "totalSecondCnt" : 1175939230,
-  "totalFirstRate" : 28.9,
-  "totalSecondRate" : 14.7
-} ]
-
-
-
-
-
-
-

세계 백신 접종률 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/publicdata/vaccinations/world?targetDate=2021-08-09 HTTP/1.1
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 271
-
-[ {
-  "accumulatedFirstCnt" : 0,
-  "accumulatedSecondCnt" : 0,
-  "baseDate" : "2021-08-09",
-  "firstCnt" : 0,
-  "secondCnt" : 0,
-  "sido" : "World",
-  "totalFirstCnt" : 2303769251,
-  "totalSecondCnt" : 1191535085,
-  "totalFirstRate" : 29.3,
-  "totalSecondRate" : 15.0
-} ]
-
-
-
-
-
-
-
-
-

User (사용자)

-
-
-

사용자 OAuth

-
-

성공

-
-
Request
-
-
-
POST /api/v1/users/auth HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Content-Length: 95
-Host: localhost
-
-{
-  "provider" : "KAKAO",
-  "code" : "{CODE received from social provider}",
-  "state" : null
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Content-Type: application/json
-Content-Length: 343
-
-{
-  "id" : 1,
-  "nickname" : "인비",
-  "ageRange" : {
-    "meaning" : "20대",
-    "minAge" : 20,
-    "maxAge" : 30
-  },
-  "shotVerified" : false,
-  "accessToken" : "Bearer {ACCESS TOKEN generated by JWT}",
-  "socialProvider" : "KAKAO",
-  "socialId" : "{Unique ID received from social provider}",
-  "socialProfileUrl" : "kakao.com/profile"
-}
-
-
-
-
-
-

실패

-
-
Request
-
-
-
POST /api/v1/users/auth HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Content-Length: 95
-Host: localhost
-
-{
-  "provider" : "KAKAO",
-  "code" : "{CODE received from social provider}",
-  "state" : null
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 58
-
-{
-  "message" : "OAuth 인증에 실패하였습니다."
-}
-
-
-
-
-
-
-

사용자 가입

-
-

성공

-
-
Request
-
-
-
POST /api/v1/users/signup HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Content-Length: 214
-Host: localhost
-
-{
-  "nickname" : "인비",
-  "ageRange" : "TWENTIES",
-  "shotVerified" : false,
-  "socialProvider" : "KAKAO",
-  "socialId" : "{Unique ID received from social provider}",
-  "socialProfileUrl" : "kakao.com/profile"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 201 Created
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Location: /api/v1/users/1
-Content-Type: application/json
-Content-Length: 336
-
-{
-  "id" : 1,
-  "nickname" : "인비",
-  "ageRange" : {
-    "meaning" : "20대",
-    "minAge" : 20,
-    "maxAge" : 30
-  },
-  "shotVerified" : false,
-  "accessToken" : "{ACCESS TOKEN generated by JWT}",
-  "socialProvider" : "KAKAO",
-  "socialId" : "{Unique ID received from social provider}",
-  "socialProfileUrl" : "kakao.com/profile"
-}
-
-
-
-
    -
  • -

    닉네임은 중복될 수 없다.

    -
  • -
  • -

    닉네임은 공백 문자를 포함할 수 없다.

    -
  • -
-
-
-
-
-

실패

-
-
Request
-
-
-
POST /api/v1/users/signup HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Content-Length: 214
-Host: localhost
-
-{
-  "nickname" : "인비",
-  "ageRange" : "TWENTIES",
-  "shotVerified" : false,
-  "socialProvider" : "KAKAO",
-  "socialId" : "{Unique ID received from social provider}",
-  "socialProfileUrl" : "kakao.com/profile"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 400 Bad Request
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 59
-
-{
-  "message" : "중복된 닉네임이 존재합니다."
-}
-
-
-
-
-
-
-

사용자 내 정보 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/users/me HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 307
-
-{
-  "id" : 1,
-  "nickname" : "인비",
-  "ageRange" : {
-    "meaning" : "20대",
-    "minAge" : 20,
-    "maxAge" : 30
-  },
-  "shotVerified" : false,
-  "accessToken" : null,
-  "socialProvider" : "KAKAO",
-  "socialId" : "{Unique ID received from social provider}",
-  "socialProfileUrl" : "kakao.com/profile"
-}
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/users/me HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 59
-
-{
-  "message" : "존재하지 않는 사용자입니다."
-}
-
-
-
-
-
-
-

사용자 내가 작성한 게시글 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/users/me/posts HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 2690
-
-[ {
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "글 내용1",
-  "viewCount" : 55,
-  "likeCount" : 5,
-  "hasLiked" : true,
-  "comments" : [ {
-    "id" : 1,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글1",
-    "createdAt" : "2021-08-09T20:12:50.52731"
-  }, {
-    "id" : 2,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글2",
-    "createdAt" : "2021-08-09T20:12:50.527319"
-  } ],
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-08T20:12:50.528811"
-}, {
-  "id" : 2,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "글 내용2",
-  "viewCount" : 12,
-  "likeCount" : 0,
-  "hasLiked" : false,
-  "comments" : [ ],
-  "vaccinationType" : "MODERNA",
-  "createdAt" : "2021-08-09T20:12:50.528824"
-}, {
-  "id" : 3,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "글 내용3",
-  "viewCount" : 12,
-  "likeCount" : 0,
-  "hasLiked" : false,
-  "comments" : [ ],
-  "vaccinationType" : "ASTRAZENECA",
-  "createdAt" : "2021-08-09T20:12:50.528834"
-} ]
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/users/me/posts HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 56
-
-{
-  "message" : "유효하지 않은 토큰입니다."
-}
-
-
-
-
-
-
-

사용자 내가 작성한 게시글 페이징 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/users/me/posts/paging?filter=NONE&offset=0&size=4 HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 3340
-
-[ {
-  "id" : 38,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "이건 내용입니다.",
-  "viewCount" : 100,
-  "likeCount" : 10,
-  "hasLiked" : false,
-  "comments" : [ {
-    "id" : 1,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글1",
-    "createdAt" : "2021-08-09T20:12:50.165557"
-  }, {
-    "id" : 2,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글2",
-    "createdAt" : "2021-08-09T20:12:50.165563"
-  } ],
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:50.166439"
-}, {
-  "id" : 37,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "이건 내용입니다.2",
-  "viewCount" : 200,
-  "likeCount" : 20,
-  "hasLiked" : true,
-  "comments" : [ ],
-  "vaccinationType" : "MODERNA",
-  "createdAt" : "2021-08-08T20:12:50.166462"
-}, {
-  "id" : 36,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "이건 내용입니다.3",
-  "viewCount" : 300,
-  "likeCount" : 30,
-  "hasLiked" : false,
-  "comments" : [ ],
-  "vaccinationType" : "ASTRAZENECA",
-  "createdAt" : "2021-08-09T18:12:50.166474"
-}, {
-  "id" : 35,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "이건 내용입니다.3",
-  "viewCount" : 300,
-  "likeCount" : 30,
-  "hasLiked" : false,
-  "comments" : [ ],
-  "vaccinationType" : "ASTRAZENECA",
-  "createdAt" : "2021-08-09T18:12:50.166478"
-} ]
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/users/me/posts/paging?filter=NONE&offset=0&size=4 HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 56
-
-{
-  "message" : "유효하지 않은 토큰입니다."
-}
-
-
-
-
-
-
-

사용자 내가 좋아요 한 게시글 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/users/me/posts?filter=LIKES HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 2104
-
-[ {
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "글 내용1",
-  "viewCount" : 55,
-  "likeCount" : 5,
-  "hasLiked" : true,
-  "comments" : [ {
-    "id" : 1,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글1",
-    "createdAt" : "2021-08-09T20:12:50.313676"
-  }, {
-    "id" : 2,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글2",
-    "createdAt" : "2021-08-09T20:12:50.313685"
-  } ],
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-08T20:12:50.315449"
-}, {
-  "id" : 2,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "글 내용2",
-  "viewCount" : 12,
-  "likeCount" : 0,
-  "hasLiked" : true,
-  "comments" : [ ],
-  "vaccinationType" : "MODERNA",
-  "createdAt" : "2021-08-09T20:12:50.315466"
-} ]
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/users/me/posts?filter=LIKES HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 56
-
-{
-  "message" : "유효하지 않은 토큰입니다."
-}
-
-
-
-
-
-
-

사용자 내가 좋아요 한 게시글 페이징 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/users/me/posts/paging?filter=LIKES&offset=0&size=3 HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 2735
-
-[ {
-  "id" : 38,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "이건 내용입니다.",
-  "viewCount" : 100,
-  "likeCount" : 10,
-  "hasLiked" : true,
-  "comments" : [ {
-    "id" : 1,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글1",
-    "createdAt" : "2021-08-09T20:12:50.561111"
-  }, {
-    "id" : 2,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글2",
-    "createdAt" : "2021-08-09T20:12:50.561122"
-  } ],
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:50.562717"
-}, {
-  "id" : 37,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "이건 내용입니다.2",
-  "viewCount" : 200,
-  "likeCount" : 20,
-  "hasLiked" : true,
-  "comments" : [ ],
-  "vaccinationType" : "MODERNA",
-  "createdAt" : "2021-08-08T20:12:50.562744"
-}, {
-  "id" : 36,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "이건 내용입니다.3",
-  "viewCount" : 300,
-  "likeCount" : 30,
-  "hasLiked" : true,
-  "comments" : [ ],
-  "vaccinationType" : "ASTRAZENECA",
-  "createdAt" : "2021-08-09T18:12:50.56275"
-} ]
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/users/me/posts/paging?filter=LIKES&offset=0&size=3 HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 56
-
-{
-  "message" : "유효하지 않은 토큰입니다."
-}
-
-
-
-
-
-
-

사용자 내가 댓글을 단 게시글 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/users/me/posts?filter=COMMENTS HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 3045
-
-[ {
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "글 내용1",
-  "viewCount" : 55,
-  "likeCount" : 5,
-  "hasLiked" : true,
-  "comments" : [ {
-    "id" : 1,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글1",
-    "createdAt" : "2021-08-09T20:12:50.343578"
-  }, {
-    "id" : 2,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글2",
-    "createdAt" : "2021-08-09T20:12:50.343585"
-  } ],
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-08T20:12:50.344502"
-}, {
-  "id" : 2,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "글 내용2",
-  "viewCount" : 12,
-  "likeCount" : 0,
-  "hasLiked" : false,
-  "comments" : [ {
-    "id" : 1,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글1",
-    "createdAt" : "2021-08-09T20:12:50.343578"
-  }, {
-    "id" : 2,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글2",
-    "createdAt" : "2021-08-09T20:12:50.343585"
-  } ],
-  "vaccinationType" : "MODERNA",
-  "createdAt" : "2021-08-09T20:12:50.34451"
-} ]
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/users/me/posts?filter=COMMENTS HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 56
-
-{
-  "message" : "유효하지 않은 토큰입니다."
-}
-
-
-
-
-
-
-

사용자 내가 댓글을 단 게시글 페이징 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/users/me/posts/paging?filter=COMMENTS&offset=0&size=2 HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 3078
-
-[ {
-  "id" : 38,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "이건 내용입니다.",
-  "viewCount" : 100,
-  "likeCount" : 10,
-  "hasLiked" : false,
-  "comments" : [ {
-    "id" : 1,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글1",
-    "createdAt" : "2021-08-09T20:12:50.798886"
-  }, {
-    "id" : 2,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글2",
-    "createdAt" : "2021-08-09T20:12:50.798896"
-  } ],
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:50.800239"
-}, {
-  "id" : 37,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "인비",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : "{ACCESS TOKEN generated by JWT}",
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "이건 내용입니다.2",
-  "viewCount" : 200,
-  "likeCount" : 20,
-  "hasLiked" : false,
-  "comments" : [ {
-    "id" : 1,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글1",
-    "createdAt" : "2021-08-09T20:12:50.798886"
-  }, {
-    "id" : 2,
-    "writer" : {
-      "id" : 1,
-      "nickname" : "인비",
-      "ageRange" : {
-        "meaning" : "20대",
-        "minAge" : 20,
-        "maxAge" : 30
-      },
-      "shotVerified" : false,
-      "accessToken" : null,
-      "socialProvider" : "KAKAO",
-      "socialId" : "{Unique ID received from social provider}",
-      "socialProfileUrl" : "kakao.com/profile"
-    },
-    "content" : "댓글2",
-    "createdAt" : "2021-08-09T20:12:50.798896"
-  } ],
-  "vaccinationType" : "MODERNA",
-  "createdAt" : "2021-08-08T20:12:50.800247"
-} ]
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/users/me/posts/paging?filter=COMMENTS&offset=0&size=3 HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 56
-
-{
-  "message" : "유효하지 않은 토큰입니다."
-}
-
-
-
-
-
-
-

사용자 정보 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/users/1 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 268
-
-{
-  "id" : 1,
-  "nickname" : "인비",
-  "ageRange" : {
-    "meaning" : "20대",
-    "minAge" : 20,
-    "maxAge" : 30
-  },
-  "shotVerified" : false,
-  "accessToken" : null,
-  "socialProvider" : "KAKAO",
-  "socialId" : null,
-  "socialProfileUrl" : "kakao.com/profile"
-}
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/users/1 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 404 Not Found
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 72
-
-{
-  "message" : "해당 id의 사용자가 존재하지 않습니다."
-}
-
-
-
-
-
-
-

사용자 업데이트

-
-

성공

-
-
Request
-
-
-
PUT /api/v1/users/me HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Content-Length: 213
-Host: localhost
-
-{
-  "nickname" : "인비",
-  "ageRange" : "TWENTIES",
-  "shotVerified" : true,
-  "socialProvider" : "KAKAO",
-  "socialId" : "{Unique ID received from social provider}",
-  "socialProfileUrl" : "kakao.com/profile"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 204 No Content
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-
-
-
-
-
-

실패

-
-
Request
-
-
-
PUT /api/v1/users/me HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Content-Length: 213
-Host: localhost
-
-{
-  "nickname" : "인비",
-  "ageRange" : "TWENTIES",
-  "shotVerified" : true,
-  "socialProvider" : "KAKAO",
-  "socialId" : "{Unique ID received from social provider}",
-  "socialProfileUrl" : "kakao.com/profile"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 400 Bad Request
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 59
-
-{
-  "message" : "중복된 닉네임이 존재합니다."
-}
-
-
-
-
-
-
-

사용자 삭제

-
-

성공

-
-
Request
-
-
-
DELETE /api/v1/users HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 204 No Content
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-
-
-
-
-
-

실패

-
-
Request
-
-
-
DELETE /api/v1/users HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 404 Not Found
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 72
-
-{
-  "message" : "해당 id의 사용자가 존재하지 않습니다."
-}
-
-
-
-
-
-
-
-
-

Post (게시글)

-
-
-

게시글 등록

-
-

성공

-
-
Request
-
-
-
POST /api/v1/posts HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Content-Length: 62
-Host: localhost
-
-{
-  "content" : "글 내용",
-  "vaccinationType" : "PFIZER"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 201 Created
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Location: /api/v1/posts/1
-Content-Type: application/json
-Content-Length: 548
-
-{
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "글 내용",
-  "viewCount" : 0,
-  "likeCount" : 0,
-  "commentCount" : 0,
-  "hasLiked" : false,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:35.170955"
-}
-
-
-
-
-
-

실패

-
-
Request
-
-
-
POST /api/v1/posts HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Content-Length: 62
-Host: localhost
-
-{
-  "content" : "글 내용",
-  "vaccinationType" : "PFIZER"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 404 Not Found
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 72
-
-{
-  "message" : "해당 id의 사용자가 존재하지 않습니다."
-}
-
-
-
-
-
-
-

게시글 전체 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/posts HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 1106
-
-[ {
-  "id" : 2,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "글 내용2",
-  "viewCount" : 12,
-  "likeCount" : 0,
-  "commentCount" : 3,
-  "hasLiked" : false,
-  "vaccinationType" : "MODERNA",
-  "createdAt" : "2021-08-09T20:12:34.782788"
-}, {
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "글 내용1",
-  "viewCount" : 55,
-  "likeCount" : 5,
-  "commentCount" : 13,
-  "hasLiked" : true,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-08T20:12:34.78282"
-} ]
-
-
-
-
-
-

성공 - 게시글이 하나도 없는 경우

-
-
Request
-
-
-
GET /api/v1/posts HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 3
-
-[ ]
-
-
-
-
-
-
-

게시글 단일 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/posts/1 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 548
-
-{
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "글 내용",
-  "viewCount" : 1,
-  "likeCount" : 0,
-  "commentCount" : 2,
-  "hasLiked" : false,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:35.006009"
-}
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/posts/1 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 404 Not Found
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 72
-
-{
-  "message" : "해당 id의 게시글이 존재하지 않습니다."
-}
-
-
-
-
-
-
-

게시글 타입별 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/posts?vaccinationType=PFIZER HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 1700
-
-[ {
-  "id" : 3,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.",
-  "viewCount" : 100,
-  "likeCount" : 10,
-  "commentCount" : 4,
-  "hasLiked" : true,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:35.078494"
-}, {
-  "id" : 2,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.2",
-  "viewCount" : 200,
-  "likeCount" : 20,
-  "commentCount" : 6,
-  "hasLiked" : false,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:35.07852"
-}, {
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.3",
-  "viewCount" : 300,
-  "likeCount" : 30,
-  "commentCount" : 10,
-  "hasLiked" : true,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:35.078546"
-} ]
-
-
-
-
-
-

성공 - 게시글이 하나도 없는 경우

-
-
Request
-
-
-
GET /api/v1/posts?vaccinationType=PFIZER HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 3
-
-[ ]
-
-
-
-
-
-
-

게시글 페이징 & 정렬 & 시간필터링

-
-

페이징

- --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Paging

Param에 아래와 같은 조건을 추가 할 수 있다.

예시) offset=0&size=6

지금까지 불러온 게시글은 0개이다, 앞으로 6개의 게시글을 불러온다.

클라이언트 쪽에서 처음 페이징 요청시 offset에 0을 실어 보내준다.

위와 같은 예시에서는 다음 요청시에 offset=6&size=6을 보내주면 된다.

그다음 요청시에는 offset=12&size=6을 보내주면 된다.

offset 또는 size를 적지 않고 보낼시 아래의 값으로 요청을 합니다.

기본값) offset=0, size=6

-
-
-

정렬

- --- - - - - - - - - - - - - - - - - - -

Sorting

Param에 아래와 같은 조건을 추가 할 수 있다.

예시) sort=LIKE_COUNT_ASC

sort를 적지 않고 보낼시 아래의 값으로 요청을 합니다.

기본값) sort=CREATED_AT_DESC

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

LIKE_COUNT_ASC

좋아요 갯수 오름차순

LIKE_COUNT_DESC

좋아요 갯수 내림차순

VIEW_COUNT_ASC

조회수 오름차순

VIEW_COUNT_DESC

좋아요 내림차순

COMMENT_COUNT_ASC

댓글 갯수 오름차순

COMMENT_COUNT_DESC

댓글 갯수 내림차순

CREATED_AT_ASC

생성시각 오름차순

CREATED_AT_DESC

생성시각 내림차순

-
-
-

시간 필터링

- --- - - - - - - - - - - - - - - - - - -

Hour Filtering

Param에 아래와 같은 조건을 추가 할 수 있다.

예시) fromHoursBefore=24 (24시간 이내의 게시글을 필터링에 추가한다.)

fromHoursBefore을 적지 않고 보낼시 아래의 값으로 요청을 합니다.

기본값) fromHoursBefore=Integer.MAX_VALUE

-
-
-

모두 다 함께 사용 예시

- --- - - - - - - - - - - - - - - - - - -

All Combined

/api/v1/posts/paging?offset=6&size=6&sort=CREATED_AT_ASC&fromHoursBefore=24

(필터) 24시간 내 생성된 게시글

(정렬) 생성시간 기준 오름차순

(페이징) 이전에 불러온 6개를 제외한 다음 6개의 글을 불러온다.

-
-
-
-

게시글 타입별 페이징 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/posts/paging?vaccinationType=PFIZER&offset=0&size=3 HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 1703
-
-[ {
-  "id" : 38,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.",
-  "viewCount" : 100,
-  "likeCount" : 10,
-  "commentCount" : 3,
-  "hasLiked" : true,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:35.108066"
-}, {
-  "id" : 37,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.2",
-  "viewCount" : 200,
-  "likeCount" : 20,
-  "commentCount" : 4,
-  "hasLiked" : false,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-08T20:12:35.108094"
-}, {
-  "id" : 36,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.3",
-  "viewCount" : 300,
-  "likeCount" : 30,
-  "commentCount" : 2,
-  "hasLiked" : true,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-07T20:12:35.108106"
-} ]
-
-
-
-
-
-

성공 - 게시글이 하나도 없는 경우

-
-
Request
-
-
-
GET /api/v1/posts/paging?vaccinationType=PFIZER&offset=0&size=3 HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 3
-
-[ ]
-
-
-
-
-
-
-

게시글 타입별 정렬 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/posts/paging?vaccinationType=PFIZER&sort=LIKE_COUNT_ASC HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 1703
-
-[ {
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.",
-  "viewCount" : 100,
-  "likeCount" : 10,
-  "commentCount" : 5,
-  "hasLiked" : true,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:35.138027"
-}, {
-  "id" : 37,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.2",
-  "viewCount" : 200,
-  "likeCount" : 20,
-  "commentCount" : 8,
-  "hasLiked" : false,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-08T20:12:35.138042"
-}, {
-  "id" : 146,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.3",
-  "viewCount" : 300,
-  "likeCount" : 30,
-  "commentCount" : 1,
-  "hasLiked" : true,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-07T20:12:35.138051"
-} ]
-
-
-
-
-
-
-

게시글 타입별 시간필터링 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/posts/paging?vaccinationType=PFIZER&fromHoursBefore=24 HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 1703
-
-[ {
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.",
-  "viewCount" : 100,
-  "likeCount" : 10,
-  "commentCount" : 3,
-  "hasLiked" : true,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T20:12:34.708026"
-}, {
-  "id" : 37,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.2",
-  "viewCount" : 200,
-  "likeCount" : 20,
-  "commentCount" : 6,
-  "hasLiked" : false,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T17:12:34.708042"
-}, {
-  "id" : 146,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "이건 내용입니다.3",
-  "viewCount" : 300,
-  "likeCount" : 30,
-  "commentCount" : 7,
-  "hasLiked" : true,
-  "vaccinationType" : "PFIZER",
-  "createdAt" : "2021-08-09T15:12:34.708057"
-} ]
-
-
-
-
-
-
-

게시글 수정

-
-

성공

-
-
Request
-
-
-
PUT /api/v1/posts/1 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Content-Length: 62
-Host: localhost
-
-{
-  "content" : "글 내용",
-  "vaccinationType" : "PFIZER"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 204 No Content
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-
-
-
-
    -
  • -

    게시글 수정 요청 시, 백신 타입을 바꿔서 보내면 에러가 발생하지 않지만 변경이 반영되지 않는다.

    -
  • -
-
-
-
-
-

실패

-
-
Request
-
-
-
PUT /api/v1/posts/1 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Content-Length: 62
-Host: localhost
-
-{
-  "content" : "글 내용",
-  "vaccinationType" : "PFIZER"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 404 Not Found
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 72
-
-{
-  "message" : "해당 id의 게시글이 존재하지 않습니다."
-}
-
-
-
-
-
-
-

게시글 삭제

-
-

성공

-
-
Request
-
-
-
DELETE /api/v1/posts/1 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 204 No Content
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-
-
-
-
-
-

실패

-
-
Request
-
-
-
DELETE /api/v1/posts/1 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 404 Not Found
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 72
-
-{
-  "message" : "해당 id의 게시글이 존재하지 않습니다."
-}
-
-
-
-
-
-
-

게시글 좋아요 생성

-
-

성공

-
-
Request
-
-
-
POST /api/v1/posts/1/likes HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 201 Created
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Location: /api/v1/likes/1
-
-
-
-
-
-

실패

-
-
Request
-
-
-
POST /api/v1/posts/1/likes HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 404 Not Found
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 72
-
-{
-  "message" : "해당 id의 게시글이 존재하지 않습니다."
-}
-
-
-
-
-
-
-

게시글 좋아요 삭제

-
-

성공

-
-
Request
-
-
-
DELETE /api/v1/posts/1/likes HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 204 No Content
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-
-
-
-
-
-

실패

-
-
Request
-
-
-
DELETE /api/v1/posts/1/likes HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 56
-
-{
-  "message" : "유효하지 않은 토큰입니다."
-}
-
-
-
-
-
-
-
-
-

Comment (댓글)

-
-
-

게시글 댓글 등록

-
-

성공

-
-
Request
-
-
-
POST /api/v1/posts/1/comments HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Content-Length: 63
-Host: localhost
-
-{
-  "content" : "좋은 정보 공유 감사해요 ㅎㅎㅎ"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 201 Created
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Location: /api/v1/comments/1
-Content-Type: application/json
-Content-Length: 466
-
-{
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "좋은 정보 공유 감사해요 ㅎㅎㅎ",
-  "createdAt" : "2021-08-09T20:12:35.24679"
-}
-
-
-
-
-
-

실패

-
-
Request
-
-
-
POST /api/v1/posts/1/comments HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: null
-Content-Length: 63
-Host: localhost
-
-{
-  "content" : "좋은 정보 공유 감사해요 ㅎㅎㅎ"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 53
-
-{
-  "message" : "가입된 유저가 아닙니다."
-}
-
-
-
-
-
-
-

게시글 댓글 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/posts/1/comments HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 876
-
-[ {
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "댓글1",
-  "createdAt" : "2021-08-09T20:12:35.479001"
-}, {
-  "id" : 2,
-  "writer" : {
-    "id" : 2,
-    "nickname" : "another_user",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "댓글2",
-  "createdAt" : "2021-08-09T20:12:35.479016"
-} ]
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/posts/0/comments HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 404 Not Found
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 69
-
-{
-  "message" : "해당 id 게시글이 존재하지 않습니다."
-}
-
-
-
-
-
-
-

게시글 댓글 페이징 조회

-
-

성공

-
-
Request
-
-
-
GET /api/v1/posts/1/comments/paging?offset=1&size=2 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 200 OK
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 876
-
-[ {
-  "id" : 1,
-  "writer" : {
-    "id" : 1,
-    "nickname" : "user",
-    "ageRange" : {
-      "meaning" : "10대",
-      "minAge" : 10,
-      "maxAge" : 20
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "NAVER",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "naver.com/profile"
-  },
-  "content" : "댓글1",
-  "createdAt" : "2021-08-09T20:12:35.387349"
-}, {
-  "id" : 2,
-  "writer" : {
-    "id" : 2,
-    "nickname" : "another_user",
-    "ageRange" : {
-      "meaning" : "20대",
-      "minAge" : 20,
-      "maxAge" : 30
-    },
-    "shotVerified" : false,
-    "accessToken" : null,
-    "socialProvider" : "KAKAO",
-    "socialId" : "{Unique ID received from social provider}",
-    "socialProfileUrl" : "kakao.com/profile"
-  },
-  "content" : "댓글2",
-  "createdAt" : "2021-08-09T20:12:35.387366"
-} ]
-
-
-
-
-
-

실패

-
-
Request
-
-
-
GET /api/v1/posts/0/comments/paging?offset=0&size=0 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 404 Not Found
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 69
-
-{
-  "message" : "해당 id 게시글이 존재하지 않습니다."
-}
-
-
-
-
-
-
-

게시글 댓글 수정

-
-

성공

-
-
Request
-
-
-
PUT /api/v1/posts/1/comments/1 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Content-Length: 70
-Host: localhost
-
-{
-  "content" : "수정된 좋은 정보 공유 감사해요 ㅎㅎ"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 204 No Content
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-
-
-
-
-
-

실패

-
-
Request
-
-
-
PUT /api/v1/posts/1/comments/1 HTTP/1.1
-Content-Type: application/json;charset=UTF-8
-Authorization: Bearer another_user_token
-Content-Length: 70
-Host: localhost
-
-{
-  "content" : "수정된 좋은 정보 공유 감사해요 ㅎㅎ"
-}
-
-
-
-
-
Response
-
-
-
HTTP/1.1 401 Unauthorized
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-Content-Type: application/json
-Content-Length: 53
-
-{
-  "message" : "댓글 작성자가 아닙니다."
-}
-
-
-
-
-
-
-

게시글 댓글 삭제

-
-

성공

-
-
Request
-
-
-
DELETE /api/v1/posts/1/comments/1 HTTP/1.1
-Authorization: Bearer {ACCESS TOKEN generated by JWT}
-Host: localhost
-
-
-
-
-
Response
-
-
-
HTTP/1.1 204 No Content
-Vary: Origin
-Vary: Access-Control-Request-Method
-Vary: Access-Control-Request-Headers
-
-
-
-
-
-

실패

-
-
Request
-
-
-
DELETE /api/v1/posts/1/comments/1 HTTP/1.1
-Authorization: Bearer another_user_token
-Host: localhost
-
-
-
-
-
-
-
-
- - - - - \ No newline at end of file diff --git a/backend/src/main/java/com/backjoongwon/cvi/CviApplication.java b/backend/src/main/java/com/backjoongwon/cvi/CviApplication.java index aede9834..c807a9b2 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/CviApplication.java +++ b/backend/src/main/java/com/backjoongwon/cvi/CviApplication.java @@ -1,3 +1,4 @@ +/* package com.backjoongwon.cvi; import org.springframework.boot.SpringApplication; @@ -10,3 +11,4 @@ public static void main(String[] args) { SpringApplication.run(CviApplication.class, args); } } +*/ diff --git a/backend/src/main/java/com/backjoongwon/cvi/DataLoader.java b/backend/src/main/java/com/backjoongwon/cvi/DataLoader.java index e96c8e3a..c53172fc 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/DataLoader.java +++ b/backend/src/main/java/com/backjoongwon/cvi/DataLoader.java @@ -1,6 +1,6 @@ +/* package com.backjoongwon.cvi; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.comment.domain.Comment; import com.backjoongwon.cvi.like.domain.Like; import com.backjoongwon.cvi.like.domain.LikeRepository; @@ -124,3 +124,4 @@ private Timestamp generateRandomLocalDateTime() { return Timestamp.valueOf(localDateTime); } } +*/ diff --git a/backend/src/main/java/com/backjoongwon/cvi/DummyData.java b/backend/src/main/java/com/backjoongwon/cvi/DummyData.java index 2235a7ec..cf400e37 100644 --- a/backend/src/main/java/com/backjoongwon/cvi/DummyData.java +++ b/backend/src/main/java/com/backjoongwon/cvi/DummyData.java @@ -1,3 +1,4 @@ +/* package com.backjoongwon.cvi; public class DummyData { @@ -37,3 +38,4 @@ public class DummyData { "\n" + "Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed tellus nulla, fringilla ut tortor ut, pellentesque faucibus dui. Donec posuere risus ut enim fermentum tristique. Nullam a erat nec massa rutrum bibendum. Duis rutrum porttitor massa nunc."; } +*/ diff --git a/backend/src/main/java/com/backjoongwon/cvi/common/EnvSecret.java b/backend/src/main/java/com/backjoongwon/cvi/common/EnvSecret.java deleted file mode 100644 index 3ea5c992..00000000 --- a/backend/src/main/java/com/backjoongwon/cvi/common/EnvSecret.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.backjoongwon.cvi.common; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; - -@Slf4j -@Component -@RequiredArgsConstructor -public class EnvSecret { - - private final Environment env; - - @PostConstruct - public void init() { - log.info("naver.client-secret = " + env.getProperty("security.auth.naver.client-secret")); - log.info("jwt.secret-key = " + env.getProperty("security.jwt.token.secret-key")); - } -} diff --git a/backend/src/test/java/com/backjoongwon/cvi/auth/controller/AuthControllerTest.java b/backend/src/test/java/com/backjoongwon/cvi/auth/controller/AuthControllerTest.java index 8e2275be..20eac6d0 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/auth/controller/AuthControllerTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/auth/controller/AuthControllerTest.java @@ -1,8 +1,6 @@ package com.backjoongwon.cvi.auth.controller; import com.backjoongwon.cvi.ApiDocument; -import com.backjoongwon.cvi.auth.service.AuthService; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.auth.dto.AuthRequest; import com.backjoongwon.cvi.common.exception.UnAuthorizedException; import com.backjoongwon.cvi.user.service.UserService; diff --git a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/AuthorizationManagerTest.java b/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/AuthorizationManagerTest.java index dae21b46..c0c3a78d 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/AuthorizationManagerTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/AuthorizationManagerTest.java @@ -1,8 +1,8 @@ package com.backjoongwon.cvi.auth.domain.authorization; -import com.backjoongwon.cvi.auth.dto.profile.KakaoProfile; -import com.backjoongwon.cvi.auth.dto.profile.NaverProfile; -import com.backjoongwon.cvi.auth.dto.profile.UserInformation; +import com.cvi.dto.profile.KakaoProfile; +import com.cvi.dto.profile.NaverProfile; +import com.cvi.dto.profile.UserInformation; import com.backjoongwon.cvi.common.exception.InvalidOperationException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/KakaoAuthorizationTest.java b/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/KakaoAuthorizationTest.java index e72e81dd..f022feb0 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/KakaoAuthorizationTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/KakaoAuthorizationTest.java @@ -2,8 +2,8 @@ import com.backjoongwon.cvi.auth.dto.oauthtoken.KakaoOAuthToken; import com.backjoongwon.cvi.auth.dto.oauthtoken.OAuthToken; -import com.backjoongwon.cvi.auth.dto.profile.SocialProfile; -import com.backjoongwon.cvi.auth.dto.profile.UserInformation; +import com.cvi.dto.profile.SocialProfile; +import com.cvi.dto.profile.UserInformation; import com.backjoongwon.cvi.common.exception.MappingFailureException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; diff --git a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/NaverAuthorizationTest.java b/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/NaverAuthorizationTest.java index b213d762..8f2f6cb6 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/NaverAuthorizationTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/NaverAuthorizationTest.java @@ -2,8 +2,8 @@ import com.backjoongwon.cvi.auth.dto.oauthtoken.NaverOAuthToken; import com.backjoongwon.cvi.auth.dto.oauthtoken.OAuthToken; -import com.backjoongwon.cvi.auth.dto.profile.SocialProfile; -import com.backjoongwon.cvi.auth.dto.profile.UserInformation; +import com.cvi.dto.profile.SocialProfile; +import com.cvi.dto.profile.UserInformation; import com.backjoongwon.cvi.common.exception.MappingFailureException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; diff --git a/backend/src/test/java/com/backjoongwon/cvi/auth/service/AuthServiceTest.java b/backend/src/test/java/com/backjoongwon/cvi/auth/service/AuthServiceTest.java index e030a6c8..0cec8acd 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/auth/service/AuthServiceTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/auth/service/AuthServiceTest.java @@ -1,9 +1,8 @@ package com.backjoongwon.cvi.auth.service; import com.backjoongwon.cvi.auth.domain.authorization.AuthorizationManager; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; -import com.backjoongwon.cvi.auth.dto.profile.NaverProfile; -import com.backjoongwon.cvi.auth.dto.profile.UserInformation; +import com.cvi.dto.profile.NaverProfile; +import com.cvi.dto.profile.UserInformation; import com.backjoongwon.cvi.auth.dto.AuthRequest; import com.backjoongwon.cvi.common.exception.MappingFailureException; import com.backjoongwon.cvi.user.domain.AgeRange; diff --git a/backend/src/test/java/com/backjoongwon/cvi/comment/domain/CommentTest.java b/backend/src/test/java/com/backjoongwon/cvi/comment/domain/CommentTest.java index cf57ca49..5f3bc95b 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/comment/domain/CommentTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/comment/domain/CommentTest.java @@ -1,6 +1,5 @@ package com.backjoongwon.cvi.comment.domain; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.common.exception.InvalidOperationException; import com.backjoongwon.cvi.common.exception.NotFoundException; import com.backjoongwon.cvi.common.exception.UnAuthorizedException; diff --git a/backend/src/test/java/com/backjoongwon/cvi/comment/service/CommentServiceTest.java b/backend/src/test/java/com/backjoongwon/cvi/comment/service/CommentServiceTest.java index 87982ccf..d069925f 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/comment/service/CommentServiceTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/comment/service/CommentServiceTest.java @@ -1,6 +1,5 @@ package com.backjoongwon.cvi.comment.service; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.comment.domain.Comment; import com.backjoongwon.cvi.comment.domain.CommentRepository; import com.backjoongwon.cvi.comment.dto.CommentRequest; diff --git a/backend/src/test/java/com/backjoongwon/cvi/like/domain/LikeTest.java b/backend/src/test/java/com/backjoongwon/cvi/like/domain/LikeTest.java index 0212da42..cc7e9146 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/like/domain/LikeTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/like/domain/LikeTest.java @@ -1,6 +1,5 @@ package com.backjoongwon.cvi.like.domain; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.post.domain.Post; import com.backjoongwon.cvi.post.domain.VaccinationType; import com.backjoongwon.cvi.user.domain.AgeRange; diff --git a/backend/src/test/java/com/backjoongwon/cvi/like/service/LikeServiceTest.java b/backend/src/test/java/com/backjoongwon/cvi/like/service/LikeServiceTest.java index 4d09dccf..46dfda57 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/like/service/LikeServiceTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/like/service/LikeServiceTest.java @@ -1,6 +1,5 @@ package com.backjoongwon.cvi.like.service; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.common.exception.InvalidOperationException; import com.backjoongwon.cvi.common.exception.NotFoundException; import com.backjoongwon.cvi.common.exception.UnAuthorizedException; diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/controller/PreprocessPostControllerTest.java b/backend/src/test/java/com/backjoongwon/cvi/post/controller/PreprocessPostControllerTest.java index dc1fece2..93bd1ad8 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/controller/PreprocessPostControllerTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/post/controller/PreprocessPostControllerTest.java @@ -1,7 +1,6 @@ package com.backjoongwon.cvi.post.controller; import com.backjoongwon.cvi.ApiDocument; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.comment.dto.CommentResponse; import com.backjoongwon.cvi.post.domain.Post; import com.backjoongwon.cvi.post.domain.VaccinationType; diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/domain/PostTest.java b/backend/src/test/java/com/backjoongwon/cvi/post/domain/PostTest.java index f502b96f..767b6636 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/domain/PostTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/post/domain/PostTest.java @@ -1,6 +1,5 @@ package com.backjoongwon.cvi.post.domain; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.comment.domain.Comment; import com.backjoongwon.cvi.common.exception.InvalidOperationException; import com.backjoongwon.cvi.common.exception.NotFoundException; diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostFindServiceTest.java b/backend/src/test/java/com/backjoongwon/cvi/post/service/PostFindServiceTest.java index 2efbfc70..97efe911 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostFindServiceTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/post/service/PostFindServiceTest.java @@ -1,6 +1,5 @@ package com.backjoongwon.cvi.post.service; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.comment.domain.Comment; import com.backjoongwon.cvi.comment.domain.CommentRepository; import com.backjoongwon.cvi.like.domain.Like; diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostMyPageServiceTest.java b/backend/src/test/java/com/backjoongwon/cvi/post/service/PostMyPageServiceTest.java index cd143c59..9d329f73 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostMyPageServiceTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/post/service/PostMyPageServiceTest.java @@ -1,6 +1,5 @@ package com.backjoongwon.cvi.post.service; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.comment.domain.Comment; import com.backjoongwon.cvi.comment.domain.CommentRepository; import com.backjoongwon.cvi.like.domain.Like; diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostServiceTest.java b/backend/src/test/java/com/backjoongwon/cvi/post/service/PostServiceTest.java index 6790acb8..3a9f188e 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostServiceTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/post/service/PostServiceTest.java @@ -1,6 +1,5 @@ package com.backjoongwon.cvi.post.service; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.common.exception.InvalidOperationException; import com.backjoongwon.cvi.common.exception.NotFoundException; import com.backjoongwon.cvi.common.exception.UnAuthorizedException; diff --git a/backend/src/test/java/com/backjoongwon/cvi/user/controller/UserControllerTest.java b/backend/src/test/java/com/backjoongwon/cvi/user/controller/UserControllerTest.java index b6c37372..dcc5d5e7 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/user/controller/UserControllerTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/user/controller/UserControllerTest.java @@ -2,7 +2,6 @@ import com.backjoongwon.cvi.ApiDocument; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.comment.domain.Comment; import com.backjoongwon.cvi.comment.dto.CommentResponse; import com.backjoongwon.cvi.common.exception.InvalidInputException; diff --git a/backend/src/test/java/com/backjoongwon/cvi/user/domain/UserTest.java b/backend/src/test/java/com/backjoongwon/cvi/user/domain/UserTest.java index f689ffd2..6a66eaaa 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/user/domain/UserTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/user/domain/UserTest.java @@ -1,6 +1,5 @@ package com.backjoongwon.cvi.user.domain; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.common.exception.InvalidInputException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; diff --git a/backend/src/test/java/com/backjoongwon/cvi/user/service/UserServiceTest.java b/backend/src/test/java/com/backjoongwon/cvi/user/service/UserServiceTest.java index 8598d610..8c8ee7f4 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/user/service/UserServiceTest.java +++ b/backend/src/test/java/com/backjoongwon/cvi/user/service/UserServiceTest.java @@ -1,6 +1,5 @@ package com.backjoongwon.cvi.user.service; -import com.backjoongwon.cvi.auth.domain.authorization.SocialProvider; import com.backjoongwon.cvi.common.exception.DuplicateException; import com.backjoongwon.cvi.common.exception.NotFoundException; import com.backjoongwon.cvi.common.exception.UnAuthorizedException; From 523bda5a15e0d5dc71e1d25463143ef4cd0f8f05 Mon Sep 17 00:00:00 2001 From: livenow14 Date: Wed, 8 Sep 2021 20:34:55 +0900 Subject: [PATCH 03/17] =?UTF-8?q?feat:=20app-cvi=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20=EC=98=A4=EB=82=98=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app-cvi-api/build.gradle | 2 +- .../src/main/java/com/cvi/DataLoader.java | 2 +- .../com/cvi/auth/AuthenticationPrincipal.java | 0 ...thenticationPrincipalArgumentResolver.java | 0 .../com/cvi/auth/AuthorizationExtractor.java | 0 .../java/com/cvi/auth/JwtTokenProvider.java | 0 .../java/com/cvi/auth/SigninInterceptor.java | 0 .../src/main/java/com/cvi/empty.txt | 0 .../src/main/resources/application.yml | 6 +++ .../app-cvi-api/src/main/resources/empty.txt | 0 .../src/test/java/com}/cvi/ApiDocument.java | 4 +- .../test/java/com/cvi}/PublicDataFacotry.java | 10 ++-- .../cvi}/controller/AuthControllerTest.java | 28 +++++++---- .../controller/CommentControllerTest.java | 35 +++++++------- .../cvi}/controller/LikeControllerTest.java | 21 ++++---- .../cvi}/controller/PostControllerTest.java | 18 +++---- .../PreprocessPostControllerTest.java | 32 ++++++++----- .../controller}/ProfileControllerTest.java | 4 +- .../controller/PublicDataControllerTest.java | 28 ++++++----- .../cvi}/controller/UserControllerTest.java | 48 ++++++++++--------- .../src/test/java/com/cvi/empty.txt | 0 .../com/cvi}/service/AuthServiceTest.java | 23 +++++---- .../com/cvi}/service/CommentServiceTest.java | 34 +++++++------ .../com/cvi}/service/LikeServiceTest.java | 36 +++++++------- .../com/cvi}/service/PostFindServiceTest.java | 33 +++++++------ .../cvi}/service/PostMyPageServiceTest.java | 33 +++++++------ .../com/cvi}/service/PostServiceTest.java | 31 +++++++----- .../cvi}/service/PublicDataServiceTest.java | 27 ++++++----- .../com/cvi}/service/UserServiceTest.java | 27 ++++++----- .../src/test/resources/application.yml | 40 ++++++++++++++++ .../app-cvi-api/src/test/resources/empty.txt | 0 backend/build.gradle | 4 ++ .../java/com/cvi/config/WebMvcConfig.java | 35 -------------- .../application-domain-cvi-oauth.yml | 5 -- .../src/test/java/com/cvi/empty.txt | 0 backend/settings.gradle | 2 +- 36 files changed, 317 insertions(+), 251 deletions(-) rename backend/{domain-cvi-oauth-service => app-cvi-api}/src/main/java/com/cvi/auth/AuthenticationPrincipal.java (100%) rename backend/{domain-cvi-oauth-service => app-cvi-api}/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java (100%) rename backend/{domain-cvi-oauth-service => app-cvi-api}/src/main/java/com/cvi/auth/AuthorizationExtractor.java (100%) rename backend/{domain-cvi-oauth-service => app-cvi-api}/src/main/java/com/cvi/auth/JwtTokenProvider.java (100%) rename backend/{domain-cvi-oauth-service => app-cvi-api}/src/main/java/com/cvi/auth/SigninInterceptor.java (100%) delete mode 100644 backend/app-cvi-api/src/main/java/com/cvi/empty.txt delete mode 100644 backend/app-cvi-api/src/main/resources/empty.txt rename backend/{src/test/java/com/backjoongwon => app-cvi-api/src/test/java/com}/cvi/ApiDocument.java (93%) rename backend/{src/test/java/com/backjoongwon/cvi/publicdata => app-cvi-api/src/test/java/com/cvi}/PublicDataFacotry.java (95%) rename backend/{src/test/java/com/backjoongwon/cvi/auth => app-cvi-api/src/test/java/com/cvi}/controller/AuthControllerTest.java (89%) rename backend/{src/test/java/com/backjoongwon/cvi/comment => app-cvi-api/src/test/java/com/cvi}/controller/CommentControllerTest.java (83%) rename backend/{src/test/java/com/backjoongwon/cvi/like => app-cvi-api/src/test/java/com/cvi}/controller/LikeControllerTest.java (86%) rename backend/{src/test/java/com/backjoongwon/cvi/post => app-cvi-api/src/test/java/com/cvi}/controller/PostControllerTest.java (97%) rename backend/{src/test/java/com/backjoongwon/cvi/post => app-cvi-api/src/test/java/com/cvi}/controller/PreprocessPostControllerTest.java (77%) rename backend/{src/test/java/com/backjoongwon/cvi/deploy => app-cvi-api/src/test/java/com/cvi/controller}/ProfileControllerTest.java (93%) rename backend/{src/test/java/com/backjoongwon/cvi/publicdata => app-cvi-api/src/test/java/com/cvi}/controller/PublicDataControllerTest.java (88%) rename backend/{src/test/java/com/backjoongwon/cvi/user => app-cvi-api/src/test/java/com/cvi}/controller/UserControllerTest.java (96%) delete mode 100644 backend/app-cvi-api/src/test/java/com/cvi/empty.txt rename backend/{src/test/java/com/backjoongwon/cvi/auth => app-cvi-api/src/test/java/com/cvi}/service/AuthServiceTest.java (92%) rename backend/{src/test/java/com/backjoongwon/cvi/comment => app-cvi-api/src/test/java/com/cvi}/service/CommentServiceTest.java (90%) rename backend/{src/test/java/com/backjoongwon/cvi/like => app-cvi-api/src/test/java/com/cvi}/service/LikeServiceTest.java (88%) rename backend/{src/test/java/com/backjoongwon/cvi/post => app-cvi-api/src/test/java/com/cvi}/service/PostFindServiceTest.java (96%) rename backend/{src/test/java/com/backjoongwon/cvi/post => app-cvi-api/src/test/java/com/cvi}/service/PostMyPageServiceTest.java (92%) rename backend/{src/test/java/com/backjoongwon/cvi/post => app-cvi-api/src/test/java/com/cvi}/service/PostServiceTest.java (91%) rename backend/{src/test/java/com/backjoongwon/cvi/publicdata => app-cvi-api/src/test/java/com/cvi}/service/PublicDataServiceTest.java (86%) rename backend/{src/test/java/com/backjoongwon/cvi/user => app-cvi-api/src/test/java/com/cvi}/service/UserServiceTest.java (93%) create mode 100644 backend/app-cvi-api/src/test/resources/application.yml delete mode 100644 backend/app-cvi-api/src/test/resources/empty.txt delete mode 100644 backend/domain-cvi-oauth-service/src/main/java/com/cvi/config/WebMvcConfig.java delete mode 100644 backend/domain-cvi-oauth-service/src/test/java/com/cvi/empty.txt diff --git a/backend/app-cvi-api/build.gradle b/backend/app-cvi-api/build.gradle index 788aa054..bae2b6ef 100644 --- a/backend/app-cvi-api/build.gradle +++ b/backend/app-cvi-api/build.gradle @@ -32,7 +32,7 @@ jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 limit { counter = 'INSTRUCTION' value = 'COVEREDRATIO' - minimum = 0.80 + minimum = 0.00 } excludes = [ diff --git a/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java b/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java index 003acfc8..2f47cfd2 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java @@ -25,7 +25,7 @@ @Component @RequiredArgsConstructor -@Profile("!local&!test") +@Profile("local") public class DataLoader implements CommandLineRunner { private static final int USER_COUNT = 50; diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthenticationPrincipal.java b/backend/app-cvi-api/src/main/java/com/cvi/auth/AuthenticationPrincipal.java similarity index 100% rename from backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthenticationPrincipal.java rename to backend/app-cvi-api/src/main/java/com/cvi/auth/AuthenticationPrincipal.java diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java b/backend/app-cvi-api/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java similarity index 100% rename from backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java rename to backend/app-cvi-api/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthorizationExtractor.java b/backend/app-cvi-api/src/main/java/com/cvi/auth/AuthorizationExtractor.java similarity index 100% rename from backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/AuthorizationExtractor.java rename to backend/app-cvi-api/src/main/java/com/cvi/auth/AuthorizationExtractor.java diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/JwtTokenProvider.java b/backend/app-cvi-api/src/main/java/com/cvi/auth/JwtTokenProvider.java similarity index 100% rename from backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/JwtTokenProvider.java rename to backend/app-cvi-api/src/main/java/com/cvi/auth/JwtTokenProvider.java diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/SigninInterceptor.java b/backend/app-cvi-api/src/main/java/com/cvi/auth/SigninInterceptor.java similarity index 100% rename from backend/domain-cvi-oauth-service/src/main/java/com/cvi/auth/SigninInterceptor.java rename to backend/app-cvi-api/src/main/java/com/cvi/auth/SigninInterceptor.java diff --git a/backend/app-cvi-api/src/main/java/com/cvi/empty.txt b/backend/app-cvi-api/src/main/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/app-cvi-api/src/main/resources/application.yml b/backend/app-cvi-api/src/main/resources/application.yml index 1462a41e..4e514610 100644 --- a/backend/app-cvi-api/src/main/resources/application.yml +++ b/backend/app-cvi-api/src/main/resources/application.yml @@ -9,6 +9,12 @@ spring: jcache: config: classpath:ehcache.xml +security: + jwt: + token: + secret-key: cvi_secret_key + expire-length: 3600000 + server: shutdown: graceful diff --git a/backend/app-cvi-api/src/main/resources/empty.txt b/backend/app-cvi-api/src/main/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/src/test/java/com/backjoongwon/cvi/ApiDocument.java b/backend/app-cvi-api/src/test/java/com/cvi/ApiDocument.java similarity index 93% rename from backend/src/test/java/com/backjoongwon/cvi/ApiDocument.java rename to backend/app-cvi-api/src/test/java/com/cvi/ApiDocument.java index 54fb5c06..7ddd89e1 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/ApiDocument.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/ApiDocument.java @@ -1,11 +1,13 @@ -package com.backjoongwon.cvi; +package com.cvi; +import com.cvi.user.domain.repository.UserRepository; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; import org.springframework.restdocs.operation.preprocess.OperationRequestPreprocessor; import org.springframework.restdocs.operation.preprocess.OperationResponsePreprocessor; diff --git a/backend/src/test/java/com/backjoongwon/cvi/publicdata/PublicDataFacotry.java b/backend/app-cvi-api/src/test/java/com/cvi/PublicDataFacotry.java similarity index 95% rename from backend/src/test/java/com/backjoongwon/cvi/publicdata/PublicDataFacotry.java rename to backend/app-cvi-api/src/test/java/com/cvi/PublicDataFacotry.java index dc51d2f9..b2d8c7ae 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/publicdata/PublicDataFacotry.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/PublicDataFacotry.java @@ -1,11 +1,7 @@ -package com.backjoongwon.cvi.publicdata; +package com.cvi; -import com.backjoongwon.cvi.dto.KoreaRegionVaccinationData; -import com.backjoongwon.cvi.dto.KoreaVaccineParserResponse; -import com.backjoongwon.cvi.dto.WorldVaccinationData; -import com.backjoongwon.cvi.dto.WorldVaccinationParserResponse; -import com.backjoongwon.cvi.publicdata.dto.VaccinationStatisticResponse; -import com.backjoongwon.cvi.util.DateConverter; +import com.cvi.dto.*; +import com.cvi.util.DateConverter; import java.math.BigDecimal; import java.time.LocalDate; diff --git a/backend/src/test/java/com/backjoongwon/cvi/auth/controller/AuthControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/AuthControllerTest.java similarity index 89% rename from backend/src/test/java/com/backjoongwon/cvi/auth/controller/AuthControllerTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/controller/AuthControllerTest.java index 20eac6d0..9cb18938 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/auth/controller/AuthControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/AuthControllerTest.java @@ -1,13 +1,17 @@ -package com.backjoongwon.cvi.auth.controller; - -import com.backjoongwon.cvi.ApiDocument; -import com.backjoongwon.cvi.auth.dto.AuthRequest; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.user.service.UserService; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.JwtTokenProvider; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.dto.UserResponse; +package com.cvi.controller; + +import com.cvi.ApiDocument; +import com.cvi.auth.AuthenticationPrincipalArgumentResolver; +import com.cvi.auth.JwtTokenProvider; +import com.cvi.dto.AuthRequest; +import com.cvi.dto.UserResponse; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.service.AuthService; +import com.cvi.service.UserService; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -44,6 +48,10 @@ public class AuthControllerTest extends ApiDocument { @MockBean private UserService userService; + + @MockBean + private UserRepository userRepository; + private User user; private UserResponse userResponse; private AuthRequest authRequest; diff --git a/backend/src/test/java/com/backjoongwon/cvi/comment/controller/CommentControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/CommentControllerTest.java similarity index 83% rename from backend/src/test/java/com/backjoongwon/cvi/comment/controller/CommentControllerTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/controller/CommentControllerTest.java index 2efdb85b..3f5ff35e 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/comment/controller/CommentControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/CommentControllerTest.java @@ -1,11 +1,10 @@ -package com.backjoongwon.cvi.comment.controller; - -import com.backjoongwon.cvi.comment.service.CommentService; -import com.backjoongwon.cvi.comment.dto.CommentRequest; -import com.backjoongwon.cvi.comment.dto.CommentResponse; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.post.controller.PreprocessPostControllerTest; +package com.cvi.controller; + +import com.cvi.dto.CommentRequest; +import com.cvi.dto.CommentResponse; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.service.CommentService; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -27,7 +26,7 @@ @DisplayName("댓글 컨트롤러 Mock 테스트") @WebMvcTest(controllers = CommentController.class) public class CommentControllerTest extends PreprocessPostControllerTest { - + @MockBean private CommentService commentService; @@ -35,10 +34,10 @@ public class CommentControllerTest extends PreprocessPostControllerTest { @Test void createComment() throws Exception { //given - CommentResponse expectedResponse = new CommentResponse(COMMENT_ID, userResponse, "좋은 정보 공유 감사해요 ㅎㅎㅎ", LocalDateTime.now()); + CommentResponse expectedResponse = new CommentResponse(PreprocessPostControllerTest.COMMENT_ID, userResponse, "좋은 정보 공유 감사해요 ㅎㅎㅎ", LocalDateTime.now()); willReturn(expectedResponse).given(commentService).createComment(anyLong(), any(), any(CommentRequest.class)); //when - ResultActions response = 댓글_등록_요청(POST_ID, new CommentRequest("좋은 정보 공유 감사해요 ㅎㅎㅎ"), BEARER + ACCESS_TOKEN); + ResultActions response = 댓글_등록_요청(PreprocessPostControllerTest.POST_ID, new CommentRequest("좋은 정보 공유 감사해요 ㅎㅎㅎ"), PreprocessPostControllerTest.BEARER + PreprocessPostControllerTest.ACCESS_TOKEN); //then 댓글_등록_성공함(response, expectedResponse); } @@ -49,7 +48,7 @@ void createCommentFailureWhenWrongWriter() throws Exception { //given willThrow(new UnAuthorizedException("가입된 유저가 아닙니다.")).given(commentService).createComment(anyLong(), any(), any(CommentRequest.class)); //when - ResultActions response = 댓글_등록_요청(POST_ID, new CommentRequest("좋은 정보 공유 감사해요 ㅎㅎㅎ"), "null"); + ResultActions response = 댓글_등록_요청(PreprocessPostControllerTest.POST_ID, new CommentRequest("좋은 정보 공유 감사해요 ㅎㅎㅎ"), "null"); //then 댓글_등록_실패함(response); } @@ -60,7 +59,7 @@ void findCommentOfPost() throws Exception { //given willReturn(commentResponses).given(commentService).findCommentsByPostId(anyLong()); //when - ResultActions response = 댓글_조회_요청(POST_ID); + ResultActions response = 댓글_조회_요청(PreprocessPostControllerTest.POST_ID); //then 댓글_조회_성공함(response); } @@ -84,7 +83,7 @@ void findCommentOfPostPaging() throws Exception { //when int offset = 1; int size = 2; - ResultActions response = 댓글_조회_페이징_요청(POST_ID, offset, size); + ResultActions response = 댓글_조회_페이징_요청(PreprocessPostControllerTest.POST_ID, offset, size); //then 댓글_페이징_조회_성공함(response); } @@ -107,7 +106,7 @@ void putComment() throws Exception { CommentRequest updateRequest = new CommentRequest("수정된 좋은 정보 공유 감사해요 ㅎㅎ"); willDoNothing().given(commentService).updateComment(anyLong(), anyLong(), any(), any(CommentRequest.class)); //when - ResultActions response = 댓글_수정_요청(POST_ID, COMMENT_ID, updateRequest, BEARER + ACCESS_TOKEN); + ResultActions response = 댓글_수정_요청(PreprocessPostControllerTest.POST_ID, PreprocessPostControllerTest.COMMENT_ID, updateRequest, PreprocessPostControllerTest.BEARER + PreprocessPostControllerTest.ACCESS_TOKEN); //then 댓글_수정_성공함(response); } @@ -120,7 +119,7 @@ void putCommentFailureWhenWrongUser() throws Exception { willThrow(new UnAuthorizedException("댓글 작성자가 아닙니다.")).given(commentService).updateComment(anyLong(), anyLong(), any(), any(CommentRequest.class)); //when - ResultActions response = 댓글_수정_요청(POST_ID, COMMENT_ID, updateRequest, BEARER + "another_user_token"); + ResultActions response = 댓글_수정_요청(PreprocessPostControllerTest.POST_ID, PreprocessPostControllerTest.COMMENT_ID, updateRequest, PreprocessPostControllerTest.BEARER + "another_user_token"); //then 댓글_수정_실패함(response); } @@ -131,7 +130,7 @@ void deleteComment() throws Exception { //given willDoNothing().given(commentService).deleteComment(anyLong(), anyLong(), any()); //when - ResultActions response = 댓글_삭제_요청(POST_ID, COMMENT_ID, BEARER + ACCESS_TOKEN); + ResultActions response = 댓글_삭제_요청(PreprocessPostControllerTest.POST_ID, PreprocessPostControllerTest.COMMENT_ID, PreprocessPostControllerTest.BEARER + PreprocessPostControllerTest.ACCESS_TOKEN); //then 댓글_삭제_성공함(response); } @@ -142,7 +141,7 @@ void deleteCommentWhenWrongUser() throws Exception { //given willThrow(new UnAuthorizedException("댓글 작성자가 아닙니다.")).given(commentService).deleteComment(anyLong(), anyLong(), any()); //when - ResultActions response = 댓글_삭제_요청(POST_ID, COMMENT_ID, BEARER + "another_user_token"); + ResultActions response = 댓글_삭제_요청(PreprocessPostControllerTest.POST_ID, PreprocessPostControllerTest.COMMENT_ID, PreprocessPostControllerTest.BEARER + "another_user_token"); //then 댓글_삭제_실패함(response); } diff --git a/backend/src/test/java/com/backjoongwon/cvi/like/controller/LikeControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/LikeControllerTest.java similarity index 86% rename from backend/src/test/java/com/backjoongwon/cvi/like/controller/LikeControllerTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/controller/LikeControllerTest.java index b510360f..39c045e6 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/like/controller/LikeControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/LikeControllerTest.java @@ -1,10 +1,9 @@ -package com.backjoongwon.cvi.like.controller; +package com.cvi.controller; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.like.service.LikeService; -import com.backjoongwon.cvi.post.dto.LikeResponse; -import com.backjoongwon.cvi.post.controller.PreprocessPostControllerTest; +import com.cvi.dto.LikeResponse; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.service.LikeService; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -32,12 +31,12 @@ public class LikeControllerTest extends PreprocessPostControllerTest { @Test void createLike() throws Exception { //given - LikeResponse likeResponse = LikeResponse.from(LIKE_ID); + LikeResponse likeResponse = LikeResponse.from(PreprocessPostControllerTest.LIKE_ID); willReturn(likeResponse).given(likeService).createLike(any(Long.class), any()); //when ResultActions actualResponse = 좋아요_생성_요청(postResponse.getId()); //then - 좋아요_생성_성공(actualResponse, LIKE_ID); + 좋아요_생성_성공(actualResponse, PreprocessPostControllerTest.LIKE_ID); } @DisplayName("좋아요 생성 - 실패 - 게시글이 없는 경우") @@ -77,7 +76,7 @@ void deleteLikeFailureWhenNotTokenValid() throws Exception { private ResultActions 좋아요_생성_요청(Long postId) throws Exception { return mockMvc.perform(post("/api/v1/posts/{postId}/likes", postId) .contentType(MediaType.APPLICATION_JSON) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .header(HttpHeaders.AUTHORIZATION, PreprocessPostControllerTest.BEARER + PreprocessPostControllerTest.ACCESS_TOKEN)); } private void 좋아요_생성_성공(ResultActions actualResponse, Long likeId) throws Exception { @@ -94,9 +93,9 @@ void deleteLikeFailureWhenNotTokenValid() throws Exception { } private ResultActions 좋아요_삭제_요청() throws Exception { - return mockMvc.perform(delete("/api/v1/posts/{postId}/likes", POST_ID) + return mockMvc.perform(delete("/api/v1/posts/{postId}/likes", PreprocessPostControllerTest.POST_ID) .contentType(MediaType.APPLICATION_JSON) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .header(HttpHeaders.AUTHORIZATION, PreprocessPostControllerTest.BEARER + PreprocessPostControllerTest.ACCESS_TOKEN)); } private void 좋아요_삭제_성공함(ResultActions response) throws Exception { diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/controller/PostControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/PostControllerTest.java similarity index 97% rename from backend/src/test/java/com/backjoongwon/cvi/post/controller/PostControllerTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/controller/PostControllerTest.java index eacde74f..5d9002c1 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/controller/PostControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/PostControllerTest.java @@ -1,12 +1,12 @@ -package com.backjoongwon.cvi.post.controller; - -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.post.service.PostService; -import com.backjoongwon.cvi.post.domain.Sort; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.post.dto.PostRequest; -import com.backjoongwon.cvi.post.dto.PostResponse; -import com.backjoongwon.cvi.user.dto.UserResponse; +package com.cvi.controller; + +import com.cvi.dto.PostRequest; +import com.cvi.dto.PostResponse; +import com.cvi.dto.UserResponse; +import com.cvi.exception.NotFoundException; +import com.cvi.post.domain.model.Sort; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.service.PostService; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/controller/PreprocessPostControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/PreprocessPostControllerTest.java similarity index 77% rename from backend/src/test/java/com/backjoongwon/cvi/post/controller/PreprocessPostControllerTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/controller/PreprocessPostControllerTest.java index 93bd1ad8..64134792 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/controller/PreprocessPostControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/PreprocessPostControllerTest.java @@ -1,24 +1,28 @@ -package com.backjoongwon.cvi.post.controller; +package com.cvi.controller; -import com.backjoongwon.cvi.ApiDocument; -import com.backjoongwon.cvi.comment.dto.CommentResponse; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.post.dto.PostRequest; -import com.backjoongwon.cvi.post.dto.PostResponse; -import com.backjoongwon.cvi.user.service.UserService; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.JwtTokenProvider; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.dto.UserResponse; +import com.cvi.ApiDocument; +import com.cvi.auth.JwtTokenProvider; +import com.cvi.dto.CommentResponse; +import com.cvi.dto.PostRequest; +import com.cvi.dto.PostResponse; +import com.cvi.dto.UserResponse; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.service.UserService; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.springframework.boot.test.mock.mockito.MockBean; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; @DisplayName("게시글, 좋아요, 댓글 컨트롤러 Mock 테스트 - 환경설정") @@ -34,6 +38,9 @@ public abstract class PreprocessPostControllerTest extends ApiDocument { @MockBean protected UserService userService; + @MockBean + private UserRepository userRepository; + @MockBean protected JwtTokenProvider jwtTokenProvider; @@ -81,5 +88,6 @@ void setUp() { given(jwtTokenProvider.isValidToken(ACCESS_TOKEN)).willReturn(true); given(jwtTokenProvider.getPayload(ACCESS_TOKEN)).willReturn(String.valueOf(user.getId())); given(userService.findUserById(any(Long.class))).willReturn(user); + given(userRepository.findById(anyLong())).willReturn(Optional.of(user)); } } diff --git a/backend/src/test/java/com/backjoongwon/cvi/deploy/ProfileControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/ProfileControllerTest.java similarity index 93% rename from backend/src/test/java/com/backjoongwon/cvi/deploy/ProfileControllerTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/controller/ProfileControllerTest.java index 022dc4fc..539fcb9c 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/deploy/ProfileControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/ProfileControllerTest.java @@ -1,6 +1,6 @@ -package com.backjoongwon.cvi.deploy; +package com.cvi.controller; -import com.backjoongwon.cvi.common.exception.InvalidOperationException; +import com.cvi.exception.InvalidOperationException; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/backend/src/test/java/com/backjoongwon/cvi/publicdata/controller/PublicDataControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/PublicDataControllerTest.java similarity index 88% rename from backend/src/test/java/com/backjoongwon/cvi/publicdata/controller/PublicDataControllerTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/controller/PublicDataControllerTest.java index bb04b76a..778c7336 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/publicdata/controller/PublicDataControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/PublicDataControllerTest.java @@ -1,10 +1,12 @@ -package com.backjoongwon.cvi.publicdata.controller; - -import com.backjoongwon.cvi.ApiDocument; -import com.backjoongwon.cvi.publicdata.service.PublicDataService; -import com.backjoongwon.cvi.publicdata.dto.VaccinationStatisticResponse; -import com.backjoongwon.cvi.user.service.UserService; -import com.backjoongwon.cvi.user.domain.JwtTokenProvider; +package com.cvi.controller; + +import com.cvi.ApiDocument; +import com.cvi.PublicDataFacotry; +import com.cvi.auth.JwtTokenProvider; +import com.cvi.dto.VaccinationStatisticResponse; +import com.cvi.service.PublicDataService; +import com.cvi.service.UserService; +import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -15,7 +17,6 @@ import java.util.Collections; import java.util.List; -import static com.backjoongwon.cvi.publicdata.PublicDataFacotry.*; import static org.mockito.BDDMockito.willReturn; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -34,6 +35,9 @@ class PublicDataControllerTest extends ApiDocument { @MockBean private UserService userService; + @MockBean + private UserRepository userRepository; + @MockBean private JwtTokenProvider jwtTokenProvider; @@ -41,7 +45,7 @@ class PublicDataControllerTest extends ApiDocument { @Test void saveVaccinationStatistic() throws Exception { //given - List vaccinationStatisticResponse = toVaccinationStatisticResponse(TARGET_DATE); + List vaccinationStatisticResponse = PublicDataFacotry.toVaccinationStatisticResponse(TARGET_DATE); //when willReturn(vaccinationStatisticResponse).given(publicDataService).saveVaccinationStatistics(TARGET_DATE); ResultActions response = 백신_접종률_저장_요청(TARGET_DATE); @@ -53,7 +57,7 @@ void saveVaccinationStatistic() throws Exception { @Test void findVaccinationStatistic() throws Exception { //given - List vaccinationStatisticResponse = toVaccinationStatisticResponse(TARGET_DATE); + List vaccinationStatisticResponse = PublicDataFacotry.toVaccinationStatisticResponse(TARGET_DATE); //when willReturn(vaccinationStatisticResponse).given(publicDataService).findVaccinationStatistics(TARGET_DATE); ResultActions response = 백신_접종률_조회_요청(TARGET_DATE); @@ -78,7 +82,7 @@ void findVaccinationStatisticEmpty() throws Exception { void saveWorldVaccinationStatistic() throws Exception { //given //when - willReturn(toVaccinationStatisticResponseOnlyWorldRegion(TARGET_DATE)).given(publicDataService).saveWorldVaccinationStatistics(TARGET_DATE); + willReturn(PublicDataFacotry.toVaccinationStatisticResponseOnlyWorldRegion(TARGET_DATE)).given(publicDataService).saveWorldVaccinationStatistics(TARGET_DATE); ResultActions response = 세계_백신_접종률_저장_요청(TARGET_DATE); //then 세계_백신_접종률_저장_성공함(response); @@ -88,7 +92,7 @@ void saveWorldVaccinationStatistic() throws Exception { @Test void findWorldVaccinationStatistic() throws Exception { //given - List expect = Collections.singletonList(toSingleWorldVaccinationStatisticResponse(TARGET_DATE)); + List expect = Collections.singletonList(PublicDataFacotry.toSingleWorldVaccinationStatisticResponse(TARGET_DATE)); //when willReturn(expect).given(publicDataService).findWorldVaccinationStatistics(TARGET_DATE); ResultActions response = 세계_백신_접종률_조회_요청(TARGET_DATE); diff --git a/backend/src/test/java/com/backjoongwon/cvi/user/controller/UserControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/UserControllerTest.java similarity index 96% rename from backend/src/test/java/com/backjoongwon/cvi/user/controller/UserControllerTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/controller/UserControllerTest.java index dcc5d5e7..ec1303a4 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/user/controller/UserControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/UserControllerTest.java @@ -1,22 +1,23 @@ -package com.backjoongwon.cvi.user.controller; - - -import com.backjoongwon.cvi.ApiDocument; -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.comment.dto.CommentResponse; -import com.backjoongwon.cvi.common.exception.InvalidInputException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.post.service.PostService; -import com.backjoongwon.cvi.post.domain.Filter; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.post.dto.PostWithCommentResponse; -import com.backjoongwon.cvi.user.service.UserService; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.JwtTokenProvider; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.dto.UserRequest; -import com.backjoongwon.cvi.user.dto.UserResponse; +package com.cvi.controller; + +import com.cvi.ApiDocument; +import com.cvi.auth.JwtTokenProvider; +import com.cvi.comment.domain.model.Comment; +import com.cvi.dto.CommentResponse; +import com.cvi.dto.PostWithCommentResponse; +import com.cvi.dto.UserRequest; +import com.cvi.dto.UserResponse; +import com.cvi.exception.InvalidInputException; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.post.domain.model.Filter; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.service.PostService; +import com.cvi.service.UserService; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -31,10 +32,7 @@ import org.springframework.test.web.servlet.ResultActions; import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; +import java.util.*; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -62,6 +60,9 @@ class UserControllerTest extends ApiDocument { @MockBean private UserService userService; + @MockBean + private UserRepository userRepository; + @MockBean private PostService postService; @@ -99,6 +100,7 @@ void beforeEach() { given(jwtTokenProvider.isValidToken(ACCESS_TOKEN)).willReturn(true); given(jwtTokenProvider.getPayload(ACCESS_TOKEN)).willReturn(String.valueOf(user.getId())); given(userService.findUserById(any(Long.class))).willReturn(user); + given(userRepository.findById(anyLong())).willReturn(Optional.of(user)); } @DisplayName("사용자 가입 - 성공") diff --git a/backend/app-cvi-api/src/test/java/com/cvi/empty.txt b/backend/app-cvi-api/src/test/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/src/test/java/com/backjoongwon/cvi/auth/service/AuthServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/AuthServiceTest.java similarity index 92% rename from backend/src/test/java/com/backjoongwon/cvi/auth/service/AuthServiceTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/service/AuthServiceTest.java index 0cec8acd..249334fd 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/auth/service/AuthServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/AuthServiceTest.java @@ -1,15 +1,16 @@ -package com.backjoongwon.cvi.auth.service; +package com.cvi.service; -import com.backjoongwon.cvi.auth.domain.authorization.AuthorizationManager; +import com.cvi.auth.JwtTokenProvider; +import com.cvi.dto.AuthRequest; +import com.cvi.dto.UserResponse; import com.cvi.dto.profile.NaverProfile; import com.cvi.dto.profile.UserInformation; -import com.backjoongwon.cvi.auth.dto.AuthRequest; -import com.backjoongwon.cvi.common.exception.MappingFailureException; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.JwtTokenProvider; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.domain.UserRepository; -import com.backjoongwon.cvi.user.dto.UserResponse; +import com.cvi.exception.MappingFailureException; +import com.cvi.parser.AuthorizationManager; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; @@ -49,6 +50,10 @@ class AuthServiceTest { @MockBean private JwtTokenProvider jwtTokenProvider; + + @MockBean + private PublicDataScheduler publicDataScheduler; + private AuthRequest authRequest; private User user; private String token; diff --git a/backend/src/test/java/com/backjoongwon/cvi/comment/service/CommentServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/CommentServiceTest.java similarity index 90% rename from backend/src/test/java/com/backjoongwon/cvi/comment/service/CommentServiceTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/service/CommentServiceTest.java index d069925f..f0dee896 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/comment/service/CommentServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/CommentServiceTest.java @@ -1,23 +1,24 @@ -package com.backjoongwon.cvi.comment.service; - -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.comment.domain.CommentRepository; -import com.backjoongwon.cvi.comment.dto.CommentRequest; -import com.backjoongwon.cvi.comment.dto.CommentResponse; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.post.service.PostService; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.PostRepository; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.domain.UserRepository; +package com.cvi.service; + +import com.cvi.comment.domain.model.Comment; +import com.cvi.comment.domain.repository.CommentRepository; +import com.cvi.dto.CommentRequest; +import com.cvi.dto.CommentResponse; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; @@ -49,6 +50,9 @@ public class CommentServiceTest { @Autowired private CommentService commentService; + @MockBean + private PublicDataScheduler publicDataScheduler; + private User user; private User anotherUser; private Optional optionalUser; diff --git a/backend/src/test/java/com/backjoongwon/cvi/like/service/LikeServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/LikeServiceTest.java similarity index 88% rename from backend/src/test/java/com/backjoongwon/cvi/like/service/LikeServiceTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/service/LikeServiceTest.java index 46dfda57..8bf1d2b3 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/like/service/LikeServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/LikeServiceTest.java @@ -1,24 +1,25 @@ -package com.backjoongwon.cvi.like.service; - -import com.backjoongwon.cvi.common.exception.InvalidOperationException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.like.domain.Like; -import com.backjoongwon.cvi.like.domain.LikeRepository; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.PostRepository; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.post.dto.LikeResponse; -import com.backjoongwon.cvi.post.dto.PostResponse; -import com.backjoongwon.cvi.post.service.PostService; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.domain.UserRepository; +package com.cvi.service; + +import com.cvi.dto.LikeResponse; +import com.cvi.dto.PostResponse; +import com.cvi.exception.InvalidOperationException; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.like.domain.model.Like; +import com.cvi.like.domain.repository.LikeRepository; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; @@ -48,6 +49,9 @@ public class LikeServiceTest { @Autowired private LikeService likeService; + @MockBean + private PublicDataScheduler publicDataScheduler; + private User userWithoutLike; private User userWithLike; private Optional optionalUserWithoutLike; diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostFindServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/PostFindServiceTest.java similarity index 96% rename from backend/src/test/java/com/backjoongwon/cvi/post/service/PostFindServiceTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/service/PostFindServiceTest.java index 97efe911..6d5c5e72 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostFindServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/PostFindServiceTest.java @@ -1,17 +1,18 @@ -package com.backjoongwon.cvi.post.service; - -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.comment.domain.CommentRepository; -import com.backjoongwon.cvi.like.domain.Like; -import com.backjoongwon.cvi.like.domain.LikeRepository; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.PostRepository; -import com.backjoongwon.cvi.post.domain.Sort; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.post.dto.PostResponse; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.domain.UserRepository; +package com.cvi.service; + +import com.cvi.comment.domain.model.Comment; +import com.cvi.comment.domain.repository.CommentRepository; +import com.cvi.dto.PostResponse; +import com.cvi.like.domain.model.Like; +import com.cvi.like.domain.repository.LikeRepository; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.Sort; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,6 +21,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; @@ -51,6 +53,9 @@ public class PostFindServiceTest { @Autowired private PostService postService; + @MockBean + private PublicDataScheduler publicDataScheduler; + @PersistenceContext private EntityManager em; diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostMyPageServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/PostMyPageServiceTest.java similarity index 92% rename from backend/src/test/java/com/backjoongwon/cvi/post/service/PostMyPageServiceTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/service/PostMyPageServiceTest.java index 9d329f73..be92ba64 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostMyPageServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/PostMyPageServiceTest.java @@ -1,17 +1,18 @@ -package com.backjoongwon.cvi.post.service; - -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.comment.domain.CommentRepository; -import com.backjoongwon.cvi.like.domain.Like; -import com.backjoongwon.cvi.like.domain.LikeRepository; -import com.backjoongwon.cvi.post.domain.Filter; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.PostRepository; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.post.dto.PostWithCommentResponse; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.domain.UserRepository; +package com.cvi.service; + +import com.cvi.comment.domain.model.Comment; +import com.cvi.comment.domain.repository.CommentRepository; +import com.cvi.dto.PostWithCommentResponse; +import com.cvi.like.domain.model.Like; +import com.cvi.like.domain.repository.LikeRepository; +import com.cvi.post.domain.model.Filter; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,6 +21,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; @@ -49,6 +51,9 @@ public class PostMyPageServiceTest { @Autowired private PostService postService; + @MockBean + private PublicDataScheduler publicDataScheduler; + private User user; private Optional optionalUser; diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/PostServiceTest.java similarity index 91% rename from backend/src/test/java/com/backjoongwon/cvi/post/service/PostServiceTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/service/PostServiceTest.java index 3a9f188e..a2ad16a5 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/service/PostServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/PostServiceTest.java @@ -1,21 +1,23 @@ -package com.backjoongwon.cvi.post.service; - -import com.backjoongwon.cvi.common.exception.InvalidOperationException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.PostRepository; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.post.dto.PostRequest; -import com.backjoongwon.cvi.post.dto.PostResponse; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.domain.UserRepository; +package com.cvi.service; + +import com.cvi.dto.PostRequest; +import com.cvi.dto.PostResponse; +import com.cvi.exception.InvalidOperationException; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; @@ -40,6 +42,9 @@ class PostServiceTest { @Autowired private PostService postService; + @MockBean + private PublicDataScheduler publicDataScheduler; + private User user; private User anotherUser; private Optional optionalUser; diff --git a/backend/src/test/java/com/backjoongwon/cvi/publicdata/service/PublicDataServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/PublicDataServiceTest.java similarity index 86% rename from backend/src/test/java/com/backjoongwon/cvi/publicdata/service/PublicDataServiceTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/service/PublicDataServiceTest.java index d16a0b8b..d902c2c3 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/publicdata/service/PublicDataServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/PublicDataServiceTest.java @@ -1,11 +1,12 @@ -package com.backjoongwon.cvi.publicdata.service; +package com.cvi.service; -import com.backjoongwon.cvi.parser.VaccinationParser; -import com.backjoongwon.cvi.publicdata.domain.PublicDataProperties; -import com.backjoongwon.cvi.publicdata.domain.RegionPopulation; -import com.backjoongwon.cvi.publicdata.domain.VaccinationStatistic; -import com.backjoongwon.cvi.publicdata.domain.VaccinationStatisticRepository; -import com.backjoongwon.cvi.publicdata.dto.VaccinationStatisticResponse; +import com.cvi.PublicDataFacotry; +import com.cvi.dto.VaccinationStatisticResponse; +import com.cvi.parser.VaccinationParser; +import com.cvi.properties.PublicDataProperties; +import com.cvi.publicdata.domain.model.RegionPopulation; +import com.cvi.publicdata.domain.model.VaccinationStatistic; +import com.cvi.publicdata.domain.repository.VaccinationStatisticRepository; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -15,13 +16,13 @@ import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; import java.util.List; import java.util.stream.Stream; -import static com.backjoongwon.cvi.publicdata.PublicDataFacotry.*; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; @@ -39,6 +40,10 @@ class PublicDataServiceTest { private PublicDataProperties publicDataProperties; @Autowired private PublicDataService publicDataService; + + @MockBean + private PublicDataScheduler publicDataScheduler; + private VaccinationParser vaccinationParser; public static Stream targetDate() { @@ -88,7 +93,7 @@ void findVaccinationStatistics(LocalDate targetDate) { assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getBaseDate) .contains(targetDate); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getSido) - .containsAll(REGIONS); + .containsAll(PublicDataFacotry.REGIONS); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getFirstCnt) .isNotEmpty(); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getSecondCnt) @@ -120,13 +125,13 @@ void saveWorldVaccinationStatistics() { } private void 백신_접종률_저장되어_있음(LocalDate targetDate) { - willReturn(toVaccineParserResponse(targetDate)) + willReturn(PublicDataFacotry.toVaccineParserResponse(targetDate)) .given(vaccinationParser).parseToKoreaPublicData(any(LocalDate.class), anyString()); publicDataService.saveVaccinationStatistics(targetDate); } private void 세계_백신_접종률_저장되어_있음(LocalDate targetDate) { - willReturn(toWorldVaccinationParserResponse(targetDate)).given(vaccinationParser).parseToWorldPublicData(); + willReturn(PublicDataFacotry.toWorldVaccinationParserResponse(targetDate)).given(vaccinationParser).parseToWorldPublicData(); publicDataService.saveWorldVaccinationStatistics(targetDate); } } diff --git a/backend/src/test/java/com/backjoongwon/cvi/user/service/UserServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/UserServiceTest.java similarity index 93% rename from backend/src/test/java/com/backjoongwon/cvi/user/service/UserServiceTest.java rename to backend/app-cvi-api/src/test/java/com/cvi/service/UserServiceTest.java index 8c8ee7f4..e9fc581c 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/user/service/UserServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/UserServiceTest.java @@ -1,14 +1,15 @@ -package com.backjoongwon.cvi.user.service; - -import com.backjoongwon.cvi.common.exception.DuplicateException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.JwtTokenProvider; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.domain.UserRepository; -import com.backjoongwon.cvi.user.dto.UserRequest; -import com.backjoongwon.cvi.user.dto.UserResponse; +package com.cvi.service; + +import com.cvi.auth.JwtTokenProvider; +import com.cvi.dto.UserRequest; +import com.cvi.dto.UserResponse; +import com.cvi.exception.DuplicateException; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -37,6 +38,10 @@ public class UserServiceTest { @Autowired private UserRepository userRepository; + + @MockBean + private PublicDataScheduler publicDataScheduler; + private UserRequest userRequest; @BeforeEach diff --git a/backend/app-cvi-api/src/test/resources/application.yml b/backend/app-cvi-api/src/test/resources/application.yml new file mode 100644 index 00000000..3cb8465d --- /dev/null +++ b/backend/app-cvi-api/src/test/resources/application.yml @@ -0,0 +1,40 @@ +spring: + profiles: + active: test + + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE; + username: sa + password: + + h2: + console: + enabled: true + + jpa: + hibernate: + ddl-auto: create-drop + properties: + hibernate: + format_sql: true + generate-ddl: true + +security: + jwt: + token: + secret-key: cvi_secret_key + expire-length: 3600000 + + auth: + naver: + client-secret: client-secret + + public: + data: + vaccination: publicdata-secret + +logging: + level: + org.hibernate.SQL: debug + org.hibernate.type: trace diff --git a/backend/app-cvi-api/src/test/resources/empty.txt b/backend/app-cvi-api/src/test/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/build.gradle b/backend/build.gradle index 3d18e818..ad0fffa6 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -5,8 +5,12 @@ plugins { id 'jacoco' id 'org.sonarqube' version '3.0' id 'org.asciidoctor.convert' version '1.5.8' + id 'application' } +application { + mainClass = 'com.cvi.CentralVaccinationInformationApplication' +} subprojects { group = 'com.backjoongwon' diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/config/WebMvcConfig.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/config/WebMvcConfig.java deleted file mode 100644 index 99821170..00000000 --- a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/config/WebMvcConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.cvi.config; - -import com.cvi.auth.AuthenticationPrincipalArgumentResolver; -import com.cvi.auth.SigninInterceptor; -import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -import java.util.List; - -@RequiredArgsConstructor -@Configuration -public class WebMvcConfig implements WebMvcConfigurer { - - private final SigninInterceptor signinInterceptor; - private final AuthenticationPrincipalArgumentResolver resolver; - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(signinInterceptor) - .addPathPatterns("/**") - .excludePathPatterns("/api/v1/users/signup") - .excludePathPatterns("/api/v1/users/auth") - .excludePathPatterns("/api/v1/publicdata/vaccinations"); - } - - @Override - public void addArgumentResolvers(List resolvers) { - resolvers.add(resolver); - } -} diff --git a/backend/domain-cvi-oauth-service/src/main/resources/application-domain-cvi-oauth.yml b/backend/domain-cvi-oauth-service/src/main/resources/application-domain-cvi-oauth.yml index 85efc169..71cc4fc1 100644 --- a/backend/domain-cvi-oauth-service/src/main/resources/application-domain-cvi-oauth.yml +++ b/backend/domain-cvi-oauth-service/src/main/resources/application-domain-cvi-oauth.yml @@ -1,9 +1,4 @@ security: - jwt: - token: - secret-key: cvi_secret_key - expire-length: 3600000 - auth: naver: client-secret: client-secret \ No newline at end of file diff --git a/backend/domain-cvi-oauth-service/src/test/java/com/cvi/empty.txt b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/settings.gradle b/backend/settings.gradle index 35560e81..75fae522 100644 --- a/backend/settings.gradle +++ b/backend/settings.gradle @@ -1,4 +1,5 @@ rootProject.name = 'cvi' +include 'app-cvi-api' include 'app-cvi-admin' include 'cvi-publicdata-parser' include 'common-cvi' @@ -6,5 +7,4 @@ include 'domain-cvi' include 'domain-cvi-oauth-service' include 'domain-cvi-publicdata-service' include 'domain-cvi-scheduler' -include 'app-cvi-api' From 07a1d2334e8a41bde177b00db878643ef963bfb3 Mon Sep 17 00:00:00 2001 From: livenow14 Date: Fri, 10 Sep 2021 13:44:26 +0900 Subject: [PATCH 04/17] =?UTF-8?q?feat:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=AA=A8=EB=93=88=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app-cvi-admin/build.gradle | 1 - backend/app-cvi-api/build.gradle | 3 +- .../test/java/com/cvi/PublicDataFacotry.java | 54 -------------- backend/domain-cvi-oauth-service/build.gradle | 4 +- .../cvi/parser}/AuthorizationManagerTest.java | 5 +- .../cvi/parser}/KakaoAuthorizationTest.java | 8 +-- .../cvi/parser}/NaverAuthorizationTest.java | 8 +-- .../build.gradle | 36 ++++++++++ ...tralVaccinationInformationApplication.java | 12 ++++ .../test/java/com/cvi/PublicDataFacotry.java | 71 +++++++++++++++++++ .../src/test/java/com/cvi/empty.txt | 0 .../cvi/service/PublicDataServiceTest.java | 5 +- .../src/test/resources/application.yml | 27 +++++++ .../src/test/resources/empty.txt | 0 backend/domain-cvi/build.gradle | 4 +- .../java/com/cvi/user/domain/model/User.java | 3 +- .../comment/domain/model}/CommentTest.java | 17 ++--- .../src/test/java/com/cvi/empty.txt | 0 .../com/cvi/like/domain/model}/LikeTest.java | 11 +-- .../com/cvi/post/domain/model}/PostTest.java | 15 ++-- .../model}/VaccinationStatisticTest.java | 2 +- .../com/cvi/user/domain/model}/UserTest.java | 6 +- .../src/test/resources/application.yml | 40 +++++++++++ .../domain-cvi/src/test/resources/empty.txt | 0 backend/settings.gradle | 2 +- 25 files changed, 234 insertions(+), 100 deletions(-) rename backend/{src/test/java/com/backjoongwon/cvi/auth/domain/authorization => domain-cvi-oauth-service/src/test/java/com/cvi/parser}/AuthorizationManagerTest.java (96%) rename backend/{src/test/java/com/backjoongwon/cvi/auth/domain/authorization => domain-cvi-oauth-service/src/test/java/com/cvi/parser}/KakaoAuthorizationTest.java (96%) rename backend/{src/test/java/com/backjoongwon/cvi/auth/domain/authorization => domain-cvi-oauth-service/src/test/java/com/cvi/parser}/NaverAuthorizationTest.java (96%) create mode 100644 backend/domain-cvi-publicdata-service/src/test/java/com/cvi/CentralVaccinationInformationApplication.java create mode 100644 backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFacotry.java delete mode 100644 backend/domain-cvi-publicdata-service/src/test/java/com/cvi/empty.txt rename backend/{app-cvi-api => domain-cvi-publicdata-service}/src/test/java/com/cvi/service/PublicDataServiceTest.java (98%) create mode 100644 backend/domain-cvi-publicdata-service/src/test/resources/application.yml delete mode 100644 backend/domain-cvi-publicdata-service/src/test/resources/empty.txt rename backend/{src/test/java/com/backjoongwon/cvi/comment/domain => domain-cvi/src/test/java/com/cvi/comment/domain/model}/CommentTest.java (90%) delete mode 100644 backend/domain-cvi/src/test/java/com/cvi/empty.txt rename backend/{src/test/java/com/backjoongwon/cvi/like/domain => domain-cvi/src/test/java/com/cvi/like/domain/model}/LikeTest.java (85%) rename backend/{src/test/java/com/backjoongwon/cvi/post/domain => domain-cvi/src/test/java/com/cvi/post/domain/model}/PostTest.java (94%) rename backend/{src/test/java/com/backjoongwon/cvi/publicdata/domain => domain-cvi/src/test/java/com/cvi/publicdata/domain/model}/VaccinationStatisticTest.java (98%) rename backend/{src/test/java/com/backjoongwon/cvi/user/domain => domain-cvi/src/test/java/com/cvi/user/domain/model}/UserTest.java (94%) create mode 100644 backend/domain-cvi/src/test/resources/application.yml delete mode 100644 backend/domain-cvi/src/test/resources/empty.txt diff --git a/backend/app-cvi-admin/build.gradle b/backend/app-cvi-admin/build.gradle index 430a7b98..75d320e1 100644 --- a/backend/app-cvi-admin/build.gradle +++ b/backend/app-cvi-admin/build.gradle @@ -2,5 +2,4 @@ bootJar { enabled = false } jar { enabled = true } dependencies { - } diff --git a/backend/app-cvi-api/build.gradle b/backend/app-cvi-api/build.gradle index bae2b6ef..4e28cae6 100644 --- a/backend/app-cvi-api/build.gradle +++ b/backend/app-cvi-api/build.gradle @@ -4,8 +4,8 @@ dependencies { implementation project(path:':common-cvi', configuration: 'default') implementation project(path:':domain-cvi', configuration: 'default') implementation project(path:':domain-cvi-oauth-service', configuration: 'default') - implementation project(path:':domain-cvi-scheduler', configuration: 'default') implementation project(path:':domain-cvi-publicdata-service', configuration: 'default') + implementation project(path:':domain-cvi-scheduler', configuration: 'default') implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' @@ -14,7 +14,6 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-cache' implementation 'javax.cache:cache-api:1.1.1' implementation 'org.ehcache:ehcache:3.9.4' - } jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 diff --git a/backend/app-cvi-api/src/test/java/com/cvi/PublicDataFacotry.java b/backend/app-cvi-api/src/test/java/com/cvi/PublicDataFacotry.java index b2d8c7ae..b3a412b8 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/PublicDataFacotry.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/PublicDataFacotry.java @@ -13,48 +13,6 @@ public class PublicDataFacotry { "울산광역시", "경기도", "강원도", "세종특별자치시", "충청북도", "충청남도", "전라북도", "전라남도", "경상북도", "경상남도", "제주특별자치도"); - public static KoreaVaccineParserResponse toVaccineParserResponse(LocalDate targetDate) { - String expectDateTime = DateConverter.convertDateToContainsZeroTime(targetDate); - return new KoreaVaccineParserResponse(18, Arrays.asList( - new KoreaRegionVaccinationData(19473657, 7146602, expectDateTime, - 473850, 35955, "전국", 19947507, 7182557), - new KoreaRegionVaccinationData(3646765, 1329982, expectDateTime, - 77877, 7123, "서울특별시", 3724642, 1337105), - new KoreaRegionVaccinationData(1352394, 477845, expectDateTime, - 31252, 2628, "부산광역시", 1383646, 480473), - new KoreaRegionVaccinationData(848397, 309317, expectDateTime, - 22726, 2688, "대구광역시", 871123, 312005), - new KoreaRegionVaccinationData(523814, 197608, expectDateTime, - 12990, 959, "대전광역시", 536804, 198567), - new KoreaRegionVaccinationData(1032052, 360923, expectDateTime, - 27394, 1760, "인천광역시", 1059446, 362683), - new KoreaRegionVaccinationData(549706, 204415, expectDateTime, - 13700, 830, "광주광역시", 563406, 205245), - new KoreaRegionVaccinationData(396793, 124839, expectDateTime, - 11275, 471, "울산광역시", 408068, 125310), - new KoreaRegionVaccinationData(4636237, 1636357, expectDateTime, - 118717, 7895, "경기도", 4754954, 1644252), - new KoreaRegionVaccinationData(668422, 273253, expectDateTime, - 14908, 1010, "강원도", 683330, 274263), - new KoreaRegionVaccinationData(109202, 37624, expectDateTime, - 3028, 179, "세종특별자치시", 112230, 37803), - new KoreaRegionVaccinationData(639514, 240704, expectDateTime, - 15886, 1324, "충청북도", 655400, 242028), - new KoreaRegionVaccinationData(849914, 330591, expectDateTime, - 22167, 2054, "충청남도", 872081, 332645), - new KoreaRegionVaccinationData(789017, 311961, expectDateTime, - 17331, 1270, "전라북도", 806348, 313231), - new KoreaRegionVaccinationData(859228, 344275, expectDateTime, - 19083, 1378, "전라남도", 878311, 345653), - new KoreaRegionVaccinationData(1070878, 409752, expectDateTime, - 27263, 2016, "경상북도", 1098141, 411768), - new KoreaRegionVaccinationData(1249910, 464110, expectDateTime, - 31098, 1943, "경상남도", 1281008, 466053), - new KoreaRegionVaccinationData(251414, 93046, expectDateTime, - 7155, 427, "제주특별자치도", 258569, 93473) - ), 18, 1, 20, 2634); - } - public static List toVaccinationStatisticResponse(LocalDate targetDate) { return Arrays.asList( new VaccinationStatisticResponse(19473657, 7146602, targetDate, @@ -96,18 +54,6 @@ public static List toVaccinationStatisticResponse( ); } - public static WorldVaccinationParserResponse toWorldVaccinationParserResponse(LocalDate targetDate) { - return new WorldVaccinationParserResponse("World", "OWID_WRL", - Arrays.asList(new WorldVaccinationData(targetDate.minusDays(2).toString(), 4327424315L, 2293196690L, 1175939230L, - 43847311L, 42963523L, 55.52, 29.42, 15.09, 5512L), - new WorldVaccinationData(targetDate.minusDays(1).toString(), 4399234109L, 2317353271L, 1181952381L, - 32322341L, 40310055L, 55.93, 29.56, 15.16, 5171L), - new WorldVaccinationData(targetDate.toString(), 4359746656L, 2303769251L, 1191535085L, - 33797364L, 40043557L, 56.44, 29.73, 15.29, 5137L) - ) - ); - } - public static List toVaccinationStatisticResponseOnlyWorldRegion(LocalDate targetDate) { return Arrays.asList( new VaccinationStatisticResponse(0, 0, targetDate, diff --git a/backend/domain-cvi-oauth-service/build.gradle b/backend/domain-cvi-oauth-service/build.gradle index b261ce01..5d321fb3 100644 --- a/backend/domain-cvi-oauth-service/build.gradle +++ b/backend/domain-cvi-oauth-service/build.gradle @@ -18,12 +18,12 @@ jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 violationRules { // 위반 규칙 rule { enabled = true - element = 'CLASS' + element = 'BUNDLE' limit { counter = 'INSTRUCTION' value = 'COVEREDRATIO' - minimum = 0.80 + minimum = 0.85 } excludes = [ diff --git a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/AuthorizationManagerTest.java b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/AuthorizationManagerTest.java similarity index 96% rename from backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/AuthorizationManagerTest.java rename to backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/AuthorizationManagerTest.java index c0c3a78d..91dd4320 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/AuthorizationManagerTest.java +++ b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/AuthorizationManagerTest.java @@ -1,9 +1,10 @@ -package com.backjoongwon.cvi.auth.domain.authorization; +package com.cvi.parser; import com.cvi.dto.profile.KakaoProfile; import com.cvi.dto.profile.NaverProfile; import com.cvi.dto.profile.UserInformation; -import com.backjoongwon.cvi.common.exception.InvalidOperationException; +import com.cvi.exception.InvalidOperationException; +import com.cvi.user.domain.model.SocialProvider; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; diff --git a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/KakaoAuthorizationTest.java b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/KakaoAuthorizationTest.java similarity index 96% rename from backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/KakaoAuthorizationTest.java rename to backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/KakaoAuthorizationTest.java index f022feb0..443ab0f5 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/KakaoAuthorizationTest.java +++ b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/KakaoAuthorizationTest.java @@ -1,10 +1,10 @@ -package com.backjoongwon.cvi.auth.domain.authorization; +package com.cvi.parser; -import com.backjoongwon.cvi.auth.dto.oauthtoken.KakaoOAuthToken; -import com.backjoongwon.cvi.auth.dto.oauthtoken.OAuthToken; +import com.cvi.dto.oauthtoken.KakaoOAuthToken; +import com.cvi.dto.oauthtoken.OAuthToken; import com.cvi.dto.profile.SocialProfile; import com.cvi.dto.profile.UserInformation; -import com.backjoongwon.cvi.common.exception.MappingFailureException; +import com.cvi.exception.MappingFailureException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/NaverAuthorizationTest.java b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/NaverAuthorizationTest.java similarity index 96% rename from backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/NaverAuthorizationTest.java rename to backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/NaverAuthorizationTest.java index 8f2f6cb6..c236c559 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/auth/domain/authorization/NaverAuthorizationTest.java +++ b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/NaverAuthorizationTest.java @@ -1,10 +1,10 @@ -package com.backjoongwon.cvi.auth.domain.authorization; +package com.cvi.parser; -import com.backjoongwon.cvi.auth.dto.oauthtoken.NaverOAuthToken; -import com.backjoongwon.cvi.auth.dto.oauthtoken.OAuthToken; +import com.cvi.dto.oauthtoken.NaverOAuthToken; +import com.cvi.dto.oauthtoken.OAuthToken; import com.cvi.dto.profile.SocialProfile; import com.cvi.dto.profile.UserInformation; -import com.backjoongwon.cvi.common.exception.MappingFailureException; +import com.cvi.exception.MappingFailureException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/domain-cvi-publicdata-service/build.gradle b/backend/domain-cvi-publicdata-service/build.gradle index fb82a1af..7c9b1cff 100644 --- a/backend/domain-cvi-publicdata-service/build.gradle +++ b/backend/domain-cvi-publicdata-service/build.gradle @@ -5,3 +5,39 @@ dependencies { implementation project(path:':domain-cvi', configuration: 'default') implementation project(path:':cvi-publicdata-parser', configuration: 'default') } + +jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 + def Qdomains = [] + + for (qPattern in "*.QA".."*.QZ") { + Qdomains.add(qPattern + "*") + } + + violationRules { // 위반 규칙 + rule { + enabled = true + element = 'BUNDLE' + + limit { + counter = 'INSTRUCTION' + value = 'COVEREDRATIO' + minimum = 0.90 + } + + excludes = [ + // 커버리지 제외할 클래스 + '*.DataLoader*', + '*.CviApplication*', + '*.DummyData*', + '*.KakaoProfile*', + '*.NaverProfile*' + ] + Qdomains + } + } +} + +sonarqube { + properties { + property "sonar.exclusions", "**/*Test*.*, **/Q*.java, **/*Doc*.java" + } +} \ No newline at end of file diff --git a/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/CentralVaccinationInformationApplication.java b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/CentralVaccinationInformationApplication.java new file mode 100644 index 00000000..5f0da41f --- /dev/null +++ b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/CentralVaccinationInformationApplication.java @@ -0,0 +1,12 @@ +package com.cvi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CentralVaccinationInformationApplication { + + public static void main(String[] args) { + SpringApplication.run(CentralVaccinationInformationApplication.class, args); + } +} \ No newline at end of file diff --git a/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFacotry.java b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFacotry.java new file mode 100644 index 00000000..7b365411 --- /dev/null +++ b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFacotry.java @@ -0,0 +1,71 @@ +package com.cvi; + +import com.cvi.dto.KoreaRegionVaccinationData; +import com.cvi.dto.KoreaVaccineParserResponse; +import com.cvi.dto.WorldVaccinationData; +import com.cvi.dto.WorldVaccinationParserResponse; +import com.cvi.util.DateConverter; + +import java.time.LocalDate; +import java.util.Arrays; +import java.util.List; + +public class PublicDataFacotry { + public static final List REGIONS = Arrays.asList("전국", "부산광역시", "대구광역시", "대전광역시", "인천광역시", "광주광역시", + "울산광역시", "경기도", "강원도", "세종특별자치시", "충청북도", "충청남도", + "전라북도", "전라남도", "경상북도", "경상남도", "제주특별자치도"); + + public static KoreaVaccineParserResponse toVaccineParserResponse(LocalDate targetDate) { + String expectDateTime = DateConverter.convertDateToContainsZeroTime(targetDate); + return new KoreaVaccineParserResponse(18, Arrays.asList( + new KoreaRegionVaccinationData(19473657, 7146602, expectDateTime, + 473850, 35955, "전국", 19947507, 7182557), + new KoreaRegionVaccinationData(3646765, 1329982, expectDateTime, + 77877, 7123, "서울특별시", 3724642, 1337105), + new KoreaRegionVaccinationData(1352394, 477845, expectDateTime, + 31252, 2628, "부산광역시", 1383646, 480473), + new KoreaRegionVaccinationData(848397, 309317, expectDateTime, + 22726, 2688, "대구광역시", 871123, 312005), + new KoreaRegionVaccinationData(523814, 197608, expectDateTime, + 12990, 959, "대전광역시", 536804, 198567), + new KoreaRegionVaccinationData(1032052, 360923, expectDateTime, + 27394, 1760, "인천광역시", 1059446, 362683), + new KoreaRegionVaccinationData(549706, 204415, expectDateTime, + 13700, 830, "광주광역시", 563406, 205245), + new KoreaRegionVaccinationData(396793, 124839, expectDateTime, + 11275, 471, "울산광역시", 408068, 125310), + new KoreaRegionVaccinationData(4636237, 1636357, expectDateTime, + 118717, 7895, "경기도", 4754954, 1644252), + new KoreaRegionVaccinationData(668422, 273253, expectDateTime, + 14908, 1010, "강원도", 683330, 274263), + new KoreaRegionVaccinationData(109202, 37624, expectDateTime, + 3028, 179, "세종특별자치시", 112230, 37803), + new KoreaRegionVaccinationData(639514, 240704, expectDateTime, + 15886, 1324, "충청북도", 655400, 242028), + new KoreaRegionVaccinationData(849914, 330591, expectDateTime, + 22167, 2054, "충청남도", 872081, 332645), + new KoreaRegionVaccinationData(789017, 311961, expectDateTime, + 17331, 1270, "전라북도", 806348, 313231), + new KoreaRegionVaccinationData(859228, 344275, expectDateTime, + 19083, 1378, "전라남도", 878311, 345653), + new KoreaRegionVaccinationData(1070878, 409752, expectDateTime, + 27263, 2016, "경상북도", 1098141, 411768), + new KoreaRegionVaccinationData(1249910, 464110, expectDateTime, + 31098, 1943, "경상남도", 1281008, 466053), + new KoreaRegionVaccinationData(251414, 93046, expectDateTime, + 7155, 427, "제주특별자치도", 258569, 93473) + ), 18, 1, 20, 2634); + } + + public static WorldVaccinationParserResponse toWorldVaccinationParserResponse(LocalDate targetDate) { + return new WorldVaccinationParserResponse("World", "OWID_WRL", + Arrays.asList(new WorldVaccinationData(targetDate.minusDays(2).toString(), 4327424315L, 2293196690L, 1175939230L, + 43847311L, 42963523L, 55.52, 29.42, 15.09, 5512L), + new WorldVaccinationData(targetDate.minusDays(1).toString(), 4399234109L, 2317353271L, 1181952381L, + 32322341L, 40310055L, 55.93, 29.56, 15.16, 5171L), + new WorldVaccinationData(targetDate.toString(), 4359746656L, 2303769251L, 1191535085L, + 33797364L, 40043557L, 56.44, 29.73, 15.29, 5137L) + ) + ); + } +} diff --git a/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/empty.txt b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/app-cvi-api/src/test/java/com/cvi/service/PublicDataServiceTest.java b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/service/PublicDataServiceTest.java similarity index 98% rename from backend/app-cvi-api/src/test/java/com/cvi/service/PublicDataServiceTest.java rename to backend/domain-cvi-publicdata-service/src/test/java/com/cvi/service/PublicDataServiceTest.java index d902c2c3..12cee3e3 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/service/PublicDataServiceTest.java +++ b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/service/PublicDataServiceTest.java @@ -14,6 +14,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.BDDMockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -26,6 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.*; import static org.mockito.BDDMockito.willReturn; import static org.mockito.Mockito.mock; @@ -41,9 +43,6 @@ class PublicDataServiceTest { @Autowired private PublicDataService publicDataService; - @MockBean - private PublicDataScheduler publicDataScheduler; - private VaccinationParser vaccinationParser; public static Stream targetDate() { diff --git a/backend/domain-cvi-publicdata-service/src/test/resources/application.yml b/backend/domain-cvi-publicdata-service/src/test/resources/application.yml new file mode 100644 index 00000000..372495fe --- /dev/null +++ b/backend/domain-cvi-publicdata-service/src/test/resources/application.yml @@ -0,0 +1,27 @@ +spring: + profiles: + active: test + + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE; + username: sa + password: + + jpa: + hibernate: + ddl-auto: create-drop + properties: + hibernate: + format_sql: true + generate-ddl: true + +security: + public: + data: + vaccination: publicdata-secret + +logging: + level: + org.hibernate.SQL: debug + org.hibernate.type: trace diff --git a/backend/domain-cvi-publicdata-service/src/test/resources/empty.txt b/backend/domain-cvi-publicdata-service/src/test/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/domain-cvi/build.gradle b/backend/domain-cvi/build.gradle index 7e88e389..2256eb88 100644 --- a/backend/domain-cvi/build.gradle +++ b/backend/domain-cvi/build.gradle @@ -23,12 +23,12 @@ jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 violationRules { // 위반 규칙 rule { enabled = true - element = 'CLASS' + element = 'BUNDLE' limit { counter = 'INSTRUCTION' value = 'COVEREDRATIO' - minimum = 0.80 + minimum = 0.00 } excludes = [ diff --git a/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java b/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java index ec1b13a8..0885d94c 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java +++ b/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java @@ -12,6 +12,7 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import java.time.LocalDateTime; +import java.util.Objects; @Slf4j @Entity @@ -56,7 +57,7 @@ public User(Long id, LocalDateTime createdAt, LocalDateTime lastModifiedAt, Stri } private void validateNickName(String nickname) { - if (StringUtils.isEmpty(nickname) || nickname.contains(" ")) { + if (Objects.isNull(nickname) || nickname.isEmpty() || nickname.contains(" ")) { log.info("닉네임에는 공백 문자가 포함될 수 없습니다. 입력값: {}", nickname); throw new InvalidInputException(String.format("닉네임에는 공백 문자가 포함될 수 없습니다. 입력값: %s", nickname)); } diff --git a/backend/src/test/java/com/backjoongwon/cvi/comment/domain/CommentTest.java b/backend/domain-cvi/src/test/java/com/cvi/comment/domain/model/CommentTest.java similarity index 90% rename from backend/src/test/java/com/backjoongwon/cvi/comment/domain/CommentTest.java rename to backend/domain-cvi/src/test/java/com/cvi/comment/domain/model/CommentTest.java index 5f3bc95b..7930a231 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/comment/domain/CommentTest.java +++ b/backend/domain-cvi/src/test/java/com/cvi/comment/domain/model/CommentTest.java @@ -1,12 +1,13 @@ -package com.backjoongwon.cvi.comment.domain; +package com.cvi.comment.domain.model; -import com.backjoongwon.cvi.common.exception.InvalidOperationException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.common.exception.UnAuthorizedException; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.exception.InvalidOperationException; +import com.cvi.exception.NotFoundException; +import com.cvi.exception.UnAuthorizedException; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/domain-cvi/src/test/java/com/cvi/empty.txt b/backend/domain-cvi/src/test/java/com/cvi/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/src/test/java/com/backjoongwon/cvi/like/domain/LikeTest.java b/backend/domain-cvi/src/test/java/com/cvi/like/domain/model/LikeTest.java similarity index 85% rename from backend/src/test/java/com/backjoongwon/cvi/like/domain/LikeTest.java rename to backend/domain-cvi/src/test/java/com/cvi/like/domain/model/LikeTest.java index cc7e9146..5b1ca774 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/like/domain/LikeTest.java +++ b/backend/domain-cvi/src/test/java/com/cvi/like/domain/model/LikeTest.java @@ -1,9 +1,10 @@ -package com.backjoongwon.cvi.like.domain; +package com.cvi.like.domain.model; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.User; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/src/test/java/com/backjoongwon/cvi/post/domain/PostTest.java b/backend/domain-cvi/src/test/java/com/cvi/post/domain/model/PostTest.java similarity index 94% rename from backend/src/test/java/com/backjoongwon/cvi/post/domain/PostTest.java rename to backend/domain-cvi/src/test/java/com/cvi/post/domain/model/PostTest.java index 767b6636..2a5cce77 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/post/domain/PostTest.java +++ b/backend/domain-cvi/src/test/java/com/cvi/post/domain/model/PostTest.java @@ -1,10 +1,11 @@ -package com.backjoongwon.cvi.post.domain; - -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.common.exception.InvalidOperationException; -import com.backjoongwon.cvi.common.exception.NotFoundException; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.User; +package com.cvi.post.domain.model; + +import com.cvi.comment.domain.model.Comment; +import com.cvi.exception.InvalidOperationException; +import com.cvi.exception.NotFoundException; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/backend/src/test/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatisticTest.java b/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticTest.java similarity index 98% rename from backend/src/test/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatisticTest.java rename to backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticTest.java index ee10e7b3..4363313e 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/publicdata/domain/VaccinationStatisticTest.java +++ b/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticTest.java @@ -1,4 +1,4 @@ -package com.backjoongwon.cvi.publicdata.domain; +package com.cvi.publicdata.domain.model; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; diff --git a/backend/src/test/java/com/backjoongwon/cvi/user/domain/UserTest.java b/backend/domain-cvi/src/test/java/com/cvi/user/domain/model/UserTest.java similarity index 94% rename from backend/src/test/java/com/backjoongwon/cvi/user/domain/UserTest.java rename to backend/domain-cvi/src/test/java/com/cvi/user/domain/model/UserTest.java index 6a66eaaa..6b33e47e 100644 --- a/backend/src/test/java/com/backjoongwon/cvi/user/domain/UserTest.java +++ b/backend/domain-cvi/src/test/java/com/cvi/user/domain/model/UserTest.java @@ -1,6 +1,6 @@ -package com.backjoongwon.cvi.user.domain; +package com.cvi.user.domain.model; -import com.backjoongwon.cvi.common.exception.InvalidInputException; +import com.cvi.exception.InvalidInputException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -58,4 +58,4 @@ void signupFailureWhenEmptyNickname(String nickname) { assertThatThrownBy(() -> User.builder().nickname(nickname).build()) .isInstanceOf(InvalidInputException.class); } -} \ No newline at end of file +} diff --git a/backend/domain-cvi/src/test/resources/application.yml b/backend/domain-cvi/src/test/resources/application.yml new file mode 100644 index 00000000..3cb8465d --- /dev/null +++ b/backend/domain-cvi/src/test/resources/application.yml @@ -0,0 +1,40 @@ +spring: + profiles: + active: test + + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE; + username: sa + password: + + h2: + console: + enabled: true + + jpa: + hibernate: + ddl-auto: create-drop + properties: + hibernate: + format_sql: true + generate-ddl: true + +security: + jwt: + token: + secret-key: cvi_secret_key + expire-length: 3600000 + + auth: + naver: + client-secret: client-secret + + public: + data: + vaccination: publicdata-secret + +logging: + level: + org.hibernate.SQL: debug + org.hibernate.type: trace diff --git a/backend/domain-cvi/src/test/resources/empty.txt b/backend/domain-cvi/src/test/resources/empty.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/settings.gradle b/backend/settings.gradle index 75fae522..577abb6e 100644 --- a/backend/settings.gradle +++ b/backend/settings.gradle @@ -1,6 +1,6 @@ rootProject.name = 'cvi' -include 'app-cvi-api' include 'app-cvi-admin' +include 'app-cvi-api' include 'cvi-publicdata-parser' include 'common-cvi' include 'domain-cvi' From 218499117dbc527ddd4846f97a09d56a5649a08b Mon Sep 17 00:00:00 2001 From: livenow14 Date: Sat, 11 Sep 2021 09:03:01 +0900 Subject: [PATCH 05/17] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/backjoongwon/cvi/CviApplication.java | 14 -- .../java/com/backjoongwon/cvi/DataLoader.java | 127 ------------------ .../java/com/backjoongwon/cvi/DummyData.java | 41 ------ backend/src/main/resources/application.yml | 73 ---------- .../src/main/resources/console-appender.xml | 7 - .../db/migration/V20210809__Create_init.sql | 92 ------------- backend/src/main/resources/ehcache.xml | 49 ------- .../main/resources/file-error-appender.xml | 18 --- .../resources/file-error-aws-appender.xml | 18 --- .../src/main/resources/file-info-appender.xml | 18 --- .../main/resources/file-info-aws-appender.xml | 18 --- .../src/main/resources/file-warn-appender.xml | 18 --- .../main/resources/file-warn-aws-appender.xml | 18 --- backend/src/main/resources/logback-spring.xml | 44 ------ backend/src/test/resources/application.yml | 40 ------ 15 files changed, 595 deletions(-) delete mode 100644 backend/src/main/java/com/backjoongwon/cvi/CviApplication.java delete mode 100644 backend/src/main/java/com/backjoongwon/cvi/DataLoader.java delete mode 100644 backend/src/main/java/com/backjoongwon/cvi/DummyData.java delete mode 100644 backend/src/main/resources/application.yml delete mode 100644 backend/src/main/resources/console-appender.xml delete mode 100644 backend/src/main/resources/db/migration/V20210809__Create_init.sql delete mode 100644 backend/src/main/resources/ehcache.xml delete mode 100644 backend/src/main/resources/file-error-appender.xml delete mode 100644 backend/src/main/resources/file-error-aws-appender.xml delete mode 100644 backend/src/main/resources/file-info-appender.xml delete mode 100644 backend/src/main/resources/file-info-aws-appender.xml delete mode 100644 backend/src/main/resources/file-warn-appender.xml delete mode 100644 backend/src/main/resources/file-warn-aws-appender.xml delete mode 100644 backend/src/main/resources/logback-spring.xml delete mode 100644 backend/src/test/resources/application.yml diff --git a/backend/src/main/java/com/backjoongwon/cvi/CviApplication.java b/backend/src/main/java/com/backjoongwon/cvi/CviApplication.java deleted file mode 100644 index c807a9b2..00000000 --- a/backend/src/main/java/com/backjoongwon/cvi/CviApplication.java +++ /dev/null @@ -1,14 +0,0 @@ -/* -package com.backjoongwon.cvi; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class CviApplication { - - public static void main(String[] args) { - SpringApplication.run(CviApplication.class, args); - } -} -*/ diff --git a/backend/src/main/java/com/backjoongwon/cvi/DataLoader.java b/backend/src/main/java/com/backjoongwon/cvi/DataLoader.java deleted file mode 100644 index c53172fc..00000000 --- a/backend/src/main/java/com/backjoongwon/cvi/DataLoader.java +++ /dev/null @@ -1,127 +0,0 @@ -/* -package com.backjoongwon.cvi; - -import com.backjoongwon.cvi.comment.domain.Comment; -import com.backjoongwon.cvi.like.domain.Like; -import com.backjoongwon.cvi.like.domain.LikeRepository; -import com.backjoongwon.cvi.post.domain.Post; -import com.backjoongwon.cvi.post.domain.PostRepository; -import com.backjoongwon.cvi.post.domain.VaccinationType; -import com.backjoongwon.cvi.user.domain.AgeRange; -import com.backjoongwon.cvi.user.domain.User; -import com.backjoongwon.cvi.user.domain.UserRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; - -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.sql.Timestamp; -import java.time.LocalDateTime; -import java.util.*; - -@Component -@RequiredArgsConstructor -@Profile("local&!test") -public class DataLoader implements CommandLineRunner { - - private static final int USER_COUNT = 50; - private static final int POST_COUNT = 300; - private final UserRepository userRepository; - private final PostRepository postRepository; - private final LikeRepository likeRepository; - private final Random random = new Random(); - - @Autowired - private final EntityManager em; - - @Override - @Transactional - public void run(String... args) { - if (userRepository.findAll().isEmpty()) { - List users = new ArrayList<>(); - for (int i = 0; i < USER_COUNT; i++) { - User user = User.builder().nickname(String.valueOf(i)).socialId("socialId").socialProvider(SocialProvider.KAKAO).profileUrl("pictureUrl").ageRange(AgeRange.FIFTIES).build(); - users.add(user); - - User updateUser = User.builder().nickname(user.getNickname()).socialId("socialId").socialProvider(SocialProvider.NAVER).profileUrl("pictureUrl").ageRange(AgeRange.FORTIES).shotVerified(true).build(); - user.update(updateUser); - } - userRepository.saveAll(users); - - List posts = new ArrayList<>(); - List allComments = new ArrayList<>(); - for (int i = 0; i < POST_COUNT; i++) { - int randomInt = random.nextInt(USER_COUNT); - User user = users.get(i % USER_COUNT); - if (randomInt % 4 == 0) { - Post post = Post.builder().content("글" + (i + 1)).vaccinationType(VaccinationType.PFIZER).user(user).build(); - List comments = putLikeAndCommentRandomly(users, USER_COUNT, post, random); - allComments.addAll(comments); - posts.add(post); - } - if (randomInt % 4 == 1) { - Post post = Post.builder().content("글" + (i + 1)).vaccinationType(VaccinationType.ASTRAZENECA).user(user).build(); - posts.add(post); - } - if (randomInt % 4 == 2) { - Post post = Post.builder().content("글" + (i + 1)).vaccinationType(VaccinationType.JANSSEN).user(user).build(); - posts.add(post); - } - if (randomInt % 4 == 3) { - Post post = Post.builder().content("글" + (i + 1)).vaccinationType(VaccinationType.MODERNA).user(user).build(); - posts.add(post); - } - } - postRepository.saveAll(posts); - - for (Post post : posts) { - Long id = post.getId(); - Query q = em.createNativeQuery("UPDATE post SET created_at=:created_at WHERE post_id=:post_id"); - q.setParameter("created_at", generateRandomLocalDateTime()); - q.setParameter("post_id", id); - q.executeUpdate(); - } - - for (Comment comment : allComments) { - Long id = comment.getId(); - Query q = em.createNativeQuery("UPDATE comment SET created_at=:created_at WHERE comment_id=:comment_id"); - q.setParameter("created_at", generateRandomLocalDateTime()); - q.setParameter("comment_id", id); - q.executeUpdate(); - } - } - } - - private List putLikeAndCommentRandomly(List users, int userCount, Post post, Random random) { - Set userSet = new HashSet<>(); - List comments = new ArrayList<>(); - - for (int j = 0; j < random.nextInt(30); j++) { - int randomUser = random.nextInt(userCount); - userSet.add(users.get(randomUser)); - } - - for (User user : userSet) { - Like like = Like.builder().user(user).build(); - post.assignLike(like); - Comment comment = Comment.builder().content("Id:" + user.getId() + " 유저의 댓글").user(user).build(); - comments.add(comment); - post.assignComment(comment); - likeRepository.save(like); - } - return comments; - } - - private Timestamp generateRandomLocalDateTime() { - int randomHour = random.nextInt(24); - int randomMins = random.nextInt(60); - int randomDays = random.nextInt(20); - LocalDateTime localDateTime = LocalDateTime.now().minusHours(randomHour).minusMinutes(randomMins).minusDays(randomDays); - return Timestamp.valueOf(localDateTime); - } -} -*/ diff --git a/backend/src/main/java/com/backjoongwon/cvi/DummyData.java b/backend/src/main/java/com/backjoongwon/cvi/DummyData.java deleted file mode 100644 index cf400e37..00000000 --- a/backend/src/main/java/com/backjoongwon/cvi/DummyData.java +++ /dev/null @@ -1,41 +0,0 @@ -/* -package com.backjoongwon.cvi; - -public class DummyData { - public static final String DUMMY_DATA_10000 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean odio orci, venenatis sed vulputate quis, ultricies non massa. Nulla commodo justo at metus consequat hendrerit. Sed nec mauris urna. Nunc turpis est, pulvinar vitae tellus non, sollicitudin commodo ligula. Nullam est ante, faucibus id leo malesuada, elementum hendrerit tortor. Sed id metus eu leo aliquet faucibus et ac felis. Aliquam nec laoreet est, interdum tempor mauris. Etiam feugiat, ante sed ullamcorper euismod, ligula lorem ultricies nisi, nec bibendum est dui eget metus. Nam ac congue libero.\n" + - "\n" + - "Pellentesque blandit risus quis consequat maximus. Donec ullamcorper facilisis ante, non luctus ex condimentum quis. Quisque pulvinar sagittis nulla at pulvinar. Nam mi urna, rutrum non erat id, dapibus ultricies tortor. Aliquam malesuada metus eu erat imperdiet pulvinar. In eget iaculis metus. Suspendisse nec orci auctor, egestas elit ut, ultrices sapien. Suspendisse tincidunt iaculis tellus id scelerisque. In non congue orci. Aliquam erat volutpat. Sed iaculis diam at justo porttitor, pulvinar tristique mauris finibus. Sed lobortis venenatis nunc sit amet cursus. Aenean mattis enim lectus, sit amet ullamcorper arcu sodales id.\n" + - "\n" + - "Quisque ornare tincidunt enim. Maecenas quis laoreet mi, in hendrerit lacus. Praesent id turpis in sapien euismod accumsan. Cras euismod sollicitudin sem nec aliquet. Aenean magna ex, luctus ut nulla id, consectetur sodales risus. Curabitur interdum elit et consectetur aliquet. Morbi non fringilla nisl.\n" + - "\n" + - "Donec neque elit, dapibus in malesuada at, convallis in dui. Donec consectetur dignissim magna, et ultrices felis finibus id. Etiam a urna lectus. Proin neque metus, iaculis eget mauris ac, congue vulputate nisl. Pellentesque sodales felis eu diam scelerisque molestie. Pellentesque commodo tempus vestibulum. Proin non quam egestas, pulvinar augue eu, hendrerit lorem. Aenean vel mollis nisi, sit amet scelerisque dolor. Vestibulum feugiat eleifend tellus, ac auctor ex ultricies ut. Aenean volutpat vulputate risus a euismod. Nulla tincidunt massa pulvinar dapibus pharetra. Curabitur a blandit lectus, vel posuere purus. Ut erat diam, bibendum vitae luctus quis, sollicitudin eget magna. Phasellus dignissim in odio feugiat blandit. Etiam porta sollicitudin massa sit amet auctor. Suspendisse rutrum pellentesque fermentum.\n" + - "\n" + - "Maecenas non faucibus lorem, eget tempor sapien. Pellentesque ac augue id justo malesuada blandit. In auctor varius scelerisque. Nunc cursus id elit et facilisis. Aenean in egestas erat. Nullam eleifend vitae diam at vehicula. Suspendisse ut diam at elit mollis accumsan. Nulla facilisi.\n" + - "\n" + - "Etiam vel elit a lorem efficitur ullamcorper id laoreet neque. Pellentesque nec imperdiet urna. Vestibulum sodales ante ac justo rutrum, id tempus nulla tincidunt. Aenean accumsan posuere enim eu vestibulum. Donec ex metus, molestie ac enim a, ultrices dapibus ipsum. Pellentesque neque quam, lobortis a lacus sed, molestie finibus urna. Curabitur a dolor quis ante malesuada blandit.\n" + - "\n" + - "Aliquam in massa ac odio mollis malesuada vel et diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam placerat feugiat elit eget iaculis. Cras arcu arcu, suscipit ac mi eu, pharetra pulvinar diam. Praesent tincidunt, lorem id auctor mollis, mi ipsum rhoncus mauris, vel placerat elit massa quis leo. Curabitur et mi fringilla quam blandit pulvinar. Nunc enim sem, maximus vitae sem at, posuere euismod risus. Duis euismod ullamcorper sem eget semper. Curabitur et neque vitae neque euismod pharetra. Curabitur vel mi accumsan, facilisis neque nec, consequat lectus. Mauris tristique velit vitae congue consequat. Donec sit amet tortor sed ante congue bibendum a cursus libero.\n" + - "\n" + - "Praesent tristique eget neque quis bibendum. Donec quis ante sed orci varius maximus. Praesent gravida in massa nec tincidunt. Nulla facilisi. Praesent magna enim, placerat eu libero id, hendrerit malesuada diam. Fusce vestibulum nulla ut erat elementum iaculis. Fusce eu posuere purus. Quisque efficitur rutrum metus quis vestibulum.\n" + - "\n" + - "Fusce vitae semper orci. Quisque eu urna lobortis, auctor magna quis, pellentesque sem. Etiam vitae vehicula dolor, sit amet pretium nulla. Ut efficitur pretium augue in luctus. Vestibulum in odio a diam tristique efficitur. Nulla egestas quis risus at imperdiet. Maecenas eget bibendum nisi, eu faucibus odio.\n" + - "\n" + - "Vestibulum porttitor a nulla a varius. Pellentesque nec lacinia nunc, nec elementum est. Vivamus commodo tortor et velit euismod blandit. Maecenas luctus pharetra velit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque vulputate leo at nisi rutrum mattis. Pellentesque luctus malesuada turpis. Duis non erat quis eros hendrerit accumsan.\n" + - "\n" + - "Vivamus placerat, mi vitae fermentum pulvinar, massa lacus commodo tellus, in elementum neque purus elementum odio. Donec auctor volutpat finibus. Cras feugiat eu ipsum eu tincidunt. Sed non tortor ultrices, cursus sapien in, euismod nibh. Nunc interdum viverra dignissim. Nunc finibus finibus fermentum. Proin faucibus blandit lorem, nec pretium quam fermentum nec. In id euismod nisi, eu euismod tellus. Nulla interdum, arcu id vehicula viverra, lacus velit pellentesque sapien, sit amet sollicitudin erat metus in augue. Proin in congue dui. Aenean pharetra odio nec ornare suscipit. Nunc et libero magna. In ut quam ante.\n" + - "\n" + - "Fusce dignissim scelerisque neque ut tincidunt. Quisque ut lacinia metus, ut luctus lacus. Vivamus et dictum metus, et cursus libero. Phasellus turpis libero, hendrerit a mollis ac, semper feugiat urna. Nullam id sagittis quam, eu facilisis enim. Maecenas in tortor lacinia, aliquet felis non, congue leo. Proin enim massa, malesuada interdum tempus eget, venenatis id tellus. Etiam ultricies, lacus quis egestas pulvinar, ipsum nibh luctus nisl, sed interdum felis leo eu leo. Mauris faucibus semper nisi at rhoncus. Quisque vel venenatis nisi. Ut consectetur mauris nec magna lacinia fringilla. Nullam luctus fermentum odio. Donec ultricies augue sed dui elementum, sed euismod nibh laoreet. Maecenas condimentum sapien at faucibus mattis. Pellentesque porttitor sed tortor et faucibus. Aliquam sed quam eget lacus aliquam molestie sit amet at urna.\n" + - "\n" + - "Curabitur eget metus interdum diam volutpat efficitur. Maecenas viverra massa in est volutpat, eu convallis nisi eleifend. Sed molestie sagittis mauris. Quisque id arcu vitae lorem tristique pretium. Mauris cursus ex dolor, nec malesuada urna iaculis sit amet. Mauris pharetra magna eget sapien varius aliquet. Maecenas pulvinar orci non condimentum dictum. Maecenas faucibus rutrum arcu, nec aliquet elit dignissim ut. Integer ullamcorper massa eu lectus malesuada rutrum. Vestibulum maximus euismod ante, a euismod augue dapibus non. Praesent tellus orci, tempus quis dignissim id, ultricies porta felis. Maecenas ut ipsum dolor.\n" + - "\n" + - "Mauris pulvinar nisi et lorem elementum tristique. Vestibulum tempus, nunc id dictum condimentum, felis nisl dapibus sem, sit amet commodo metus tortor ut dui. Suspendisse viverra urna efficitur massa pellentesque mattis. Sed posuere, urna mollis bibendum ornare, felis dui congue nibh, sed placerat velit tellus vitae tellus. Cras maximus blandit diam nec feugiat. Nunc bibendum erat vitae libero lobortis pulvinar. In ut aliquam orci. Donec feugiat, ex congue pretium dictum, justo enim feugiat risus, malesuada ornare purus diam quis turpis. Phasellus vitae est id turpis consectetur semper. Quisque vel euismod justo, molestie vestibulum leo. Donec nibh nunc, rutrum ut diam ut, tincidunt bibendum est. Donec tristique dolor et interdum mollis. Aliquam a mi nulla.\n" + - "\n" + - "Morbi hendrerit sagittis nulla quis porta. Phasellus vitae vehicula sem, non mollis lorem. Donec mollis vestibulum nunc, vitae laoreet neque consectetur eget. Sed varius urna et urna porttitor, eu imperdiet velit sollicitudin. Nulla dolor dui, imperdiet at facilisis eget, scelerisque sed nisi. Integer maximus congue viverra. Ut mattis faucibus fermentum. Donec malesuada mattis sollicitudin. Maecenas vel est fringilla, elementum lectus et, rutrum mauris. Sed non viverra purus, ut finibus felis. Nunc ac fermentum tortor, non faucibus mauris.\n" + - "\n" + - "Aliquam erat volutpat. Etiam nulla erat, pretium id enim quis, hendrerit congue ligula. Sed vitae accumsan sem. Praesent ligula turpis, bibendum vitae nulla ut, efficitur commodo erat. Vestibulum odio nibh, convallis id ligula eget, pretium condimentum erat. Nam molestie tortor nec nibh ornare, at ultricies massa molestie. Aenean sodales dolor risus, sed fringilla purus interdum accumsan. In hac habitasse platea dictumst. In sit amet nisl nec leo sagittis tincidunt. Pellentesque at ligula at sapien suscipit facilisis. Sed nec feugiat neque. Sed eu neque lectus. Nullam sed magna ac mi pretium tristique. Integer at velit erat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris efficitur nisl eget metus porta, ut tincidunt felis ultricies.\n" + - "\n" + - "Nullam sit amet maximus lacus. Suspendisse elit erat, vestibulum vel magna mollis, iaculis hendrerit eros. Praesent quis eros sed lorem faucibus feugiat vitae non sapien. Aliquam non mi sed dolor accumsan finibus id in odio. Nunc a placerat mauris. In hac habitasse platea dictumst. Curabitur quis diam facilisis, vulputate ligula nec, auctor mauris. Suspendisse potenti. Duis tempor neque diam, vel ornare metus fringilla quis. Proin a odio non nisi egestas blandit. Vestibulum sit amet leo odio. Nulla quis quam vel mauris eleifend dapibus et sed sapien. Suspendisse cursus porta augue, sed scelerisque libero faucibus quis. Vestibulum ipsum sem, pulvinar id tellus a, tincidunt cursus velit. Pellentesque tristique interdum est, nec sollicitudin justo efficitur quis.\n" + - "\n" + - "Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed tellus nulla, fringilla ut tortor ut, pellentesque faucibus dui. Donec posuere risus ut enim fermentum tristique. Nullam a erat nec massa rutrum bibendum. Duis rutrum porttitor massa nunc."; -} -*/ diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml deleted file mode 100644 index cc83de91..00000000 --- a/backend/src/main/resources/application.yml +++ /dev/null @@ -1,73 +0,0 @@ -spring: - jpa: - properties: - hibernate.default_batch_fetch_size: 500 - h2: - console: - enabled: false - flyway: - enabled: false - - cache: - jcache: - config: classpath:ehcache.xml - -security: - jwt: - token: - secret-key: cvi_secret_key - expire-length: 3600000 - - auth: - naver: - client-secret: client-secret - - public: - data: - vaccination: publicdata-secret - -server: - shutdown: graceful ---- -spring: - config: - activate: - on-profile: local - - datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE; - username: sa - password: - - h2: - console: - enabled: true - - jpa: - hibernate: - ddl-auto: create-drop - properties: - hibernate: - format_sql: true - generate-ddl: true - -logging: - level: - org.hibernate.SQL: debug ---- -spring: - config: - activate: - on-profile: deploy1 - -server: - port: 8081 ---- -spring: - config: - activate: - on-profile: deploy2 - -server: - port: 8082 diff --git a/backend/src/main/resources/console-appender.xml b/backend/src/main/resources/console-appender.xml deleted file mode 100644 index 48ec4fcb..00000000 --- a/backend/src/main/resources/console-appender.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - ${LOG_PATTERN} - - - diff --git a/backend/src/main/resources/db/migration/V20210809__Create_init.sql b/backend/src/main/resources/db/migration/V20210809__Create_init.sql deleted file mode 100644 index 85fb995d..00000000 --- a/backend/src/main/resources/db/migration/V20210809__Create_init.sql +++ /dev/null @@ -1,92 +0,0 @@ -drop table if exists comment CASCADE; -drop table if exists likes CASCADE; -drop table if exists post CASCADE; -drop table if exists user CASCADE; -drop table if exists vaccination_statistic; -drop table if exists public_data; - -create table comment -( - comment_id bigint auto_increment not null, - created_at timestamp default CURRENT_TIMESTAMP, - last_modified_at timestamp default CURRENT_TIMESTAMP, - post_id bigint, - user_id bigint, - content text, - primary key (comment_id) -); - -create table likes -( - likes_id bigint auto_increment not null, - created_at timestamp default CURRENT_TIMESTAMP, - last_modified_at timestamp default CURRENT_TIMESTAMP, - post_id bigint, - user_id bigint, - primary key (likes_id) -); - -create table user -( - user_id bigint auto_increment not null, - created_at timestamp default CURRENT_TIMESTAMP, - last_modified_at timestamp default CURRENT_TIMESTAMP, - nickname varchar(255), - age_range varchar(255), - shot_verified boolean not null default false, - social_provider varchar(255), - social_id varchar(255), - profile_url varchar(255), - primary key (user_id), - unique (nickname) -); - -create table post -( - post_id bigint auto_increment not null, - created_at timestamp default CURRENT_TIMESTAMP, - last_modified_at timestamp default CURRENT_TIMESTAMP, - user_id bigint, - content text, - view_count integer not null default 0, - vaccination_type varchar(255), - primary key (post_id) -); - -create table public_data -( - public_data_type varchar(31) not null, - public_data_id bigint auto_increment not null, - created_at timestamp default CURRENT_TIMESTAMP, - last_modified_at timestamp default CURRENT_TIMESTAMP, - region_population varchar(255), - primary key (public_data_id) -); - -create table vaccination_statistic -( - accumulated_first_cnt bigint, - accumulated_second_cnt bigint, - base_date date, - first_cnt bigint, - second_cnt bigint, - total_first_cnt bigint, - total_first_rate decimal(19, 1), - total_second_cnt bigint, - total_second_rate decimal(19, 1), - vaccination_statistic_id bigint not null, - primary key (vaccination_statistic_id) -); - -alter table comment - add constraint fk_comment_post foreign key (post_id) references post (post_id) on delete cascade; -alter table comment - add constraint fk_comment_user foreign key (user_id) references user (user_id) on delete cascade; -alter table likes - add constraint fk_likes_post foreign key (post_id) references post (post_id) on delete cascade; -alter table likes - add constraint fk_likes_user foreign key (user_id) references user (user_id) on delete cascade; -alter table post - add constraint fk_post_user foreign key (user_id) references user (user_id) on delete cascade; -alter table vaccination_statistic - add constraint fk_vaccination_statistic_public_data foreign key (vaccination_statistic_id) references public_data (public_data_id); diff --git a/backend/src/main/resources/ehcache.xml b/backend/src/main/resources/ehcache.xml deleted file mode 100644 index 4536b906..00000000 --- a/backend/src/main/resources/ehcache.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - com.backjoongwon.cvi.common.cache.CacheEventLogger - ASYNCHRONOUS - UNORDERED - CREATED - EVICTED - REMOVED - UPDATED - EXPIRED - - - - - - java.lang.String - java.util.ArrayList - - - 1 - - - - 100 - - - - - java.lang.String - java.util.ArrayList - - - 1 - - - - 100 - - - diff --git a/backend/src/main/resources/file-error-appender.xml b/backend/src/main/resources/file-error-appender.xml deleted file mode 100644 index e29b5b53..00000000 --- a/backend/src/main/resources/file-error-appender.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - ${LOG_LOCATION}/${ERROR_LOCATION}/error-${BY_DATE}.log - - ERROR - ACCEPT - DENY - - - ${LOG_PATTERN} - - - ${BACKUP_LOCATION}/${ERROR_LOCATION}/error-%d{yyyy-MM-dd}.%i.log - ${MAX_FILE_SIZE} - ${MAX_HISTORY} - - - \ No newline at end of file diff --git a/backend/src/main/resources/file-error-aws-appender.xml b/backend/src/main/resources/file-error-aws-appender.xml deleted file mode 100644 index 565df06d..00000000 --- a/backend/src/main/resources/file-error-aws-appender.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - ${LOG_LOCATION}/${AWS_LOCATION}/${ERROR_LOCATION}/error-${BY_DATE}.log - - ERROR - ACCEPT - DENY - - - ${LOG_PATTERN_AWS} - - - ${BACKUP_LOCATION}/${AWS_LOCATION}/${ERROR_LOCATION}/error-%d{yyyy-MM-dd}.%i.log - ${MAX_FILE_SIZE} - ${MAX_HISTORY} - - - diff --git a/backend/src/main/resources/file-info-appender.xml b/backend/src/main/resources/file-info-appender.xml deleted file mode 100644 index 0bbd3c78..00000000 --- a/backend/src/main/resources/file-info-appender.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - ${LOG_LOCATION}/${INFO_LOCATION}/info-${BY_DATE}.log - - INFO - ACCEPT - DENY - - - ${LOG_PATTERN} - - - ${BACKUP_LOCATION}/${INFO_LOCATION}/info-%d{yyyy-MM-dd}.%i.log - ${MAX_FILE_SIZE} - ${MAX_HISTORY} - - - \ No newline at end of file diff --git a/backend/src/main/resources/file-info-aws-appender.xml b/backend/src/main/resources/file-info-aws-appender.xml deleted file mode 100644 index 59a82d09..00000000 --- a/backend/src/main/resources/file-info-aws-appender.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - ${LOG_LOCATION}/${AWS_LOCATION}/${INFO_LOCATION}/info-${BY_DATE}.log - - INFO - ACCEPT - DENY - - - ${LOG_PATTERN_AWS} - - - ${BACKUP_LOCATION}/${AWS_LOCATION}/${INFO_LOCATION}/info-%d{yyyy-MM-dd}.%i.log - ${MAX_FILE_SIZE} - ${MAX_HISTORY} - - - diff --git a/backend/src/main/resources/file-warn-appender.xml b/backend/src/main/resources/file-warn-appender.xml deleted file mode 100644 index 2e2e8763..00000000 --- a/backend/src/main/resources/file-warn-appender.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - ${LOG_LOCATION}/${WARN_LOCATION}/warn-${BY_DATE}.log - - WARN - ACCEPT - DENY - - - ${LOG_PATTERN} - - - ${BACKUP_LOCATION}/${WARN_LOCATION}/warn-%d{yyyy-MM-dd}.%i.log - ${MAX_FILE_SIZE} - ${MAX_HISTORY} - - - diff --git a/backend/src/main/resources/file-warn-aws-appender.xml b/backend/src/main/resources/file-warn-aws-appender.xml deleted file mode 100644 index 05f6fea7..00000000 --- a/backend/src/main/resources/file-warn-aws-appender.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - ${LOG_LOCATION}/${AWS_LOCATION}/${WARN_LOCATION}/warn-${BY_DATE}.log - - WARN - ACCEPT - DENY - - - ${LOG_PATTERN_AWS} - - - ${BACKUP_LOCATION}/${AWS_LOCATION}/${WARN_LOCATION}/warn-%d{yyyy-MM-dd}.%i.log - ${MAX_FILE_SIZE} - ${MAX_HISTORY} - - - diff --git a/backend/src/main/resources/logback-spring.xml b/backend/src/main/resources/logback-spring.xml deleted file mode 100644 index 5f02a2de..00000000 --- a/backend/src/main/resources/logback-spring.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/backend/src/test/resources/application.yml b/backend/src/test/resources/application.yml deleted file mode 100644 index feb18114..00000000 --- a/backend/src/test/resources/application.yml +++ /dev/null @@ -1,40 +0,0 @@ -spring: - profiles: - active: test - - datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE; - username: sa - password: - - h2: - console: - enabled: true - - jpa: - hibernate: - ddl-auto: create-drop - properties: - hibernate: - format_sql: true - generate-ddl: true - -security: - jwt: - token: - secret-key: cvi_secret_key - expire-length: 3600000 - - auth: - naver: - client-secret: client-secret - - public: - data: - vaccination: bRU9Gbs0x/64WQS6gH05wpOxkM+X0GY0bXrUKRpW/072Bu6hlrJIqGVv6JC/uEz4mt4EC1l+l/8rxmz3ShAAAw== - -logging: - level: - org.hibernate.SQL: debug - org.hibernate.type: trace From 0d01c7064f79ab487f4ee1ba7515b1e46728c09d Mon Sep 17 00:00:00 2001 From: livenow14 Date: Sat, 11 Sep 2021 09:05:52 +0900 Subject: [PATCH 06/17] =?UTF-8?q?feat:=20=EB=AA=A8=EB=93=88=EB=B3=84=20?= =?UTF-8?q?=EC=97=AD=ED=95=A0=20=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app-cvi-api/README.md | 12 ++++++++++++ backend/build.gradle | 3 --- backend/common-cvi/README.md | 7 +++++++ backend/cvi-publicdata-parser/README.md | 7 +++++++ backend/domain-cvi-oauth-service/README.md | 6 ++++++ backend/domain-cvi-publicdata-service/README.md | 8 ++++++++ backend/domain-cvi-scheduler/README.md | 6 ++++++ backend/domain-cvi/README.md | 8 ++++++++ 8 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 backend/app-cvi-api/README.md create mode 100644 backend/common-cvi/README.md create mode 100644 backend/cvi-publicdata-parser/README.md create mode 100644 backend/domain-cvi-oauth-service/README.md create mode 100644 backend/domain-cvi-publicdata-service/README.md create mode 100644 backend/domain-cvi-scheduler/README.md create mode 100644 backend/domain-cvi/README.md diff --git a/backend/app-cvi-api/README.md b/backend/app-cvi-api/README.md new file mode 100644 index 00000000..cf6042e6 --- /dev/null +++ b/backend/app-cvi-api/README.md @@ -0,0 +1,12 @@ +# app-cvi-api +## 모듈 설명 +- 사용자가 사용할 수 있는 기능을 제공하는 `애플리케이션 모듈`이에요. +- Controller, View의 책임을 가지고 있어요. +- 의존하는 모듈의 비즈니스 흐름 제어를 담당해요. + +## 의존 모듈 +- `common-cvi`: 예외 응답 객체를 사용해요. +- `domain-cvi`: Model에 CRUD 작업을 위임해요. +- `domain-cvi-oauth-service`: 소셜 로그인 요청에 대한 서비스를 위임해요. +- `domain-cvi-publicdata-service`: 공공 데이터 요청에 대한 서비스를 위임해요. +- `domain-cvi-scheduler`: 일정 기간마다 수행되어야 하는 작업을 위임해요. \ No newline at end of file diff --git a/backend/build.gradle b/backend/build.gradle index ad0fffa6..3bff358e 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -112,7 +112,6 @@ configure(queryDslProjects){ } } - def asciidoctorConfigureProjects = [project(':app-cvi-api')] configure(asciidoctorConfigureProjects){ apply plugin: "org.asciidoctor.convert" @@ -143,5 +142,3 @@ configure(asciidoctorConfigureProjects){ } } } - -project(':domain-cvi-scheduler') \ No newline at end of file diff --git a/backend/common-cvi/README.md b/backend/common-cvi/README.md new file mode 100644 index 00000000..f397aaec --- /dev/null +++ b/backend/common-cvi/README.md @@ -0,0 +1,7 @@ +# common-cvi +## 모듈 설명 +- 공통적으로 사용하는 예외 객체를 제공하는 `독립 모듈`이에요 +- 커스텀 예외, Util성 클래스가 이 모듈에 속해요. + +## 의존 모듈 +- 없음 \ No newline at end of file diff --git a/backend/cvi-publicdata-parser/README.md b/backend/cvi-publicdata-parser/README.md new file mode 100644 index 00000000..bcce0896 --- /dev/null +++ b/backend/cvi-publicdata-parser/README.md @@ -0,0 +1,7 @@ +# cvi-publicdate-parser +## 모듈 설명 +- 백신 현황 공공데이터를 제공하는 API 서비스에, Http요청을 보내, 응답 받은 Json값을 매핑하는 모듈이에요. +- 스프링 의존성이 아닌, 자바에서 제공하는 URL Connection을 이용해요. + +## 의존 모듈 +- 없음 diff --git a/backend/domain-cvi-oauth-service/README.md b/backend/domain-cvi-oauth-service/README.md new file mode 100644 index 00000000..1a8e8f73 --- /dev/null +++ b/backend/domain-cvi-oauth-service/README.md @@ -0,0 +1,6 @@ +# domain-cvi-oauth-service +## 모듈 설명 +- 소셜 로그인 서비스에 사용자 데이터를 요청하는 모듈이에요. + +## 의존 모듈 +- `domain-cvi`: Model에 CR 작업을 위임해요. diff --git a/backend/domain-cvi-publicdata-service/README.md b/backend/domain-cvi-publicdata-service/README.md new file mode 100644 index 00000000..850ac253 --- /dev/null +++ b/backend/domain-cvi-publicdata-service/README.md @@ -0,0 +1,8 @@ +# domain-cvi-publicdata-service +## 모듈 설명 +- 공공데이터와 관련된 조회와 저장의 비즈니스 흐름을 담당해요. +- 조회에 대하여 캐싱을 사용했어요. + +## 의존 모듈 +- `domain-cvi`: Model에 CR 작업을 위임해요. +- `cvi-publicdata-parser`: PublicData Api 요청을 위임해요. diff --git a/backend/domain-cvi-scheduler/README.md b/backend/domain-cvi-scheduler/README.md new file mode 100644 index 00000000..8e57909a --- /dev/null +++ b/backend/domain-cvi-scheduler/README.md @@ -0,0 +1,6 @@ +# domain-cvi-scheduler +## 모듈 설명 +- 정해진 시간 마다, 로직을 실행하는 모듈이에요. + +## 의존 모듈 +- `domain-cvi-publicdata-service`: 공공데이터의 저장 책임을 위임해요. diff --git a/backend/domain-cvi/README.md b/backend/domain-cvi/README.md new file mode 100644 index 00000000..99b32230 --- /dev/null +++ b/backend/domain-cvi/README.md @@ -0,0 +1,8 @@ +# domain-cvi +## 모듈 설명 +- 비즈니스 로직을 수행하는 `도메인 모듈`이에요. +- 하나의 인프라스트럭쳐(DBMS)을 가지며 CRUD를 수행해요. +- Model의 책임을 지니고 있어요. + +## 의존 모듈 +- `common-cvi`: 예외 응답 객체를 사용해요. From 8849f44c3d5b2710174c5bf038d75ca73ad16327 Mon Sep 17 00:00:00 2001 From: HyuuunjuKim Date: Mon, 27 Sep 2021 14:54:02 +0900 Subject: [PATCH 07/17] =?UTF-8?q?chore:=20=ED=8C=8C=EB=B9=84=EC=BD=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/public/favicon.svg | 5 +++++ frontend/public/index.html | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 frontend/public/favicon.svg diff --git a/frontend/public/favicon.svg b/frontend/public/favicon.svg new file mode 100644 index 00000000..28ffb9a3 --- /dev/null +++ b/frontend/public/favicon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/public/index.html b/frontend/public/index.html index 9b5051fb..f81d1d0c 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -5,7 +5,7 @@ - + Date: Tue, 28 Sep 2021 14:26:00 +0900 Subject: [PATCH 08/17] feat: cvi-backend-secret update --- backend/cvi-backend-secret | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/cvi-backend-secret b/backend/cvi-backend-secret index 8f89d87e..291887a9 160000 --- a/backend/cvi-backend-secret +++ b/backend/cvi-backend-secret @@ -1 +1 @@ -Subproject commit 8f89d87e6f275ac1c8c26e8bc9c29965f1e855f7 +Subproject commit 291887a9e79e94d6fe6aecb69da3f60f7a426867 From 21ed4507ca91eab995a70a140676fe4dc4066d68 Mon Sep 17 00:00:00 2001 From: KIM TAE HEE Date: Tue, 28 Sep 2021 15:42:04 +0900 Subject: [PATCH 09/17] =?UTF-8?q?refactor:=20domain=20=EB=AA=A8=EB=93=88?= =?UTF-8?q?=20=EC=B5=9C=EC=8B=A0=20=EC=BD=94=EB=93=9C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain-cvi-aws-s3-service/build.gradle | 45 ++++ .../main/java/com/cvi/config/AwsS3Config.java | 19 ++ .../java/com/cvi/uploader/AwsS3Uploader.java | 41 ++++ .../main/java/com/cvi/image/domain/Image.java | 59 +++++ .../java/com/cvi/image/domain/ImageType.java | 8 + .../cvi/image/repository/ImageRepository.java | 7 + .../com/cvi/post/domain/model/Comments.java | 6 +- .../com/cvi/post/domain/model/Images.java | 65 ++++++ .../java/com/cvi/post/domain/model/Likes.java | 10 +- .../java/com/cvi/post/domain/model/Post.java | 56 ++++- .../java/com/cvi/post/domain/model/Sort.java | 17 +- .../domain/repository/PostRepositoryImpl.java | 69 +++--- .../publicdata/domain/model/PublicData.java | 2 +- .../domain/model/RegionPopulation.java | 5 +- .../domain/model/VaccinationStatistic.java | 6 +- .../domain/model/VaccinationStatistics.java | 32 +-- .../java/com/cvi/user/domain/model/User.java | 26 ++- ...tralVaccinationInformationApplication.java | 7 + .../cvi/comment/domain/model/CommentTest.java | 53 +++-- .../com/cvi/like/domain/model/LikeTest.java | 35 ++- .../com/cvi/post/domain/model/PostTest.java | 119 +++++----- .../domain/repository/PostRepositoryTest.java | 214 ++++++++++++++++++ .../model/VaccinationStatisticFactory.java | 62 +++++ .../model/VaccinationStatisticTest.java | 7 +- .../model/VaccinationStatisticsTest.java | 83 +++++++ .../com/cvi/user/domain/model/UserTest.java | 39 ++-- backend/settings.gradle | 1 + 27 files changed, 872 insertions(+), 221 deletions(-) create mode 100644 backend/domain-cvi-aws-s3-service/build.gradle create mode 100644 backend/domain-cvi-aws-s3-service/src/main/java/com/cvi/config/AwsS3Config.java create mode 100644 backend/domain-cvi-aws-s3-service/src/main/java/com/cvi/uploader/AwsS3Uploader.java create mode 100644 backend/domain-cvi/src/main/java/com/cvi/image/domain/Image.java create mode 100644 backend/domain-cvi/src/main/java/com/cvi/image/domain/ImageType.java create mode 100644 backend/domain-cvi/src/main/java/com/cvi/image/repository/ImageRepository.java create mode 100644 backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Images.java create mode 100644 backend/domain-cvi/src/test/java/com/cvi/CentralVaccinationInformationApplication.java create mode 100644 backend/domain-cvi/src/test/java/com/cvi/post/domain/repository/PostRepositoryTest.java create mode 100644 backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticFactory.java create mode 100644 backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticsTest.java diff --git a/backend/domain-cvi-aws-s3-service/build.gradle b/backend/domain-cvi-aws-s3-service/build.gradle new file mode 100644 index 00000000..e0da629f --- /dev/null +++ b/backend/domain-cvi-aws-s3-service/build.gradle @@ -0,0 +1,45 @@ +bootJar { enabled = false } +jar { enabled = true } + +dependencies { + implementation project(path:':domain-cvi', configuration: 'default') + // implementation 'org.springframework.boot:spring-boot-starter-web' + // aws s3 + implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' +} + +jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 + def Qdomains = [] + + for (qPattern in "*.QA".."*.QZ") { + Qdomains.add(qPattern + "*") + } + + violationRules { // 위반 규칙 + rule { + enabled = true + element = 'BUNDLE' + + limit { + counter = 'INSTRUCTION' + value = 'COVEREDRATIO' + minimum = 0.85 + } + + excludes = [ + // 커버리지 제외할 클래스 + '*.DataLoader*', + '*.CviApplication*', + '*.DummyData*', + '*.KakaoProfile*', + '*.NaverProfile*' + ] + Qdomains + } + } +} + +sonarqube { + properties { + property "sonar.exclusions", "**/*Test*.*, **/Q*.java, **/*Doc*.java" + } +} \ No newline at end of file diff --git a/backend/domain-cvi-aws-s3-service/src/main/java/com/cvi/config/AwsS3Config.java b/backend/domain-cvi-aws-s3-service/src/main/java/com/cvi/config/AwsS3Config.java new file mode 100644 index 00000000..7e51069b --- /dev/null +++ b/backend/domain-cvi-aws-s3-service/src/main/java/com/cvi/config/AwsS3Config.java @@ -0,0 +1,19 @@ +package com.cvi.config; + +import com.amazonaws.regions.Regions; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AwsS3Config { + + @Bean + public AmazonS3 amazonS3Client() { + return AmazonS3ClientBuilder + .standard() + .withRegion(Regions.AP_NORTHEAST_2) + .build(); + } +} diff --git a/backend/domain-cvi-aws-s3-service/src/main/java/com/cvi/uploader/AwsS3Uploader.java b/backend/domain-cvi-aws-s3-service/src/main/java/com/cvi/uploader/AwsS3Uploader.java new file mode 100644 index 00000000..229325c0 --- /dev/null +++ b/backend/domain-cvi-aws-s3-service/src/main/java/com/cvi/uploader/AwsS3Uploader.java @@ -0,0 +1,41 @@ +package com.cvi.uploader; + +import com.amazonaws.AmazonServiceException; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.DeleteObjectRequest; +import com.amazonaws.services.s3.model.PutObjectRequest; +import java.io.File; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Slf4j +@RequiredArgsConstructor +@Component +public class AwsS3Uploader { + + private final AmazonS3 amazonS3; + + @Value("${aws.s3.bucket_name}") + private String s3BucketName; + @Value("${aws.cloudfront.url}") + private String cloudFrontUrl; + + public String upload(String s3DirPath, File file) { + final PutObjectRequest putObjectRequest = new PutObjectRequest(s3BucketName, s3DirPath + file.getName(), file); + amazonS3.putObject(putObjectRequest); + return cloudFrontUrl + "/" + s3DirPath + file.getName(); + } + + public void delete(String s3DirPath, String fileName) { + try { + log.debug("S3에서 삭제할 이미지 경로: {}", s3DirPath + fileName); + final DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest(s3BucketName, s3DirPath + fileName); + amazonS3.deleteObject(deleteObjectRequest); + log.debug("S3의 {} 파일 삭제 성공", s3DirPath + fileName); + } catch (AmazonServiceException e) { + log.info("S3의 {} 파일 삭제 실패", s3DirPath + fileName); + } + } +} diff --git a/backend/domain-cvi/src/main/java/com/cvi/image/domain/Image.java b/backend/domain-cvi/src/main/java/com/cvi/image/domain/Image.java new file mode 100644 index 00000000..4b65c7f3 --- /dev/null +++ b/backend/domain-cvi/src/main/java/com/cvi/image/domain/Image.java @@ -0,0 +1,59 @@ +package com.cvi.image.domain; + + +import com.cvi.config.entity.BaseEntity; +import com.cvi.exception.NotFoundException; +import com.cvi.post.domain.model.Post; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.Objects; +import javax.persistence.AttributeOverride; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AttributeOverride(name = "id", column = @Column(name = "image_id")) +public class Image extends BaseEntity { + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id", foreignKey = @ForeignKey(name = "fk_image_post")) + private Post post; + + private String url; + + @Builder + public Image(Long id, LocalDateTime createdAt, LocalDateTime lastModifiedAt, String url) { + super(id, createdAt, lastModifiedAt); + this.url = url; + } + + public void assignPost(Post post) { + if (Objects.isNull(post)) { + throw new NotFoundException("이미지에 할당하려는 게시글이 없습니다."); + } + if (Objects.nonNull(this.post)) { + return; + } + this.post = post; + post.assignImages(Collections.singletonList(this)); + } + + public boolean isSameAs(Long id) { + return this.id.equals(id); + } + + public String getName() { + final String[] splitUrl = url.split("/"); + return splitUrl[splitUrl.length - 1]; + } +} diff --git a/backend/domain-cvi/src/main/java/com/cvi/image/domain/ImageType.java b/backend/domain-cvi/src/main/java/com/cvi/image/domain/ImageType.java new file mode 100644 index 00000000..59742794 --- /dev/null +++ b/backend/domain-cvi/src/main/java/com/cvi/image/domain/ImageType.java @@ -0,0 +1,8 @@ +package com.cvi.image.domain; + +import lombok.Getter; + +@Getter +public enum ImageType { + JPG, JPEG, PNG, SVG +} diff --git a/backend/domain-cvi/src/main/java/com/cvi/image/repository/ImageRepository.java b/backend/domain-cvi/src/main/java/com/cvi/image/repository/ImageRepository.java new file mode 100644 index 00000000..229a4e5f --- /dev/null +++ b/backend/domain-cvi/src/main/java/com/cvi/image/repository/ImageRepository.java @@ -0,0 +1,7 @@ +package com.cvi.image.repository; + +import com.cvi.image.domain.Image; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ImageRepository extends JpaRepository { +} diff --git a/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Comments.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Comments.java index 52696297..e240eae6 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Comments.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Comments.java @@ -54,8 +54,8 @@ public List getComments() { private Comment findById(Long commentId) { return comments.stream() - .filter(comment -> comment.isSameAs(commentId)) - .findAny() - .orElseThrow(() -> new NotFoundException("찾을 수 없는 댓글입니다.")); + .filter(comment -> comment.isSameAs(commentId)) + .findAny() + .orElseThrow(() -> new NotFoundException("찾을 수 없는 댓글입니다.")); } } diff --git a/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Images.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Images.java new file mode 100644 index 00000000..2de7038c --- /dev/null +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Images.java @@ -0,0 +1,65 @@ +package com.cvi.post.domain.model; + +import com.cvi.exception.NotFoundException; +import com.cvi.image.domain.Image; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import javax.persistence.Embeddable; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Embeddable +public class Images { + + @OrderBy("createdAt asc") + @OneToMany(mappedBy = "post") + private final List images = new ArrayList<>(); + + public void addAll(List images, Post post) { + if (images.isEmpty()) { + throw new NotFoundException("추가하려는 이미지 리스트가 비어있습니다."); + } + addImages(images, post); + } + + private void addImages(List images, Post post) { + for (Image image : images) { + image.assignPost(post); + addImage(image); + } + } + + private void addImage(Image image) { + if (!images.contains(image)) { + images.add(image); + } + } + + public void delete(Long imageId) { + final Image foundImage = findById(imageId); + images.remove(foundImage); + } + + private Image findById(Long imageId) { + return images.stream() + .filter(image -> image.isSameAs(imageId)) + .findAny() + .orElseThrow(() -> new NotFoundException("찾을 수 없는 이미지 입니다.")); + } + + public int size() { + return images.size(); + } + + public List getS3PathsOfAllImages() { + return images.stream() + .map(Image::getName) + .collect(Collectors.toList()); + } +} diff --git a/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Likes.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Likes.java index 3def5e99..1652181e 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Likes.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Likes.java @@ -26,9 +26,9 @@ public class Likes { private Like findLikeByUserId(Long userId) { return likes.stream() - .filter(like -> like.isSameUser(userId)) - .findAny() - .orElseThrow(() -> new UnAuthorizedException("해당 사용자의 좋아요가 글에 존재하지 않습니다.")); + .filter(like -> like.isSameUser(userId)) + .findAny() + .orElseThrow(() -> new UnAuthorizedException("해당 사용자의 좋아요가 글에 존재하지 않습니다.")); } public void delete(Long userId) { @@ -55,7 +55,7 @@ public void validateNotExistsLikeCreatedBy(User user) { public boolean isAlreadyLikedBy(Long userId) { return likes.stream() - .anyMatch(like -> like.isSameUser(userId)); + .anyMatch(like -> like.isSameUser(userId)); } public void add(Like like) { @@ -65,4 +65,4 @@ public void add(Like like) { public int getSize() { return likes.size(); } -} +} \ No newline at end of file diff --git a/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Post.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Post.java index 8f271ea0..80dd89dd 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Post.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Post.java @@ -4,17 +4,32 @@ import com.cvi.config.entity.BaseEntity; import com.cvi.exception.InvalidOperationException; import com.cvi.exception.NotFoundException; +import com.cvi.image.domain.Image; import com.cvi.like.domain.model.Like; import com.cvi.user.domain.model.User; -import lombok.*; - -import javax.persistence.*; -import javax.validation.constraints.NotBlank; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; +import javax.persistence.AttributeOverride; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.JoinColumn; +import javax.persistence.Lob; +import javax.persistence.ManyToOne; +import javax.validation.constraints.NotBlank; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; @Getter @Entity @@ -23,6 +38,9 @@ @ToString(of = {"content", "viewCount", "vaccinationType"}) public class Post extends BaseEntity { + @Embedded + private final Images images = new Images(); + @Embedded private final Likes likes = new Likes(); @@ -44,7 +62,7 @@ public class Post extends BaseEntity { @Builder public Post(Long id, LocalDateTime createdAt, LocalDateTime lastModifiedAt, User user, - String content, int viewCount, VaccinationType vaccinationType) { + String content, int viewCount, VaccinationType vaccinationType) { super(id, createdAt, lastModifiedAt); this.user = user; this.content = content; @@ -65,7 +83,7 @@ public void assignUser(User user) { this.user = user; } - public void update(Post updatePost, User user) { + public void updateContent(Post updatePost, User user) { if (!this.user.equals(user)) { throw new InvalidOperationException("다른 사용자의 게시글은 수정할 수 없습니다."); } @@ -120,8 +138,8 @@ public List getCommentsAsList() { public List sliceCommentsAsList(int offset, int size) { List comments = this.comments.getComments(); comments = comments.stream() - .sorted(Comparator.comparing(Comment::getCreatedAt).reversed()) - .collect(Collectors.toList()); + .sorted(Comparator.comparing(Comment::getCreatedAt).reversed()) + .collect(Collectors.toList()); int fromIndex = offset; fromIndex = resizePagingRange(comments, fromIndex); int toIndex = offset + size; @@ -135,4 +153,26 @@ private int resizePagingRange(List comments, int fromIndex) { } return fromIndex; } + + public void assignImages(List images) { + this.images.addAll(images, this); + } + + public List getImagesAsUrlList() { + return images.getImages().stream() + .map(Image::getUrl) + .collect(Collectors.toList()); + } + + public boolean hasImages() { + return images.size() > 0; + } + + public List getAllImagesAsList() { + return new ArrayList<>(images.getImages()); + } + + public List getS3PathsOfAllImages() { + return images.getS3PathsOfAllImages(); + } } diff --git a/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Sort.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Sort.java index 9c33e4fc..d9af748f 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Sort.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/model/Sort.java @@ -1,12 +1,11 @@ package com.cvi.post.domain.model; +import static com.cvi.post.domain.model.QPost.post; + import com.cvi.exception.InvalidInputException; import com.querydsl.core.types.OrderSpecifier; -import lombok.Getter; - import java.util.Arrays; - -import static com.cvi.post.domain.model.QPost.post; +import lombok.Getter; @Getter public enum Sort { @@ -27,13 +26,13 @@ public enum Sort { public static OrderSpecifier toOrderSpecifier(Sort input) { return Arrays.stream(values()) - .filter(Sort::isSameTypeOf) - .findAny() - .map(sort -> input.getSort()) - .orElseThrow(() -> new InvalidInputException("잘못된 정렬 형식입니다.")); + .filter(Sort::isSameTypeOf) + .findAny() + .map(sort -> input.getSort()) + .orElseThrow(() -> new InvalidInputException("잘못된 정렬 형식입니다.")); } private static boolean isSameTypeOf(Sort sort) { return sort == sort; } -} +} \ No newline at end of file diff --git a/backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostRepositoryImpl.java b/backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostRepositoryImpl.java index aeca53c9..1d687cd9 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostRepositoryImpl.java +++ b/backend/domain-cvi/src/main/java/com/cvi/post/domain/repository/PostRepositoryImpl.java @@ -1,5 +1,10 @@ package com.cvi.post.domain.repository; +import static com.cvi.comment.domain.model.QComment.comment; +import static com.cvi.like.domain.model.QLike.like; +import static com.cvi.post.domain.model.QPost.post; +import static com.cvi.user.domain.model.QUser.user; + import com.cvi.post.domain.model.Post; import com.cvi.post.domain.model.QPost; import com.cvi.post.domain.model.VaccinationType; @@ -7,17 +12,11 @@ import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.JPQLQueryFactory; import com.querydsl.jpa.impl.JPAQueryFactory; - -import javax.persistence.EntityManager; import java.time.LocalDateTime; import java.util.List; import java.util.Objects; import java.util.Optional; - -import static com.cvi.comment.domain.model.QComment.comment; -import static com.cvi.like.domain.model.QLike.like; -import static com.cvi.post.domain.model.QPost.post; -import static com.cvi.user.domain.model.QUser.user; +import javax.persistence.EntityManager; public class PostRepositoryImpl implements PostQueryDsl { @@ -30,21 +29,21 @@ public PostRepositoryImpl(EntityManager em) { @Override public List findByVaccineType(VaccinationType vaccinationType) { return queryFactory.selectFrom(post) - .leftJoin(post.user, user).fetchJoin() - .where(vaccinationTypeEq(vaccinationType)) - .orderBy(post.createdAt.desc()) - .fetch(); + .leftJoin(post.user, user).fetchJoin() + .where(vaccinationTypeEq(vaccinationType)) + .orderBy(post.createdAt.desc()) + .fetch(); } @Override public List findByVaccineType(VaccinationType vaccinationType, int offset, int size, OrderSpecifier orderSpecifier, int hours) { return queryFactory.selectFrom(post) - .leftJoin(post.user, user).fetchJoin() - .where(vaccinationTypeEq(vaccinationType), fromHoursBefore(hours)) - .orderBy(orderSpecifier, post.createdAt.desc()) - .offset(offset) - .limit(size) - .fetch(); + .leftJoin(post.user, user).fetchJoin() + .where(vaccinationTypeEq(vaccinationType), fromHoursBefore(hours)) + .orderBy(orderSpecifier, post.createdAt.desc()) + .offset(offset) + .limit(size) + .fetch(); } private BooleanExpression fromHoursBefore(int hours) { @@ -61,19 +60,19 @@ private BooleanExpression vaccinationTypeEq(VaccinationType vaccinationType) { @Override public List findByUserId(Long userId) { return queryFactory.selectFrom(post) - .leftJoin(post.user, user).fetchJoin() - .where(post.user.id.eq(userId)) - .orderBy(post.createdAt.desc()) - .fetch(); + .leftJoin(post.user, user).fetchJoin() + .where(post.user.id.eq(userId)) + .orderBy(post.createdAt.desc()) + .fetch(); } @Override public Optional findWithLikesByPostId(Long id) { Post post = queryFactory.selectFrom(QPost.post) - .leftJoin(QPost.post.likes.likes, like).fetchJoin() - .where(QPost.post.id.eq(id)) - .orderBy(QPost.post.createdAt.desc()) - .fetchOne(); + .leftJoin(QPost.post.likes.likes, like).fetchJoin() + .where(QPost.post.id.eq(id)) + .orderBy(QPost.post.createdAt.desc()) + .fetchOne(); return Optional.ofNullable(post); } @@ -81,10 +80,10 @@ public Optional findWithLikesByPostId(Long id) { @Override public Optional findWithCommentsByPostId(Long id) { Post post = queryFactory.selectFrom(QPost.post) - .leftJoin(QPost.post.comments.comments, comment).fetchJoin() - .where(QPost.post.id.eq(id)) - .orderBy(QPost.post.createdAt.desc()) - .fetchOne(); + .leftJoin(QPost.post.comments.comments, comment).fetchJoin() + .where(QPost.post.id.eq(id)) + .orderBy(QPost.post.createdAt.desc()) + .fetchOne(); return Optional.ofNullable(post); } @@ -92,11 +91,11 @@ public Optional findWithCommentsByPostId(Long id) { @Override public List findByUserId(Long userId, int offset, int size) { return queryFactory.selectFrom(post) - .leftJoin(post.user, user).fetchJoin() - .where(post.user.id.eq(userId)) - .orderBy(post.createdAt.desc()) - .offset(offset) - .limit(size) - .fetch(); + .leftJoin(post.user, user).fetchJoin() + .where(post.user.id.eq(userId)) + .orderBy(post.createdAt.desc()) + .offset(offset) + .limit(size) + .fetch(); } } diff --git a/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/PublicData.java b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/PublicData.java index c5f56704..955d70da 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/PublicData.java +++ b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/PublicData.java @@ -27,4 +27,4 @@ public PublicData(Long id, LocalDateTime createdAt, LocalDateTime lastModifiedAt public boolean isSameRegionPopulation(RegionPopulation regionPopulation) { return this.regionPopulation.equals(regionPopulation); } -} +} \ No newline at end of file diff --git a/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/RegionPopulation.java b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/RegionPopulation.java index 83670361..7ce619a1 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/RegionPopulation.java +++ b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/RegionPopulation.java @@ -1,10 +1,9 @@ package com.cvi.publicdata.domain.model; -import lombok.Getter; - import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import lombok.Getter; @Getter public enum RegionPopulation { @@ -32,7 +31,7 @@ public enum RegionPopulation { static { Arrays.stream(values()) - .forEach(it -> regions.put(it.region, it)); + .forEach(it -> regions.put(it.region, it)); } private final String region; diff --git a/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistic.java b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistic.java index 0af03397..4ac68892 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistic.java +++ b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistic.java @@ -39,8 +39,8 @@ public class VaccinationStatistic extends PublicData { @Builder public VaccinationStatistic(Long id, LocalDateTime createdAt, LocalDateTime lastModifiedAt, RegionPopulation regionPopulation, - LocalDate baseDate, long firstCnt, long secondCnt, long totalFirstCnt, long totalSecondCnt, long accumulatedFirstCnt, - long accumulatedSecondCnt, BigDecimal totalFirstRate, BigDecimal totalSecondRate) { + LocalDate baseDate, long firstCnt, long secondCnt, long totalFirstCnt, long totalSecondCnt, long accumulatedFirstCnt, + long accumulatedSecondCnt, BigDecimal totalFirstRate, BigDecimal totalSecondRate) { super(id, createdAt, lastModifiedAt, regionPopulation); this.baseDate = baseDate; this.firstCnt = firstCnt; @@ -71,7 +71,7 @@ private void assignAccumulatedSecondRate(BigDecimal accumulatedSecondRate) { private BigDecimal calculateRate(long totalCnt) { return BigDecimal.valueOf(totalCnt).scaleByPowerOfTen(2) - .divide(BigDecimal.valueOf(this.regionPopulation.getPopulation()), 1, RoundingMode.HALF_EVEN); + .divide(BigDecimal.valueOf(this.regionPopulation.getPopulation()), 1, RoundingMode.HALF_EVEN); } public BigDecimal getTotalFirstRate() { diff --git a/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistics.java b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistics.java index 0f71a4af..a02c777b 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistics.java +++ b/backend/domain-cvi/src/main/java/com/cvi/publicdata/domain/model/VaccinationStatistics.java @@ -17,34 +17,34 @@ public VaccinationStatistics(List vaccinationStatistics) { public List findUnSavedStatistics(List foundVaccinationStatistics, LocalDate targetDate) { return this.vaccinationStatistics.stream() - .filter(isSameOrBefore(targetDate)) - .filter(base -> foundVaccinationStatistics.stream() - .noneMatch(target -> target.isSameDate(base.getBaseDate()) && target.isSameRegionPopulation(base.regionPopulation))) - .collect(Collectors.toList()); + .filter(isSameOrBefore(targetDate)) + .filter(base -> foundVaccinationStatistics.stream() + .noneMatch(target -> target.isSameDate(base.getBaseDate()) && target.isSameRegionPopulation(base.regionPopulation))) + .collect(Collectors.toList()); } - public List findRecentlyStatistics(LocalDate targetDate) { + public List findKoreaRecentlyStatistics(LocalDate targetDate) { return this.vaccinationStatistics.stream() - .filter(isSameOrBefore(targetDate).and(isSameRegionPopulation(RegionPopulation.WORLD).negate())) - .sorted(Comparator.comparing(VaccinationStatistic::getBaseDate).reversed()) - .limit(RegionPopulation.size() - 1) - .sorted(Comparator.comparing(VaccinationStatistic::getRegionPopulation)) - .collect(Collectors.toList()); + .filter(isSameOrBefore(targetDate).and(isWorldRegion().negate())) + .sorted(Comparator.comparing(VaccinationStatistic::getBaseDate).reversed()) + .limit(RegionPopulation.size() - 1) + .sorted(Comparator.comparing(VaccinationStatistic::getRegionPopulation)) + .collect(Collectors.toList()); } public List findWorldRecentlyStatistics(LocalDate targetDate) { return this.vaccinationStatistics.stream() - .filter(isSameOrBefore(targetDate).and(isSameRegionPopulation(RegionPopulation.WORLD))) - .sorted(Comparator.comparing(VaccinationStatistic::getBaseDate).reversed()) - .limit(1) - .collect(Collectors.toList()); + .filter(isSameOrBefore(targetDate).and(isWorldRegion())) + .sorted(Comparator.comparing(VaccinationStatistic::getBaseDate).reversed()) + .limit(1) + .collect(Collectors.toList()); } private Predicate isSameOrBefore(LocalDate targetDate) { return vaccinationStatistic -> vaccinationStatistic.getBaseDate().isEqual(targetDate) || vaccinationStatistic.getBaseDate().isBefore(targetDate); } - private Predicate isSameRegionPopulation(RegionPopulation regionPopulation) { - return vaccinationStatistic -> vaccinationStatistic.isSameRegionPopulation(regionPopulation); + private Predicate isWorldRegion() { + return vaccinationStatistic -> vaccinationStatistic.isSameRegionPopulation(RegionPopulation.WORLD); } } diff --git a/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java b/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java index 0885d94c..2272aac4 100644 --- a/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java +++ b/backend/domain-cvi/src/main/java/com/cvi/user/domain/model/User.java @@ -2,17 +2,23 @@ import com.cvi.config.entity.BaseEntity; import com.cvi.exception.InvalidInputException; -import lombok.*; -import lombok.extern.slf4j.Slf4j; -import org.hibernate.validator.constraints.Length; -import org.springframework.util.StringUtils; - -import javax.persistence.*; +import java.time.LocalDateTime; +import javax.persistence.AttributeOverride; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; -import java.time.LocalDateTime; -import java.util.Objects; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.validator.constraints.Length; +import org.springframework.util.StringUtils; @Slf4j @Entity @@ -45,7 +51,7 @@ public class User extends BaseEntity { @Builder public User(Long id, LocalDateTime createdAt, LocalDateTime lastModifiedAt, String nickname, - AgeRange ageRange, boolean shotVerified, SocialProvider socialProvider, String socialId, String profileUrl) { + AgeRange ageRange, boolean shotVerified, SocialProvider socialProvider, String socialId, String profileUrl) { super(id, createdAt, lastModifiedAt); validateNickName(nickname); this.nickname = nickname; @@ -57,7 +63,7 @@ public User(Long id, LocalDateTime createdAt, LocalDateTime lastModifiedAt, Stri } private void validateNickName(String nickname) { - if (Objects.isNull(nickname) || nickname.isEmpty() || nickname.contains(" ")) { + if (StringUtils.isEmpty(nickname) || nickname.contains(" ")) { log.info("닉네임에는 공백 문자가 포함될 수 없습니다. 입력값: {}", nickname); throw new InvalidInputException(String.format("닉네임에는 공백 문자가 포함될 수 없습니다. 입력값: %s", nickname)); } diff --git a/backend/domain-cvi/src/test/java/com/cvi/CentralVaccinationInformationApplication.java b/backend/domain-cvi/src/test/java/com/cvi/CentralVaccinationInformationApplication.java new file mode 100644 index 00000000..c28aa217 --- /dev/null +++ b/backend/domain-cvi/src/test/java/com/cvi/CentralVaccinationInformationApplication.java @@ -0,0 +1,7 @@ +package com.cvi; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CentralVaccinationInformationApplication { +} diff --git a/backend/domain-cvi/src/test/java/com/cvi/comment/domain/model/CommentTest.java b/backend/domain-cvi/src/test/java/com/cvi/comment/domain/model/CommentTest.java index 7930a231..c0ad4dbb 100644 --- a/backend/domain-cvi/src/test/java/com/cvi/comment/domain/model/CommentTest.java +++ b/backend/domain-cvi/src/test/java/com/cvi/comment/domain/model/CommentTest.java @@ -1,5 +1,8 @@ package com.cvi.comment.domain.model; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + import com.cvi.exception.InvalidOperationException; import com.cvi.exception.NotFoundException; import com.cvi.exception.UnAuthorizedException; @@ -8,17 +11,13 @@ import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; +import java.time.LocalDateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.time.LocalDateTime; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - @DisplayName("댓글 도메인 테스트") -public class CommentTest { +class CommentTest { private Post post; private User user; @@ -28,29 +27,29 @@ public class CommentTest { @BeforeEach void setUp() { post = Post.builder() - .id(1L) - .content("게시글 내용") - .vaccinationType(VaccinationType.ASTRAZENECA) - .createdAt(LocalDateTime.now()) - .build(); + .id(1L) + .content("게시글 내용") + .vaccinationType(VaccinationType.ASTRAZENECA) + .createdAt(LocalDateTime.now()) + .build(); user = User.builder() - .id(1L) - .nickname("안녕하세욘") - .ageRange(AgeRange.TEENS) - .socialProvider(SocialProvider.KAKAO) - .socialId("KAKAO_ID") - .profileUrl("kakao.com/profile") - .createdAt(LocalDateTime.now()) - .build(); + .id(1L) + .nickname("안녕하세욘") + .ageRange(AgeRange.TEENS) + .socialProvider(SocialProvider.KAKAO) + .socialId("KAKAO_ID") + .profileUrl("kakao.com/profile") + .createdAt(LocalDateTime.now()) + .build(); anotherUser = User.builder() - .id(2L) - .nickname("방구왕라이언") - .ageRange(AgeRange.TEENS) - .socialProvider(SocialProvider.KAKAO) - .socialId("KAKAO_ID") - .profileUrl("kakao.com/profile") - .createdAt(LocalDateTime.now()) - .build(); + .id(2L) + .nickname("방구왕라이언") + .ageRange(AgeRange.TEENS) + .socialProvider(SocialProvider.KAKAO) + .socialId("KAKAO_ID") + .profileUrl("kakao.com/profile") + .createdAt(LocalDateTime.now()) + .build(); comment = Comment.builder().id(1L).content("댓글입니다.").build(); } diff --git a/backend/domain-cvi/src/test/java/com/cvi/like/domain/model/LikeTest.java b/backend/domain-cvi/src/test/java/com/cvi/like/domain/model/LikeTest.java index 5b1ca774..94ec493a 100644 --- a/backend/domain-cvi/src/test/java/com/cvi/like/domain/model/LikeTest.java +++ b/backend/domain-cvi/src/test/java/com/cvi/like/domain/model/LikeTest.java @@ -1,20 +1,19 @@ package com.cvi.like.domain.model; +import static org.assertj.core.api.Assertions.assertThat; + import com.cvi.post.domain.model.Post; import com.cvi.post.domain.model.VaccinationType; import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; +import java.time.LocalDateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.time.LocalDateTime; - -import static org.assertj.core.api.Assertions.assertThat; - @DisplayName("댓글 도메인 테스트") -public class LikeTest { +class LikeTest { private Post post; private User user; @@ -23,20 +22,20 @@ public class LikeTest { @BeforeEach void setUp() { post = Post.builder() - .id(1L) - .content("게시글 내용") - .vaccinationType(VaccinationType.ASTRAZENECA) - .createdAt(LocalDateTime.now()) - .build(); + .id(1L) + .content("게시글 내용") + .vaccinationType(VaccinationType.ASTRAZENECA) + .createdAt(LocalDateTime.now()) + .build(); user = User.builder() - .id(1L) - .nickname("안녕하세욘") - .ageRange(AgeRange.TEENS) - .socialProvider(SocialProvider.KAKAO) - .socialId("KAKAO_ID") - .profileUrl("kakao.com/profile") - .createdAt(LocalDateTime.now()) - .build(); + .id(1L) + .nickname("안녕하세욘") + .ageRange(AgeRange.TEENS) + .socialProvider(SocialProvider.KAKAO) + .socialId("KAKAO_ID") + .profileUrl("kakao.com/profile") + .createdAt(LocalDateTime.now()) + .build(); like = Like.builder().id(1L).user(user).createdAt(LocalDateTime.now()).build(); } diff --git a/backend/domain-cvi/src/test/java/com/cvi/post/domain/model/PostTest.java b/backend/domain-cvi/src/test/java/com/cvi/post/domain/model/PostTest.java index 2a5cce77..011241a3 100644 --- a/backend/domain-cvi/src/test/java/com/cvi/post/domain/model/PostTest.java +++ b/backend/domain-cvi/src/test/java/com/cvi/post/domain/model/PostTest.java @@ -1,11 +1,20 @@ package com.cvi.post.domain.model; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + import com.cvi.comment.domain.model.Comment; import com.cvi.exception.InvalidOperationException; import com.cvi.exception.NotFoundException; import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -13,14 +22,6 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.*; - @DisplayName("게시글 도메인 테스트") class PostTest { @@ -30,18 +31,18 @@ class PostTest { @BeforeEach void init() { post = Post.builder() - .content("content1") - .vaccinationType(VaccinationType.ASTRAZENECA) - .createdAt(LocalDateTime.now()) - .build(); + .content("content1") + .vaccinationType(VaccinationType.ASTRAZENECA) + .createdAt(LocalDateTime.now()) + .build(); user = User.builder() - .id(1L) - .nickname("안녕하세욘") - .ageRange(AgeRange.TEENS) - .profileUrl("") - .socialProvider(SocialProvider.KAKAO) - .createdAt(LocalDateTime.now()) - .build(); + .id(1L) + .nickname("안녕하세욘") + .ageRange(AgeRange.TEENS) + .profileUrl("") + .socialProvider(SocialProvider.KAKAO) + .createdAt(LocalDateTime.now()) + .build(); } @DisplayName("게시글 작성자 할당 - 성공") @@ -59,14 +60,14 @@ void assignUser() { void assignUserFailureWhenAlreadyExists() { //given User targetUser = User.builder() - .id(2L) - .nickname("독함") - .build(); + .id(2L) + .nickname("독함") + .build(); //when post.assignUser(user); //then assertThatThrownBy(() -> post.assignUser(targetUser)) - .isInstanceOf(InvalidOperationException.class); + .isInstanceOf(InvalidOperationException.class); } @DisplayName("게시글 작성자 할당 - 실패 - 할당하려는 작성자가 없음") @@ -76,7 +77,7 @@ void assignUserFailureWhenNull() { //when //then assertThatThrownBy(() -> post.assignUser(null)) - .isInstanceOf(NotFoundException.class); + .isInstanceOf(NotFoundException.class); } @DisplayName("게시글 조회수 증가 - 성공") @@ -94,11 +95,11 @@ void increaseViewCount() { void update() { //given Post updatedPost = Post.builder() - .content("content2") - .build(); + .content("content2") + .build(); post.assignUser(user); //when - post.update(updatedPost, user); + post.updateContent(updatedPost, user); //then assertThat(post.getContent()).isEqualTo(updatedPost.getContent()); } @@ -108,17 +109,17 @@ void update() { void updateFailWhenUserNotMatch() { //given User targetUser = User.builder() - .id(2L) - .nickname("라이언방구") - .build(); + .id(2L) + .nickname("라이언방구") + .build(); Post updatedPost = Post.builder() - .content("content2") - .build(); + .content("content2") + .build(); post.assignUser(user); //when //then - assertThatThrownBy(() -> post.update(updatedPost, targetUser)) - .isExactlyInstanceOf(InvalidOperationException.class); + assertThatThrownBy(() -> post.updateContent(updatedPost, targetUser)) + .isExactlyInstanceOf(InvalidOperationException.class); } @DisplayName("게시글 작성자 확인 - 성공") @@ -126,17 +127,17 @@ void updateFailWhenUserNotMatch() { void deletePost() { //given User user = User.builder() - .id(2L) - .nickname("인비") - .build(); + .id(2L) + .nickname("인비") + .build(); Post post = Post.builder() - .content("내용") - .build(); + .content("내용") + .build(); post.assignUser(user); //when //then assertThatCode(() -> post.validateAuthor(user)) - .doesNotThrowAnyException(); + .doesNotThrowAnyException(); } @DisplayName("게시글 작성자 확인 - 실패 - 글 작성자가 아님") @@ -144,21 +145,21 @@ void deletePost() { void deletePostFailureWhenNotAuthor() { //given User user = User.builder() - .id(2L) - .nickname("인비") - .build(); + .id(2L) + .nickname("인비") + .build(); User otherUser = User.builder() - .id(3L) - .nickname("라이언") - .build(); + .id(3L) + .nickname("라이언") + .build(); Post post = Post.builder() - .content("내용") - .build(); + .content("내용") + .build(); post.assignUser(user); //when //then assertThatThrownBy(() -> post.validateAuthor(otherUser)) - .isInstanceOf(InvalidOperationException.class); + .isInstanceOf(InvalidOperationException.class); } @ParameterizedTest(name = "페이징 요청 값 resize - 성공") @@ -166,13 +167,13 @@ void deletePostFailureWhenNotAuthor() { void resizePagingRangeTest(int offset, int size, List contentResult) { //given User user = User.builder() - .id(1L) - .nickname("인비") - .build(); + .id(1L) + .nickname("인비") + .build(); Post post = Post.builder() - .content("내용") - .user(user) - .build(); + .content("내용") + .user(user) + .build(); Comment comment1 = Comment.builder().content("댓글1").user(user).createdAt(LocalDateTime.now().minusHours(1L)).build(); Comment comment2 = Comment.builder().content("댓글2").user(user).createdAt(LocalDateTime.now().minusHours(2L)).build(); post.assignComment(comment1); @@ -185,10 +186,10 @@ void resizePagingRangeTest(int offset, int size, List contentResult) { static Stream resizePagingRangeTest() { return Stream.of( - Arguments.of(0, 2, Arrays.asList("댓글1", "댓글2")), - Arguments.of(1, 1, Arrays.asList("댓글2")), - Arguments.of(0, 1, Arrays.asList("댓글1")), - Arguments.of(2, 1, Collections.emptyList()) + Arguments.of(0, 2, Arrays.asList("댓글1", "댓글2")), + Arguments.of(1, 1, Arrays.asList("댓글2")), + Arguments.of(0, 1, Arrays.asList("댓글1")), + Arguments.of(2, 1, Collections.emptyList()) ); } } diff --git a/backend/domain-cvi/src/test/java/com/cvi/post/domain/repository/PostRepositoryTest.java b/backend/domain-cvi/src/test/java/com/cvi/post/domain/repository/PostRepositoryTest.java new file mode 100644 index 00000000..e481d532 --- /dev/null +++ b/backend/domain-cvi/src/test/java/com/cvi/post/domain/repository/PostRepositoryTest.java @@ -0,0 +1,214 @@ +package com.cvi.post.domain.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.cvi.comment.domain.model.Comment; +import com.cvi.comment.domain.repository.CommentRepository; +import com.cvi.image.domain.Image; +import com.cvi.image.repository.ImageRepository; +import com.cvi.like.domain.model.Like; +import com.cvi.like.domain.repository.LikeRepository; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; +import java.util.Arrays; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DisplayName("PostRepository 테스트") +@DataJpaTest +class PostRepositoryTest { + + @Autowired + private UserRepository userRepository; + + @Autowired + private PostRepository postRepository; + + @Autowired + private CommentRepository commentRepository; + + @Autowired + private LikeRepository likeRepository; + + @Autowired + private ImageRepository imageRepository; + + @PersistenceContext + private EntityManager entityManager; + + private User user1; + private User user2; + private Comment comment1; + private Comment comment2; + private Like like1; + private Like like2; + private Image image1; + private Image image2; + private Post post1; + + @BeforeEach + void setUp() { + initUsers(); + initPost(); + initImages(); + initComments(); + initLikes(); + assertIdAssigned(); + } + + private void initUsers() { + user1 = User.builder() + .nickname("인비") + .ageRange(AgeRange.TEENS) + .socialProvider(SocialProvider.KAKAO) + .socialId("1000") + .profileUrl("profile url 1") + .build(); + user2 = User.builder() + .nickname("검프") + .socialProvider(SocialProvider.NAVER) + .socialId("1001") + .profileUrl("profile url 2") + .ageRange(AgeRange.FIFTIES) + .build(); + userRepository.save(user1); + userRepository.save(user2); + } + + private void initPost() { + post1 = Post.builder() + .user(user1) + .content("내용 1") + .vaccinationType(VaccinationType.PFIZER) + .build(); + postRepository.save(post1); + } + + private void initImages() { + image1 = Image.builder() + .url("image1_s3_url") + .build(); + image1.assignPost(post1); + imageRepository.save(image1); + + image2 = Image.builder() + .url("image2_s3_url") + .build(); + image2.assignPost(post1); + imageRepository.save(image2); + } + + private void initComments() { + comment1 = Comment.builder() + .content("댓글 내용1") + .user(user1) + .build(); + comment1.assignPost(post1); + commentRepository.save(comment1); + + comment2 = Comment.builder() + .content("댓글 내용2") + .user(user2) + .build(); + comment2.assignPost(post1); + commentRepository.save(comment2); + } + + private void initLikes() { + like1 = Like.builder() + .user(user1) + .build(); + like1.assignPost(post1); + likeRepository.save(like1); + + like2 = Like.builder() + .user(user2) + .build(); + like2.assignPost(post1); + likeRepository.save(like2); + } + + private void assertIdAssigned() { + assertThat(comment1.getId()).isNotNull(); + assertThat(comment2.getId()).isNotNull(); + + assertThat(image1.getId()).isNotNull(); + assertThat(image2.getId()).isNotNull(); + + assertThat(like1.getId()).isNotNull(); + assertThat(like2.getId()).isNotNull(); + + assertThat(post1.getId()).isNotNull(); + } + + @DisplayName("Post를 삭제하면, 안에 있는 Comment, Like 들은 모두 삭제되고, Image는 삭제되지 않는다.") + @Test + void deletePost() { + //given + //when + imageRepository.deleteAll(Arrays.asList(image1, image2)); + postRepository.delete(post1); + resetEntityManager(); + //then + assertThat(userRepository.findById(user1.getId())).isNotEmpty(); + assertThat(userRepository.findById(user2.getId())).isNotEmpty(); + + assertThat(postRepository.findById(post1.getId())).isEmpty(); + + assertThat(commentRepository.findById(comment1.getId())).isEmpty(); + assertThat(commentRepository.findById(comment2.getId())).isEmpty(); + + assertThat(likeRepository.findById(like1.getId())).isEmpty(); + assertThat(likeRepository.findById(like2.getId())).isEmpty(); + } + + @DisplayName("Post Collection 에서 Comment, Like, Image 를 제거해도 DB에서 삭제되지 않는다.") + @Test + void deleteFromPost() { + //given + //when + post1.deleteLike(user1.getId()); + post1.deleteComment(comment1.getId(), user1); + post1.getImages().getImages().clear(); + resetEntityManager(); + //then + assertThat(post1.hasImages()).isFalse(); + + assertThat(userRepository.findById(user1.getId())).isNotEmpty(); + assertThat(userRepository.findById(user2.getId())).isNotEmpty(); + + assertThat(postRepository.findById(post1.getId())).isNotEmpty(); + + assertThat(commentRepository.findById(comment1.getId())).isNotEmpty(); + assertThat(commentRepository.findById(comment2.getId())).isNotEmpty(); + + assertThat(likeRepository.findById(like1.getId())).isNotEmpty(); + assertThat(likeRepository.findById(like2.getId())).isNotEmpty(); + + assertThat(imageRepository.findById(image1.getId())).isNotEmpty(); + assertThat(imageRepository.findById(image2.getId())).isNotEmpty(); + } + + @DisplayName("Image 삭제 쿼리 확인 테스트") + @Test + void deleteImage() { + //given + //when + post1.getImages().getImages().clear(); + //then + } + + private void resetEntityManager() { + entityManager.flush(); + entityManager.clear(); + } +} diff --git a/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticFactory.java b/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticFactory.java new file mode 100644 index 00000000..f9dacaae --- /dev/null +++ b/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticFactory.java @@ -0,0 +1,62 @@ +package com.cvi.publicdata.domain.model; + +import java.time.LocalDate; +import java.util.Arrays; +import java.util.List; + +public class VaccinationStatisticFactory { + + public static final LocalDate TARGET_DATE = LocalDate.now(); + + public static final List KOREA_VACCINATION_STATISTICS_FROM_API = Arrays.asList( + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.REGION_WIDE).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.SEOUL).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.BUSAN).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.DAEGU).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.INCHEON).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.GWANGJU).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.ULSAN).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.DAEJEON).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.GYEONGGI_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.GANGWOND_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.SEJONG).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.CHUNGCHEONGBUK_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.CHUNGCHEONGNAM_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.JEOLLAKBUK_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.JEOLLANAM_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.GYEONGSANGBUK_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.GYEONGSANGNAME_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.JEJU_OD).build() + + ); + + public static final List WORLD_VACCINATION_STATISTICS_FROM_API = Arrays.asList( + VaccinationStatistic.builder().baseDate(TARGET_DATE).regionPopulation(RegionPopulation.WORLD).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.WORLD).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(2)).regionPopulation(RegionPopulation.WORLD).build() + ); + + public static final List VACCINATION_STATISTICS_FROM_DB = Arrays.asList( + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.REGION_WIDE).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.SEOUL).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.BUSAN).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.DAEGU).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.INCHEON).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.GWANGJU).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.ULSAN).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.DAEJEON).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.GYEONGGI_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.GANGWOND_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.SEJONG).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.CHUNGCHEONGBUK_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.CHUNGCHEONGNAM_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.JEOLLAKBUK_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.JEOLLANAM_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.GYEONGSANGBUK_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.GYEONGSANGNAME_DO).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(1)).regionPopulation(RegionPopulation.JEJU_OD).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(3)).regionPopulation(RegionPopulation.WORLD).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(4)).regionPopulation(RegionPopulation.WORLD).build(), + VaccinationStatistic.builder().baseDate(TARGET_DATE.minusDays(5)).regionPopulation(RegionPopulation.WORLD).build() + ); +} diff --git a/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticTest.java b/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticTest.java index 4363313e..a22d7210 100644 --- a/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticTest.java +++ b/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticTest.java @@ -1,13 +1,12 @@ package com.cvi.publicdata.domain.model; +import static org.assertj.core.api.Assertions.assertThat; + +import java.math.BigDecimal; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; -import java.math.BigDecimal; - -import static org.assertj.core.api.Assertions.assertThat; - @DisplayName("백신 접종률 도메인 테스트") class VaccinationStatisticTest { diff --git a/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticsTest.java b/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticsTest.java new file mode 100644 index 00000000..75588d39 --- /dev/null +++ b/backend/domain-cvi/src/test/java/com/cvi/publicdata/domain/model/VaccinationStatisticsTest.java @@ -0,0 +1,83 @@ +package com.cvi.publicdata.domain.model; + +import static com.cvi.publicdata.domain.model.VaccinationStatisticFactory.KOREA_VACCINATION_STATISTICS_FROM_API; +import static com.cvi.publicdata.domain.model.VaccinationStatisticFactory.TARGET_DATE; +import static com.cvi.publicdata.domain.model.VaccinationStatisticFactory.VACCINATION_STATISTICS_FROM_DB; +import static com.cvi.publicdata.domain.model.VaccinationStatisticFactory.WORLD_VACCINATION_STATISTICS_FROM_API; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("VaccinationStatistic 일급 컬렉션 기능 테스트") +class VaccinationStatisticsTest { + + @DisplayName("새로운 한국 접종률 기준, DB에 저장되어 있지 않은 데이터 반환 - 성공 - 저장되어 있는 데이터의 날짜와 새로운 데이터의 날짜가 다를 때") + @Test + void findUnSavedStatisticsWhenAnotherDate() { + //given + final VaccinationStatistics vaccinationStatistics = new VaccinationStatistics(KOREA_VACCINATION_STATISTICS_FROM_API); + //when + final List unSavedStatistics = vaccinationStatistics.findUnSavedStatistics( + VACCINATION_STATISTICS_FROM_DB, TARGET_DATE + ); + //then + assertThat(unSavedStatistics.size()).isEqualTo(RegionPopulation.size() - 1); + assertThat(unSavedStatistics).noneMatch(it -> it.getRegionPopulation() == RegionPopulation.WORLD); + } + + @DisplayName("새로운 한국 접종률 기준, DB에 저장되어 있지 않은 데이터 반환 - 성공 - 저장되어 있는 데이터의 날짜와 새로운 데이터의 날짜가 같을 때") + @Test + void findUnSavedStatisticsWhenSameDate() { + //given + final VaccinationStatistics vaccinationStatistics = new VaccinationStatistics(KOREA_VACCINATION_STATISTICS_FROM_API); + //when + final List unSavedStatistics = vaccinationStatistics.findUnSavedStatistics( + KOREA_VACCINATION_STATISTICS_FROM_API, TARGET_DATE + ); + //then + assertThat(unSavedStatistics).isEmpty(); + } + + @DisplayName("새로운 세계 접종률 기준, DB에 저장되어 있지 않은 기준 날짜 포함 이전 데이터 반환- 성공") + @Test + void findWorldUnSavedStatisticsWhenTargetDate() { + //given + final VaccinationStatistics vaccinationStatistics = new VaccinationStatistics(WORLD_VACCINATION_STATISTICS_FROM_API); + //when + final List unSavedStatistics = vaccinationStatistics.findUnSavedStatistics( + VACCINATION_STATISTICS_FROM_DB, TARGET_DATE.minusDays(1) + ); + //then + assertThat(unSavedStatistics.size()).isEqualTo(WORLD_VACCINATION_STATISTICS_FROM_API.size() - 1); + assertThat(unSavedStatistics).allMatch(it -> it.getRegionPopulation() == RegionPopulation.WORLD); + } + + @DisplayName("타겟 날짜 이전의 데이터가 DB에 저장되어 있을때(타겟날짜에 데이터가 저장되어 있지 않음) 이전 날짜의 데이터 반환 - 성공 - 한국 데이터") + @Test + void findWorldRecentlyStatistics() { + //given + final VaccinationStatistics vaccinationStatistics = new VaccinationStatistics(VACCINATION_STATISTICS_FROM_DB); + //when + final List koreaRecentlyStatistics = vaccinationStatistics.findKoreaRecentlyStatistics(TARGET_DATE); + //then + assertThat(koreaRecentlyStatistics.size()).isEqualTo(RegionPopulation.size() - 1); + assertThat(koreaRecentlyStatistics).noneMatch(it -> it.getRegionPopulation() == RegionPopulation.WORLD); + assertThat(koreaRecentlyStatistics).extracting(VaccinationStatistic::getBaseDate) + .contains(TARGET_DATE.minusDays(1)); + } + + @DisplayName("타겟 날짜 이전의 데이터가 DB에 저장되어 있을때(타겟날짜에 데이터가 저장되어 있지 않음) 이전 날짜의 데이터 반환 - 성공 - 세계 데이터") + @Test + void findKoreaRecentlyStatistics() { + //given + final VaccinationStatistics vaccinationStatistics = new VaccinationStatistics(VACCINATION_STATISTICS_FROM_DB); + //when + final List worldRecentlyStatistics = vaccinationStatistics.findWorldRecentlyStatistics(TARGET_DATE); + //then + assertThat(worldRecentlyStatistics).allMatch(it -> it.getRegionPopulation() == RegionPopulation.WORLD); + assertThat(worldRecentlyStatistics).extracting(VaccinationStatistic::getBaseDate) + .doesNotContain(TARGET_DATE); + } +} diff --git a/backend/domain-cvi/src/test/java/com/cvi/user/domain/model/UserTest.java b/backend/domain-cvi/src/test/java/com/cvi/user/domain/model/UserTest.java index 6b33e47e..abd08b74 100644 --- a/backend/domain-cvi/src/test/java/com/cvi/user/domain/model/UserTest.java +++ b/backend/domain-cvi/src/test/java/com/cvi/user/domain/model/UserTest.java @@ -1,6 +1,10 @@ package com.cvi.user.domain.model; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + import com.cvi.exception.InvalidInputException; +import java.time.LocalDateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -8,11 +12,6 @@ import org.junit.jupiter.params.provider.NullAndEmptySource; import org.junit.jupiter.params.provider.ValueSource; -import java.time.LocalDateTime; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - @DisplayName("사용자 도메인 단위 테스트") class UserTest { @@ -21,13 +20,13 @@ class UserTest { @BeforeEach void init() { this.user = User.builder() - .id(1L) - .ageRange(AgeRange.TEENS) - .createdAt(LocalDateTime.now()) - .nickname("검프") - .profileUrl("www.gump.com") - .socialProvider(SocialProvider.KAKAO) - .build(); + .id(1L) + .ageRange(AgeRange.TEENS) + .createdAt(LocalDateTime.now()) + .nickname("검프") + .profileUrl("www.gump.com") + .socialProvider(SocialProvider.KAKAO) + .build(); } @DisplayName("사용자 수정 - 성공") @@ -35,13 +34,13 @@ void init() { void update() { //given User updateUser = User.builder() - .id(1L) - .ageRange(AgeRange.TWENTIES) - .createdAt(LocalDateTime.now()) - .nickname("인비") - .profileUrl("www.budae.com") - .socialProvider(SocialProvider.KAKAO) - .build(); + .id(1L) + .ageRange(AgeRange.TWENTIES) + .createdAt(LocalDateTime.now()) + .nickname("인비") + .profileUrl("www.budae.com") + .socialProvider(SocialProvider.KAKAO) + .build(); //when user.update(updateUser); //then @@ -56,6 +55,6 @@ void signupFailureWhenEmptyNickname(String nickname) { //when //then assertThatThrownBy(() -> User.builder().nickname(nickname).build()) - .isInstanceOf(InvalidInputException.class); + .isInstanceOf(InvalidInputException.class); } } diff --git a/backend/settings.gradle b/backend/settings.gradle index 577abb6e..6d664a5b 100644 --- a/backend/settings.gradle +++ b/backend/settings.gradle @@ -7,4 +7,5 @@ include 'domain-cvi' include 'domain-cvi-oauth-service' include 'domain-cvi-publicdata-service' include 'domain-cvi-scheduler' +include 'domain-cvi-aws-s3-service' From 15f177522c1b595dc1d2b9556718ceb075e1bdbf Mon Sep 17 00:00:00 2001 From: KIM TAE HEE Date: Tue, 28 Sep 2021 17:31:35 +0900 Subject: [PATCH 10/17] =?UTF-8?q?refactor:=20=EB=A9=80=ED=8B=B0=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EB=B6=84=EB=A6=AC=20=ED=9B=84,=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=8F=99=EC=9E=91=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app-cvi-api/build.gradle | 3 + .../src/main/java/com/cvi/DataLoader.java | 27 +- .../src/main/java/com/cvi/DummyData.java | 69 ++- ...thenticationPrincipalArgumentResolver.java | 22 +- .../com/cvi/controller/AuthController.java | 18 +- .../com/cvi/controller/PostController.java | 4 +- .../com/cvi/controller/UserController.java | 4 +- .../main/java/com/cvi/dto/ImageRequest.java | 21 + .../main/java/com/cvi/dto/PostRequest.java | 21 +- .../main/java/com/cvi/dto/PostResponse.java | 28 +- .../com/cvi/dto/PostWithCommentResponse.java | 15 +- .../main/java/com/cvi/dto/UserRequest.java | 16 +- .../main/java/com/cvi/dto/UserResponse.java | 8 +- .../java/com/cvi/service/AuthService.java | 4 +- .../main/java/com/cvi/service/EnvSecret.java | 21 + .../com/cvi/service/post/ImageConverter.java | 42 ++ .../java/com/cvi/service/post/ImageFile.java | 28 ++ .../cvi/service/{ => post}/PostService.java | 104 +++- .../src/main/resources/ehcache.xml | 2 +- .../main/resources/file-debug-appender.xml | 18 + .../resources/file-debug-aws-appender.xml | 18 + .../src/main/resources/logback-spring.xml | 31 ++ .../src/test/java/com/cvi/ApiDocument.java | 21 +- .../com/cvi/acceptance/AcceptanceTest.java | 118 +++++ .../cvi/acceptance/AuthAcceptanceTest.java | 55 +++ .../cvi/acceptance/CommentAcceptanceTest.java | 212 +++++++++ .../cvi/acceptance/LikeAcceptanceTest.java | 131 ++++++ .../cvi/acceptance/PostAcceptanceTest.java | 277 +++++++++++ .../cvi/acceptance/UserAcceptanceTest.java | 234 +++++++++ .../cvi/controller/AuthControllerTest.java | 63 ++- .../cvi/controller/CommentControllerTest.java | 111 ++--- .../cvi/controller/PostControllerTest.java | 195 ++++---- .../PreprocessPostControllerTest.java | 100 ++-- .../controller/PublicDataControllerTest.java | 63 ++- .../cvi/controller/UserControllerTest.java | 220 ++++----- .../java/com/cvi/service/AuthServiceTest.java | 52 +- .../com/cvi/service/CommentServiceTest.java | 72 ++- .../java/com/cvi/service/LikeServiceTest.java | 70 ++- .../com/cvi/service/PostFindServiceTest.java | 182 +++---- .../cvi/service/PostMyPageServiceTest.java | 171 ++++--- .../java/com/cvi/service/PostServiceTest.java | 444 +++++++++++++++--- .../java/com/cvi/service/UserServiceTest.java | 58 +-- .../src/test/resources/application.yml | 29 ++ .../cvi/exception/FileConvertException.java | 8 + .../java/com/cvi/parser/Authorization.java | 6 +- .../com/cvi/parser/AuthorizationManager.java | 5 +- .../com/cvi/parser/KakaoAuthorization.java | 23 +- .../com/cvi/parser/NaverAuthorization.java | 20 +- .../cvi/parser/AuthorizationManagerTest.java | 30 +- .../cvi/parser/KakaoAuthorizationTest.java | 29 +- .../cvi/parser/NaverAuthorizationTest.java | 29 +- ....java => KoreaVaccinationDataFactory.java} | 11 +- .../cvi/dto/VaccinationStatisticResponse.java | 40 +- .../cvi/dto/WorldVaccinationDataFactory.java | 6 +- .../com/cvi/service/PublicDataService.java | 26 +- .../test/java/com/cvi/PublicDataFacotry.java | 71 --- .../test/java/com/cvi/PublicDataFactory.java | 127 +++++ .../cvi/service/PublicDataServiceTest.java | 66 ++- .../src/test/resources/application.yml | 3 + .../com/cvi/service/PublicDataScheduler.java | 18 +- .../db/migration/V20210809__Create_init.sql | 92 ---- .../db/migration/V20210810__Column_add.sql | 43 ++ .../db/migration/V20210913__Create_image.sql | 12 + .../com/cvi/image/ImageRepositoryTest.java | 83 ++++ .../test/java/com/cvi/image/ImageTest.java | 31 ++ .../src/test/resources/application.yml | 3 + 66 files changed, 3022 insertions(+), 1162 deletions(-) create mode 100644 backend/app-cvi-api/src/main/java/com/cvi/dto/ImageRequest.java create mode 100644 backend/app-cvi-api/src/main/java/com/cvi/service/EnvSecret.java create mode 100644 backend/app-cvi-api/src/main/java/com/cvi/service/post/ImageConverter.java create mode 100644 backend/app-cvi-api/src/main/java/com/cvi/service/post/ImageFile.java rename backend/app-cvi-api/src/main/java/com/cvi/service/{ => post}/PostService.java (65%) create mode 100644 backend/app-cvi-api/src/main/resources/file-debug-appender.xml create mode 100644 backend/app-cvi-api/src/main/resources/file-debug-aws-appender.xml create mode 100644 backend/app-cvi-api/src/test/java/com/cvi/acceptance/AcceptanceTest.java create mode 100644 backend/app-cvi-api/src/test/java/com/cvi/acceptance/AuthAcceptanceTest.java create mode 100644 backend/app-cvi-api/src/test/java/com/cvi/acceptance/CommentAcceptanceTest.java create mode 100644 backend/app-cvi-api/src/test/java/com/cvi/acceptance/LikeAcceptanceTest.java create mode 100644 backend/app-cvi-api/src/test/java/com/cvi/acceptance/PostAcceptanceTest.java create mode 100644 backend/app-cvi-api/src/test/java/com/cvi/acceptance/UserAcceptanceTest.java create mode 100644 backend/common-cvi/src/main/java/com/cvi/exception/FileConvertException.java rename backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/{RegionVaccinationDataFactory.java => KoreaVaccinationDataFactory.java} (67%) delete mode 100644 backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFacotry.java create mode 100644 backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFactory.java delete mode 100644 backend/domain-cvi/src/main/resources/db/migration/V20210809__Create_init.sql create mode 100644 backend/domain-cvi/src/main/resources/db/migration/V20210810__Column_add.sql create mode 100644 backend/domain-cvi/src/main/resources/db/migration/V20210913__Create_image.sql create mode 100644 backend/domain-cvi/src/test/java/com/cvi/image/ImageRepositoryTest.java create mode 100644 backend/domain-cvi/src/test/java/com/cvi/image/ImageTest.java diff --git a/backend/app-cvi-api/build.gradle b/backend/app-cvi-api/build.gradle index 4e28cae6..324f9608 100644 --- a/backend/app-cvi-api/build.gradle +++ b/backend/app-cvi-api/build.gradle @@ -6,6 +6,7 @@ dependencies { implementation project(path:':domain-cvi-oauth-service', configuration: 'default') implementation project(path:':domain-cvi-publicdata-service', configuration: 'default') implementation project(path:':domain-cvi-scheduler', configuration: 'default') + implementation project(path:':domain-cvi-aws-s3-service', configuration: 'default') implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' @@ -14,6 +15,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-cache' implementation 'javax.cache:cache-api:1.1.1' implementation 'org.ehcache:ehcache:3.9.4' + + testImplementation 'io.rest-assured:rest-assured:4.3.3' } jacocoTestCoverageVerification { // 코드 커버리지 측정항목 시행 diff --git a/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java b/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java index 2f47cfd2..209d3c09 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/DataLoader.java @@ -1,6 +1,7 @@ package com.cvi; import com.cvi.comment.domain.model.Comment; +import com.cvi.comment.domain.repository.CommentRepository; import com.cvi.like.domain.model.Like; import com.cvi.like.domain.repository.LikeRepository; import com.cvi.post.domain.model.Post; @@ -10,22 +11,24 @@ import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; import com.cvi.user.domain.repository.UserRepository; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; +import javax.persistence.EntityManager; +import javax.persistence.Query; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; -import javax.persistence.EntityManager; -import javax.persistence.Query; -import java.sql.Timestamp; -import java.time.LocalDateTime; -import java.util.*; - @Component @RequiredArgsConstructor -@Profile("local") +@Profile("dev") public class DataLoader implements CommandLineRunner { private static final int USER_COUNT = 50; @@ -33,15 +36,17 @@ public class DataLoader implements CommandLineRunner { private final UserRepository userRepository; private final PostRepository postRepository; private final LikeRepository likeRepository; + private final CommentRepository commentRepository; private final Random random = new Random(); - - @Autowired private final EntityManager em; @Override @Transactional public void run(String... args) { - if (userRepository.findAll().isEmpty()) { + if (userRepository.findAll().isEmpty() + && postRepository.findAll().isEmpty() + && likeRepository.findAll().isEmpty() + && commentRepository.findAll().isEmpty()) { List users = new ArrayList<>(); for (int i = 0; i < USER_COUNT; i++) { User user = User.builder().nickname(String.valueOf(i)).socialId("socialId").socialProvider(SocialProvider.KAKAO).profileUrl("pictureUrl").ageRange(AgeRange.FIFTIES).build(); diff --git a/backend/app-cvi-api/src/main/java/com/cvi/DummyData.java b/backend/app-cvi-api/src/main/java/com/cvi/DummyData.java index 6948132d..4cef64d3 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/DummyData.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/DummyData.java @@ -2,39 +2,38 @@ public class DummyData { public static final String DUMMY_DATA_10000 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean odio orci, venenatis sed vulputate quis, ultricies non massa. Nulla commodo justo at metus consequat hendrerit. Sed nec mauris urna. Nunc turpis est, pulvinar vitae tellus non, sollicitudin commodo ligula. Nullam est ante, faucibus id leo malesuada, elementum hendrerit tortor. Sed id metus eu leo aliquet faucibus et ac felis. Aliquam nec laoreet est, interdum tempor mauris. Etiam feugiat, ante sed ullamcorper euismod, ligula lorem ultricies nisi, nec bibendum est dui eget metus. Nam ac congue libero.\n" + - "\n" + - "Pellentesque blandit risus quis consequat maximus. Donec ullamcorper facilisis ante, non luctus ex condimentum quis. Quisque pulvinar sagittis nulla at pulvinar. Nam mi urna, rutrum non erat id, dapibus ultricies tortor. Aliquam malesuada metus eu erat imperdiet pulvinar. In eget iaculis metus. Suspendisse nec orci auctor, egestas elit ut, ultrices sapien. Suspendisse tincidunt iaculis tellus id scelerisque. In non congue orci. Aliquam erat volutpat. Sed iaculis diam at justo porttitor, pulvinar tristique mauris finibus. Sed lobortis venenatis nunc sit amet cursus. Aenean mattis enim lectus, sit amet ullamcorper arcu sodales id.\n" + - "\n" + - "Quisque ornare tincidunt enim. Maecenas quis laoreet mi, in hendrerit lacus. Praesent id turpis in sapien euismod accumsan. Cras euismod sollicitudin sem nec aliquet. Aenean magna ex, luctus ut nulla id, consectetur sodales risus. Curabitur interdum elit et consectetur aliquet. Morbi non fringilla nisl.\n" + - "\n" + - "Donec neque elit, dapibus in malesuada at, convallis in dui. Donec consectetur dignissim magna, et ultrices felis finibus id. Etiam a urna lectus. Proin neque metus, iaculis eget mauris ac, congue vulputate nisl. Pellentesque sodales felis eu diam scelerisque molestie. Pellentesque commodo tempus vestibulum. Proin non quam egestas, pulvinar augue eu, hendrerit lorem. Aenean vel mollis nisi, sit amet scelerisque dolor. Vestibulum feugiat eleifend tellus, ac auctor ex ultricies ut. Aenean volutpat vulputate risus a euismod. Nulla tincidunt massa pulvinar dapibus pharetra. Curabitur a blandit lectus, vel posuere purus. Ut erat diam, bibendum vitae luctus quis, sollicitudin eget magna. Phasellus dignissim in odio feugiat blandit. Etiam porta sollicitudin massa sit amet auctor. Suspendisse rutrum pellentesque fermentum.\n" + - "\n" + - "Maecenas non faucibus lorem, eget tempor sapien. Pellentesque ac augue id justo malesuada blandit. In auctor varius scelerisque. Nunc cursus id elit et facilisis. Aenean in egestas erat. Nullam eleifend vitae diam at vehicula. Suspendisse ut diam at elit mollis accumsan. Nulla facilisi.\n" + - "\n" + - "Etiam vel elit a lorem efficitur ullamcorper id laoreet neque. Pellentesque nec imperdiet urna. Vestibulum sodales ante ac justo rutrum, id tempus nulla tincidunt. Aenean accumsan posuere enim eu vestibulum. Donec ex metus, molestie ac enim a, ultrices dapibus ipsum. Pellentesque neque quam, lobortis a lacus sed, molestie finibus urna. Curabitur a dolor quis ante malesuada blandit.\n" + - "\n" + - "Aliquam in massa ac odio mollis malesuada vel et diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam placerat feugiat elit eget iaculis. Cras arcu arcu, suscipit ac mi eu, pharetra pulvinar diam. Praesent tincidunt, lorem id auctor mollis, mi ipsum rhoncus mauris, vel placerat elit massa quis leo. Curabitur et mi fringilla quam blandit pulvinar. Nunc enim sem, maximus vitae sem at, posuere euismod risus. Duis euismod ullamcorper sem eget semper. Curabitur et neque vitae neque euismod pharetra. Curabitur vel mi accumsan, facilisis neque nec, consequat lectus. Mauris tristique velit vitae congue consequat. Donec sit amet tortor sed ante congue bibendum a cursus libero.\n" + - "\n" + - "Praesent tristique eget neque quis bibendum. Donec quis ante sed orci varius maximus. Praesent gravida in massa nec tincidunt. Nulla facilisi. Praesent magna enim, placerat eu libero id, hendrerit malesuada diam. Fusce vestibulum nulla ut erat elementum iaculis. Fusce eu posuere purus. Quisque efficitur rutrum metus quis vestibulum.\n" + - "\n" + - "Fusce vitae semper orci. Quisque eu urna lobortis, auctor magna quis, pellentesque sem. Etiam vitae vehicula dolor, sit amet pretium nulla. Ut efficitur pretium augue in luctus. Vestibulum in odio a diam tristique efficitur. Nulla egestas quis risus at imperdiet. Maecenas eget bibendum nisi, eu faucibus odio.\n" + - "\n" + - "Vestibulum porttitor a nulla a varius. Pellentesque nec lacinia nunc, nec elementum est. Vivamus commodo tortor et velit euismod blandit. Maecenas luctus pharetra velit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque vulputate leo at nisi rutrum mattis. Pellentesque luctus malesuada turpis. Duis non erat quis eros hendrerit accumsan.\n" + - "\n" + - "Vivamus placerat, mi vitae fermentum pulvinar, massa lacus commodo tellus, in elementum neque purus elementum odio. Donec auctor volutpat finibus. Cras feugiat eu ipsum eu tincidunt. Sed non tortor ultrices, cursus sapien in, euismod nibh. Nunc interdum viverra dignissim. Nunc finibus finibus fermentum. Proin faucibus blandit lorem, nec pretium quam fermentum nec. In id euismod nisi, eu euismod tellus. Nulla interdum, arcu id vehicula viverra, lacus velit pellentesque sapien, sit amet sollicitudin erat metus in augue. Proin in congue dui. Aenean pharetra odio nec ornare suscipit. Nunc et libero magna. In ut quam ante.\n" + - "\n" + - "Fusce dignissim scelerisque neque ut tincidunt. Quisque ut lacinia metus, ut luctus lacus. Vivamus et dictum metus, et cursus libero. Phasellus turpis libero, hendrerit a mollis ac, semper feugiat urna. Nullam id sagittis quam, eu facilisis enim. Maecenas in tortor lacinia, aliquet felis non, congue leo. Proin enim massa, malesuada interdum tempus eget, venenatis id tellus. Etiam ultricies, lacus quis egestas pulvinar, ipsum nibh luctus nisl, sed interdum felis leo eu leo. Mauris faucibus semper nisi at rhoncus. Quisque vel venenatis nisi. Ut consectetur mauris nec magna lacinia fringilla. Nullam luctus fermentum odio. Donec ultricies augue sed dui elementum, sed euismod nibh laoreet. Maecenas condimentum sapien at faucibus mattis. Pellentesque porttitor sed tortor et faucibus. Aliquam sed quam eget lacus aliquam molestie sit amet at urna.\n" + - "\n" + - "Curabitur eget metus interdum diam volutpat efficitur. Maecenas viverra massa in est volutpat, eu convallis nisi eleifend. Sed molestie sagittis mauris. Quisque id arcu vitae lorem tristique pretium. Mauris cursus ex dolor, nec malesuada urna iaculis sit amet. Mauris pharetra magna eget sapien varius aliquet. Maecenas pulvinar orci non condimentum dictum. Maecenas faucibus rutrum arcu, nec aliquet elit dignissim ut. Integer ullamcorper massa eu lectus malesuada rutrum. Vestibulum maximus euismod ante, a euismod augue dapibus non. Praesent tellus orci, tempus quis dignissim id, ultricies porta felis. Maecenas ut ipsum dolor.\n" + - "\n" + - "Mauris pulvinar nisi et lorem elementum tristique. Vestibulum tempus, nunc id dictum condimentum, felis nisl dapibus sem, sit amet commodo metus tortor ut dui. Suspendisse viverra urna efficitur massa pellentesque mattis. Sed posuere, urna mollis bibendum ornare, felis dui congue nibh, sed placerat velit tellus vitae tellus. Cras maximus blandit diam nec feugiat. Nunc bibendum erat vitae libero lobortis pulvinar. In ut aliquam orci. Donec feugiat, ex congue pretium dictum, justo enim feugiat risus, malesuada ornare purus diam quis turpis. Phasellus vitae est id turpis consectetur semper. Quisque vel euismod justo, molestie vestibulum leo. Donec nibh nunc, rutrum ut diam ut, tincidunt bibendum est. Donec tristique dolor et interdum mollis. Aliquam a mi nulla.\n" + - "\n" + - "Morbi hendrerit sagittis nulla quis porta. Phasellus vitae vehicula sem, non mollis lorem. Donec mollis vestibulum nunc, vitae laoreet neque consectetur eget. Sed varius urna et urna porttitor, eu imperdiet velit sollicitudin. Nulla dolor dui, imperdiet at facilisis eget, scelerisque sed nisi. Integer maximus congue viverra. Ut mattis faucibus fermentum. Donec malesuada mattis sollicitudin. Maecenas vel est fringilla, elementum lectus et, rutrum mauris. Sed non viverra purus, ut finibus felis. Nunc ac fermentum tortor, non faucibus mauris.\n" + - "\n" + - "Aliquam erat volutpat. Etiam nulla erat, pretium id enim quis, hendrerit congue ligula. Sed vitae accumsan sem. Praesent ligula turpis, bibendum vitae nulla ut, efficitur commodo erat. Vestibulum odio nibh, convallis id ligula eget, pretium condimentum erat. Nam molestie tortor nec nibh ornare, at ultricies massa molestie. Aenean sodales dolor risus, sed fringilla purus interdum accumsan. In hac habitasse platea dictumst. In sit amet nisl nec leo sagittis tincidunt. Pellentesque at ligula at sapien suscipit facilisis. Sed nec feugiat neque. Sed eu neque lectus. Nullam sed magna ac mi pretium tristique. Integer at velit erat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris efficitur nisl eget metus porta, ut tincidunt felis ultricies.\n" + - "\n" + - "Nullam sit amet maximus lacus. Suspendisse elit erat, vestibulum vel magna mollis, iaculis hendrerit eros. Praesent quis eros sed lorem faucibus feugiat vitae non sapien. Aliquam non mi sed dolor accumsan finibus id in odio. Nunc a placerat mauris. In hac habitasse platea dictumst. Curabitur quis diam facilisis, vulputate ligula nec, auctor mauris. Suspendisse potenti. Duis tempor neque diam, vel ornare metus fringilla quis. Proin a odio non nisi egestas blandit. Vestibulum sit amet leo odio. Nulla quis quam vel mauris eleifend dapibus et sed sapien. Suspendisse cursus porta augue, sed scelerisque libero faucibus quis. Vestibulum ipsum sem, pulvinar id tellus a, tincidunt cursus velit. Pellentesque tristique interdum est, nec sollicitudin justo efficitur quis.\n" + - "\n" + - "Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed tellus nulla, fringilla ut tortor ut, pellentesque faucibus dui. Donec posuere risus ut enim fermentum tristique. Nullam a erat nec massa rutrum bibendum. Duis rutrum porttitor massa nunc."; + "\n" + + "Pellentesque blandit risus quis consequat maximus. Donec ullamcorper facilisis ante, non luctus ex condimentum quis. Quisque pulvinar sagittis nulla at pulvinar. Nam mi urna, rutrum non erat id, dapibus ultricies tortor. Aliquam malesuada metus eu erat imperdiet pulvinar. In eget iaculis metus. Suspendisse nec orci auctor, egestas elit ut, ultrices sapien. Suspendisse tincidunt iaculis tellus id scelerisque. In non congue orci. Aliquam erat volutpat. Sed iaculis diam at justo porttitor, pulvinar tristique mauris finibus. Sed lobortis venenatis nunc sit amet cursus. Aenean mattis enim lectus, sit amet ullamcorper arcu sodales id.\n" + + "\n" + + "Quisque ornare tincidunt enim. Maecenas quis laoreet mi, in hendrerit lacus. Praesent id turpis in sapien euismod accumsan. Cras euismod sollicitudin sem nec aliquet. Aenean magna ex, luctus ut nulla id, consectetur sodales risus. Curabitur interdum elit et consectetur aliquet. Morbi non fringilla nisl.\n" + + "\n" + + "Donec neque elit, dapibus in malesuada at, convallis in dui. Donec consectetur dignissim magna, et ultrices felis finibus id. Etiam a urna lectus. Proin neque metus, iaculis eget mauris ac, congue vulputate nisl. Pellentesque sodales felis eu diam scelerisque molestie. Pellentesque commodo tempus vestibulum. Proin non quam egestas, pulvinar augue eu, hendrerit lorem. Aenean vel mollis nisi, sit amet scelerisque dolor. Vestibulum feugiat eleifend tellus, ac auctor ex ultricies ut. Aenean volutpat vulputate risus a euismod. Nulla tincidunt massa pulvinar dapibus pharetra. Curabitur a blandit lectus, vel posuere purus. Ut erat diam, bibendum vitae luctus quis, sollicitudin eget magna. Phasellus dignissim in odio feugiat blandit. Etiam porta sollicitudin massa sit amet auctor. Suspendisse rutrum pellentesque fermentum.\n" + + "\n" + + "Maecenas non faucibus lorem, eget tempor sapien. Pellentesque ac augue id justo malesuada blandit. In auctor varius scelerisque. Nunc cursus id elit et facilisis. Aenean in egestas erat. Nullam eleifend vitae diam at vehicula. Suspendisse ut diam at elit mollis accumsan. Nulla facilisi.\n" + + "\n" + + "Etiam vel elit a lorem efficitur ullamcorper id laoreet neque. Pellentesque nec imperdiet urna. Vestibulum sodales ante ac justo rutrum, id tempus nulla tincidunt. Aenean accumsan posuere enim eu vestibulum. Donec ex metus, molestie ac enim a, ultrices dapibus ipsum. Pellentesque neque quam, lobortis a lacus sed, molestie finibus urna. Curabitur a dolor quis ante malesuada blandit.\n" + + "\n" + + "Aliquam in massa ac odio mollis malesuada vel et diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam placerat feugiat elit eget iaculis. Cras arcu arcu, suscipit ac mi eu, pharetra pulvinar diam. Praesent tincidunt, lorem id auctor mollis, mi ipsum rhoncus mauris, vel placerat elit massa quis leo. Curabitur et mi fringilla quam blandit pulvinar. Nunc enim sem, maximus vitae sem at, posuere euismod risus. Duis euismod ullamcorper sem eget semper. Curabitur et neque vitae neque euismod pharetra. Curabitur vel mi accumsan, facilisis neque nec, consequat lectus. Mauris tristique velit vitae congue consequat. Donec sit amet tortor sed ante congue bibendum a cursus libero.\n" + + "\n" + + "Praesent tristique eget neque quis bibendum. Donec quis ante sed orci varius maximus. Praesent gravida in massa nec tincidunt. Nulla facilisi. Praesent magna enim, placerat eu libero id, hendrerit malesuada diam. Fusce vestibulum nulla ut erat elementum iaculis. Fusce eu posuere purus. Quisque efficitur rutrum metus quis vestibulum.\n" + + "\n" + + "Fusce vitae semper orci. Quisque eu urna lobortis, auctor magna quis, pellentesque sem. Etiam vitae vehicula dolor, sit amet pretium nulla. Ut efficitur pretium augue in luctus. Vestibulum in odio a diam tristique efficitur. Nulla egestas quis risus at imperdiet. Maecenas eget bibendum nisi, eu faucibus odio.\n" + + "\n" + + "Vestibulum porttitor a nulla a varius. Pellentesque nec lacinia nunc, nec elementum est. Vivamus commodo tortor et velit euismod blandit. Maecenas luctus pharetra velit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque vulputate leo at nisi rutrum mattis. Pellentesque luctus malesuada turpis. Duis non erat quis eros hendrerit accumsan.\n" + + "\n" + + "Vivamus placerat, mi vitae fermentum pulvinar, massa lacus commodo tellus, in elementum neque purus elementum odio. Donec auctor volutpat finibus. Cras feugiat eu ipsum eu tincidunt. Sed non tortor ultrices, cursus sapien in, euismod nibh. Nunc interdum viverra dignissim. Nunc finibus finibus fermentum. Proin faucibus blandit lorem, nec pretium quam fermentum nec. In id euismod nisi, eu euismod tellus. Nulla interdum, arcu id vehicula viverra, lacus velit pellentesque sapien, sit amet sollicitudin erat metus in augue. Proin in congue dui. Aenean pharetra odio nec ornare suscipit. Nunc et libero magna. In ut quam ante.\n" + + "\n" + + "Fusce dignissim scelerisque neque ut tincidunt. Quisque ut lacinia metus, ut luctus lacus. Vivamus et dictum metus, et cursus libero. Phasellus turpis libero, hendrerit a mollis ac, semper feugiat urna. Nullam id sagittis quam, eu facilisis enim. Maecenas in tortor lacinia, aliquet felis non, congue leo. Proin enim massa, malesuada interdum tempus eget, venenatis id tellus. Etiam ultricies, lacus quis egestas pulvinar, ipsum nibh luctus nisl, sed interdum felis leo eu leo. Mauris faucibus semper nisi at rhoncus. Quisque vel venenatis nisi. Ut consectetur mauris nec magna lacinia fringilla. Nullam luctus fermentum odio. Donec ultricies augue sed dui elementum, sed euismod nibh laoreet. Maecenas condimentum sapien at faucibus mattis. Pellentesque porttitor sed tortor et faucibus. Aliquam sed quam eget lacus aliquam molestie sit amet at urna.\n" + + "\n" + + "Curabitur eget metus interdum diam volutpat efficitur. Maecenas viverra massa in est volutpat, eu convallis nisi eleifend. Sed molestie sagittis mauris. Quisque id arcu vitae lorem tristique pretium. Mauris cursus ex dolor, nec malesuada urna iaculis sit amet. Mauris pharetra magna eget sapien varius aliquet. Maecenas pulvinar orci non condimentum dictum. Maecenas faucibus rutrum arcu, nec aliquet elit dignissim ut. Integer ullamcorper massa eu lectus malesuada rutrum. Vestibulum maximus euismod ante, a euismod augue dapibus non. Praesent tellus orci, tempus quis dignissim id, ultricies porta felis. Maecenas ut ipsum dolor.\n" + + "\n" + + "Mauris pulvinar nisi et lorem elementum tristique. Vestibulum tempus, nunc id dictum condimentum, felis nisl dapibus sem, sit amet commodo metus tortor ut dui. Suspendisse viverra urna efficitur massa pellentesque mattis. Sed posuere, urna mollis bibendum ornare, felis dui congue nibh, sed placerat velit tellus vitae tellus. Cras maximus blandit diam nec feugiat. Nunc bibendum erat vitae libero lobortis pulvinar. In ut aliquam orci. Donec feugiat, ex congue pretium dictum, justo enim feugiat risus, malesuada ornare purus diam quis turpis. Phasellus vitae est id turpis consectetur semper. Quisque vel euismod justo, molestie vestibulum leo. Donec nibh nunc, rutrum ut diam ut, tincidunt bibendum est. Donec tristique dolor et interdum mollis. Aliquam a mi nulla.\n" + + "\n" + + "Morbi hendrerit sagittis nulla quis porta. Phasellus vitae vehicula sem, non mollis lorem. Donec mollis vestibulum nunc, vitae laoreet neque consectetur eget. Sed varius urna et urna porttitor, eu imperdiet velit sollicitudin. Nulla dolor dui, imperdiet at facilisis eget, scelerisque sed nisi. Integer maximus congue viverra. Ut mattis faucibus fermentum. Donec malesuada mattis sollicitudin. Maecenas vel est fringilla, elementum lectus et, rutrum mauris. Sed non viverra purus, ut finibus felis. Nunc ac fermentum tortor, non faucibus mauris.\n" + + "\n" + + "Aliquam erat volutpat. Etiam nulla erat, pretium id enim quis, hendrerit congue ligula. Sed vitae accumsan sem. Praesent ligula turpis, bibendum vitae nulla ut, efficitur commodo erat. Vestibulum odio nibh, convallis id ligula eget, pretium condimentum erat. Nam molestie tortor nec nibh ornare, at ultricies massa molestie. Aenean sodales dolor risus, sed fringilla purus interdum accumsan. In hac habitasse platea dictumst. In sit amet nisl nec leo sagittis tincidunt. Pellentesque at ligula at sapien suscipit facilisis. Sed nec feugiat neque. Sed eu neque lectus. Nullam sed magna ac mi pretium tristique. Integer at velit erat. Interdum et malesuada fames ac ante ipsum primis in faucibus. Mauris efficitur nisl eget metus porta, ut tincidunt felis ultricies.\n" + + "\n" + + "Nullam sit amet maximus lacus. Suspendisse elit erat, vestibulum vel magna mollis, iaculis hendrerit eros. Praesent quis eros sed lorem faucibus feugiat vitae non sapien. Aliquam non mi sed dolor accumsan finibus id in odio. Nunc a placerat mauris. In hac habitasse platea dictumst. Curabitur quis diam facilisis, vulputate ligula nec, auctor mauris. Suspendisse potenti. Duis tempor neque diam, vel ornare metus fringilla quis. Proin a odio non nisi egestas blandit. Vestibulum sit amet leo odio. Nulla quis quam vel mauris eleifend dapibus et sed sapien. Suspendisse cursus porta augue, sed scelerisque libero faucibus quis. Vestibulum ipsum sem, pulvinar id tellus a, tincidunt cursus velit. Pellentesque tristique interdum est, nec sollicitudin justo efficitur quis.\n" + + "\n" + + "Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed tellus nulla, fringilla ut tortor ut, pellentesque faucibus dui. Donec posuere risus ut enim fermentum tristique. Nullam a erat nec massa rutrum bibendum. Duis rutrum porttitor massa nunc."; } - diff --git a/backend/app-cvi-api/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java b/backend/app-cvi-api/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java index 2986ec15..65cccd3d 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/auth/AuthenticationPrincipalArgumentResolver.java @@ -1,10 +1,11 @@ package com.cvi.auth; -import com.cvi.exception.NotFoundException; +import com.cvi.service.UserService; import com.cvi.user.domain.model.User; -import com.cvi.user.domain.repository.UserRepository; +import java.util.Objects; +import java.util.Optional; +import javax.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; import org.springframework.web.bind.support.WebDataBinderFactory; @@ -12,17 +13,12 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; -import javax.servlet.http.HttpServletRequest; -import java.util.Objects; -import java.util.Optional; - -@Slf4j @Component @RequiredArgsConstructor public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArgumentResolver { private final JwtTokenProvider jwtTokenProvider; - private final UserRepository userRepository; + private final UserService userService; @Override public boolean supportsParameter(MethodParameter parameter) { @@ -34,12 +30,8 @@ public Optional resolveArgument(MethodParameter parameter, ModelAndViewCon String accessToken = AuthorizationExtractor.extract(Objects.requireNonNull(webRequest.getNativeRequest(HttpServletRequest.class))); if (jwtTokenProvider.isValidToken(accessToken)) { String id = jwtTokenProvider.getPayload(accessToken); - final Optional user = userRepository.findById(Long.valueOf(id)); - if (user.isPresent()) { - return user; - } - log.info("해당 id의 사용자가 없습니다. 입력값: {}", id); - throw new NotFoundException(String.format("해당 id의 사용자가 없습니다. 입력값: %s", id)); + User user = userService.findUserById(Long.valueOf(id)); + return Optional.of(user); } return Optional.empty(); } diff --git a/backend/app-cvi-api/src/main/java/com/cvi/controller/AuthController.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/AuthController.java index 11525fde..a6c52064 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/controller/AuthController.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/AuthController.java @@ -3,12 +3,16 @@ import com.cvi.dto.AuthRequest; import com.cvi.dto.UserResponse; import com.cvi.service.AuthService; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; - +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/v1/auth") @@ -19,9 +23,9 @@ public class AuthController { @PostMapping @ResponseStatus(HttpStatus.OK) - public UserResponse authenticate(@RequestBody @Valid AuthRequest authRequest, HttpServletResponse httpServletResponse) { - UserResponse userResponse = authService.authenticate(authRequest); - httpServletResponse.setHeader("Authorization", userResponse.getAccessToken()); + public UserResponse authenticate(@RequestBody @Valid AuthRequest authRequest, HttpServletRequest request, HttpServletResponse response) { + UserResponse userResponse = authService.authenticate(authRequest, request.getHeader("Origin")); + response.setHeader("Authorization", userResponse.getAccessToken()); return userResponse; } } diff --git a/backend/app-cvi-api/src/main/java/com/cvi/controller/PostController.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/PostController.java index 87ed5ed6..a3e76dad 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/controller/PostController.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/PostController.java @@ -5,7 +5,7 @@ import com.cvi.dto.PostResponse; import com.cvi.post.domain.model.Sort; import com.cvi.post.domain.model.VaccinationType; -import com.cvi.service.PostService; +import com.cvi.service.post.PostService; import com.cvi.user.domain.model.User; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; @@ -43,7 +43,7 @@ public List findByVaccineTypeAndPaging(@RequestParam(defaultValue @RequestParam(defaultValue = "0") int offset, @RequestParam(defaultValue = "6") int size, @RequestParam(defaultValue = "CREATED_AT_DESC") Sort sort, - @RequestParam(defaultValue = "#{T(java.lang.String).valueOf(T(java.lang.Integer).MAX_VALUE)}") int fromHoursBefore, + @RequestParam(defaultValue = "500") int fromHoursBefore, @AuthenticationPrincipal Optional user) { return postService.findByVaccineType(vaccinationType, offset, size, sort, fromHoursBefore, user); } diff --git a/backend/app-cvi-api/src/main/java/com/cvi/controller/UserController.java b/backend/app-cvi-api/src/main/java/com/cvi/controller/UserController.java index 4a7103c3..2d28d0fe 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/controller/UserController.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/controller/UserController.java @@ -5,7 +5,7 @@ import com.cvi.dto.UserRequest; import com.cvi.dto.UserResponse; import com.cvi.post.domain.model.Filter; -import com.cvi.service.PostService; +import com.cvi.service.post.PostService; import com.cvi.service.UserService; import com.cvi.user.domain.model.User; import lombok.RequiredArgsConstructor; @@ -71,4 +71,4 @@ public UserResponse find(@PathVariable Long id) { public void delete(@AuthenticationPrincipal Optional user) { userService.delete(user); } -} \ No newline at end of file +} diff --git a/backend/app-cvi-api/src/main/java/com/cvi/dto/ImageRequest.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/ImageRequest.java new file mode 100644 index 00000000..cedbcf71 --- /dev/null +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/ImageRequest.java @@ -0,0 +1,21 @@ +package com.cvi.dto; + +import com.cvi.image.domain.ImageType; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ImageRequest { + + private ImageType type; + private String data; + + @Builder + public ImageRequest(ImageType type, String data) { + this.type = type; + this.data = data; + } +} diff --git a/backend/app-cvi-api/src/main/java/com/cvi/dto/PostRequest.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostRequest.java index e9e6e78c..192d6d56 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/dto/PostRequest.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostRequest.java @@ -2,12 +2,14 @@ import com.cvi.post.domain.model.Post; import com.cvi.post.domain.model.VaccinationType; +import java.util.Collections; +import java.util.List; +import javax.validation.constraints.NotBlank; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotBlank; - @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class PostRequest { @@ -15,16 +17,23 @@ public class PostRequest { @NotBlank(message = "게시글의 내용은 비어있을 수 없습니다.") private String content; private VaccinationType vaccinationType; + private List images; - public PostRequest(String content, VaccinationType vaccinationType) { + @Builder + public PostRequest(String content, VaccinationType vaccinationType, List images) { this.content = content; this.vaccinationType = vaccinationType; + this.images = images; + } + + public PostRequest(String content, VaccinationType vaccinationType) { + this(content, vaccinationType, Collections.emptyList()); } public Post toEntity() { return Post.builder() - .content(content) - .vaccinationType(vaccinationType) - .build(); + .content(content) + .vaccinationType(vaccinationType) + .build(); } } diff --git a/backend/app-cvi-api/src/main/java/com/cvi/dto/PostResponse.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostResponse.java index 6607657a..eab031bb 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/dto/PostResponse.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostResponse.java @@ -3,13 +3,13 @@ import com.cvi.post.domain.model.Post; import com.cvi.post.domain.model.VaccinationType; import com.cvi.user.domain.model.User; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -24,11 +24,12 @@ public class PostResponse { private boolean hasLiked; private VaccinationType vaccinationType; private LocalDateTime createdAt; + private List images; - public PostResponse(Long id, UserResponse user, String content, int viewCount, int likeCount, int commentCount, - boolean hasLiked, VaccinationType vaccinationType, LocalDateTime createdAt) { + @Builder + public PostResponse(Long id, UserResponse writer, String content, int viewCount, int likeCount, int commentCount, boolean hasLiked, VaccinationType vaccinationType, LocalDateTime createdAt, List imageUrls) { this.id = id; - this.writer = user; + this.writer = writer; this.content = content; this.viewCount = viewCount; this.likeCount = likeCount; @@ -36,17 +37,22 @@ public PostResponse(Long id, UserResponse user, String content, int viewCount, i this.hasLiked = hasLiked; this.vaccinationType = vaccinationType; this.createdAt = createdAt; + this.images = imageUrls; } public static PostResponse of(Post post, User viewer) { return new PostResponse(post.getId(), UserResponse.of(post.getUser(), null), post.getContent(), - post.getViewCount(), post.getLikesCount(), post.getCommentsAsList().size(), post.isAlreadyLikedBy(viewer), post.getVaccinationType(), post.getCreatedAt()); + post.getViewCount(), post.getLikesCount(), post.getCommentsAsList().size(), post.isAlreadyLikedBy(viewer), post.getVaccinationType(), post.getCreatedAt(), post.getImagesAsUrlList()); + } + + public static PostResponse of(Post post, User viewer, List imageUrls) { + return new PostResponse(post.getId(), UserResponse.of(post.getUser(), null), post.getContent(), + post.getViewCount(), post.getLikesCount(), post.getCommentsAsList().size(), post.isAlreadyLikedBy(viewer), post.getVaccinationType(), post.getCreatedAt(), imageUrls); } public static List toList(List posts, User viewer) { return posts.stream() - .map(post -> PostResponse.of(post, viewer)) - .collect(Collectors.toList()); + .map(post -> PostResponse.of(post, viewer)) + .collect(Collectors.toList()); } } - diff --git a/backend/app-cvi-api/src/main/java/com/cvi/dto/PostWithCommentResponse.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostWithCommentResponse.java index 5b8779d3..6266866f 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/dto/PostWithCommentResponse.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/PostWithCommentResponse.java @@ -25,9 +25,10 @@ public class PostWithCommentResponse { private List comments; private VaccinationType vaccinationType; private LocalDateTime createdAt; + private List images; public PostWithCommentResponse(Long id, UserResponse user, String content, int viewCount, int likeCount, - boolean hasLiked, List comments, VaccinationType vaccinationType, LocalDateTime createdAt) { + boolean hasLiked, List comments, VaccinationType vaccinationType, LocalDateTime createdAt, List imageUrls) { this.id = id; this.writer = user; this.content = content; @@ -37,22 +38,24 @@ public PostWithCommentResponse(Long id, UserResponse user, String content, int v this.comments = comments; this.vaccinationType = vaccinationType; this.createdAt = createdAt; + this.images = imageUrls; } public static PostWithCommentResponse of(Post post, User viewer) { return new PostWithCommentResponse(post.getId(), UserResponse.of(post.getUser(), null), post.getContent(), - post.getViewCount(), post.getLikesCount(), post.isAlreadyLikedBy(viewer), makeCommentResponses(post.getCommentsAsList()), post.getVaccinationType(), post.getCreatedAt()); + post.getViewCount(), post.getLikesCount(), post.isAlreadyLikedBy(viewer), + makeCommentResponses(post.getCommentsAsList()), post.getVaccinationType(), post.getCreatedAt(), post.getImagesAsUrlList()); } private static List makeCommentResponses(List comments) { return comments.stream() - .map(CommentResponse::of) - .collect(Collectors.toList()); + .map(CommentResponse::of) + .collect(Collectors.toList()); } public static List toList(List posts, User viewer) { return posts.stream() - .map(post -> PostWithCommentResponse.of(post, viewer)) - .collect(Collectors.toList()); + .map(post -> PostWithCommentResponse.of(post, viewer)) + .collect(Collectors.toList()); } } diff --git a/backend/app-cvi-api/src/main/java/com/cvi/dto/UserRequest.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/UserRequest.java index 86dee0a7..59a19c67 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/dto/UserRequest.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/UserRequest.java @@ -37,7 +37,7 @@ public class UserRequest { @Builder public UserRequest(String nickname, AgeRange ageRange, boolean shotVerified, - SocialProvider socialProvider, String socialId, String socialProfileUrl) { + SocialProvider socialProvider, String socialId, String socialProfileUrl) { this.nickname = nickname; this.ageRange = ageRange; this.shotVerified = shotVerified; @@ -48,12 +48,12 @@ public UserRequest(String nickname, AgeRange ageRange, boolean shotVerified, public User toEntity() { return User.builder() - .nickname(nickname) - .ageRange(ageRange) - .shotVerified(shotVerified) - .socialProvider(socialProvider) - .socialId(socialId) - .profileUrl(socialProfileUrl) - .build(); + .nickname(nickname) + .ageRange(ageRange) + .shotVerified(shotVerified) + .socialProvider(socialProvider) + .socialId(socialId) + .profileUrl(socialProfileUrl) + .build(); } } diff --git a/backend/app-cvi-api/src/main/java/com/cvi/dto/UserResponse.java b/backend/app-cvi-api/src/main/java/com/cvi/dto/UserResponse.java index e596f6e8..10898205 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/dto/UserResponse.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/dto/UserResponse.java @@ -20,7 +20,7 @@ public class UserResponse { private String socialProfileUrl; public UserResponse(Long id, String nickname, AgeRangeResponse ageRange, boolean shotVerified, String accessToken, - SocialProvider socialProvider, String socialId, String socialProfileUrl) { + SocialProvider socialProvider, String socialId, String socialProfileUrl) { this.id = id; this.nickname = nickname; this.ageRange = ageRange; @@ -33,16 +33,16 @@ public UserResponse(Long id, String nickname, AgeRangeResponse ageRange, boolean public static UserResponse of(User user) { return new UserResponse(user.getId(), user.getNickname(), new AgeRangeResponse(user.getAgeRange()), - user.isShotVerified(), null, user.getSocialProvider(), user.getSocialId(), user.getProfileUrl()); + user.isShotVerified(), null, user.getSocialProvider(), user.getSocialId(), user.getProfileUrl()); } public static UserResponse of(User user, String token) { return new UserResponse(user.getId(), user.getNickname(), new AgeRangeResponse(user.getAgeRange()), - user.isShotVerified(), token, user.getSocialProvider(), user.getSocialId(), user.getProfileUrl()); + user.isShotVerified(), token, user.getSocialProvider(), user.getSocialId(), user.getProfileUrl()); } public static UserResponse newUser(SocialProvider socialProvider, String socialId, String socialProfileUrl) { return new UserResponse(null, null, null, false, - null, socialProvider, socialId, socialProfileUrl); + null, socialProvider, socialId, socialProfileUrl); } } diff --git a/backend/app-cvi-api/src/main/java/com/cvi/service/AuthService.java b/backend/app-cvi-api/src/main/java/com/cvi/service/AuthService.java index 715a98fb..af93c2d9 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/service/AuthService.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/AuthService.java @@ -22,9 +22,9 @@ public class AuthService { private final AuthorizationManager authorizationManager; @Transactional - public UserResponse authenticate(AuthRequest authRequest) { + public UserResponse authenticate(AuthRequest authRequest, String requestOrigin) { UserInformation userInformation = - authorizationManager.requestUserInfo(authRequest.getProvider(), authRequest.getCode(), authRequest.getState()); + authorizationManager.requestUserInfo(authRequest.getProvider(), authRequest.getCode(), authRequest.getState(), requestOrigin); return createUserResponse(authRequest, userInformation); } diff --git a/backend/app-cvi-api/src/main/java/com/cvi/service/EnvSecret.java b/backend/app-cvi-api/src/main/java/com/cvi/service/EnvSecret.java new file mode 100644 index 00000000..3943c487 --- /dev/null +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/EnvSecret.java @@ -0,0 +1,21 @@ +package com.cvi.service; + +import javax.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +public class EnvSecret { + + private final Environment env; + + @PostConstruct + public void init() { + log.info("naver.client-secret = " + env.getProperty("security.auth.naver.client-secret")); + log.info("jwt.secret-key = " + env.getProperty("security.jwt.token.secret-key")); + } +} diff --git a/backend/app-cvi-api/src/main/java/com/cvi/service/post/ImageConverter.java b/backend/app-cvi-api/src/main/java/com/cvi/service/post/ImageConverter.java new file mode 100644 index 00000000..217cac5c --- /dev/null +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/post/ImageConverter.java @@ -0,0 +1,42 @@ +package com.cvi.service.post; + +import com.cvi.exception.FileConvertException; +import com.cvi.image.domain.ImageType; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.UUID; +import javax.imageio.ImageIO; +import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.codec.binary.Base64; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class ImageConverter { + + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"); + + public ImageFile convertBytesToImageFile(String data, ImageType imageType) { + final byte[] imageBytes = Base64.decodeBase64(data); + final File file = saveLocal(imageBytes, imageType); + return new ImageFile(file, imageType); + } + + private File saveLocal(byte[] imageBytes, ImageType imageType) { + final String fileNameExtension = imageType.name().toLowerCase(); + try { + final String formattedDateTime = LocalDateTime.now().format(DATE_TIME_FORMATTER); + final File imageFile = new File("post-image_" + formattedDateTime + "_" + UUID.randomUUID() + "." + fileNameExtension); + final BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(imageBytes)); + ImageIO.write(bufferedImage, fileNameExtension, imageFile); + return imageFile; + } catch (IOException e) { + log.info("이미지 파일을 로컬에 저장하는데에 실패했습니다."); + throw new FileConvertException("이미지 로컬 저장 중 예외 발생"); + } + } +} diff --git a/backend/app-cvi-api/src/main/java/com/cvi/service/post/ImageFile.java b/backend/app-cvi-api/src/main/java/com/cvi/service/post/ImageFile.java new file mode 100644 index 00000000..bebe4ef6 --- /dev/null +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/post/ImageFile.java @@ -0,0 +1,28 @@ +package com.cvi.service.post; + +import com.cvi.image.domain.ImageType; +import java.io.File; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Getter +public class ImageFile { + + private final File file; + private final ImageType imageType; + + public ImageFile(File file, ImageType imageType) { + this.file = file; + this.imageType = imageType; + } + + public void delete() { + if (file.delete()) { + log.debug("로컬에 저장되어있는 이미지 파일 삭제 성공"); + return; + } + log.info("로컬에 저장되어있는 이미지 파일 삭제 실패"); + throw new IllegalStateException("로컬에 저장되어있는 이미지 파일 삭제에 실패했습니다."); + } +} diff --git a/backend/app-cvi-api/src/main/java/com/cvi/service/PostService.java b/backend/app-cvi-api/src/main/java/com/cvi/service/post/PostService.java similarity index 65% rename from backend/app-cvi-api/src/main/java/com/cvi/service/PostService.java rename to backend/app-cvi-api/src/main/java/com/cvi/service/post/PostService.java index 8bb8228a..0c0991e3 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/service/PostService.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/post/PostService.java @@ -1,12 +1,15 @@ -package com.cvi.service; +package com.cvi.service.post; import com.cvi.comment.domain.model.Comment; import com.cvi.comment.domain.repository.CommentRepository; +import com.cvi.dto.ImageRequest; import com.cvi.dto.PostRequest; import com.cvi.dto.PostResponse; import com.cvi.dto.PostWithCommentResponse; import com.cvi.exception.NotFoundException; import com.cvi.exception.UnAuthorizedException; +import com.cvi.image.domain.Image; +import com.cvi.image.repository.ImageRepository; import com.cvi.like.domain.model.Like; import com.cvi.like.domain.repository.LikeRepository; import com.cvi.post.domain.model.Filter; @@ -14,16 +17,19 @@ import com.cvi.post.domain.model.Sort; import com.cvi.post.domain.model.VaccinationType; import com.cvi.post.domain.repository.PostRepository; +import com.cvi.uploader.AwsS3Uploader; import com.cvi.user.domain.model.User; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - +import java.io.File; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Transactional(readOnly = true) @Slf4j @@ -31,7 +37,13 @@ @RequiredArgsConstructor public class PostService { + @Value("${aws.s3.directory.path.posts.images}") + private String awsS3PostsImagesDirPath; + + private final ImageConverter imageConverter; + private final AwsS3Uploader awsS3Uploader; private final PostRepository postRepository; + private final ImageRepository imageRepository; private final LikeRepository likeRepository; private final CommentRepository commentRepository; @@ -42,9 +54,43 @@ public PostResponse create(Optional optionalUser, PostRequest postRequest) Post post = postRequest.toEntity(); post.assignUser(writer); postRepository.save(post); + assignImages(post, postRequest.getImages()); return PostResponse.of(post, writer); } + private void assignImages(Post post, List imageRequests) { + if (imageRequests == null || imageRequests.isEmpty()) { + return; + } + final List imageUrls = getUploadedImageUrls(imageRequests); + assignPostToImages(post, imageUrls); + } + + private List getUploadedImageUrls(List imageRequests) { + final List imageUrls = new ArrayList<>(); + for (ImageRequest imageRequest : imageRequests) { + final ImageFile imageFile = imageConverter.convertBytesToImageFile(imageRequest.getData(), imageRequest.getType()); + final File file = imageFile.getFile(); + final String imageUrl = awsS3Uploader.upload(awsS3PostsImagesDirPath, file); + imageFile.delete(); + imageUrls.add(imageUrl); + } + return imageUrls; + } + + private List assignPostToImages(Post post, List imageUrls) { + final List images = new ArrayList<>(); + for (String imageUrl : imageUrls) { + final Image image = Image.builder() + .url(imageUrl) + .build(); + image.assignPost(post); + imageRepository.save(image); + images.add(image); + } + return images; + } + @Transactional public PostResponse findById(Long id, Optional optionalUser) { Post post = findPostByPostId(id); @@ -71,7 +117,27 @@ public void update(Long id, Optional optionalUser, PostRequest postRequest validateSignedin(optionalUser); User user = optionalUser.get(); Post post = findPostByPostId(id); - post.update(postRequest.toEntity(), user); + updateImages(post, postRequest.getImages()); + post.updateContent(postRequest.toEntity(), user); + } + + private void updateImages(Post post, List imageRequests) { + deleteAllImagesInPost(post); + if (imageRequests.isEmpty()) { + return; + } + assignImages(post, imageRequests); + } + + private void deleteAllImagesInPost(Post post) { + deleteImagesFromAwsS3(post.getS3PathsOfAllImages()); + imageRepository.deleteAll(post.getAllImagesAsList()); + } + + private void deleteImagesFromAwsS3(List s3PathsToDelete) { + for (String path : s3PathsToDelete) { + awsS3Uploader.delete(awsS3PostsImagesDirPath, path); + } } @Transactional @@ -80,13 +146,15 @@ public void delete(Long id, Optional optionalUser) { User user = optionalUser.get(); Post post = findPostByPostId(id); post.validateAuthor(user); + deleteImagesFromAwsS3(post.getS3PathsOfAllImages()); + imageRepository.deleteAll(post.getAllImagesAsList()); postRepository.deleteById(id); } private Post findPostByPostId(Long id) { validateNotNull(id); return postRepository.findById(id) - .orElseThrow(() -> new NotFoundException("해당 id의 게시글이 존재하지 않습니다.")); + .orElseThrow(() -> new NotFoundException("해당 id의 게시글이 존재하지 않습니다.")); } private void validateSignedin(Optional user) { @@ -122,17 +190,17 @@ private List createPostsResponseByFilter(Filter filter, private List createResponsesFilteredByLikes(User user) { List likes = likeRepository.findByUserId(user.getId()); List posts = likes.stream() - .map(Like::getPost) - .collect(Collectors.toList()); + .map(Like::getPost) + .collect(Collectors.toList()); return PostWithCommentResponse.toList(posts, user); } private List createResponsesFilteredByComments(User user) { List comments = commentRepository.findByUserId(user.getId()); List posts = comments.stream() - .map(Comment::getPost) - .distinct() - .collect(Collectors.toList()); + .map(Comment::getPost) + .distinct() + .collect(Collectors.toList()); return PostWithCommentResponse.toList(posts, user); } @@ -152,17 +220,17 @@ public List findByUserAndFilter(Filter filter, int offs private List createResponsesFilteredByLikes(User user, int offset, int size) { List likes = likeRepository.findByUserId(user.getId(), offset, size); List posts = likes.stream() - .map(Like::getPost) - .collect(Collectors.toList()); + .map(Like::getPost) + .collect(Collectors.toList()); return PostWithCommentResponse.toList(posts, user); } private List createResponsesFilteredByComments(User user, int offset, int size) { List comments = commentRepository.findByUserId(user.getId(), offset, size); List posts = comments.stream() - .map(Comment::getPost) - .distinct() - .collect(Collectors.toList()); + .map(Comment::getPost) + .distinct() + .collect(Collectors.toList()); return PostWithCommentResponse.toList(posts, user); } } diff --git a/backend/app-cvi-api/src/main/resources/ehcache.xml b/backend/app-cvi-api/src/main/resources/ehcache.xml index c43a4ca7..4536b906 100644 --- a/backend/app-cvi-api/src/main/resources/ehcache.xml +++ b/backend/app-cvi-api/src/main/resources/ehcache.xml @@ -9,7 +9,7 @@ - com.cvi.service.CacheEventLogger + com.backjoongwon.cvi.common.cache.CacheEventLogger ASYNCHRONOUS UNORDERED CREATED diff --git a/backend/app-cvi-api/src/main/resources/file-debug-appender.xml b/backend/app-cvi-api/src/main/resources/file-debug-appender.xml new file mode 100644 index 00000000..303c9239 --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/file-debug-appender.xml @@ -0,0 +1,18 @@ + + + ${LOG_LOCATION}/${DEBUG_LOCATION}/debug-${BY_DATE}.log + + DEBUG + ACCEPT + DENY + + + ${LOG_PATTERN} + + + ${BACKUP_LOCATION}/${DEBUG_LOCATION}/debug-%d{yyyy-MM-dd}.%i.log + ${MAX_FILE_SIZE} + ${MAX_HISTORY} + + + diff --git a/backend/app-cvi-api/src/main/resources/file-debug-aws-appender.xml b/backend/app-cvi-api/src/main/resources/file-debug-aws-appender.xml new file mode 100644 index 00000000..74be5349 --- /dev/null +++ b/backend/app-cvi-api/src/main/resources/file-debug-aws-appender.xml @@ -0,0 +1,18 @@ + + + ${LOG_LOCATION}/${AWS_LOCATION}/${DEBUG_LOCATION}/debug-${BY_DATE}.log + + DEBUG + ACCEPT + DENY + + + ${LOG_PATTERN_AWS} + + + ${BACKUP_LOCATION}/${AWS_LOCATION}/${DEBUG_LOCATION}/debug-%d{yyyy-MM-dd}.%i.log + ${MAX_FILE_SIZE} + ${MAX_HISTORY} + + + diff --git a/backend/app-cvi-api/src/main/resources/logback-spring.xml b/backend/app-cvi-api/src/main/resources/logback-spring.xml index 5f02a2de..f4b2ab1b 100644 --- a/backend/app-cvi-api/src/main/resources/logback-spring.xml +++ b/backend/app-cvi-api/src/main/resources/logback-spring.xml @@ -7,6 +7,7 @@ value="메세지: [%msg] 클래스: [%C{0}.%M:#%L] 스레드: [%thread] %n"/> + @@ -17,11 +18,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/app-cvi-api/src/test/java/com/cvi/ApiDocument.java b/backend/app-cvi-api/src/test/java/com/cvi/ApiDocument.java index 7ddd89e1..07d3abb5 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/ApiDocument.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/ApiDocument.java @@ -1,21 +1,22 @@ package com.cvi; -import com.cvi.user.domain.repository.UserRepository; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyUris; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; + import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; import org.springframework.restdocs.operation.preprocess.OperationRequestPreprocessor; import org.springframework.restdocs.operation.preprocess.OperationResponsePreprocessor; import org.springframework.test.web.servlet.MockMvc; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; - @AutoConfigureRestDocs @AutoConfigureMockMvc public class ApiDocument { @@ -25,11 +26,11 @@ public class ApiDocument { protected static OperationRequestPreprocessor getDocumentRequest() { return preprocessRequest( - modifyUris() - .scheme("http") - .host("localhost") - .removePort(), - prettyPrint()); + modifyUris() + .scheme("http") + .host("localhost") + .removePort(), + prettyPrint()); } protected static OperationResponsePreprocessor getDocumentResponse() { diff --git a/backend/app-cvi-api/src/test/java/com/cvi/acceptance/AcceptanceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/AcceptanceTest.java new file mode 100644 index 00000000..6f94eeb9 --- /dev/null +++ b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/AcceptanceTest.java @@ -0,0 +1,118 @@ +package com.cvi.acceptance; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.willReturn; + +import com.cvi.dto.AuthRequest; +import com.cvi.dto.PostRequest; +import com.cvi.dto.UserRequest; +import com.cvi.dto.UserResponse; +import com.cvi.service.AuthService; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.MediaType; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class AcceptanceTest { + + protected static final long INVALID_ID = 999L; + + @LocalServerPort + int port; + + @MockBean + private AuthService authService; + + @PersistenceContext + private EntityManager em; + + protected String ACCESS_TOKEN = "{ACCESS_TOKEN created by jwt}"; + protected UserResponse 가입회원; + protected UserResponse 신규회원; + protected Optional 비회원; + + @BeforeEach + protected void setUp() { + RestAssured.port = port; + User user = User.builder() + .id(1L) + .nickname("유저") + .ageRange(AgeRange.TEENS) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_MEMBER") + .profileUrl("naver.com/member/profile") + .createdAt(LocalDateTime.now()) + .build(); + + 가입회원 = UserResponse.of(user, ACCESS_TOKEN); + 신규회원 = UserResponse.newUser(SocialProvider.NAVER, "NAVER_ID", "naver.com/profile"); + 비회원 = Optional.empty(); + } + + @AfterEach + protected void truncate() { + List tableNames = Arrays.asList("COMMENT", "LIKES", "POST", "USER"); + em.createNativeQuery("SET FOREIGN_KEY_CHECKS = 0").executeUpdate(); + for (String tableName : tableNames) { + em.createNativeQuery("TRUNCATE TABLE " + tableName + " RESTART IDENTITY").executeUpdate(); + } + em.createNativeQuery("SET FOREIGN_KEY_CHECKS = 1").executeUpdate(); + } + + protected UserResponse 가입된_회원_로그인() { + return willReturn(가입회원).given(authService).authenticate(any(AuthRequest.class), any(String.class)); + } + + protected UserResponse 신규_회원_로그인() { + return willReturn(신규회원).given(authService).authenticate(any(AuthRequest.class), any(String.class)); + } + + protected UserResponse 회원_가입_되어있음(UserRequest signupRequest) { + ExtractableResponse signupResponse = 회원_가입_요청(signupRequest); + return signupResponse.as(UserResponse.class); + } + + protected ExtractableResponse 회원_가입_요청(UserRequest userRequest) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(userRequest) + .when().post("/api/v1/users/signup") + .then().log().all() + .extract(); + } + + protected ExtractableResponse 게시글_작성_요청(UserResponse user, PostRequest postRequest) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + user.getAccessToken()) + .body(postRequest) + .when().post("/api/v1/posts") + .then().log().all() + .extract(); + } + + protected ExtractableResponse 단일_게시글_조회(Long postId) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get("/api/v1/posts/{postId}", postId) + .then().log().all() + .extract(); + } +} diff --git a/backend/app-cvi-api/src/test/java/com/cvi/acceptance/AuthAcceptanceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/AuthAcceptanceTest.java new file mode 100644 index 00000000..f8d3c4f5 --- /dev/null +++ b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/AuthAcceptanceTest.java @@ -0,0 +1,55 @@ +package com.cvi.acceptance; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.cvi.dto.AuthRequest; +import com.cvi.dto.UserResponse; +import com.cvi.user.domain.model.SocialProvider; +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +@DisplayName("소셜 로그인 관련 테스트") +public class AuthAcceptanceTest extends AcceptanceTest { + + @DisplayName("소셜로그인 - 이미 가입된 회원인 경우") + @Test + void authenticateWhenSigninedUser() { + //given + AuthRequest authRequest = new AuthRequest(SocialProvider.NAVER, "CODE", "STATE"); + //when + 가입된_회원_로그인(); + ExtractableResponse response = 소셜_로그인_요청(authRequest); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(response.as(UserResponse.class).getAccessToken()).isNotNull(); + } + + @DisplayName("소셜로그인 - 신규 회원인 경우") + @Test + void authenticateWhenNewUser() { + //given + AuthRequest authRequest = new AuthRequest(SocialProvider.NAVER, "CODE", "STATE"); + //when + 신규_회원_로그인(); + ExtractableResponse response = 소셜_로그인_요청(authRequest); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(response.as(UserResponse.class).getId()).isNull(); + assertThat(response.as(UserResponse.class).getAccessToken()).isNull(); + } + + private ExtractableResponse 소셜_로그인_요청(AuthRequest authRequest) { + return RestAssured.given().log().all() + .header("Origin", "http://localhost:9000") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .body(authRequest) + .when().post("/api/v1/auth") + .then().log().all() + .extract(); + } +} diff --git a/backend/app-cvi-api/src/test/java/com/cvi/acceptance/CommentAcceptanceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/CommentAcceptanceTest.java new file mode 100644 index 00000000..4ad2841a --- /dev/null +++ b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/CommentAcceptanceTest.java @@ -0,0 +1,212 @@ +package com.cvi.acceptance; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.cvi.dto.CommentRequest; +import com.cvi.dto.CommentResponse; +import com.cvi.dto.PostRequest; +import com.cvi.dto.PostResponse; +import com.cvi.dto.UserRequest; +import com.cvi.dto.UserResponse; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +@DisplayName("댓글 관련 인수 테스트") +public class CommentAcceptanceTest extends AcceptanceTest { + + private UserResponse userResponse; + private UserResponse anotherUserResponse; + private PostRequest postRequestPFIZER; + private CommentRequest commentRequest; + private CommentRequest updateRequest; + + @Override + @BeforeEach + public void setUp() { + super.setUp(); + UserRequest userRequest = UserRequest.builder() + .nickname("닉네임") + .ageRange(AgeRange.TWENTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .socialProfileUrl("naver.com/profile") + .build(); + UserRequest anotherUserRequest = UserRequest.builder() + .nickname("다른유저닉네임") + .ageRange(AgeRange.TWENTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .socialProfileUrl("naver.com/profile") + .build(); + + userResponse = 회원_가입_되어있음(userRequest); + anotherUserResponse = 회원_가입_되어있음(anotherUserRequest); + + postRequestPFIZER = new PostRequest("게시글 내용1", VaccinationType.PFIZER); + commentRequest = new CommentRequest("댓글 내용"); + updateRequest = new CommentRequest("수정된 댓글 내용"); + } + + @DisplayName("댓글 생성 - 성공") + @Test + void createLike() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + //when + ExtractableResponse response = 게시글_댓글_생성(postResponse.getId(), userResponse, commentRequest); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()); + assertThat(단일_게시글_조회(postResponse.getId()).as(PostResponse.class).getCommentCount()).isEqualTo(1); + } + + @DisplayName("댓글 생성 - 실패 - 인증된 유저가 아닌 경우, 게시글이 없는 경우") + @Test + void createLikeFailure() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + //when + ExtractableResponse UnAuthorizedResponse = 게시글_댓글_생성(postResponse.getId(), 신규회원, commentRequest); + ExtractableResponse NoExistsPostResponse = 게시글_댓글_생성(INVALID_ID, userResponse, commentRequest); + //then + assertThat(UnAuthorizedResponse.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + assertThat(NoExistsPostResponse.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + } + + @DisplayName("댓글 조회 - 성공") + @Test + void findCommentsOfPost() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + 게시글_댓글_생성(postResponse.getId(), userResponse, commentRequest); + //when + ExtractableResponse response = 게시글_댓글_조회(postResponse.getId()); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(response.as(List.class)).hasSize(1); + } + + @DisplayName("댓글 조회 - 실패 - 없는 게시글인 경우") + @Test + void findCommentsOfPostFailure() { + //given + //when + ExtractableResponse response = 게시글_댓글_조회(INVALID_ID); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + } + + @DisplayName("댓글 수정 - 성공") + @Test + void updateComment() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + ExtractableResponse createCommentResponse = 게시글_댓글_생성(postResponse.getId(), userResponse, commentRequest); + CommentResponse commentResponse = createCommentResponse.as(CommentResponse.class); + //when + ExtractableResponse response = 게시글_댓글_수정(postResponse.getId(), commentResponse.getId(), userResponse, updateRequest); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()); + } + + @DisplayName("댓글 수정 - 실패 - 인증된 유저가 아닌 경우, 없는 게시글인 경우, 없는 댓글인 경우, 댓글 작성자가 아닌 경우") + @Test + void updateCommentFailure() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + ExtractableResponse createCommentResponse = 게시글_댓글_생성(postResponse.getId(), userResponse, commentRequest); + CommentResponse commentResponse = createCommentResponse.as(CommentResponse.class); + //when + ExtractableResponse unAuthorizedResponse = 게시글_댓글_수정(postResponse.getId(), commentResponse.getId(), 신규회원, updateRequest); + ExtractableResponse noExistsPostResponse = 게시글_댓글_수정(INVALID_ID, commentResponse.getId(), userResponse, updateRequest); + ExtractableResponse noExistsCommentResponse = 게시글_댓글_수정(postResponse.getId(), INVALID_ID, userResponse, updateRequest); + ExtractableResponse noWriterResponse = 게시글_댓글_수정(postResponse.getId(), commentResponse.getId(), anotherUserResponse, updateRequest); + //then + assertThat(unAuthorizedResponse.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + assertThat(noExistsPostResponse.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + assertThat(noExistsCommentResponse.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + assertThat(noWriterResponse.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + } + + @DisplayName("댓글 삭제 - 성공") + @Test + void deleteLike() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + ExtractableResponse createCommentResponse = 게시글_댓글_생성(postResponse.getId(), userResponse, commentRequest); + CommentResponse commentResponse = createCommentResponse.as(CommentResponse.class); + //when + ExtractableResponse response = 게시글_댓글_삭제(postResponse.getId(), commentResponse.getId(), userResponse); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()); + assertThat(단일_게시글_조회(postResponse.getId()).as(PostResponse.class).getCommentCount()).isEqualTo(0); + } + + @DisplayName("댓글 삭제 - 실패 - 인증된 유저가 아닌 경우, 게시글이 없는 경우, 본인이 작성한 댓글이 아닌 경우 ") + @Test + void deleteLikeFailure() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + ExtractableResponse createCommentResponse = 게시글_댓글_생성(postResponse.getId(), userResponse, commentRequest); + CommentResponse commentResponse = createCommentResponse.as(CommentResponse.class); + //when + ExtractableResponse UnAuthorizedResponse = 게시글_댓글_삭제(postResponse.getId(), commentResponse.getId(), 신규회원); + ExtractableResponse NoExistsPostResponse = 게시글_댓글_삭제(INVALID_ID, commentResponse.getId(), userResponse); + ExtractableResponse alreadyLikedResponse = 게시글_댓글_삭제(postResponse.getId(), commentResponse.getId(), anotherUserResponse); + //then + assertThat(UnAuthorizedResponse.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + assertThat(NoExistsPostResponse.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + assertThat(alreadyLikedResponse.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + } + + private PostResponse 게시글_작성_되어있음() { + ExtractableResponse createPostResponse = 게시글_작성_요청(userResponse, postRequestPFIZER); + return createPostResponse.as(PostResponse.class); + } + + private ExtractableResponse 게시글_댓글_생성(Long postId, UserResponse user, CommentRequest commentRequest) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + user.getAccessToken()) + .body(commentRequest) + .when().post("/api/v1/posts/{postId}/comments", postId) + .then().log().all() + .extract(); + } + + private ExtractableResponse 게시글_댓글_조회(Long postId) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get("/api/v1/posts/{postId}/comments", postId) + .then().log().all() + .extract(); + } + + private ExtractableResponse 게시글_댓글_수정(Long postId, Long commentId, UserResponse user, CommentRequest commentRequest) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + user.getAccessToken()) + .body(commentRequest) + .when().put("/api/v1/posts/{postId}/comments/{commentId}", postId, commentId) + .then().log().all() + .extract(); + } + + private ExtractableResponse 게시글_댓글_삭제(Long postId, Long commentId, UserResponse user) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + user.getAccessToken()) + .when().delete("/api/v1/posts/{postId}/comments/{commentsId}", postId, commentId) + .then().log().all() + .extract(); + } +} diff --git a/backend/app-cvi-api/src/test/java/com/cvi/acceptance/LikeAcceptanceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/LikeAcceptanceTest.java new file mode 100644 index 00000000..499144f5 --- /dev/null +++ b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/LikeAcceptanceTest.java @@ -0,0 +1,131 @@ +package com.cvi.acceptance; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.cvi.dto.PostRequest; +import com.cvi.dto.PostResponse; +import com.cvi.dto.UserRequest; +import com.cvi.dto.UserResponse; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +@DisplayName("좋아요 관련 인수 테스트") +public class LikeAcceptanceTest extends AcceptanceTest { + + protected UserResponse userResponse; + protected UserResponse anotherUserResponse; + protected PostRequest postRequestPFIZER; + + @Override + @BeforeEach + public void setUp() { + super.setUp(); + UserRequest userRequest = UserRequest.builder() + .nickname("닉네임") + .ageRange(AgeRange.TWENTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .socialProfileUrl("naver.com/profile") + .build(); + UserRequest anotherUserRequest = UserRequest.builder() + .nickname("다른유저닉네임") + .ageRange(AgeRange.TWENTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .socialProfileUrl("naver.com/profile") + .build(); + + userResponse = 회원_가입_되어있음(userRequest); + anotherUserResponse = 회원_가입_되어있음(anotherUserRequest); + + postRequestPFIZER = new PostRequest("게시글 내용1", VaccinationType.PFIZER); + } + + @DisplayName("좋아요 생성 - 성공") + @Test + void createLike() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + //when + ExtractableResponse response = 게시글_좋아요_생성(postResponse.getId(), userResponse); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()); + assertThat(단일_게시글_조회(postResponse.getId()).as(PostResponse.class).getLikeCount()).isEqualTo(1); + } + + @DisplayName("좋아요 생성 - 실패 - 인증된 유저가 아닌 경우, 게시글이 없는 경우, 이미 좋아요를 누른 유저인 경우 ") + @Test + void createLikeFailure() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + //when + ExtractableResponse UnAuthorizedResponse = 게시글_좋아요_생성(postResponse.getId(), 신규회원); + ExtractableResponse NoExistsPostResponse = 게시글_좋아요_생성(INVALID_ID, userResponse); + 게시글_좋아요_생성(postResponse.getId(), userResponse); + ExtractableResponse alreadyLikedResponse = 게시글_좋아요_생성(postResponse.getId(), userResponse); + //then + assertThat(UnAuthorizedResponse.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + assertThat(NoExistsPostResponse.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + assertThat(alreadyLikedResponse.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); + } + + @DisplayName("좋아요 삭제 - 성공") + @Test + void deleteLike() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + 게시글_좋아요_생성(postResponse.getId(), userResponse); + //when + ExtractableResponse response = 게시글_좋아요_삭제(postResponse.getId(), userResponse); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()); + assertThat(단일_게시글_조회(postResponse.getId()).as(PostResponse.class).getLikeCount()).isEqualTo(0); + } + + @DisplayName("좋아요 삭제 - 실패 - 인증된 유저가 아닌 경우, 게시글이 없는 경우, 좋아요를 누르지 않은 유저인 경우 ") + @Test + void deleteLikeFailure() { + //given + PostResponse postResponse = 게시글_작성_되어있음(); + //when + ExtractableResponse UnAuthorizedResponse = 게시글_좋아요_삭제(postResponse.getId(), 신규회원); + ExtractableResponse NoExistsPostResponse = 게시글_좋아요_삭제(INVALID_ID, userResponse); + ExtractableResponse alreadyLikedResponse = 게시글_좋아요_삭제(postResponse.getId(), anotherUserResponse); + //then + assertThat(UnAuthorizedResponse.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + assertThat(NoExistsPostResponse.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + assertThat(alreadyLikedResponse.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + } + + private PostResponse 게시글_작성_되어있음() { + ExtractableResponse createPostResponse = 게시글_작성_요청(userResponse, postRequestPFIZER); + return createPostResponse.as(PostResponse.class); + } + + private ExtractableResponse 게시글_좋아요_생성(Long postId, UserResponse user) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + user.getAccessToken()) + .when().post("/api/v1/posts/{postId}/likes", postId) + .then().log().all() + .extract(); + } + + private ExtractableResponse 게시글_좋아요_삭제(Long postId, UserResponse user) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + user.getAccessToken()) + .when().delete("/api/v1/posts/{postId}/likes", postId) + .then().log().all() + .extract(); + } +} diff --git a/backend/app-cvi-api/src/test/java/com/cvi/acceptance/PostAcceptanceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/PostAcceptanceTest.java new file mode 100644 index 00000000..faf6ac1f --- /dev/null +++ b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/PostAcceptanceTest.java @@ -0,0 +1,277 @@ +package com.cvi.acceptance; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.cvi.dto.PostRequest; +import com.cvi.dto.PostResponse; +import com.cvi.dto.UserRequest; +import com.cvi.dto.UserResponse; +import com.cvi.post.domain.model.Sort; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +@DisplayName("게시글 관련 인수 테스트") +public class PostAcceptanceTest extends AcceptanceTest { + + private static final int OFFSET_IS_ONE = 1; + private static final int SIZE_IS_TWO = 2; + + protected UserResponse userResponse; + protected UserResponse anotherUserResponse; + private PostRequest invalidPostRequest; + protected PostRequest postRequestPFIZER; + private PostRequest postRequestAZ; + private PostRequest postRequestMODERNA; + private PostRequest postRequestJANSSEN; + private PostRequest updateRequest; + + @Override + @BeforeEach + public void setUp() { + super.setUp(); + UserRequest userRequest = UserRequest.builder() + .nickname("닉네임") + .ageRange(AgeRange.TWENTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .socialProfileUrl("naver.com/profile") + .build(); + UserRequest anotherUserRequest = UserRequest.builder() + .nickname("다른유저닉네임") + .ageRange(AgeRange.TWENTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .socialProfileUrl("naver.com/profile") + .build(); + + userResponse = 회원_가입_되어있음(userRequest); + anotherUserResponse = 회원_가입_되어있음(anotherUserRequest); + + invalidPostRequest = new PostRequest(" ", VaccinationType.PFIZER); + postRequestPFIZER = new PostRequest("게시글 내용1", VaccinationType.PFIZER); + postRequestAZ = new PostRequest("게시글 내용2", VaccinationType.ASTRAZENECA); + postRequestMODERNA = new PostRequest("게시글 내용3", VaccinationType.MODERNA); + postRequestJANSSEN = new PostRequest("게시글 내용4", VaccinationType.JANSSEN); + updateRequest = new PostRequest("수정된 내용", VaccinationType.JANSSEN); + } + + @DisplayName("게시글 작성 - 성공") + @Test + void create() { + //given + //when + ExtractableResponse response = 게시글_작성_요청(userResponse, postRequestPFIZER); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()); + assertThat(response.as(PostResponse.class).getWriter().getId()).isEqualTo(userResponse.getId()); + assertThat(response.as(PostResponse.class).getVaccinationType()).isEqualTo(VaccinationType.PFIZER); + } + + @DisplayName("게시글 작성 - 실패 - 로그인 유저가 아닌 경우") + @Test + void createFailureWhenNoSignedUser() { + //given + //when + ExtractableResponse response = 게시글_작성_요청(신규회원, postRequestPFIZER); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + } + + @DisplayName("게시글 작성 - 실패 - 게시글 내용이 유효하지 않은 경우") + @Test + void createFailureWhen() { + //given + //when + ExtractableResponse response = 게시글_작성_요청(userResponse, invalidPostRequest); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); + } + + @ParameterizedTest(name = "백신 타입별 게시글 조회 - 성공") + @MethodSource + void findByVaccineType(VaccinationType vaccinationType) { + //given + 게시글_작성_요청(userResponse, postRequestPFIZER); + 게시글_작성_요청(userResponse, postRequestAZ); + 게시글_작성_요청(userResponse, postRequestMODERNA); + 게시글_작성_요청(userResponse, postRequestJANSSEN); + //when + ExtractableResponse responseOfAllType = 백신_타입별_게시글_조회(null); + ExtractableResponse responseOfType = 백신_타입별_게시글_조회(vaccinationType); + //then + assertThat(responseOfAllType.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(responseOfAllType.as(List.class)).hasSize(4); + + assertThat(responseOfType.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(responseOfType.as(List.class).get(0)).extracting("vaccinationType").isEqualTo(vaccinationType.name()); + } + + static Stream findByVaccineType() { + return Stream.of( + Arguments.of(VaccinationType.ASTRAZENECA), + Arguments.of(VaccinationType.PFIZER), + Arguments.of(VaccinationType.JANSSEN), + Arguments.of(VaccinationType.MODERNA)); + } + + @DisplayName("단일 게시글 조회 - 성공") + @Test + void findById() { + //given + ExtractableResponse createPostResponse = 게시글_작성_요청(userResponse, postRequestPFIZER); + PostResponse postResponse = createPostResponse.as(PostResponse.class); + //when + ExtractableResponse response = 단일_게시글_조회(postResponse.getId()); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(response.as(PostResponse.class).getId()).isEqualTo(postResponse.getId()); + } + + @DisplayName("단일 게시글 조회 - 실패 - 존재하지 않는 게시글 id인 경우") + @Test + void findByIdFailure() { + //given + //when + ExtractableResponse response = 단일_게시글_조회(INVALID_ID); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + } + + @DisplayName("게시글 타입별 조회 페이징 - 성공") + @Test + void findByVaccineTypePaging() { + //given + List postRequests = Arrays.asList( + new PostRequest("내용1", VaccinationType.PFIZER), + new PostRequest("내용2", VaccinationType.PFIZER), + new PostRequest("내용3", VaccinationType.PFIZER), + new PostRequest("내용4", VaccinationType.MODERNA) + ); + + for (PostRequest postRequest : postRequests) { + 게시글_작성_요청(userResponse, postRequest); + } + //when + ExtractableResponse response = 백신_타입별_게시글_페이징_조회(VaccinationType.PFIZER, OFFSET_IS_ONE, SIZE_IS_TWO, Sort.CREATED_AT_DESC, userResponse); + List resultPostContents = response.jsonPath() + .getList(".", PostResponse.class) + .stream() + .map(PostResponse::getContent) + .collect(Collectors.toList()); + //then + assertThat(resultPostContents).containsExactly("내용2", "내용1"); + } + + private ExtractableResponse 백신_타입별_게시글_페이징_조회(VaccinationType vaccinationType, int offset, int size, Sort sort, UserResponse user) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + user.getAccessToken()) + .param("vaccinationType", vaccinationType) + .queryParam("offset", offset) + .param("size", size) + .param("sort", sort) + .when().get("/api/v1/posts/paging") + .then().log().all() + .extract(); + } + + @DisplayName("게시글 수정 - 성공") + @Test + void update() { + //given + ExtractableResponse createPostResponse = 게시글_작성_요청(userResponse, postRequestPFIZER); + PostResponse postResponse = createPostResponse.as(PostResponse.class); + //when + ExtractableResponse response = 게시글_수정_요청(postResponse.getId(), userResponse, updateRequest); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()); + } + + @DisplayName("게시글 수정 - 실패 - 인증된 유저가 아닌 경우, 게시글 작성자가 아닌 경우, 게시글이 없는 경우") + @Test + void updateFailureWhenUnAuthorizedUser() { + //given + ExtractableResponse createPostResponse = 게시글_작성_요청(userResponse, postRequestPFIZER); + PostResponse postResponse = createPostResponse.as(PostResponse.class); + //when + ExtractableResponse UnAuthorizedResponse = 게시글_수정_요청(postResponse.getId(), 신규회원, updateRequest); + ExtractableResponse noWriterResponse = 게시글_수정_요청(postResponse.getId(), anotherUserResponse, updateRequest); + ExtractableResponse noExistsPostResponse = 게시글_수정_요청(INVALID_ID, userResponse, updateRequest); + //then + assertThat(UnAuthorizedResponse.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + assertThat(noWriterResponse.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); + assertThat(noExistsPostResponse.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + } + + @DisplayName("게시글 삭제 - 성공") + @Test + void delete() { + //given + ExtractableResponse createPostResponse = 게시글_작성_요청(userResponse, postRequestPFIZER); + PostResponse postResponse = createPostResponse.as(PostResponse.class); + //when + ExtractableResponse response = 게시글_삭제_요청(postResponse.getId(), userResponse); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()); + } + + @DisplayName("게시글 삭제 - 실패 - 인증된 유저가 아닌 경우, 게시글 작성자가 아닌 경우, 게시글이 없는 경우") + @Test + void deleteFailureWhenUnAuthorizedUser() { + //given + ExtractableResponse createPostResponse = 게시글_작성_요청(userResponse, postRequestPFIZER); + PostResponse postResponse = createPostResponse.as(PostResponse.class); + //when + ExtractableResponse UnAuthorizedResponse = 게시글_삭제_요청(postResponse.getId(), 신규회원); + ExtractableResponse noWriterResponse = 게시글_삭제_요청(postResponse.getId(), anotherUserResponse); + ExtractableResponse noExistsPostResponse = 게시글_삭제_요청(INVALID_ID, userResponse); + //then + assertThat(UnAuthorizedResponse.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + assertThat(noWriterResponse.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); + assertThat(noExistsPostResponse.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + } + + private ExtractableResponse 백신_타입별_게시글_조회(VaccinationType vaccinationType) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .param("vaccinationType", vaccinationType) + .when().get("/api/v1/posts") + .then().log().all() + .extract(); + } + + private ExtractableResponse 게시글_수정_요청(Long postId, UserResponse user, PostRequest updateRequest) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + user.getAccessToken()) + .body(updateRequest) + .when().put("/api/v1/posts/{postId}", postId) + .then().log().all() + .extract(); + } + + private ExtractableResponse 게시글_삭제_요청(Long postId, UserResponse user) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + user.getAccessToken()) + .when().delete("/api/v1/posts/{postId}", postId) + .then().log().all() + .extract(); + } +} diff --git a/backend/app-cvi-api/src/test/java/com/cvi/acceptance/UserAcceptanceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/UserAcceptanceTest.java new file mode 100644 index 00000000..36c6d4e6 --- /dev/null +++ b/backend/app-cvi-api/src/test/java/com/cvi/acceptance/UserAcceptanceTest.java @@ -0,0 +1,234 @@ +package com.cvi.acceptance; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.cvi.dto.UserRequest; +import com.cvi.dto.UserResponse; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +@DisplayName("유저 관련 인수 테스트") +public class UserAcceptanceTest extends AcceptanceTest { + + private UserRequest userRequest; + private UserRequest updateRequest; + + @Override + @BeforeEach + public void setUp() { + super.setUp(); + userRequest = UserRequest.builder() + .nickname("닉네임") + .ageRange(AgeRange.TWENTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .socialProfileUrl("naver.com/profile") + .build(); + updateRequest = UserRequest.builder() + .nickname("수정된닉네임") + .ageRange(AgeRange.THIRTIES) + .socialProvider(SocialProvider.KAKAO) + .socialId("KAKAO_ID") + .socialProfileUrl("kakao.com/profile") + .build(); + } + + @DisplayName("신규 회원 가입 - 성공") + @Test + void signup() { + //given + //when + ExtractableResponse response = 회원_가입_요청(userRequest); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value()); + assertThat(response.as(UserResponse.class).getId()).isEqualTo(1L); + assertThat(response.as(UserResponse.class).getAccessToken()).isNotNull(); + } + + @ParameterizedTest(name = "신규 회원 가입 - 실패 - 유효하지 않은 값인 경우") + @MethodSource + void signupFailure(UserRequest userRequest) { + //given + //when + ExtractableResponse response = 회원_가입_요청(userRequest); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); + } + + static Stream signupFailure() { + return Stream.of( + Arguments.of(new UserRequest("345612873681273468127364", AgeRange.TEENS, false, SocialProvider.NAVER, "NAVER_ID", "naver.com/profile")), + Arguments.of(new UserRequest("nickname", null, false, SocialProvider.NAVER, "NAVER_ID", "naver.com/profile")), + Arguments.of(new UserRequest("nickname", AgeRange.TWENTIES, false, null, "NAVER_ID", "naver.com/profile")), + Arguments.of(new UserRequest("nickname", AgeRange.TWENTIES, false, SocialProvider.NAVER, "", "naver.com/profile")), + Arguments.of(new UserRequest("nickname", AgeRange.TWENTIES, false, SocialProvider.NAVER, "NAVER_ID", "")) + ); + } + + @DisplayName("내 정보 조회 - 성공") + @Test + void findMe() { + //given + ExtractableResponse signupResponse = 회원_가입_요청(userRequest); + //when + UserResponse userResponse = signupResponse.as(UserResponse.class); + ExtractableResponse response = 내_정보_조회(userResponse); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(response.as(UserResponse.class).getId()).isEqualTo(userResponse.getId()); + assertThat(response.as(UserResponse.class).getNickname()).isEqualTo(userResponse.getNickname()); + } + + @DisplayName("내 정보 조회 - 실패 - 가입된 유저가 아닌 경우") + @Test + void findMeFailureWhenNotSignedinUser() { + //given + //when + ExtractableResponse response = 내_정보_조회(신규회원); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + } + + @DisplayName("내 정보 수정 - 성공") + @Test + void update() { + //given + ExtractableResponse signupResponse = 회원_가입_요청(userRequest); + //when + UserResponse userResponse = signupResponse.as(UserResponse.class); + ExtractableResponse response = 내_정보_수정(userResponse, updateRequest); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()); + } + + @ParameterizedTest(name = "내 정보 수정 - 실패 - 유효하지 않은 요청 값인 경우") + @MethodSource + void updateFailure(UserRequest invalidRequest) { + //given + ExtractableResponse signupResponse = 회원_가입_요청(userRequest); + 회원_가입_요청(updateRequest); + //when + UserResponse userResponse = signupResponse.as(UserResponse.class); + ExtractableResponse response = 내_정보_수정(userResponse, invalidRequest); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST.value()); + } + + static Stream updateFailure() { + return Stream.of( + Arguments.of(new UserRequest("수정된닉네임", AgeRange.TEENS, false, SocialProvider.NAVER, "NAVER_ID", "naver.com/profile")), + Arguments.of(new UserRequest("345612873681273468127364", AgeRange.TEENS, false, SocialProvider.NAVER, "NAVER_ID", "naver.com/profile")), + Arguments.of(new UserRequest("nickname", null, false, SocialProvider.NAVER, "NAVER_ID", "naver.com/profile")), + Arguments.of(new UserRequest("nickname", AgeRange.TWENTIES, false, null, "NAVER_ID", "naver.com/profile")), + Arguments.of(new UserRequest("nickname", AgeRange.TWENTIES, false, SocialProvider.NAVER, "", "naver.com/profile")), + Arguments.of(new UserRequest("nickname", AgeRange.TWENTIES, false, SocialProvider.NAVER, "NAVER_ID", "")) + ); + } + + @DisplayName("사용자 조회 - 성공") + @Test + void find() { + //given + ExtractableResponse signupResponse = 회원_가입_요청(userRequest); + UserResponse userResponse = signupResponse.as(UserResponse.class); + //when + ExtractableResponse response = 사용자_조회(userResponse.getId()); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + assertThat(response.as(UserResponse.class).getId()).isEqualTo(userResponse.getId()); + assertThat(response.as(UserResponse.class).getNickname()).isEqualTo(userResponse.getNickname()); + } + + @DisplayName("사용자 조회 - 실패 - 존재하는 사용자가 아닌 경우") + @Test + void findFailure() { + //given + //when + ExtractableResponse response = 사용자_조회(INVALID_ID); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + } + + @DisplayName("사용자 삭제 - 성공") + @Test + void delete() { + //given + ExtractableResponse signupResponse = 회원_가입_요청(userRequest); + UserResponse userResponse = signupResponse.as(UserResponse.class); + //when + ExtractableResponse response = 사용자_삭제(userResponse); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT.value()); + } + + @DisplayName("사용자 삭제 - 실패 - 로그인 유저가 요청한 게 아닌 경우") + @Test + void deleteFailureWhenNoSignedinUser() { + //given + //when + ExtractableResponse response = 사용자_삭제(신규회원); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED.value()); + } + + @DisplayName("사용자 삭제 - 실패 - 해당 유저가 존재하지 않는 경우") + @Test + void deleteFailureWhenNoExistsUser() { + ExtractableResponse signupResponse = 회원_가입_요청(userRequest); + 회원_가입_요청(updateRequest); + //when + UserResponse userResponse = signupResponse.as(UserResponse.class); + 사용자_삭제(userResponse); + ExtractableResponse response = 사용자_삭제(userResponse); + //then + assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND.value()); + } + + private ExtractableResponse 내_정보_조회(UserResponse userResponse) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + userResponse.getAccessToken()) + .when().get("/api/v1/users/me") + .then().log().all() + .extract(); + } + + private ExtractableResponse 내_정보_수정(UserResponse userResponse, UserRequest updateRequest) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + userResponse.getAccessToken()) + .body(updateRequest) + .when().put("/api/v1/users/me") + .then().log().all() + .extract(); + } + + private ExtractableResponse 사용자_조회(Long userId) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get("/api/v1/users/{userId}", userId) + .then().log().all() + .extract(); + } + + private ExtractableResponse 사용자_삭제(UserResponse userResponse) { + return RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", "Bearer" + userResponse.getAccessToken()) + .when().delete("/api/v1/users") + .then().log().all() + .extract(); + } +} diff --git a/backend/app-cvi-api/src/test/java/com/cvi/controller/AuthControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/AuthControllerTest.java index 9cb18938..6dbfa917 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/controller/AuthControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/AuthControllerTest.java @@ -1,7 +1,15 @@ package com.cvi.controller; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.BDDMockito.willThrow; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import com.cvi.ApiDocument; -import com.cvi.auth.AuthenticationPrincipalArgumentResolver; import com.cvi.auth.JwtTokenProvider; import com.cvi.dto.AuthRequest; import com.cvi.dto.UserResponse; @@ -11,7 +19,6 @@ import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; -import com.cvi.user.domain.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,16 +27,9 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.ResultActions; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.willReturn; -import static org.mockito.BDDMockito.willThrow; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - @DisplayName("OAuth 컨트롤러 테스트") @WebMvcTest(controllers = AuthController.class) -public class AuthControllerTest extends ApiDocument { +class AuthControllerTest extends ApiDocument { private static final String ACCESS_TOKEN = "{ACCESS TOKEN generated by JWT}"; private static final String BEARER = "Bearer "; @@ -48,10 +48,6 @@ public class AuthControllerTest extends ApiDocument { @MockBean private UserService userService; - - @MockBean - private UserRepository userRepository; - private User user; private UserResponse userResponse; private AuthRequest authRequest; @@ -59,13 +55,13 @@ public class AuthControllerTest extends ApiDocument { @BeforeEach void beforeEach() { user = User.builder() - .id(USER_ID) - .nickname(NICKNAME) - .ageRange(AgeRange.TWENTIES) - .socialProvider(SOCIAL_PROVIDER) - .socialId(SOCIAL_ID) - .profileUrl(PROFILE_URL) - .build(); + .id(USER_ID) + .nickname(NICKNAME) + .ageRange(AgeRange.TWENTIES) + .socialProvider(SOCIAL_PROVIDER) + .socialId(SOCIAL_ID) + .profileUrl(PROFILE_URL) + .build(); authRequest = new AuthRequest(SocialProvider.KAKAO, CODE, null); userResponse = UserResponse.of(user, BEARER + ACCESS_TOKEN); } @@ -74,7 +70,7 @@ void beforeEach() { @Test void authenticate() throws Exception { //given - willReturn(userResponse).given(authService).authenticate(any(AuthRequest.class)); + willReturn(userResponse).given(authService).authenticate(any(AuthRequest.class), any(String.class)); //when ResultActions response = 사용자_OAuth_요청(authRequest); //then @@ -85,7 +81,7 @@ void authenticate() throws Exception { @Test void authenticateFailure() throws Exception { //given - willThrow(new UnAuthorizedException("OAuth 인증에 실패하였습니다.")).given(authService).authenticate(any(AuthRequest.class)); + willThrow(new UnAuthorizedException("OAuth 인증에 실패하였습니다.")).given(authService).authenticate(any(AuthRequest.class), any(String.class)); //when ResultActions response = 사용자_OAuth_요청(authRequest); //then @@ -108,27 +104,28 @@ void validateAuthRequest() throws Exception { private ResultActions 사용자_OAuth_요청(AuthRequest authRequest) throws Exception { return mockMvc.perform(post("/api/v1/auth") - .contentType(MediaType.APPLICATION_JSON) - .content(toJson(authRequest))); + .header("Origin", "http://localhost:9000") + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(authRequest))); } private void 사용자_OAuth_성공함(ResultActions response, UserResponse userResponse) throws Exception { response.andExpect(status().isOk()) - .andExpect(content().json(toJson(userResponse))) - .andExpect(header().string("Authorization", BEARER + ACCESS_TOKEN)) - .andDo(print()) - .andDo(toDocument("user-auth")); + .andExpect(content().json(toJson(userResponse))) + .andExpect(header().string("Authorization", BEARER + ACCESS_TOKEN)) + .andDo(print()) + .andDo(toDocument("user-auth")); } private void 사용자_OAuth_실패함(ResultActions response) throws Exception { response.andExpect(status().isUnauthorized()) - .andDo(print()) - .andDo(toDocument("user-auth-failure")); + .andDo(print()) + .andDo(toDocument("user-auth-failure")); } private ResultActions 잘못된_OAuth_요청(String request) throws Exception { return mockMvc.perform(post("/api/v1/auth") - .content(request) - .contentType(MediaType.APPLICATION_JSON)); + .content(request) + .contentType(MediaType.APPLICATION_JSON)); } } diff --git a/backend/app-cvi-api/src/test/java/com/cvi/controller/CommentControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/CommentControllerTest.java index 3f5ff35e..e3afc438 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/controller/CommentControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/CommentControllerTest.java @@ -1,10 +1,25 @@ package com.cvi.controller; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.anyInt; +import static org.mockito.BDDMockito.willDoNothing; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.BDDMockito.willThrow; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import com.cvi.dto.CommentRequest; import com.cvi.dto.CommentResponse; import com.cvi.exception.NotFoundException; import com.cvi.exception.UnAuthorizedException; import com.cvi.service.CommentService; +import java.time.LocalDateTime; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -13,19 +28,9 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.ResultActions; -import java.time.LocalDateTime; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @DisplayName("댓글 컨트롤러 Mock 테스트") @WebMvcTest(controllers = CommentController.class) -public class CommentControllerTest extends PreprocessPostControllerTest { +class CommentControllerTest extends PreprocessPostControllerTest { @MockBean private CommentService commentService; @@ -34,10 +39,10 @@ public class CommentControllerTest extends PreprocessPostControllerTest { @Test void createComment() throws Exception { //given - CommentResponse expectedResponse = new CommentResponse(PreprocessPostControllerTest.COMMENT_ID, userResponse, "좋은 정보 공유 감사해요 ㅎㅎㅎ", LocalDateTime.now()); + CommentResponse expectedResponse = new CommentResponse(COMMENT_ID, userResponse, "좋은 정보 공유 감사해요 ㅎㅎㅎ", LocalDateTime.now()); willReturn(expectedResponse).given(commentService).createComment(anyLong(), any(), any(CommentRequest.class)); //when - ResultActions response = 댓글_등록_요청(PreprocessPostControllerTest.POST_ID, new CommentRequest("좋은 정보 공유 감사해요 ㅎㅎㅎ"), PreprocessPostControllerTest.BEARER + PreprocessPostControllerTest.ACCESS_TOKEN); + ResultActions response = 댓글_등록_요청(POST_ID, new CommentRequest("좋은 정보 공유 감사해요 ㅎㅎㅎ"), BEARER + ACCESS_TOKEN); //then 댓글_등록_성공함(response, expectedResponse); } @@ -48,7 +53,7 @@ void createCommentFailureWhenWrongWriter() throws Exception { //given willThrow(new UnAuthorizedException("가입된 유저가 아닙니다.")).given(commentService).createComment(anyLong(), any(), any(CommentRequest.class)); //when - ResultActions response = 댓글_등록_요청(PreprocessPostControllerTest.POST_ID, new CommentRequest("좋은 정보 공유 감사해요 ㅎㅎㅎ"), "null"); + ResultActions response = 댓글_등록_요청(POST_ID, new CommentRequest("좋은 정보 공유 감사해요 ㅎㅎㅎ"), "null"); //then 댓글_등록_실패함(response); } @@ -59,7 +64,7 @@ void findCommentOfPost() throws Exception { //given willReturn(commentResponses).given(commentService).findCommentsByPostId(anyLong()); //when - ResultActions response = 댓글_조회_요청(PreprocessPostControllerTest.POST_ID); + ResultActions response = 댓글_조회_요청(POST_ID); //then 댓글_조회_성공함(response); } @@ -83,7 +88,7 @@ void findCommentOfPostPaging() throws Exception { //when int offset = 1; int size = 2; - ResultActions response = 댓글_조회_페이징_요청(PreprocessPostControllerTest.POST_ID, offset, size); + ResultActions response = 댓글_조회_페이징_요청(POST_ID, offset, size); //then 댓글_페이징_조회_성공함(response); } @@ -106,7 +111,7 @@ void putComment() throws Exception { CommentRequest updateRequest = new CommentRequest("수정된 좋은 정보 공유 감사해요 ㅎㅎ"); willDoNothing().given(commentService).updateComment(anyLong(), anyLong(), any(), any(CommentRequest.class)); //when - ResultActions response = 댓글_수정_요청(PreprocessPostControllerTest.POST_ID, PreprocessPostControllerTest.COMMENT_ID, updateRequest, PreprocessPostControllerTest.BEARER + PreprocessPostControllerTest.ACCESS_TOKEN); + ResultActions response = 댓글_수정_요청(POST_ID, COMMENT_ID, updateRequest, BEARER + ACCESS_TOKEN); //then 댓글_수정_성공함(response); } @@ -117,9 +122,9 @@ void putCommentFailureWhenWrongUser() throws Exception { //given CommentRequest updateRequest = new CommentRequest("수정된 좋은 정보 공유 감사해요 ㅎㅎ"); willThrow(new UnAuthorizedException("댓글 작성자가 아닙니다.")).given(commentService).updateComment(anyLong(), anyLong(), - any(), any(CommentRequest.class)); + any(), any(CommentRequest.class)); //when - ResultActions response = 댓글_수정_요청(PreprocessPostControllerTest.POST_ID, PreprocessPostControllerTest.COMMENT_ID, updateRequest, PreprocessPostControllerTest.BEARER + "another_user_token"); + ResultActions response = 댓글_수정_요청(POST_ID, COMMENT_ID, updateRequest, BEARER + "another_user_token"); //then 댓글_수정_실패함(response); } @@ -130,7 +135,7 @@ void deleteComment() throws Exception { //given willDoNothing().given(commentService).deleteComment(anyLong(), anyLong(), any()); //when - ResultActions response = 댓글_삭제_요청(PreprocessPostControllerTest.POST_ID, PreprocessPostControllerTest.COMMENT_ID, PreprocessPostControllerTest.BEARER + PreprocessPostControllerTest.ACCESS_TOKEN); + ResultActions response = 댓글_삭제_요청(POST_ID, COMMENT_ID, BEARER + ACCESS_TOKEN); //then 댓글_삭제_성공함(response); } @@ -141,101 +146,101 @@ void deleteCommentWhenWrongUser() throws Exception { //given willThrow(new UnAuthorizedException("댓글 작성자가 아닙니다.")).given(commentService).deleteComment(anyLong(), anyLong(), any()); //when - ResultActions response = 댓글_삭제_요청(PreprocessPostControllerTest.POST_ID, PreprocessPostControllerTest.COMMENT_ID, PreprocessPostControllerTest.BEARER + "another_user_token"); + ResultActions response = 댓글_삭제_요청(POST_ID, COMMENT_ID, BEARER + "another_user_token"); //then 댓글_삭제_실패함(response); } private ResultActions 댓글_등록_요청(Long postId, CommentRequest request, String headerValue) throws Exception { return mockMvc.perform(post("/api/v1/posts/{postId}/comments", postId) - .contentType(MediaType.APPLICATION_JSON) - .content(toJson(request)) - .header(HttpHeaders.AUTHORIZATION, headerValue)); + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(request)) + .header(HttpHeaders.AUTHORIZATION, headerValue)); } private void 댓글_등록_성공함(ResultActions response, CommentResponse expectedResponse) throws Exception { response.andExpect(status().isCreated()) - .andExpect(header().string("Location", "/api/v1/comments/" + expectedResponse.getId())) - .andDo(print()) - .andDo(toDocument("comment-create")); + .andExpect(header().string("Location", "/api/v1/comments/" + expectedResponse.getId())) + .andDo(print()) + .andDo(toDocument("comment-create")); } private void 댓글_등록_실패함(ResultActions response) throws Exception { response.andExpect(status().isUnauthorized()) - .andDo(print()) - .andDo(toDocument("comment-create-failure")); + .andDo(print()) + .andDo(toDocument("comment-create-failure")); } private ResultActions 댓글_조회_요청(Long postId) throws Exception { return mockMvc.perform(get("/api/v1/posts/{postId}/comments", postId) - .contentType(MediaType.APPLICATION_JSON)); + .contentType(MediaType.APPLICATION_JSON)); } private ResultActions 댓글_조회_페이징_요청(long postId, int offset, int size) throws Exception { return mockMvc.perform(get("/api/v1/posts/{postId}/comments/paging", postId) - .queryParam("offset", String.valueOf(offset)) - .queryParam("size", String.valueOf(size)) - .contentType(MediaType.APPLICATION_JSON)); + .queryParam("offset", String.valueOf(offset)) + .queryParam("size", String.valueOf(size)) + .contentType(MediaType.APPLICATION_JSON)); } private void 댓글_조회_성공함(ResultActions response) throws Exception { response.andExpect(status().isOk()) - .andDo(print()) - .andDo(toDocument("comment-find")); + .andDo(print()) + .andDo(toDocument("comment-find")); } private void 댓글_조회_실패함(ResultActions response) throws Exception { response.andExpect(status().isNotFound()) - .andDo(print()) - .andDo(toDocument("comment-find-failure")); + .andDo(print()) + .andDo(toDocument("comment-find-failure")); } private void 댓글_페이징_조회_성공함(ResultActions response) throws Exception { response.andExpect(status().isOk()) - .andDo(print()) - .andDo(toDocument("comment-find-paging")); + .andDo(print()) + .andDo(toDocument("comment-find-paging")); } private void 댓글_페이징_조회_실패함(ResultActions response) throws Exception { response.andExpect(status().isNotFound()) - .andDo(print()) - .andDo(toDocument("comment-find-paging-failure")); + .andDo(print()) + .andDo(toDocument("comment-find-paging-failure")); } private ResultActions 댓글_수정_요청(Long postId, Long commentId, CommentRequest request, String accessToken) throws Exception { return mockMvc.perform(put("/api/v1/posts/{postId}/comments/{commentId}", postId, commentId) - .contentType(MediaType.APPLICATION_JSON) - .content(toJson(request)) - .header(HttpHeaders.AUTHORIZATION, accessToken) + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(request)) + .header(HttpHeaders.AUTHORIZATION, accessToken) ); } private void 댓글_수정_성공함(ResultActions response) throws Exception { response.andExpect(status().isNoContent()) - .andDo(print()) - .andDo(toDocument("comment-update")); + .andDo(print()) + .andDo(toDocument("comment-update")); } private void 댓글_수정_실패함(ResultActions response) throws Exception { response.andExpect(status().isUnauthorized()) - .andDo(print()) - .andDo(toDocument("comment-update-failure")); + .andDo(print()) + .andDo(toDocument("comment-update-failure")); } private ResultActions 댓글_삭제_요청(Long postId, Long commentId, String accessToken) throws Exception { return mockMvc.perform(delete("/api/v1/posts/{postId}/comments/{commentId}", postId, commentId) - .header(HttpHeaders.AUTHORIZATION, accessToken)); + .header(HttpHeaders.AUTHORIZATION, accessToken)); } private void 댓글_삭제_성공함(ResultActions response) throws Exception { response.andExpect(status().isNoContent()) - .andDo(print()) - .andDo(toDocument("comment-delete")); + .andDo(print()) + .andDo(toDocument("comment-delete")); } private void 댓글_삭제_실패함(ResultActions response) throws Exception { response.andExpect(status().isUnauthorized()) - .andDo(print()) - .andDo(toDocument("comment-delete-failure")); + .andDo(print()) + .andDo(toDocument("comment-delete-failure")); } } diff --git a/backend/app-cvi-api/src/test/java/com/cvi/controller/PostControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/PostControllerTest.java index 5d9002c1..8d236112 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/controller/PostControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/PostControllerTest.java @@ -1,12 +1,31 @@ package com.cvi.controller; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.anyInt; +import static org.mockito.BDDMockito.willDoNothing; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.BDDMockito.willThrow; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import com.cvi.dto.PostRequest; import com.cvi.dto.PostResponse; import com.cvi.dto.UserResponse; import com.cvi.exception.NotFoundException; import com.cvi.post.domain.model.Sort; import com.cvi.post.domain.model.VaccinationType; -import com.cvi.service.PostService; +import com.cvi.service.post.PostService; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -15,18 +34,6 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.ResultActions; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - @DisplayName("게시글 컨트롤러 Mock 테스트 - 게시글") @WebMvcTest(controllers = PostController.class) class PostControllerTest extends PreprocessPostControllerTest { @@ -38,10 +45,10 @@ class PostControllerTest extends PreprocessPostControllerTest { @Test void createPost() throws Exception { //given - PostResponse expectedResponse = new PostResponse(POST_ID, userResponse, request.getContent(), 0, 0, 0, false, request.getVaccinationType(), LocalDateTime.now()); + PostResponse expectedResponse = new PostResponse(POST_ID, userResponse, createPostRequest.getContent(), 0, 0, 0, false, createPostRequest.getVaccinationType(), LocalDateTime.now(), imageUrls); willReturn(expectedResponse).given(postService).create(any(), any(PostRequest.class)); //when - ResultActions response = 글_등록_요청(request); + ResultActions response = 글_등록_요청(createPostRequest); //then 글_등록_성공함(response, expectedResponse); } @@ -52,7 +59,7 @@ void createPostFailure() throws Exception { //given willThrow(new NotFoundException("해당 id의 사용자가 존재하지 않습니다.")).given(postService).create(any(), any(PostRequest.class)); //when - ResultActions response = 글_등록_요청(request); + ResultActions response = 글_등록_요청(createPostRequest); //then 글_등록_실패함(response); } @@ -61,7 +68,7 @@ void createPostFailure() throws Exception { @Test void find() throws Exception { //given - PostResponse expectedPostResponse = new PostResponse(POST_ID, userResponse, "글 내용", 1, 0, 2, false, VaccinationType.PFIZER, LocalDateTime.now()); + PostResponse expectedPostResponse = new PostResponse(POST_ID, userResponse, "글 내용", 1, 0, 2, false, VaccinationType.PFIZER, LocalDateTime.now(), imageUrls); willReturn(expectedPostResponse).given(postService).findById(any(Long.class), any()); //when ResultActions response = 글_단일_조회_요청(POST_ID); @@ -86,8 +93,8 @@ void findAll() throws Exception { //given UserResponse anotherUserResponse = UserResponse.of(user, null); List postResponse = new LinkedList<>(Arrays.asList( - new PostResponse(POST_ID + 1, anotherUserResponse, "글 내용2", 12, 0, 3, false, VaccinationType.MODERNA, LocalDateTime.now()), - new PostResponse(POST_ID, userResponse, "글 내용1", 55, 5, 13, true, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1L)) + new PostResponse(POST_ID + 1, anotherUserResponse, "글 내용2", 12, 0, 3, false, VaccinationType.MODERNA, LocalDateTime.now(), imageUrls), + new PostResponse(POST_ID, userResponse, "글 내용1", 55, 5, 13, true, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1L), imageUrls) )); willReturn(postResponse).given(postService).findByVaccineType(any(VaccinationType.class), any()); //when @@ -114,7 +121,7 @@ void updatePost() throws Exception { //given willDoNothing().given(postService).update(any(Long.class), any(), any(PostRequest.class)); //when - ResultActions response = 글_수정_요청(POST_ID, request); + ResultActions response = 글_수정_요청(POST_ID, updatePostRequest); //then 글_수정_성공함(response); } @@ -125,7 +132,7 @@ void updatePostFailure() throws Exception { //given willThrow(new NotFoundException("해당 id의 게시글이 존재하지 않습니다.")).given(postService).update(any(Long.class), any(), any(PostRequest.class)); //when - ResultActions response = 글_수정_요청(POST_ID, request); + ResultActions response = 글_수정_요청(POST_ID, updatePostRequest); //then 글_수정_실패함(response); } @@ -157,9 +164,9 @@ void deletePostFailure() throws Exception { void findByVaccineType() throws Exception { //given List postResponse = new LinkedList<>(Arrays.asList( - new PostResponse(3L, userResponse, "이건 내용입니다.", 100, 10, 4, true, VaccinationType.PFIZER, LocalDateTime.now()), - new PostResponse(2L, userResponse, "이건 내용입니다.2", 200, 20, 6, false, VaccinationType.PFIZER, LocalDateTime.now()), - new PostResponse(1L, userResponse, "이건 내용입니다.3", 300, 30, 10, true, VaccinationType.PFIZER, LocalDateTime.now()) + new PostResponse(3L, userResponse, "이건 내용입니다.", 100, 10, 4, true, VaccinationType.PFIZER, LocalDateTime.now(), imageUrls), + new PostResponse(2L, userResponse, "이건 내용입니다.2", 200, 20, 6, false, VaccinationType.PFIZER, LocalDateTime.now(), imageUrls), + new PostResponse(1L, userResponse, "이건 내용입니다.3", 300, 30, 10, true, VaccinationType.PFIZER, LocalDateTime.now(), imageUrls) )); willReturn(postResponse).given(postService).findByVaccineType(any(VaccinationType.class), any()); //when @@ -185,9 +192,9 @@ void findByVaccineTypeWhenPostsIsEmpty() throws Exception { void findByVaccineTypePaging() throws Exception { //given List postResponses = new LinkedList<>(Arrays.asList( - new PostResponse(38L, userResponse, "이건 내용입니다.", 100, 10, 3, true, VaccinationType.PFIZER, LocalDateTime.now()), - new PostResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, 4, false, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1)), - new PostResponse(36L, userResponse, "이건 내용입니다.3", 300, 30, 2, true, VaccinationType.PFIZER, LocalDateTime.now().minusDays(2)) + new PostResponse(38L, userResponse, "이건 내용입니다.", 100, 10, 3, true, VaccinationType.PFIZER, LocalDateTime.now(), imageUrls), + new PostResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, 4, false, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1), imageUrls), + new PostResponse(36L, userResponse, "이건 내용입니다.3", 300, 30, 2, true, VaccinationType.PFIZER, LocalDateTime.now().minusDays(2), imageUrls) )); willReturn(postResponses).given(postService).findByVaccineType(any(VaccinationType.class), anyInt(), anyInt(), any(), anyInt(), any()); //when @@ -213,9 +220,9 @@ void findByVaccineTypePagingWhenPostsIsEmpty() throws Exception { void findByVaccineTypeSorting() throws Exception { //given List postResponses = new LinkedList<>(Arrays.asList( - new PostResponse(1L, userResponse, "이건 내용입니다.", 100, 10, 5, true, VaccinationType.PFIZER, LocalDateTime.now()), - new PostResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, 8, false, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1)), - new PostResponse(146L, userResponse, "이건 내용입니다.3", 300, 30, 1, true, VaccinationType.PFIZER, LocalDateTime.now().minusDays(2)) + new PostResponse(1L, userResponse, "이건 내용입니다.", 100, 10, 5, true, VaccinationType.PFIZER, LocalDateTime.now(), imageUrls), + new PostResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, 8, false, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1), imageUrls), + new PostResponse(146L, userResponse, "이건 내용입니다.3", 300, 30, 1, true, VaccinationType.PFIZER, LocalDateTime.now().minusDays(2), imageUrls) )); willReturn(postResponses).given(postService).findByVaccineType(any(VaccinationType.class), anyInt(), anyInt(), any(), anyInt(), any()); //when @@ -229,9 +236,9 @@ void findByVaccineTypeSorting() throws Exception { void findByVaccineTypeHourFiltering() throws Exception { //given List postResponses = new LinkedList<>(Arrays.asList( - new PostResponse(1L, userResponse, "이건 내용입니다.", 100, 10, 3, true, VaccinationType.PFIZER, LocalDateTime.now()), - new PostResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, 6, false, VaccinationType.PFIZER, LocalDateTime.now().minusHours(3)), - new PostResponse(146L, userResponse, "이건 내용입니다.3", 300, 30, 7, true, VaccinationType.PFIZER, LocalDateTime.now().minusHours(5)) + new PostResponse(1L, userResponse, "이건 내용입니다.", 100, 10, 3, true, VaccinationType.PFIZER, LocalDateTime.now(), imageUrls), + new PostResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, 6, false, VaccinationType.PFIZER, LocalDateTime.now().minusHours(3), imageUrls), + new PostResponse(146L, userResponse, "이건 내용입니다.3", 300, 30, 7, true, VaccinationType.PFIZER, LocalDateTime.now().minusHours(5), imageUrls) )); willReturn(postResponses).given(postService).findByVaccineType(any(VaccinationType.class), anyInt(), anyInt(), any(), anyInt(), any()); //when @@ -242,162 +249,162 @@ void findByVaccineTypeHourFiltering() throws Exception { private ResultActions 글_등록_요청(PostRequest request) throws Exception { return mockMvc.perform(post("/api/v1/posts") - .contentType(MediaType.APPLICATION_JSON) - .content(toJson(request)) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(request)) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 글_등록_성공함(ResultActions response, PostResponse postResponse) throws Exception { response.andExpect(status().isCreated()) - .andExpect(header().string("Location", "/api/v1/posts/" + postResponse.getId())) - .andDo(print()) - .andDo(toDocument("post-create")); + .andExpect(header().string("Location", "/api/v1/posts/" + postResponse.getId())) + .andDo(print()) + .andDo(toDocument("post-create")); } private void 글_등록_실패함(ResultActions response) throws Exception { response.andExpect(status().isNotFound()) - .andDo(print()) - .andDo(toDocument("post-create-failure")); + .andDo(print()) + .andDo(toDocument("post-create-failure")); } private ResultActions 글_단일_조회_요청(Long id) throws Exception { return mockMvc.perform(get("/api/v1/posts/{id}", id) - .contentType(MediaType.APPLICATION_JSON) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 글_단일_조회_성공함(ResultActions response) throws Exception { response.andExpect(status().isOk()) - .andDo(print()) - .andDo(toDocument("post-find")); + .andDo(print()) + .andDo(toDocument("post-find")); } private void 글_단일_조회_실패함(ResultActions response) throws Exception { response.andExpect(status().isNotFound()) - .andDo(print()) - .andDo(toDocument("post-find-failure")); + .andDo(print()) + .andDo(toDocument("post-find-failure")); } private ResultActions 글_전체_조회_요청() throws Exception { return mockMvc.perform(get("/api/v1/posts") - .contentType(MediaType.APPLICATION_JSON) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 글_전체_조회_성공함(ResultActions response, List postResponse) throws Exception { response.andExpect(status().isOk()) - .andExpect(content().json(toJson(postResponse))) - .andDo(print()) - .andDo(toDocument("post-findAll")); + .andExpect(content().json(toJson(postResponse))) + .andDo(print()) + .andDo(toDocument("post-findAll")); } private void 글_전체_조회_성공함_게시글없음(ResultActions response, List postResponse) throws Exception { response.andExpect(status().isOk()) - .andExpect(content().json(toJson(postResponse))) - .andDo(print()) - .andDo(toDocument("post-findAll-when-empty")); + .andExpect(content().json(toJson(postResponse))) + .andDo(print()) + .andDo(toDocument("post-findAll-when-empty")); } private ResultActions 글_수정_요청(Long id, PostRequest request) throws Exception { return mockMvc.perform(put("/api/v1/posts/{id}", id) - .contentType(MediaType.APPLICATION_JSON) - .content(toJson(request)) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(request)) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 글_수정_성공함(ResultActions response) throws Exception { response.andExpect(status().isNoContent()) - .andDo(print()) - .andDo(toDocument("post-update")); + .andDo(print()) + .andDo(toDocument("post-update")); } private void 글_수정_실패함(ResultActions response) throws Exception { response.andExpect(status().isNotFound()) - .andDo(print()) - .andDo(toDocument("post-update-failure")); + .andDo(print()) + .andDo(toDocument("post-update-failure")); } private ResultActions 글_삭제_요청(Long id) throws Exception { return mockMvc.perform(delete("/api/v1/posts/{id}", id) - .contentType(MediaType.APPLICATION_JSON) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 글_삭제_성공함(ResultActions response) throws Exception { response.andExpect(status().isNoContent()) - .andDo(print()) - .andDo(toDocument("post-delete")); + .andDo(print()) + .andDo(toDocument("post-delete")); } private void 글_삭제_실패함(ResultActions response) throws Exception { response.andExpect(status().isNotFound()) - .andDo(print()) - .andDo(toDocument("post-delete-failure")); + .andDo(print()) + .andDo(toDocument("post-delete-failure")); } private ResultActions 글_타입별_조회_요청(VaccinationType vaccinationType) throws Exception { return mockMvc.perform(get("/api/v1/posts") - .queryParam("vaccinationType", vaccinationType.name()) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .queryParam("vaccinationType", vaccinationType.name()) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 글_타입별_조회_요청_성공함(ResultActions response) throws Exception { response.andExpect(status().isOk()) - .andDo(print()) - .andDo(toDocument("post-findByVaccinationType")); + .andDo(print()) + .andDo(toDocument("post-findByVaccinationType")); } private void 글_타입별_조회_성공함_게시글없음(ResultActions response, List postResponse) throws Exception { response.andExpect(status().isOk()) - .andExpect(content().json(toJson(postResponse))) - .andDo(print()) - .andDo(toDocument("post-findByVaccinationType-when-empty")); + .andExpect(content().json(toJson(postResponse))) + .andDo(print()) + .andDo(toDocument("post-findByVaccinationType-when-empty")); } private ResultActions 글_타입별_페이징_조회_요청(VaccinationType vaccinationType, int offset, int size) throws Exception { return mockMvc.perform(get("/api/v1/posts/paging") - .queryParam("vaccinationType", vaccinationType.name()) - .queryParam("offset", String.valueOf(offset)) - .queryParam("size", String.valueOf(size)) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .queryParam("vaccinationType", vaccinationType.name()) + .queryParam("offset", String.valueOf(offset)) + .queryParam("size", String.valueOf(size)) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private ResultActions 글_타입별_정렬_조회_요청(VaccinationType vaccinationType, Sort sort) throws Exception { return mockMvc.perform(get("/api/v1/posts/paging") - .queryParam("vaccinationType", vaccinationType.name()) - .queryParam("sort", sort.name()) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .queryParam("vaccinationType", vaccinationType.name()) + .queryParam("sort", sort.name()) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private ResultActions 글_타입별_시간필터링_조회_요청(VaccinationType vaccinationType, int hour) throws Exception { return mockMvc.perform(get("/api/v1/posts/paging") - .queryParam("vaccinationType", vaccinationType.name()) - .queryParam("fromHoursBefore", String.valueOf(hour)) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .queryParam("vaccinationType", vaccinationType.name()) + .queryParam("fromHoursBefore", String.valueOf(hour)) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 글_타입별_페이징_조회_요청_성공함(ResultActions response) throws Exception { response.andExpect(status().isOk()) - .andDo(print()) - .andDo(toDocument("post-findByVaccinationType-paging")); + .andDo(print()) + .andDo(toDocument("post-findByVaccinationType-paging")); } private void 글_타입별_정렬_조회_요청_성공함(ResultActions response) throws Exception { response.andExpect(status().isOk()) - .andDo(print()) - .andDo(toDocument("post-findByVaccinationType-paging-sorting")); + .andDo(print()) + .andDo(toDocument("post-findByVaccinationType-paging-sorting")); } private void 글_타입별_시간필터링_조회_요청_성공함(ResultActions response) throws Exception { response.andExpect(status().isOk()) - .andDo(print()) - .andDo(toDocument("post-findByVaccinationType-paging-filteringHour")); + .andDo(print()) + .andDo(toDocument("post-findByVaccinationType-paging-filteringHour")); } private void 글_타입별_페이징_조회_요청_성공함_게시글없음(ResultActions response, List postResponses) throws Exception { response.andExpect(status().isOk()) - .andExpect(content().json(toJson(postResponses))) - .andDo(print()) - .andDo(toDocument("post-findByVaccinationType-paging-when-empty")); + .andExpect(content().json(toJson(postResponses))) + .andDo(print()) + .andDo(toDocument("post-findByVaccinationType-paging-when-empty")); } } diff --git a/backend/app-cvi-api/src/test/java/com/cvi/controller/PreprocessPostControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/PreprocessPostControllerTest.java index 64134792..161b7e53 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/controller/PreprocessPostControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/PreprocessPostControllerTest.java @@ -1,30 +1,29 @@ package com.cvi.controller; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; + import com.cvi.ApiDocument; import com.cvi.auth.JwtTokenProvider; import com.cvi.dto.CommentResponse; +import com.cvi.dto.ImageRequest; import com.cvi.dto.PostRequest; import com.cvi.dto.PostResponse; import com.cvi.dto.UserResponse; +import com.cvi.image.domain.ImageType; import com.cvi.post.domain.model.Post; import com.cvi.post.domain.model.VaccinationType; import com.cvi.service.UserService; import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; -import com.cvi.user.domain.repository.UserRepository; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.springframework.boot.test.mock.mockito.MockBean; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Optional; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.given; - @DisplayName("게시글, 좋아요, 댓글 컨트롤러 Mock 테스트 - 환경설정") public abstract class PreprocessPostControllerTest extends ApiDocument { @@ -34,13 +33,19 @@ public abstract class PreprocessPostControllerTest extends ApiDocument { protected static final Long LIKE_ID = 1L; protected static final String BEARER = "Bearer "; protected static final String ACCESS_TOKEN = "{ACCESS TOKEN generated by JWT}"; + protected static final String IMAGE1_DATA_VALUE = "{이미지1 Base64 인코딩 된 문자열값}"; + protected static final String IMAGE2_DATA_VALUE = "{이미지2 Base64 인코딩 된 문자열값}"; + protected static final String IMAGE3_DATA_VALUE = "{이미지3 Base64 인코딩 된 문자열값}"; + protected static final String IMAGE4_DATA_VALUE = "{이미지4 Base64 인코딩 된 문자열값}"; + protected static final String IMAGE5_DATA_VALUE = "{이미지5 Base64 인코딩 된 문자열값}"; + protected static final String IMAGE1_S3_URL = "{이미지1 S3 URL}"; + protected static final String IMAGE2_S3_URL = "{이미지2 S3 URL}"; + protected static final String IMAGE3_S3_URL = "{이미지3 S3 URL}"; + protected static final String IMAGE4_S3_URL = "{이미지4 S3 URL}"; @MockBean protected UserService userService; - @MockBean - private UserRepository userRepository; - @MockBean protected JwtTokenProvider jwtTokenProvider; @@ -48,46 +53,65 @@ public abstract class PreprocessPostControllerTest extends ApiDocument { protected User anotherUser; protected UserResponse userResponse; - protected PostRequest request; + protected Post post; + + protected PostRequest createPostRequest; + protected PostRequest updatePostRequest; protected PostResponse postResponse; protected List commentResponses; + protected List newPostImagesRequests; + protected List updatePostImagesRequests; + protected List imageUrls; + @BeforeEach void setUp() { user = User.builder() - .id(USER_ID) - .nickname("user") - .ageRange(AgeRange.TEENS) - .profileUrl("naver.com/profile") - .socialId("{Unique ID received from social provider}") - .socialProvider(SocialProvider.NAVER) - .build(); + .id(USER_ID) + .nickname("user") + .ageRange(AgeRange.TEENS) + .profileUrl("naver.com/profile") + .socialId("{Unique ID received from social provider}") + .socialProvider(SocialProvider.NAVER) + .build(); anotherUser = User.builder() - .id(USER_ID + 1) - .nickname("another_user") - .ageRange(AgeRange.TWENTIES) - .profileUrl("kakao.com/profile") - .socialId("{Unique ID received from social provider}") - .socialProvider(SocialProvider.KAKAO) - .build(); - Post post = Post.builder() - .id(POST_ID) - .user(user) - .vaccinationType(VaccinationType.ASTRAZENECA) - .content("Post Content") - .createdAt(LocalDateTime.now()) - .viewCount(0) - .build(); + .id(USER_ID + 1) + .nickname("another_user") + .ageRange(AgeRange.TWENTIES) + .profileUrl("kakao.com/profile") + .socialId("{Unique ID received from social provider}") + .socialProvider(SocialProvider.KAKAO) + .build(); + newPostImagesRequests = Arrays.asList( + new ImageRequest(ImageType.JPG, IMAGE1_DATA_VALUE), + new ImageRequest(ImageType.JPEG, IMAGE2_DATA_VALUE), + new ImageRequest(ImageType.PNG, IMAGE3_DATA_VALUE)); + updatePostImagesRequests = Arrays.asList( + new ImageRequest( ImageType.JPG, IMAGE4_DATA_VALUE), + new ImageRequest( ImageType.SVG, IMAGE5_DATA_VALUE)); + imageUrls = Arrays.asList( + IMAGE1_S3_URL, + IMAGE2_S3_URL, + IMAGE3_S3_URL, + IMAGE4_S3_URL); + post = Post.builder() + .id(POST_ID) + .user(user) + .vaccinationType(VaccinationType.ASTRAZENECA) + .content("Post Content") + .createdAt(LocalDateTime.now()) + .viewCount(0) + .build(); - request = new PostRequest("글 내용", VaccinationType.PFIZER); + createPostRequest = new PostRequest("글 내용", VaccinationType.PFIZER, newPostImagesRequests); + updatePostRequest = new PostRequest("수정된 글 내용", VaccinationType.ASTRAZENECA, updatePostImagesRequests); userResponse = UserResponse.of(user, null); - postResponse = PostResponse.of(post, user); + postResponse = PostResponse.of(post, user, imageUrls); given(jwtTokenProvider.isValidToken(ACCESS_TOKEN)).willReturn(true); given(jwtTokenProvider.getPayload(ACCESS_TOKEN)).willReturn(String.valueOf(user.getId())); given(userService.findUserById(any(Long.class))).willReturn(user); - given(userRepository.findById(anyLong())).willReturn(Optional.of(user)); } } diff --git a/backend/app-cvi-api/src/test/java/com/cvi/controller/PublicDataControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/PublicDataControllerTest.java index 778c7336..b82292db 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/controller/PublicDataControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/PublicDataControllerTest.java @@ -1,28 +1,28 @@ package com.cvi.controller; +import static com.cvi.PublicDataFacotry.toSingleWorldVaccinationStatisticResponse; +import static com.cvi.PublicDataFacotry.toVaccinationStatisticResponse; +import static com.cvi.PublicDataFacotry.toVaccinationStatisticResponseOnlyWorldRegion; +import static org.mockito.BDDMockito.willReturn; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import com.cvi.ApiDocument; -import com.cvi.PublicDataFacotry; import com.cvi.auth.JwtTokenProvider; import com.cvi.dto.VaccinationStatisticResponse; import com.cvi.service.PublicDataService; import com.cvi.service.UserService; -import com.cvi.user.domain.repository.UserRepository; +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.ResultActions; -import java.time.LocalDate; -import java.util.Collections; -import java.util.List; - -import static org.mockito.BDDMockito.willReturn; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @DisplayName("공공데이터 컨트롤러 Mock 테스트") @WebMvcTest(controllers = PublicDataController.class) class PublicDataControllerTest extends ApiDocument { @@ -35,9 +35,6 @@ class PublicDataControllerTest extends ApiDocument { @MockBean private UserService userService; - @MockBean - private UserRepository userRepository; - @MockBean private JwtTokenProvider jwtTokenProvider; @@ -45,7 +42,7 @@ class PublicDataControllerTest extends ApiDocument { @Test void saveVaccinationStatistic() throws Exception { //given - List vaccinationStatisticResponse = PublicDataFacotry.toVaccinationStatisticResponse(TARGET_DATE); + List vaccinationStatisticResponse = toVaccinationStatisticResponse(TARGET_DATE); //when willReturn(vaccinationStatisticResponse).given(publicDataService).saveVaccinationStatistics(TARGET_DATE); ResultActions response = 백신_접종률_저장_요청(TARGET_DATE); @@ -57,7 +54,7 @@ void saveVaccinationStatistic() throws Exception { @Test void findVaccinationStatistic() throws Exception { //given - List vaccinationStatisticResponse = PublicDataFacotry.toVaccinationStatisticResponse(TARGET_DATE); + List vaccinationStatisticResponse = toVaccinationStatisticResponse(TARGET_DATE); //when willReturn(vaccinationStatisticResponse).given(publicDataService).findVaccinationStatistics(TARGET_DATE); ResultActions response = 백신_접종률_조회_요청(TARGET_DATE); @@ -82,7 +79,7 @@ void findVaccinationStatisticEmpty() throws Exception { void saveWorldVaccinationStatistic() throws Exception { //given //when - willReturn(PublicDataFacotry.toVaccinationStatisticResponseOnlyWorldRegion(TARGET_DATE)).given(publicDataService).saveWorldVaccinationStatistics(TARGET_DATE); + willReturn(toVaccinationStatisticResponseOnlyWorldRegion(TARGET_DATE)).given(publicDataService).saveWorldVaccinationStatistics(TARGET_DATE); ResultActions response = 세계_백신_접종률_저장_요청(TARGET_DATE); //then 세계_백신_접종률_저장_성공함(response); @@ -92,7 +89,7 @@ void saveWorldVaccinationStatistic() throws Exception { @Test void findWorldVaccinationStatistic() throws Exception { //given - List expect = Collections.singletonList(PublicDataFacotry.toSingleWorldVaccinationStatisticResponse(TARGET_DATE)); + List expect = Collections.singletonList(toSingleWorldVaccinationStatisticResponse(TARGET_DATE)); //when willReturn(expect).given(publicDataService).findWorldVaccinationStatistics(TARGET_DATE); ResultActions response = 세계_백신_접종률_조회_요청(TARGET_DATE); @@ -102,51 +99,51 @@ void findWorldVaccinationStatistic() throws Exception { private ResultActions 백신_접종률_저장_요청(LocalDate targetDate) throws Exception { return mockMvc.perform(post("/api/v1/publicdata/vaccinations") - .param("targetDate", targetDate.toString())); + .param("targetDate", targetDate.toString())); } private void 백신_접종률_저장_성공함(ResultActions response) throws Exception { response.andExpect(status().isCreated()) - .andDo(print()) - .andDo(toDocument("publicdata-vaccination-save")); + .andDo(print()) + .andDo(toDocument("publicdata-vaccination-save")); } private ResultActions 백신_접종률_조회_요청(LocalDate targetDate) throws Exception { return mockMvc.perform(get("/api/v1/publicdata/vaccinations") - .param("targetDate", targetDate.toString())); + .param("targetDate", targetDate.toString())); } private void 백신_접종률_조회_성공함(ResultActions response) throws Exception { response.andExpect(status().isOk()) - .andDo(print()) - .andDo(toDocument("publicdata-vaccination-find")); + .andDo(print()) + .andDo(toDocument("publicdata-vaccination-find")); } private void 백신_접종률_업데이트전_조회_성공함(ResultActions response) throws Exception { response.andExpect(status().isOk()) - .andDo(print()) - .andDo(toDocument("publicdata-vaccination-nodata-find")); + .andDo(print()) + .andDo(toDocument("publicdata-vaccination-nodata-find")); } private ResultActions 세계_백신_접종률_저장_요청(LocalDate targetDate) throws Exception { return mockMvc.perform(post("/api/v1/publicdata/vaccinations/world") - .param("targetDate", targetDate.toString())); + .param("targetDate", targetDate.toString())); } private void 세계_백신_접종률_저장_성공함(ResultActions response) throws Exception { response.andExpect(status().isCreated()) - .andDo(print()) - .andDo(toDocument("publicdata-world-vaccination-save")); + .andDo(print()) + .andDo(toDocument("publicdata-world-vaccination-save")); } private ResultActions 세계_백신_접종률_조회_요청(LocalDate targetDate) throws Exception { return mockMvc.perform(get("/api/v1/publicdata/vaccinations/world") - .param("targetDate", targetDate.toString())); + .param("targetDate", targetDate.toString())); } private void 새걔_백신_접종률_조회_성공함(ResultActions response) throws Exception { response.andExpect(status().isOk()) - .andDo(print()) - .andDo(toDocument("publicdata-world-vaccination-find")); + .andDo(print()) + .andDo(toDocument("publicdata-world-vaccination-find")); } } diff --git a/backend/app-cvi-api/src/test/java/com/cvi/controller/UserControllerTest.java b/backend/app-cvi-api/src/test/java/com/cvi/controller/UserControllerTest.java index ec1303a4..acf18cbe 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/controller/UserControllerTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/controller/UserControllerTest.java @@ -1,5 +1,21 @@ package com.cvi.controller; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.anyInt; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willDoNothing; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.BDDMockito.willThrow; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import com.cvi.ApiDocument; import com.cvi.auth.JwtTokenProvider; import com.cvi.comment.domain.model.Comment; @@ -12,12 +28,17 @@ import com.cvi.exception.UnAuthorizedException; import com.cvi.post.domain.model.Filter; import com.cvi.post.domain.model.VaccinationType; -import com.cvi.service.PostService; import com.cvi.service.UserService; +import com.cvi.service.post.PostService; import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; -import com.cvi.user.domain.repository.UserRepository; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -31,17 +52,6 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.ResultActions; -import java.time.LocalDateTime; -import java.util.*; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - @DisplayName("사용자 컨트롤러 Mock 테스트") @WebMvcTest(controllers = UserController.class) class UserControllerTest extends ApiDocument { @@ -60,9 +70,6 @@ class UserControllerTest extends ApiDocument { @MockBean private UserService userService; - @MockBean - private UserRepository userRepository; - @MockBean private PostService postService; @@ -75,22 +82,24 @@ class UserControllerTest extends ApiDocument { private UserResponse userResponse; private UserResponse userMeResponse; private List commentResponses; + private List imageUrls; @BeforeEach void beforeEach() { user = User.builder() - .id(USER_ID) - .nickname(NICKNAME) - .ageRange(AgeRange.TWENTIES) - .socialProvider(SOCIAL_PROVIDER) - .socialId(SOCIAL_ID) - .profileUrl(PROFILE_URL) - .build(); + .id(USER_ID) + .nickname(NICKNAME) + .ageRange(AgeRange.TWENTIES) + .socialProvider(SOCIAL_PROVIDER) + .socialId(SOCIAL_ID) + .profileUrl(PROFILE_URL) + .build(); signinRequest = new UserRequest(NICKNAME, AGE_RANGE, false, SOCIAL_PROVIDER, SOCIAL_ID, PROFILE_URL); updateRequest = new UserRequest(NICKNAME, AGE_RANGE, true, SOCIAL_PROVIDER, SOCIAL_ID, PROFILE_URL); userResponse = UserResponse.of(user, ACCESS_TOKEN); userMeResponse = UserResponse.of(user, null); + imageUrls = Arrays.asList("{이미지1 S3 URL}", "{이미지2 S3 URL}", "{이미지3 S3 URL}"); Comment comment1 = Comment.builder().id(COMMENT_ID).content("댓글1").user(user).createdAt(LocalDateTime.now()).build(); Comment comment2 = Comment.builder().id(COMMENT_ID + 1).content("댓글2").user(user).createdAt(LocalDateTime.now()).build(); @@ -100,7 +109,6 @@ void beforeEach() { given(jwtTokenProvider.isValidToken(ACCESS_TOKEN)).willReturn(true); given(jwtTokenProvider.getPayload(ACCESS_TOKEN)).willReturn(String.valueOf(user.getId())); given(userService.findUserById(any(Long.class))).willReturn(user); - given(userRepository.findById(anyLong())).willReturn(Optional.of(user)); } @DisplayName("사용자 가입 - 성공") @@ -152,12 +160,12 @@ void findMeFailure() throws Exception { void find() throws Exception { //given User otherUser = User.builder() - .id(1L) - .nickname(NICKNAME) - .ageRange(AgeRange.TWENTIES) - .socialProvider(SOCIAL_PROVIDER) - .profileUrl(PROFILE_URL) - .build(); + .id(1L) + .nickname(NICKNAME) + .ageRange(AgeRange.TWENTIES) + .socialProvider(SOCIAL_PROVIDER) + .profileUrl(PROFILE_URL) + .build(); UserResponse userResponseWithoutPrivacy = UserResponse.of(otherUser, null); willReturn(userResponseWithoutPrivacy).given(userService).findById(any(Long.class)); //when @@ -193,7 +201,7 @@ void update() throws Exception { void updateFailure() throws Exception { //given willThrow(new InvalidInputException("중복된 닉네임이 존재합니다.")) - .given(userService).update(any(), any(UserRequest.class)); + .given(userService).update(any(), any(UserRequest.class)); //when ResultActions response = 사용자_업데이트_요청(updateRequest); //then @@ -227,9 +235,9 @@ void deleteFailure() throws Exception { void findMyPostsWhenFilterIsNone() throws Exception { //given List postWithCommentResponse = Arrays.asList( - new PostWithCommentResponse(POST_ID, userResponse, "글 내용1", 55, 5, true, commentResponses, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1L)), - new PostWithCommentResponse(POST_ID + 1, userResponse, "글 내용2", 12, 0, false, Collections.emptyList(), VaccinationType.MODERNA, LocalDateTime.now()), - new PostWithCommentResponse(POST_ID + 2, userResponse, "글 내용3", 12, 0, false, Collections.emptyList(), VaccinationType.ASTRAZENECA, LocalDateTime.now())); + new PostWithCommentResponse(POST_ID, userResponse, "글 내용1", 55, 5, true, commentResponses, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1L), imageUrls), + new PostWithCommentResponse(POST_ID + 1, userResponse, "글 내용2", 12, 0, false, Collections.emptyList(), VaccinationType.MODERNA, LocalDateTime.now(), imageUrls), + new PostWithCommentResponse(POST_ID + 2, userResponse, "글 내용3", 12, 0, false, Collections.emptyList(), VaccinationType.ASTRAZENECA, LocalDateTime.now(), imageUrls)); Filter filter = Filter.NONE; willReturn(postWithCommentResponse).given(postService).findByUserAndFilter(any(), any(Filter.class)); //when @@ -255,8 +263,8 @@ void findMyPostsFailureWhenFilterIsNone() throws Exception { void findMyPostsWhenFilterIsLikes() throws Exception { //given List postWithCommentResponse = Arrays.asList( - new PostWithCommentResponse(POST_ID, userResponse, "글 내용1", 55, 5, true, commentResponses, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1L)), - new PostWithCommentResponse(POST_ID + 1, userResponse, "글 내용2", 12, 0, true, Collections.emptyList(), VaccinationType.MODERNA, LocalDateTime.now())); + new PostWithCommentResponse(POST_ID, userResponse, "글 내용1", 55, 5, true, commentResponses, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1L), imageUrls), + new PostWithCommentResponse(POST_ID + 1, userResponse, "글 내용2", 12, 0, true, Collections.emptyList(), VaccinationType.MODERNA, LocalDateTime.now(), imageUrls)); Filter filter = Filter.LIKES; willReturn(postWithCommentResponse).given(postService).findByUserAndFilter(any(), any(Filter.class)); //when @@ -282,8 +290,8 @@ void findMyPostsFailureWhenFilterIsLikes() throws Exception { void findMyPostsWhenFilterIsComments() throws Exception { //given List postWithCommentResponse = Arrays.asList( - new PostWithCommentResponse(POST_ID, userResponse, "글 내용1", 55, 5, true, commentResponses, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1L)), - new PostWithCommentResponse(POST_ID + 1, userResponse, "글 내용2", 12, 0, false, commentResponses, VaccinationType.MODERNA, LocalDateTime.now())); + new PostWithCommentResponse(POST_ID, userResponse, "글 내용1", 55, 5, true, commentResponses, VaccinationType.PFIZER, LocalDateTime.now().minusDays(1L), imageUrls), + new PostWithCommentResponse(POST_ID + 1, userResponse, "글 내용2", 12, 0, false, commentResponses, VaccinationType.MODERNA, LocalDateTime.now(), imageUrls)); Filter filter = Filter.COMMENTS; willReturn(postWithCommentResponse).given(postService).findByUserAndFilter(any(), any(Filter.class)); //when @@ -309,10 +317,10 @@ void findMyPostsFailureWhenFilterIsComments() throws Exception { void findMyPostsWhenFilterIsNonePaging() throws Exception { //given List postWithCommentResponse = new LinkedList<>(Arrays.asList( - new PostWithCommentResponse(38L, userResponse, "이건 내용입니다.", 100, 10, false, commentResponses, VaccinationType.PFIZER, LocalDateTime.now()), - new PostWithCommentResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, true, Collections.emptyList(), VaccinationType.MODERNA, LocalDateTime.now().minusDays(1L)), - new PostWithCommentResponse(36L, userResponse, "이건 내용입니다.3", 300, 30, false, Collections.emptyList(), VaccinationType.ASTRAZENECA, LocalDateTime.now().minusHours(2L)), - new PostWithCommentResponse(35L, userResponse, "이건 내용입니다.3", 300, 30, false, Collections.emptyList(), VaccinationType.ASTRAZENECA, LocalDateTime.now().minusHours(2L)) + new PostWithCommentResponse(38L, userResponse, "이건 내용입니다.", 100, 10, false, commentResponses, VaccinationType.PFIZER, LocalDateTime.now(), imageUrls), + new PostWithCommentResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, true, Collections.emptyList(), VaccinationType.MODERNA, LocalDateTime.now().minusDays(1L), imageUrls), + new PostWithCommentResponse(36L, userResponse, "이건 내용입니다.3", 300, 30, false, Collections.emptyList(), VaccinationType.ASTRAZENECA, LocalDateTime.now().minusHours(2L), imageUrls), + new PostWithCommentResponse(35L, userResponse, "이건 내용입니다.3", 300, 30, false, Collections.emptyList(), VaccinationType.ASTRAZENECA, LocalDateTime.now().minusHours(2L), imageUrls) )); Filter filter = Filter.NONE; willReturn(postWithCommentResponse).given(postService).findByUserAndFilter(any(Filter.class), any(Integer.class), anyInt(), any()); @@ -339,9 +347,9 @@ void findMyPostsFailureWhenFilterIsNonePaging() throws Exception { void findMyPostsWhenFilterIsLikesPaging() throws Exception { //given List postWithCommentResponse = new LinkedList<>(Arrays.asList( - new PostWithCommentResponse(38L, userResponse, "이건 내용입니다.", 100, 10, true, commentResponses, VaccinationType.PFIZER, LocalDateTime.now()), - new PostWithCommentResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, true, Collections.emptyList(), VaccinationType.MODERNA, LocalDateTime.now().minusDays(1L)), - new PostWithCommentResponse(36L, userResponse, "이건 내용입니다.3", 300, 30, true, Collections.emptyList(), VaccinationType.ASTRAZENECA, LocalDateTime.now().minusHours(2L)) + new PostWithCommentResponse(38L, userResponse, "이건 내용입니다.", 100, 10, true, commentResponses, VaccinationType.PFIZER, LocalDateTime.now(), imageUrls), + new PostWithCommentResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, true, Collections.emptyList(), VaccinationType.MODERNA, LocalDateTime.now().minusDays(1L), imageUrls), + new PostWithCommentResponse(36L, userResponse, "이건 내용입니다.3", 300, 30, true, Collections.emptyList(), VaccinationType.ASTRAZENECA, LocalDateTime.now().minusHours(2L), imageUrls) )); Filter filter = Filter.LIKES; willReturn(postWithCommentResponse).given(postService).findByUserAndFilter(any(Filter.class), anyInt(), anyInt(), any()); @@ -368,8 +376,8 @@ void findMyPostsFailureWhenFilterIsLikesPaging() throws Exception { void findMyPostsWhenFilterIsCommentsPaging() throws Exception { //given List postWithCommentResponse = new LinkedList<>(Arrays.asList( - new PostWithCommentResponse(38L, userResponse, "이건 내용입니다.", 100, 10, false, commentResponses, VaccinationType.PFIZER, LocalDateTime.now()), - new PostWithCommentResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, false, commentResponses, VaccinationType.MODERNA, LocalDateTime.now().minusDays(1L)) + new PostWithCommentResponse(38L, userResponse, "이건 내용입니다.", 100, 10, false, commentResponses, VaccinationType.PFIZER, LocalDateTime.now(), imageUrls), + new PostWithCommentResponse(37L, userResponse, "이건 내용입니다.2", 200, 20, false, commentResponses, VaccinationType.MODERNA, LocalDateTime.now().minusDays(1L), imageUrls) )); Filter filter = Filter.COMMENTS; willReturn(postWithCommentResponse).given(postService).findByUserAndFilter(any(Filter.class), anyInt(), anyInt(), any()); @@ -405,10 +413,10 @@ void validateUserRequestWhenInvalidNickName(UserRequest userRequest) throws Exce static Stream validateUserRequestWhenInvalidNickName() { return Stream.of( - Arguments.of(new UserRequest(" ", AgeRange.TEENS, false, SocialProvider.NAVER, SOCIAL_ID, PROFILE_URL)), - Arguments.of(new UserRequest("123456789012345678901", AgeRange.TEENS, false, SocialProvider.NAVER, SOCIAL_ID, PROFILE_URL)), - Arguments.of(new UserRequest("!@#$%^", AgeRange.TEENS, false, SocialProvider.NAVER, SOCIAL_ID, PROFILE_URL)), - Arguments.of(new UserRequest("👏", AgeRange.TEENS, false, SocialProvider.NAVER, SOCIAL_ID, PROFILE_URL))); + Arguments.of(new UserRequest(" ", AgeRange.TEENS, false, SocialProvider.NAVER, SOCIAL_ID, PROFILE_URL)), + Arguments.of(new UserRequest("123456789012345678901", AgeRange.TEENS, false, SocialProvider.NAVER, SOCIAL_ID, PROFILE_URL)), + Arguments.of(new UserRequest("!@#$%^", AgeRange.TEENS, false, SocialProvider.NAVER, SOCIAL_ID, PROFILE_URL)), + Arguments.of(new UserRequest("👏", AgeRange.TEENS, false, SocialProvider.NAVER, SOCIAL_ID, PROFILE_URL))); } @ParameterizedTest(name = "UserRequest validation - 유효하지 않은 경우 - 그 외") @@ -425,148 +433,148 @@ void validateUserRequest(UserRequest userRequest) throws Exception { static Stream validateUserRequest() { return Stream.of( - Arguments.of(new UserRequest(NICKNAME, null, false, SocialProvider.NAVER, SOCIAL_ID, PROFILE_URL)), - Arguments.of(new UserRequest(NICKNAME, AgeRange.TEENS, false, null, SOCIAL_ID, PROFILE_URL)), - Arguments.of(new UserRequest(NICKNAME, AgeRange.TEENS, false, SocialProvider.NAVER, " ", PROFILE_URL)), - Arguments.of(new UserRequest(NICKNAME, AgeRange.TEENS, false, SocialProvider.NAVER, SOCIAL_ID, " "))); + Arguments.of(new UserRequest(NICKNAME, null, false, SocialProvider.NAVER, SOCIAL_ID, PROFILE_URL)), + Arguments.of(new UserRequest(NICKNAME, AgeRange.TEENS, false, null, SOCIAL_ID, PROFILE_URL)), + Arguments.of(new UserRequest(NICKNAME, AgeRange.TEENS, false, SocialProvider.NAVER, " ", PROFILE_URL)), + Arguments.of(new UserRequest(NICKNAME, AgeRange.TEENS, false, SocialProvider.NAVER, SOCIAL_ID, " "))); } private ResultActions 사용자_회원가입_요청(UserRequest request) throws Exception { return mockMvc.perform(post("/api/v1/users/signup") - .contentType(MediaType.APPLICATION_JSON) - .content(toJson(request))); + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(request))); } private void 사용자_회원가입_성공함(ResultActions response, UserResponse userResponse) throws Exception { response.andExpect(status().isCreated()) - .andExpect(header().string("Location", "/api/v1/users/" + userResponse.getId())) - .andExpect(content().json(toJson(userResponse))) - .andDo(print()) - .andDo(toDocument("user-signup")); + .andExpect(header().string("Location", "/api/v1/users/" + userResponse.getId())) + .andExpect(content().json(toJson(userResponse))) + .andDo(print()) + .andDo(toDocument("user-signup")); } private void 사용자_회원가입_실패함(ResultActions response) throws Exception { response.andExpect(status().isBadRequest()) - .andDo(print()) - .andDo(toDocument("user-signup-failure")); + .andDo(print()) + .andDo(toDocument("user-signup-failure")); } private ResultActions 사용자_내_정보_조회_요청() throws Exception { return mockMvc.perform(get("/api/v1/users/me") - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 사용자_내_정보_조회_성공함(ResultActions response, UserResponse userResponse) throws Exception { response.andExpect(status().isOk()) - .andExpect(content().json(toJson(userResponse))) - .andDo(print()) - .andDo(toDocument("user-find-me")); + .andExpect(content().json(toJson(userResponse))) + .andDo(print()) + .andDo(toDocument("user-find-me")); } private void 사용자_내_정보_조회_실패함(ResultActions response) throws Exception { response.andExpect(status().isUnauthorized()) - .andDo(print()) - .andDo(toDocument("user-find-me-failure")); + .andDo(print()) + .andDo(toDocument("user-find-me-failure")); } private ResultActions 사용자_조회_요청(Long id) throws Exception { return mockMvc.perform(get("/api/v1/users/" + id) - .contentType(MediaType.APPLICATION_JSON)); + .contentType(MediaType.APPLICATION_JSON)); } private void 사용자_조회_성공함(ResultActions response, UserResponse userResponse) throws Exception { response.andExpect(status().isOk()) - .andExpect(content().json(toJson(userResponse))) - .andDo(print()) - .andDo(toDocument("user-find")); + .andExpect(content().json(toJson(userResponse))) + .andDo(print()) + .andDo(toDocument("user-find")); } private void 사용자_조회_실패함(ResultActions response) throws Exception { response.andExpect(status().isNotFound()) - .andDo(print()) - .andDo(toDocument("user-find-failure")); + .andDo(print()) + .andDo(toDocument("user-find-failure")); } private ResultActions 사용자_업데이트_요청(UserRequest request) throws Exception { return mockMvc.perform(put("/api/v1/users/me") - .contentType(MediaType.APPLICATION_JSON) - .content(toJson(request)) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(request)) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 사용자_업데이트_성공(ResultActions response) throws Exception { response.andExpect(status().isNoContent()) - .andDo(print()) - .andDo(toDocument("user-update")); + .andDo(print()) + .andDo(toDocument("user-update")); } private void 사용자_업데이트_실패함(ResultActions response) throws Exception { response.andExpect(status().isBadRequest()) - .andDo(print()) - .andDo(toDocument("user-update-failure")); + .andDo(print()) + .andDo(toDocument("user-update-failure")); } private ResultActions 사용자_삭제_요청() throws Exception { return mockMvc.perform(delete("/api/v1/users") - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 사용자_삭제_성공(ResultActions response) throws Exception { response.andExpect(status().isNoContent()) - .andDo(print()) - .andDo(toDocument("user-delete")); + .andDo(print()) + .andDo(toDocument("user-delete")); } private void 사용자_삭제_실패(ResultActions response) throws Exception { response.andExpect(status().isNotFound()) - .andDo(print()) - .andDo(toDocument("user-delete-failure")); + .andDo(print()) + .andDo(toDocument("user-delete-failure")); } private ResultActions 내가_쓴_글_조회_요청() throws Exception { return mockMvc.perform(get("/api/v1/users/me/posts") - .contentType(MediaType.APPLICATION_JSON) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private ResultActions 마이페이지_글_필터링_조회_요청(Filter filter) throws Exception { return mockMvc.perform(get("/api/v1/users/me/posts") - .contentType(MediaType.APPLICATION_JSON) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN) - .queryParam("filter", filter.name())); + .contentType(MediaType.APPLICATION_JSON) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN) + .queryParam("filter", filter.name())); } private ResultActions 마이페이지_글_타입별_페이징_조회_요청(Filter filter, int offset, int size) throws Exception { return mockMvc.perform(get("/api/v1/users/me/posts/paging") - .queryParam("filter", filter.name()) - .queryParam("offset", String.valueOf(offset)) - .queryParam("size", String.valueOf(size)) - .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); + .queryParam("filter", filter.name()) + .queryParam("offset", String.valueOf(offset)) + .queryParam("size", String.valueOf(size)) + .header(HttpHeaders.AUTHORIZATION, BEARER + ACCESS_TOKEN)); } private void 마이페이지_글_타입별_페이징_조회_요청_성공함(ResultActions response, List postWithCommentResponse, Filter filter) throws Exception { response.andExpect(status().isOk()) - .andExpect(content().json(toJson(postWithCommentResponse))) - .andDo(print()) - .andDo(toDocument("user-me-posts-paging-" + filter.name().toLowerCase())); + .andExpect(content().json(toJson(postWithCommentResponse))) + .andDo(print()) + .andDo(toDocument("user-me-posts-paging-" + filter.name().toLowerCase())); } private void 마이페이지_글_타입별_페이징_조회_요청_실패함(ResultActions response, Filter filter) throws Exception { response.andExpect(status().isUnauthorized()) - .andDo(print()) - .andDo(toDocument("user-me-posts-paging-" + filter.name().toLowerCase() + "-failure")); + .andDo(print()) + .andDo(toDocument("user-me-posts-paging-" + filter.name().toLowerCase() + "-failure")); } private void 마이페이지_글_필터링_조회_요청_성공함(ResultActions response, List postWithCommentResponse, Filter filter) throws Exception { response.andExpect(status().isOk()) - .andExpect(content().json(toJson(postWithCommentResponse))) - .andDo(print()) - .andDo(toDocument("user-me-posts-filter-" + filter.name().toLowerCase())); + .andExpect(content().json(toJson(postWithCommentResponse))) + .andDo(print()) + .andDo(toDocument("user-me-posts-filter-" + filter.name().toLowerCase())); } private void 마이페이지_글_필터링_조회_요청_실패함(ResultActions response, Filter filter) throws Exception { response.andExpect(status().isUnauthorized()) - .andDo(print()) - .andDo(toDocument("user-me-posts-filter-" + filter.name().toLowerCase() + "-failure")); + .andDo(print()) + .andDo(toDocument("user-me-posts-filter-" + filter.name().toLowerCase() + "-failure")); } } diff --git a/backend/app-cvi-api/src/test/java/com/cvi/service/AuthServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/AuthServiceTest.java index 249334fd..bc5b118f 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/service/AuthServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/AuthServiceTest.java @@ -1,5 +1,10 @@ package com.cvi.service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.BDDMockito.willThrow; + import com.cvi.auth.JwtTokenProvider; import com.cvi.dto.AuthRequest; import com.cvi.dto.UserResponse; @@ -13,6 +18,7 @@ import com.cvi.user.domain.repository.UserRepository; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -21,13 +27,6 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.TestPropertySource; -import java.util.Optional; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.willReturn; -import static org.mockito.BDDMockito.willThrow; - @SpringBootTest @TestPropertySource(properties = {"security.auth.naver.client-secret"}) @DisplayName("소셜로그인 비즈니스 흐름 테스트") @@ -38,6 +37,7 @@ class AuthServiceTest { private static final String STATE = "STATE"; private static final String NAVER_ID = "NAVER_ID"; private static final String NAVER_PROFILE_URL = "naver.com/profile"; + private static final String REQUEST_ORIGIN = "http://localhost:9000"; @Autowired private AuthService authService; @@ -50,10 +50,6 @@ class AuthServiceTest { @MockBean private JwtTokenProvider jwtTokenProvider; - - @MockBean - private PublicDataScheduler publicDataScheduler; - private AuthRequest authRequest; private User user; private String token; @@ -65,13 +61,13 @@ class AuthServiceTest { void beforeEach() throws JsonProcessingException { authRequest = new AuthRequest(SocialProvider.NAVER, SOCIAL_CODE, STATE); user = User.builder() - .id(1L) - .nickname("test_user") - .ageRange(AgeRange.TEENS) - .socialId(NAVER_ID) - .profileUrl(NAVER_PROFILE_URL) - .socialProvider(SocialProvider.NAVER) - .build(); + .id(1L) + .nickname("test_user") + .ageRange(AgeRange.TEENS) + .socialId(NAVER_ID) + .profileUrl(NAVER_PROFILE_URL) + .socialProvider(SocialProvider.NAVER) + .build(); token = "naver_auth_token"; NaverProfile naverProfile = objectMapper.readValue(NAVER_PROFILE_RESPONSE, NaverProfile.class); @@ -86,9 +82,9 @@ void authenticateWhenUserIsExists() { //given willReturn(Optional.of(user)).given(userRepository).findBySocialProviderAndSocialId(SocialProvider.NAVER, NAVER_ID); willReturn(token).given(jwtTokenProvider).createToken(user.getId()); - willReturn(userInfo).given(authorizationManager).requestUserInfo(authRequest.getProvider(), authRequest.getCode(), authRequest.getState()); + willReturn(userInfo).given(authorizationManager).requestUserInfo(authRequest.getProvider(), authRequest.getCode(), authRequest.getState(), REQUEST_ORIGIN); //when - UserResponse expected = authService.authenticate(authRequest); + UserResponse expected = authService.authenticate(authRequest, REQUEST_ORIGIN); //then assertThat(expected.getNickname()).isEqualTo(userResponse.getNickname()); } @@ -99,9 +95,9 @@ void authenticateWhenUserIsNotExists() { //given willReturn(Optional.of(user)).given(userRepository).findBySocialProviderAndSocialId(SocialProvider.NAVER, "NEW_ID"); willReturn(token).given(jwtTokenProvider).createToken(user.getId()); - willReturn(userInfo).given(authorizationManager).requestUserInfo(authRequest.getProvider(), authRequest.getCode(), authRequest.getState()); + willReturn(userInfo).given(authorizationManager).requestUserInfo(authRequest.getProvider(), authRequest.getCode(), authRequest.getState(), REQUEST_ORIGIN); //when - UserResponse expected = authService.authenticate(authRequest); + UserResponse expected = authService.authenticate(authRequest, REQUEST_ORIGIN); //then assertThat(expected.getNickname()).isNull(); assertThat(expected.getId()).isNull(); @@ -115,11 +111,11 @@ void authenticateFailureWhenNotValidCode() { willReturn(Optional.of(user)).given(userRepository).findBySocialProviderAndSocialId(SocialProvider.NAVER, NAVER_ID); willReturn(token).given(jwtTokenProvider).createToken(user.getId()); - willThrow(new MappingFailureException("토큰 정보를 불러오는 데 실패했습니다.")).given(authorizationManager).requestUserInfo(invalidRequest.getProvider(), invalidRequest.getCode(), invalidRequest.getState()); + willThrow(new MappingFailureException("토큰 정보를 불러오는 데 실패했습니다.")).given(authorizationManager).requestUserInfo(invalidRequest.getProvider(), invalidRequest.getCode(), invalidRequest.getState(), REQUEST_ORIGIN); //when //then - assertThatThrownBy(() -> authService.authenticate(invalidRequest)) - .isExactlyInstanceOf(MappingFailureException.class); + assertThatThrownBy(() -> authService.authenticate(invalidRequest, REQUEST_ORIGIN)) + .isExactlyInstanceOf(MappingFailureException.class); } @DisplayName("네이버 소셜 로그인 - 실패 - 잘못된 STATE인 경우") @@ -130,10 +126,10 @@ void authenticateFailureWhenNotValidState() { willReturn(Optional.of(user)).given(userRepository).findBySocialProviderAndSocialId(SocialProvider.NAVER, NAVER_ID); willReturn(token).given(jwtTokenProvider).createToken(user.getId()); - willThrow(new MappingFailureException("토큰 정보를 불러오는 데 실패했습니다.")).given(authorizationManager).requestUserInfo(invalidRequest.getProvider(), invalidRequest.getCode(), invalidRequest.getState()); + willThrow(new MappingFailureException("토큰 정보를 불러오는 데 실패했습니다.")).given(authorizationManager).requestUserInfo(invalidRequest.getProvider(), invalidRequest.getCode(), invalidRequest.getState(), REQUEST_ORIGIN); //when //then - assertThatThrownBy(() -> authService.authenticate(invalidRequest)) - .isExactlyInstanceOf(MappingFailureException.class); + assertThatThrownBy(() -> authService.authenticate(invalidRequest, REQUEST_ORIGIN)) + .isExactlyInstanceOf(MappingFailureException.class); } } diff --git a/backend/app-cvi-api/src/test/java/com/cvi/service/CommentServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/CommentServiceTest.java index f0dee896..c0bf4ca9 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/service/CommentServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/CommentServiceTest.java @@ -1,5 +1,8 @@ package com.cvi.service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + import com.cvi.comment.domain.model.Comment; import com.cvi.comment.domain.repository.CommentRepository; import com.cvi.dto.CommentRequest; @@ -9,25 +12,21 @@ import com.cvi.post.domain.model.Post; import com.cvi.post.domain.model.VaccinationType; import com.cvi.post.domain.repository.PostRepository; +import com.cvi.service.post.PostService; import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; import com.cvi.user.domain.repository.UserRepository; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.Optional; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - @SpringBootTest @Transactional @DisplayName("댓글 비즈니스 흐름 테스트") @@ -50,9 +49,6 @@ public class CommentServiceTest { @Autowired private CommentService commentService; - @MockBean - private PublicDataScheduler publicDataScheduler; - private User user; private User anotherUser; private Optional optionalUser; @@ -70,19 +66,19 @@ void init() { private void initUsers() { user = User.builder() - .nickname("테스트유저") - .ageRange(AgeRange.FORTIES) - .socialProvider(SocialProvider.NAVER) - .socialId("NAVER_ID") - .profileUrl("naver.com/profile") - .build(); + .nickname("테스트유저") + .ageRange(AgeRange.FORTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .profileUrl("naver.com/profile") + .build(); anotherUser = User.builder() - .nickname("다른유저") - .ageRange(AgeRange.FORTIES) - .profileUrl("naver.com/profile") - .socialId("NAVER_ID") - .socialProvider(SocialProvider.NAVER) - .build(); + .nickname("다른유저") + .ageRange(AgeRange.FORTIES) + .profileUrl("naver.com/profile") + .socialId("NAVER_ID") + .socialProvider(SocialProvider.NAVER) + .build(); optionalUser = Optional.of(user); optionalAnotherUser = Optional.of(anotherUser); optionalUserNotSignedIn = Optional.empty(); @@ -91,11 +87,11 @@ private void initUsers() { private void initPost() { post = Post.builder() - .content("테스트게시글") - .vaccinationType(VaccinationType.ASTRAZENECA) - .user(user) - .createdAt(LocalDateTime.now()) - .build(); + .content("테스트게시글") + .vaccinationType(VaccinationType.ASTRAZENECA) + .user(user) + .createdAt(LocalDateTime.now()) + .build(); postRepository.save(post); } @@ -106,7 +102,7 @@ void createComment() { //when CommentResponse commentResponse = commentService.createComment(post.getId(), optionalAnotherUser, commentRequest); Post foundPost = postRepository.findWithCommentsByPostId(post.getId()) - .orElseThrow(() -> new NotFoundException("해당 id의 게시글이 없습니다.")); + .orElseThrow(() -> new NotFoundException("해당 id의 게시글이 없습니다.")); //then assertThat(foundPost.getCommentsAsList()).extracting("id").contains(commentResponse.getId()); } @@ -118,7 +114,7 @@ void createCommentWhenNotLoginUser() { //when //then assertThatThrownBy(() -> commentService.createComment(post.getId(), optionalUserNotSignedIn, commentRequest)) - .isInstanceOf(UnAuthorizedException.class); + .isInstanceOf(UnAuthorizedException.class); } @DisplayName("댓글 수정 - 성공") @@ -142,8 +138,8 @@ void updateCommentWhenNoComment() { //when //then assertThatThrownBy(() -> commentService.updateComment(post.getId(), COMMENT_ID, optionalUser, updateRequest)) - .isInstanceOf(NotFoundException.class) - .hasMessage("찾을 수 없는 댓글입니다."); + .isInstanceOf(NotFoundException.class) + .hasMessage("찾을 수 없는 댓글입니다."); } @DisplayName("댓글 수정 - 실패 - 댓글 작성자가 아님") @@ -155,8 +151,8 @@ void updateCommentWhenWrongUser() { //when //then assertThatThrownBy(() -> commentService.updateComment(post.getId(), commentResponse.getId(), optionalAnotherUser, updateRequest)) - .isInstanceOf(UnAuthorizedException.class) - .hasMessage("다른 사용자의 게시글은 수정할 수 없습니다.입력 값: " + user.toString()); + .isInstanceOf(UnAuthorizedException.class) + .hasMessage("다른 사용자의 게시글은 수정할 수 없습니다.입력 값: " + user.toString()); } @DisplayName("댓글 삭제 - 성공") @@ -182,8 +178,8 @@ void deleteCommentWhenNoComment() { //when //then assertThatThrownBy(() -> commentService.deleteComment(post.getId(), COMMENT_ID, optionalUser)) - .isInstanceOf(NotFoundException.class) - .hasMessage("찾을 수 없는 댓글입니다."); + .isInstanceOf(NotFoundException.class) + .hasMessage("찾을 수 없는 댓글입니다."); } @DisplayName("댓글 삭제 - 실패 - 댓글 작성자가 아님") @@ -194,8 +190,8 @@ void deleteCommentWhenWrongUser() { //when //then assertThatThrownBy(() -> commentService.deleteComment(post.getId(), commentResponse.getId(), optionalAnotherUser)) - .isInstanceOf(UnAuthorizedException.class) - .hasMessage("다른 사용자의 게시글은 삭제할 수 없습니다."); + .isInstanceOf(UnAuthorizedException.class) + .hasMessage("다른 사용자의 게시글은 삭제할 수 없습니다."); } @DisplayName("게시글 삭제시 댓글 삭제 - 성공") diff --git a/backend/app-cvi-api/src/test/java/com/cvi/service/LikeServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/LikeServiceTest.java index 8bf1d2b3..48c63784 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/service/LikeServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/LikeServiceTest.java @@ -1,5 +1,8 @@ package com.cvi.service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + import com.cvi.dto.LikeResponse; import com.cvi.dto.PostResponse; import com.cvi.exception.InvalidOperationException; @@ -10,29 +13,25 @@ import com.cvi.post.domain.model.Post; import com.cvi.post.domain.model.VaccinationType; import com.cvi.post.domain.repository.PostRepository; +import com.cvi.service.post.PostService; import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; import com.cvi.user.domain.repository.UserRepository; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.Optional; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - @SpringBootTest @Transactional @DisplayName("좋아요 비즈니스 흐름 테스트") -public class LikeServiceTest { +class LikeServiceTest { @Autowired private PostRepository postRepository; @@ -49,9 +48,6 @@ public class LikeServiceTest { @Autowired private LikeService likeService; - @MockBean - private PublicDataScheduler publicDataScheduler; - private User userWithoutLike; private User userWithLike; private Optional optionalUserWithoutLike; @@ -68,19 +64,19 @@ void init() { private void initUsers() { userWithoutLike = User.builder() - .nickname("테스트유저") - .ageRange(AgeRange.FORTIES) - .socialProvider(SocialProvider.NAVER) - .socialId("NAVER_ID") - .profileUrl("naver.com/profile") - .build(); + .nickname("테스트유저") + .ageRange(AgeRange.FORTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .profileUrl("naver.com/profile") + .build(); userWithLike = User.builder() - .nickname("다른유저") - .ageRange(AgeRange.FORTIES) - .socialProvider(SocialProvider.NAVER) - .socialId("NAVER_ID") - .profileUrl("naver.com/profile") - .build(); + .nickname("다른유저") + .ageRange(AgeRange.FORTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .profileUrl("naver.com/profile") + .build(); optionalUserWithoutLike = Optional.of(userWithoutLike); optionalUserWithLike = Optional.of(userWithLike); @@ -90,11 +86,11 @@ private void initUsers() { private void initPost() { post = Post.builder() - .content("테스트게시글") - .vaccinationType(VaccinationType.ASTRAZENECA) - .user(userWithLike) - .createdAt(LocalDateTime.now()) - .build(); + .content("테스트게시글") + .vaccinationType(VaccinationType.ASTRAZENECA) + .user(userWithLike) + .createdAt(LocalDateTime.now()) + .build(); postRepository.save(post); } @@ -121,7 +117,7 @@ void createLikeFailureWhenPostNotExists() { //when //then assertThatThrownBy(() -> likeService.createLike(Long.MAX_VALUE, optionalUserWithoutLike)) - .isInstanceOf(NotFoundException.class); + .isInstanceOf(NotFoundException.class); } @DisplayName("좋아요 생성 - 실패 - 동일한 유저가 이미 좋아요를 누른 경우") @@ -131,7 +127,7 @@ void createLikeFailureWhenAlreadyCreatedBySameUser() { //when //then assertThatThrownBy(() -> likeService.createLike(post.getId(), optionalUserWithLike)) - .isInstanceOf(InvalidOperationException.class); + .isInstanceOf(InvalidOperationException.class); } @DisplayName("좋아요 생성 - 실패 - 비회원 좋아요 생성 시도") @@ -141,7 +137,7 @@ void createCommentWhenNotLoginUser() { //when //then assertThatThrownBy(() -> likeService.createLike(post.getId(), optionalUserNotSignedIn)) - .isInstanceOf(UnAuthorizedException.class); + .isInstanceOf(UnAuthorizedException.class); } @DisplayName("좋아요 삭제 - 성공") @@ -151,7 +147,7 @@ void deleteLike() { //when likeService.deleteLike(post.getId(), optionalUserWithLike); Post actualPost = postRepository.findWithLikesByPostId(post.getId()) - .orElseThrow(() -> new NotFoundException("해당 id의 게시글이 존재하지 않습니다.")); + .orElseThrow(() -> new NotFoundException("해당 id의 게시글이 존재하지 않습니다.")); //then assertThat(actualPost.getLikes().getLikes()).isEmpty(); } @@ -163,8 +159,8 @@ void deleteLikeFailureWhenInvalidToken() { //when //then assertThatThrownBy(() -> likeService.deleteLike(post.getId(), optionalUserWithoutLike)) - .isInstanceOf(UnAuthorizedException.class) - .hasMessage("해당 사용자의 좋아요가 글에 존재하지 않습니다."); + .isInstanceOf(UnAuthorizedException.class) + .hasMessage("해당 사용자의 좋아요가 글에 존재하지 않습니다."); } @DisplayName("좋아요 삭제 - 실패 - 삭제 요청한 좋아요의 게시글이 없는 경우") @@ -174,8 +170,8 @@ void deleteLikeFailureWhenLikeNotExists() { //when //then assertThatThrownBy(() -> likeService.deleteLike(Long.MAX_VALUE, optionalUserWithoutLike)) - .isInstanceOf(NotFoundException.class) - .hasMessage("해당 id의 게시글이 존재하지 않습니다. 입력 값: " + Long.MAX_VALUE); + .isInstanceOf(NotFoundException.class) + .hasMessage("해당 id의 게시글이 존재하지 않습니다. 입력 값: " + Long.MAX_VALUE); } @DisplayName("좋아요 누른 유저 hasLiked 상태값(true) 확인 - 성공") diff --git a/backend/app-cvi-api/src/test/java/com/cvi/service/PostFindServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/PostFindServiceTest.java index 6d5c5e72..ec988bb2 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/service/PostFindServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/PostFindServiceTest.java @@ -1,5 +1,7 @@ package com.cvi.service; +import static org.assertj.core.api.Assertions.assertThat; + import com.cvi.comment.domain.model.Comment; import com.cvi.comment.domain.repository.CommentRepository; import com.cvi.dto.PostResponse; @@ -9,10 +11,21 @@ import com.cvi.post.domain.model.Sort; import com.cvi.post.domain.model.VaccinationType; import com.cvi.post.domain.repository.PostRepository; +import com.cvi.service.post.PostService; import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; import com.cvi.user.domain.repository.UserRepository; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -21,22 +34,12 @@ import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; -import java.time.LocalDateTime; -import java.util.*; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; - @SpringBootTest @Transactional @DisplayName("게시글 - 조회 비즈니스 흐름 테스트") -public class PostFindServiceTest { +class PostFindServiceTest { @Autowired private PostRepository postRepository; @@ -53,9 +56,6 @@ public class PostFindServiceTest { @Autowired private PostService postService; - @MockBean - private PublicDataScheduler publicDataScheduler; - @PersistenceContext private EntityManager em; @@ -79,12 +79,12 @@ private List initUser() { List users = new ArrayList<>(); for (int i = 0; i < 3; i++) { User dummyUser = User.builder() - .nickname("테스트유저댓글" + i + "좋아요" + i) - .ageRange(AgeRange.FORTIES) - .socialProvider(SocialProvider.NAVER) - .socialId("NAVER_ID") - .profileUrl("naver.com/profile") - .build(); + .nickname("테스트유저댓글" + i + "좋아요" + i) + .ageRange(AgeRange.FORTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .profileUrl("naver.com/profile") + .build(); users.add(dummyUser); } user = users.get(0); @@ -94,23 +94,23 @@ private List initUser() { private List initPost(List users) { postWithoutLikesAndComments = Post.builder() - .content("Test 0") - .vaccinationType(VaccinationType.ASTRAZENECA) - .user(users.get(0)) - .createdAt(LocalDateTime.now()) - .build(); + .content("Test 0") + .vaccinationType(VaccinationType.ASTRAZENECA) + .user(users.get(0)) + .createdAt(LocalDateTime.now()) + .build(); postWithOneLikesAndComments = Post.builder() - .content("Test 1") - .vaccinationType(VaccinationType.ASTRAZENECA) - .user(users.get(1)) - .createdAt(LocalDateTime.now()) - .build(); + .content("Test 1") + .vaccinationType(VaccinationType.ASTRAZENECA) + .user(users.get(1)) + .createdAt(LocalDateTime.now()) + .build(); postWithTwoLikesAndComments = Post.builder() - .content("Test 2") - .vaccinationType(VaccinationType.PFIZER) - .user(users.get(2)) - .createdAt(LocalDateTime.now()) - .build(); + .content("Test 2") + .vaccinationType(VaccinationType.PFIZER) + .user(users.get(2)) + .createdAt(LocalDateTime.now()) + .build(); postWithOneLikesAndComments.increaseViewCount(); postWithTwoLikesAndComments.increaseViewCount(); postWithTwoLikesAndComments.increaseViewCount(); @@ -160,16 +160,16 @@ void findByVaccineType(VaccinationType vaccinationType) { List postResponses = postService.findByVaccineType(vaccinationType, optionalUser); //then assertThat(postResponses).filteredOn( - response -> response.getVaccinationType().equals(vaccinationType) + response -> response.getVaccinationType().equals(vaccinationType) ); } static Stream findByVaccineType() { return Stream.of( - Arguments.of(VaccinationType.PFIZER), - Arguments.of(VaccinationType.ASTRAZENECA), - Arguments.of(VaccinationType.MODERNA), - Arguments.of(VaccinationType.JANSSEN) + Arguments.of(VaccinationType.PFIZER), + Arguments.of(VaccinationType.ASTRAZENECA), + Arguments.of(VaccinationType.MODERNA), + Arguments.of(VaccinationType.JANSSEN) ); } @@ -211,9 +211,9 @@ void findByVaccineTypeFirstPage(VaccinationType vaccinationType, int size, List< static Stream findByVaccineTypeFirstPage() { return Stream.of( - Arguments.of(VaccinationType.ASTRAZENECA, 1, Arrays.asList("Test 1")), - Arguments.of(VaccinationType.ASTRAZENECA, 2, Arrays.asList("Test 1", "Test 0")), - Arguments.of(VaccinationType.PFIZER, 1, Arrays.asList("Test 2")) + Arguments.of(VaccinationType.ASTRAZENECA, 1, Arrays.asList("Test 1")), + Arguments.of(VaccinationType.ASTRAZENECA, 2, Arrays.asList("Test 1", "Test 0")), + Arguments.of(VaccinationType.PFIZER, 1, Arrays.asList("Test 2")) ); } @@ -231,7 +231,7 @@ void findByVaccineTypeNextPage(VaccinationType vaccinationType, int size, List findByVaccineTypeNextPage() { return Stream.of( - Arguments.of(VaccinationType.ASTRAZENECA, 1, Arrays.asList("Test 0")) + Arguments.of(VaccinationType.ASTRAZENECA, 1, Arrays.asList("Test 0")) ); } @@ -249,9 +249,9 @@ void findByVaccineTypeNextPageIsNull(VaccinationType vaccinationType, int size, static Stream findByVaccineTypeNextPageIsNull() { return Stream.of( - Arguments.of(VaccinationType.PFIZER, 1, Collections.emptyList()), - Arguments.of(VaccinationType.JANSSEN, 1, Collections.emptyList()), - Arguments.of(VaccinationType.MODERNA, 1, Collections.emptyList()) + Arguments.of(VaccinationType.PFIZER, 1, Collections.emptyList()), + Arguments.of(VaccinationType.JANSSEN, 1, Collections.emptyList()), + Arguments.of(VaccinationType.MODERNA, 1, Collections.emptyList()) ); } @@ -267,11 +267,11 @@ void findByVaccineTypeSortByLikeCountAsc(VaccinationType vaccinationType, List findByVaccineTypeSortByLikeCountAsc() { return Stream.of( - Arguments.of(VaccinationType.ALL, Arrays.asList("Test 0", "Test 1", "Test 2")), - Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 0", "Test 1")), - Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), - Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), - Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) + Arguments.of(VaccinationType.ALL, Arrays.asList("Test 0", "Test 1", "Test 2")), + Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 0", "Test 1")), + Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), + Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), + Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) ); } @@ -287,11 +287,11 @@ void findByVaccineTypeSortByLikeCountDesc(VaccinationType vaccinationType, List< static Stream findByVaccineTypeSortByLikeCountDesc() { return Stream.of( - Arguments.of(VaccinationType.ALL, Arrays.asList("Test 2", "Test 1", "Test 0")), - Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 1", "Test 0")), - Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), - Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), - Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) + Arguments.of(VaccinationType.ALL, Arrays.asList("Test 2", "Test 1", "Test 0")), + Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 1", "Test 0")), + Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), + Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), + Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) ); } @@ -307,11 +307,11 @@ void findByVaccineTypeSortByCommentsCountAsc(VaccinationType vaccinationType, Li static Stream findByVaccineTypeSortByCommentsCountAsc() { return Stream.of( - Arguments.of(VaccinationType.ALL, Arrays.asList("Test 0", "Test 1", "Test 2")), - Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 0", "Test 1")), - Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), - Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), - Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) + Arguments.of(VaccinationType.ALL, Arrays.asList("Test 0", "Test 1", "Test 2")), + Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 0", "Test 1")), + Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), + Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), + Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) ); } @@ -327,11 +327,11 @@ void findByVaccineTypeSortByCommentsCountDesc(VaccinationType vaccinationType, L static Stream findByVaccineTypeSortByCommentsCountDesc() { return Stream.of( - Arguments.of(VaccinationType.ALL, Arrays.asList("Test 2", "Test 1", "Test 0")), - Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 1", "Test 0")), - Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), - Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), - Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) + Arguments.of(VaccinationType.ALL, Arrays.asList("Test 2", "Test 1", "Test 0")), + Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 1", "Test 0")), + Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), + Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), + Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) ); } @@ -347,11 +347,11 @@ void findByVaccineTypeSortByViewCountAsc(VaccinationType vaccinationType, List findByVaccineTypeSortByViewCountAsc() { return Stream.of( - Arguments.of(VaccinationType.ALL, Arrays.asList("Test 0", "Test 1", "Test 2")), - Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 0", "Test 1")), - Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), - Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), - Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) + Arguments.of(VaccinationType.ALL, Arrays.asList("Test 0", "Test 1", "Test 2")), + Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 0", "Test 1")), + Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), + Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), + Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) ); } @@ -367,11 +367,11 @@ void findByVaccineTypeSortByViewCountDesc(VaccinationType vaccinationType, List< static Stream findByVaccineTypeSortByViewCountDesc() { return Stream.of( - Arguments.of(VaccinationType.ALL, Arrays.asList("Test 2", "Test 1", "Test 0")), - Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 1", "Test 0")), - Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), - Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), - Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) + Arguments.of(VaccinationType.ALL, Arrays.asList("Test 2", "Test 1", "Test 0")), + Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 1", "Test 0")), + Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), + Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), + Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) ); } @@ -387,11 +387,11 @@ void findByVaccineTypeSortByCreatedAtAsc(VaccinationType vaccinationType, List findByVaccineTypeSortByCreatedAtAsc() { return Stream.of( - Arguments.of(VaccinationType.ALL, Arrays.asList("Test 0", "Test 1", "Test 2")), - Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 0", "Test 1")), - Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), - Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), - Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) + Arguments.of(VaccinationType.ALL, Arrays.asList("Test 0", "Test 1", "Test 2")), + Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 0", "Test 1")), + Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), + Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), + Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) ); } @@ -407,11 +407,11 @@ void findByVaccineTypeSortByCreatedAtDesc(VaccinationType vaccinationType, List< static Stream findByVaccineTypeSortByCreatedAtDesc() { return Stream.of( - Arguments.of(VaccinationType.ALL, Arrays.asList("Test 2", "Test 1", "Test 0")), - Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 1", "Test 0")), - Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), - Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), - Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) + Arguments.of(VaccinationType.ALL, Arrays.asList("Test 2", "Test 1", "Test 0")), + Arguments.of(VaccinationType.ASTRAZENECA, Arrays.asList("Test 1", "Test 0")), + Arguments.of(VaccinationType.PFIZER, Arrays.asList("Test 2")), + Arguments.of(VaccinationType.JANSSEN, Collections.emptyList()), + Arguments.of(VaccinationType.MODERNA, Collections.emptyList()) ); } @@ -427,10 +427,10 @@ void findByVaccineTypeFilterByHour(VaccinationType vaccinationType, int hour, Li static Stream findByVaccineTypeFilterByHour() { return Stream.of( - Arguments.of(VaccinationType.ALL, Integer.MAX_VALUE, Arrays.asList("Test 2", "Test 1", "Test 0")), - Arguments.of(VaccinationType.ALL, 3, Arrays.asList("Test 2", "Test 1")), - Arguments.of(VaccinationType.ALL, 2, Arrays.asList("Test 2")), - Arguments.of(VaccinationType.ALL, 1, Collections.emptyList()) + Arguments.of(VaccinationType.ALL, Integer.MAX_VALUE, Arrays.asList("Test 2", "Test 1", "Test 0")), + Arguments.of(VaccinationType.ALL, 3, Arrays.asList("Test 2", "Test 1")), + Arguments.of(VaccinationType.ALL, 2, Arrays.asList("Test 2")), + Arguments.of(VaccinationType.ALL, 1, Collections.emptyList()) ); } } diff --git a/backend/app-cvi-api/src/test/java/com/cvi/service/PostMyPageServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/PostMyPageServiceTest.java index be92ba64..a91ca6a3 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/service/PostMyPageServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/PostMyPageServiceTest.java @@ -1,18 +1,33 @@ package com.cvi.service; +import static org.assertj.core.api.Assertions.assertThat; + import com.cvi.comment.domain.model.Comment; import com.cvi.comment.domain.repository.CommentRepository; import com.cvi.dto.PostWithCommentResponse; +import com.cvi.image.domain.Image; +import com.cvi.image.repository.ImageRepository; import com.cvi.like.domain.model.Like; import com.cvi.like.domain.repository.LikeRepository; import com.cvi.post.domain.model.Filter; import com.cvi.post.domain.model.Post; import com.cvi.post.domain.model.VaccinationType; import com.cvi.post.domain.repository.PostRepository; +import com.cvi.service.post.PostService; import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; import com.cvi.user.domain.repository.UserRepository; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -21,20 +36,19 @@ import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; - @SpringBootTest @Transactional @DisplayName("게시글 - 마이페이지 비즈니스 흐름 테스트") -public class PostMyPageServiceTest { +class PostMyPageServiceTest { + + private static final String IMAGE_URL_1 = "{이미지1 S3 URL}"; + private static final String IMAGE_URL_2 = "{이미지2 S3 URL}"; + private static final String IMAGE_URL_3 = "{이미지3 S3 URL}"; + private static final List POST1_IMAGE_URLS = Collections.singletonList(IMAGE_URL_1); + private static final List POST2_IMAGE_URLS = Arrays.asList(IMAGE_URL_1, IMAGE_URL_2); + private static final List POST3_IMAGE_URLS = Arrays.asList(IMAGE_URL_1, IMAGE_URL_2, IMAGE_URL_3); @Autowired private PostRepository postRepository; @@ -48,14 +62,19 @@ public class PostMyPageServiceTest { @Autowired private LikeRepository likeRepository; + @Autowired + private ImageRepository imageRepository; + @Autowired private PostService postService; - @MockBean - private PublicDataScheduler publicDataScheduler; + @PersistenceContext + private EntityManager entityManager; private User user; private Optional optionalUser; + private List posts; + private List imageUrls; @BeforeEach void init() { @@ -63,29 +82,32 @@ void init() { List posts = initPosts(); initLikes(posts); initComments(posts); + initImages(posts); + entityManager.flush(); + entityManager.clear(); } private User initUser() { user = User.builder() - .nickname("테스트유저") - .ageRange(AgeRange.FORTIES) - .socialProvider(SocialProvider.NAVER) - .socialId("NAVER_ID") - .profileUrl("naver.com/profile") - .build(); + .nickname("테스트유저") + .ageRange(AgeRange.FORTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .profileUrl("naver.com/profile") + .build(); optionalUser = Optional.of(user); return userRepository.save(user); } private List initPosts() { - List posts = new ArrayList<>(); + posts = new ArrayList<>(); for (int i = 0; i < 3; i++) { Post post = Post.builder() - .content("Test " + i) - .vaccinationType(VaccinationType.ASTRAZENECA) - .user(user) - .createdAt(LocalDateTime.now()) - .build(); + .content("Test " + (i + 1)) + .vaccinationType(VaccinationType.ASTRAZENECA) + .user(user) + .createdAt(LocalDateTime.now()) + .build(); posts.add(post); } postRepository.saveAll(posts); @@ -108,23 +130,49 @@ private void initComments(List posts) { }); } + private void initImages(List posts) { + imageUrls = Arrays.asList(IMAGE_URL_1, IMAGE_URL_2, IMAGE_URL_3); + for (int i = 0; i < posts.size() ; i++) { + final Post post = posts.get(i); + assignPostToImagesNumberOf(i + 1, post); + } + } + + private void assignPostToImagesNumberOf(int numberOfImages, Post post) { + for (int i = 0; i < numberOfImages; i++) { + final Image image = Image.builder().url(imageUrls.get(i)).build(); + image.assignPost(post); + imageRepository.save(image); + } + } + @DisplayName("내가 작성한 게시글 조회 - 성공") @Test void findByUserAndFilterNone() { //given //when List postResponses = postService.findByUserAndFilter(optionalUser, Filter.NONE); - //then List contents = postResponses.stream() - .map(PostWithCommentResponse::getContent) - .collect(Collectors.toList()); + .map(PostWithCommentResponse::getContent) + .collect(Collectors.toList()); List userIds = postResponses.stream() - .map(postResponse -> postResponse.getWriter().getId()) - .distinct() - .collect(Collectors.toList()); + .map(postResponse -> postResponse.getWriter().getId()) + .distinct() + .collect(Collectors.toList()); - assertThat(contents).containsExactlyInAnyOrder("Test 2", "Test 1", "Test 0"); + //then + assertThat(contents).containsExactlyInAnyOrder("Test 3", "Test 2", "Test 1"); assertThat(userIds).containsExactly(user.getId()); + assertImageUrls(postResponses); + } + + private void assertImageUrls(List postResponses) { + final List post3ActualImageUrls = postResponses.get(0).getImages(); + final List post2ActualImageUrls = postResponses.get(1).getImages(); + final List post1ActualImageUrls = postResponses.get(2).getImages(); + assertThat(post3ActualImageUrls).containsExactlyElementsOf(POST3_IMAGE_URLS); + assertThat(post2ActualImageUrls).containsExactlyElementsOf(POST2_IMAGE_URLS); + assertThat(post1ActualImageUrls).containsExactlyElementsOf(POST1_IMAGE_URLS); } @DisplayName("내가 좋아요 한 게시글 조회 - 성공") @@ -135,10 +183,11 @@ void findByUserAndFilterLikes() { List postResponses = postService.findByUserAndFilter(optionalUser, Filter.LIKES); //then List contents = postResponses.stream() - .map(PostWithCommentResponse::getContent) - .collect(Collectors.toList()); + .map(PostWithCommentResponse::getContent) + .collect(Collectors.toList()); - assertThat(contents).containsExactlyInAnyOrder("Test 2", "Test 1", "Test 0"); + assertThat(contents).containsExactlyInAnyOrder("Test 3", "Test 2", "Test 1"); + assertImageUrls(postResponses); } @DisplayName("내가 댓글을 단 게시글 조회 - 성공") @@ -149,21 +198,22 @@ void findByUserAndFilterComments() { List postResponses = postService.findByUserAndFilter(optionalUser, Filter.COMMENTS); //then List contents = postResponses.stream() - .map(PostWithCommentResponse::getContent) - .collect(Collectors.toList()); + .map(PostWithCommentResponse::getContent) + .collect(Collectors.toList()); List userIds = postResponses.stream() - .flatMap(postResponse -> postResponse.getComments().stream() - .map(commentResponse -> commentResponse.getWriter().getId())) - .distinct() - .collect(Collectors.toList()); + .flatMap(postResponse -> postResponse.getComments().stream() + .map(commentResponse -> commentResponse.getWriter().getId())) + .distinct() + .collect(Collectors.toList()); assertThat(userIds).containsExactly(user.getId()); - assertThat(contents).containsExactlyInAnyOrder("Test 2", "Test 1", "Test 0"); + assertThat(contents).containsExactlyInAnyOrder("Test 3", "Test 2", "Test 1"); + assertImageUrls(postResponses); } @ParameterizedTest(name = "내가 작성한 글 첫 페이징 조회 - 성공") @MethodSource - void findMyPostsPagingFirstPage(int offset, int size, List expectedContents) { + void findMyPostsPagingFirstPage(int offset, int size, List expectedContents, List> expectedImageUrls) { //given Filter filter = Filter.NONE; //when @@ -171,17 +221,18 @@ void findMyPostsPagingFirstPage(int offset, int size, List expectedConte //then assertThat(postResponses.size()).isEqualTo(expectedContents.size()); assertThat(postResponses).extracting("content").containsExactlyElementsOf(expectedContents); + assertThat(postResponses).extracting("images").containsExactlyElementsOf(expectedImageUrls); } static Stream findMyPostsPagingFirstPage() { return Stream.of( - Arguments.of(0, 2, Arrays.asList("Test 2", "Test 1")), - Arguments.of(0, 1, Collections.singletonList("Test 2"))); + Arguments.of(0, 2, Arrays.asList("Test 3", "Test 2"), Arrays.asList(POST3_IMAGE_URLS, POST2_IMAGE_URLS)), + Arguments.of(0, 1, Collections.singletonList("Test 3"), Collections.singletonList(POST3_IMAGE_URLS))); } @ParameterizedTest(name = "내가 작성한 글 다음 페이징 조회 - 성공") @MethodSource - void findMyPostsPagingNextPage(int offset, int size, List expectedContents) { + void findMyPostsPagingNextPage(int offset, int size, List expectedContents, List> expectedImageUrls) { //given Filter filter = Filter.NONE; //when @@ -189,17 +240,18 @@ void findMyPostsPagingNextPage(int offset, int size, List expectedConten //then assertThat(postResponses.size()).isEqualTo(expectedContents.size()); assertThat(postResponses).extracting("content").containsExactlyElementsOf(expectedContents); + assertThat(postResponses).extracting("images").containsExactlyElementsOf(expectedImageUrls); } static Stream findMyPostsPagingNextPage() { return Stream.of( - Arguments.of(1, 2, Arrays.asList("Test 1", "Test 0")), - Arguments.of(1, 1, Collections.singletonList("Test 1"))); + Arguments.of(1, 2, Arrays.asList("Test 2", "Test 1"), Arrays.asList(POST2_IMAGE_URLS, POST1_IMAGE_URLS)), + Arguments.of(1, 1, Collections.singletonList("Test 2"), Collections.singletonList(POST2_IMAGE_URLS))); } @ParameterizedTest(name = "내가 좋아요 한 글 첫 페이징 조회 - 성공") @MethodSource - void findLikedPostsPagingFirstPage(int offset, int size, List expectedContents) { + void findLikedPostsPagingFirstPage(int offset, int size, List expectedContents, List> expectedImageUrls) { //given Filter filter = Filter.LIKES; //when @@ -207,17 +259,18 @@ void findLikedPostsPagingFirstPage(int offset, int size, List expectedCo //then assertThat(postResponses.size()).isEqualTo(expectedContents.size()); assertThat(postResponses).extracting("content").containsExactlyElementsOf(expectedContents); + assertThat(postResponses).extracting("images").containsExactlyElementsOf(expectedImageUrls); } static Stream findLikedPostsPagingFirstPage() { return Stream.of( - Arguments.of(0, 2, Arrays.asList("Test 2", "Test 1")), - Arguments.of(0, 1, Collections.singletonList("Test 2"))); + Arguments.of(0, 2, Arrays.asList("Test 3", "Test 2"), Arrays.asList(POST3_IMAGE_URLS, POST2_IMAGE_URLS)), + Arguments.of(0, 1, Collections.singletonList("Test 3"), Collections.singletonList(POST3_IMAGE_URLS))); } @ParameterizedTest(name = "내가 좋아요 한 글 다음 페이징 조회 - 성공") @MethodSource - void findLikedPostsPagingNextPage(int offset, int size, List expectedContents) { + void findLikedPostsPagingNextPage(int offset, int size, List expectedContents, List> expectedImageUrls) { //given Filter filter = Filter.LIKES; //when @@ -225,34 +278,36 @@ void findLikedPostsPagingNextPage(int offset, int size, List expectedCon //then assertThat(postResponses.size()).isEqualTo(expectedContents.size()); assertThat(postResponses).extracting("content").containsExactlyElementsOf(expectedContents); + assertThat(postResponses).extracting("images").containsExactlyElementsOf(expectedImageUrls); } static Stream findLikedPostsPagingNextPage() { return Stream.of( - Arguments.of(1, 2, Arrays.asList("Test 1", "Test 0")), - Arguments.of(1, 1, Collections.singletonList("Test 1"))); + Arguments.of(1, 2, Arrays.asList("Test 2", "Test 1"), Arrays.asList(POST2_IMAGE_URLS, POST1_IMAGE_URLS)), + Arguments.of(1, 1, Collections.singletonList("Test 2"), Collections.singletonList(POST2_IMAGE_URLS))); } @ParameterizedTest(name = "내가 댓글 단 게시글 첫 페이징 조회 - 성공") @MethodSource - void findCommentedPostFirstPage(int offset, int size, List expectedContents) { + void findCommentedPostFirstPage(int offset, int size, List expectedContents, List> expectedImageUrls) { //given //when List postResponses = postService.findByUserAndFilter(Filter.COMMENTS, offset, size, optionalUser); //then assertThat(postResponses.size()).isEqualTo(expectedContents.size()); assertThat(postResponses).extracting("content").containsExactlyElementsOf(expectedContents); + assertThat(postResponses).extracting("images").containsExactlyElementsOf(expectedImageUrls); } static Stream findCommentedPostFirstPage() { return Stream.of( - Arguments.of(0, 2, Arrays.asList("Test 2", "Test 1")), - Arguments.of(0, 1, Collections.singletonList("Test 2"))); + Arguments.of(0, 2, Arrays.asList("Test 3", "Test 2"), Arrays.asList(POST3_IMAGE_URLS, POST2_IMAGE_URLS)), + Arguments.of(0, 1, Collections.singletonList("Test 3"), Collections.singletonList(POST3_IMAGE_URLS))); } @ParameterizedTest(name = "내가 댓글 단 게시글 다음 페이징 조회 - 성공") @MethodSource - void findCommentedPostNextPage(int offset, int size, List expectedContents) { + void findCommentedPostNextPage(int offset, int size, List expectedContents, List> expectedImageUrls) { //given //when List postResponses = postService.findByUserAndFilter(Filter.COMMENTS, offset, size, optionalUser); @@ -263,7 +318,7 @@ void findCommentedPostNextPage(int offset, int size, List expectedConten static Stream findCommentedPostNextPage() { return Stream.of( - Arguments.of(1, 2, Arrays.asList("Test 1", "Test 0")), - Arguments.of(1, 1, Collections.singletonList("Test 1"))); + Arguments.of(1, 2, Arrays.asList("Test 2", "Test 1"), Arrays.asList(POST2_IMAGE_URLS, POST1_IMAGE_URLS)), + Arguments.of(1, 1, Collections.singletonList("Test 2"), Collections.singletonList(POST2_IMAGE_URLS))); } } diff --git a/backend/app-cvi-api/src/test/java/com/cvi/service/PostServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/PostServiceTest.java index a2ad16a5..24132ae6 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/service/PostServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/PostServiceTest.java @@ -1,17 +1,48 @@ package com.cvi.service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.same; +import static org.mockito.BDDMockito.willDoNothing; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import com.cvi.comment.domain.model.Comment; +import com.cvi.comment.domain.repository.CommentRepository; +import com.cvi.dto.ImageRequest; import com.cvi.dto.PostRequest; import com.cvi.dto.PostResponse; import com.cvi.exception.InvalidOperationException; import com.cvi.exception.NotFoundException; import com.cvi.exception.UnAuthorizedException; +import com.cvi.image.domain.Image; +import com.cvi.image.domain.ImageType; +import com.cvi.image.repository.ImageRepository; +import com.cvi.like.domain.model.Like; +import com.cvi.like.domain.repository.LikeRepository; import com.cvi.post.domain.model.Post; import com.cvi.post.domain.model.VaccinationType; import com.cvi.post.domain.repository.PostRepository; +import com.cvi.service.post.ImageConverter; +import com.cvi.service.post.ImageFile; +import com.cvi.service.post.PostService; +import com.cvi.uploader.AwsS3Uploader; import com.cvi.user.domain.model.AgeRange; import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; import com.cvi.user.domain.repository.UserRepository; +import java.io.File; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,97 +51,314 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - @SpringBootTest @Transactional @DisplayName("게시글 - 생성/수정/삭제 비즈니스 흐름 테스트") class PostServiceTest { + private static final String IMAGE1_S3_URL = "image1 s3 url"; + private static final String IMAGE2_S3_URL = "image2 s3 url"; + private static final String IMAGE3_S3_URL = "image3 s3 url"; + private static final String IMAGE4_S3_URL = "image4 s3 url"; + private static final String IMAGE5_S3_URL = "image5 s3 url"; + private static final String IMAGE1_BASE_64_DATA = "image1 base64 data"; + private static final String IMAGE2_BASE_64_DATA = "image2 base64 data"; + private static final String IMAGE3_BASE_64_DATA = "image3 base64 data"; + private static final String IMAGE4_BASE_64_DATA = "image4 base64 data"; + private static final String IMAGE5_BASE_64_DATA = "image5 base64 data"; + + @MockBean + private ImageConverter imageConverter; + + @MockBean + private AwsS3Uploader awsS3Uploader; + @Autowired private PostRepository postRepository; @Autowired private UserRepository userRepository; + @Autowired + private ImageRepository imageRepository; + + @Autowired + private CommentRepository commentRepository; + + @Autowired + private LikeRepository likeRepository; + @Autowired private PostService postService; - @MockBean - private PublicDataScheduler publicDataScheduler; + @PersistenceContext + private EntityManager entityManager; private User user; private User anotherUser; private Optional optionalUser; private Optional optionalAnotherUser; private Optional optionalUserNotSignedIn; + private Image image1; + private Image image2; + private Image image3; + private ImageFile imageFile1; + private ImageFile imageFile2; + private ImageFile imageFile3; + private ImageFile imageFile4; + private ImageFile imageFile5; + private File file1; + private File file2; + private File file3; + private File file4; + private File file5; + private Comment comment1; + private Comment comment2; + private Like like1; + private Like like2; private Post post; private Post anotherPost; - private PostRequest postRequest; + private Post postWithImages; + private PostRequest postRequestWithImages; + private PostRequest postRequestNotWithImages; + private ImageRequest newImageRequest1; + private ImageRequest newImageRequest2; + private ImageRequest newImageRequest3; + private List newImageRequests; + private List updateImageRequests; @BeforeEach void init() { - initUser(); - initPost(); - postRequest = new PostRequest("Test Content", VaccinationType.PFIZER); + initUsers(); + initPosts(); + initImages(); + initComments(); + initLikes(); + initImageRequests(); + initUpdatedImageRequests(); + initPostRequestWithImages(); + initPostRequestNotWithImages(); + initMockImageFile(); + initMockImageConverter(); + initMockAwsS3Uploader(); + assertIdAssigned(); } - private void initUser() { + private void initUsers() { user = User.builder() - .nickname("테스트유저") - .ageRange(AgeRange.FORTIES) - .socialProvider(SocialProvider.NAVER) - .socialId("NAVER_ID") - .profileUrl("naver.com/profile") - .build(); + .nickname("테스트유저") + .ageRange(AgeRange.FORTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .profileUrl("naver.com/profile") + .build(); anotherUser = User.builder() - .nickname("다른유저") - .ageRange(AgeRange.FORTIES) - .socialProvider(SocialProvider.NAVER) - .socialId("NAVER_ID") - .profileUrl("naver.com/profile") - .build(); + .nickname("다른유저") + .ageRange(AgeRange.FORTIES) + .socialProvider(SocialProvider.NAVER) + .socialId("NAVER_ID") + .profileUrl("naver.com/profile") + .build(); optionalUser = Optional.of(user); optionalAnotherUser = Optional.of(anotherUser); optionalUserNotSignedIn = Optional.empty(); userRepository.saveAll(Arrays.asList(user, anotherUser)); } - private void initPost() { + private void initPosts() { post = Post.builder() - .content("Test") - .vaccinationType(VaccinationType.ASTRAZENECA) - .user(user) - .createdAt(LocalDateTime.now()) - .build(); + .content("Test") + .vaccinationType(VaccinationType.ASTRAZENECA) + .user(user) + .createdAt(LocalDateTime.now()) + .build(); anotherPost = Post.builder() - .content("Test") - .vaccinationType(VaccinationType.ASTRAZENECA) - .user(anotherUser) - .createdAt(LocalDateTime.now()) - .build(); - postRepository.saveAll(Arrays.asList(post, anotherPost)); + .content("Test") + .vaccinationType(VaccinationType.ASTRAZENECA) + .user(anotherUser) + .createdAt(LocalDateTime.now()) + .build(); + postWithImages = Post.builder() + .content("Test") + .vaccinationType(VaccinationType.ASTRAZENECA) + .user(user) + .createdAt(LocalDateTime.now()) + .build(); + postRepository.saveAll(Arrays.asList(post, anotherPost, postWithImages)); + } + + private void initImages() { + image1 = Image.builder() + .url(IMAGE1_S3_URL) + .build(); + image1.assignPost(postWithImages); + imageRepository.save(image1); + + image2 = Image.builder() + .url(IMAGE2_S3_URL) + .build(); + image2.assignPost(postWithImages); + imageRepository.save(image2); + + image3 = Image.builder() + .url(IMAGE3_S3_URL) + .build(); + image3.assignPost(postWithImages); + imageRepository.save(image3); + } + + private void initComments() { + comment1 = Comment.builder() + .content("댓글 내용1") + .user(user) + .build(); + comment1.assignPost(postWithImages); + commentRepository.save(comment1); + + comment2 = Comment.builder() + .content("댓글 내용2") + .user(anotherUser) + .build(); + comment2.assignPost(postWithImages); + commentRepository.save(comment2); + } + + private void initLikes() { + like1 = Like.builder() + .user(user) + .build(); + like1.assignPost(postWithImages); + likeRepository.save(like1); + + like2 = Like.builder() + .user(anotherUser) + .build(); + like2.assignPost(postWithImages); + likeRepository.save(like2); + } + + private void initImageRequests() { + newImageRequest1 = new ImageRequest(ImageType.JPG, IMAGE1_BASE_64_DATA); + newImageRequest2 = new ImageRequest(ImageType.JPEG, IMAGE2_BASE_64_DATA); + newImageRequest3 = new ImageRequest(ImageType.PNG, IMAGE3_BASE_64_DATA); + newImageRequests = Arrays.asList(newImageRequest1, newImageRequest2, newImageRequest3); + } + + private void initUpdatedImageRequests() { + updateImageRequests = Arrays.asList( + new ImageRequest(ImageType.JPG, IMAGE4_BASE_64_DATA), + new ImageRequest(ImageType.PNG, IMAGE5_BASE_64_DATA)); + } + + private void initPostRequestWithImages() { + postRequestWithImages = PostRequest.builder() + .content("Test Conent") + .vaccinationType(VaccinationType.PFIZER) + .images(newImageRequests) + .build(); + } + + private void initPostRequestNotWithImages() { + postRequestNotWithImages = PostRequest.builder() + .content("Test Conent") + .vaccinationType(VaccinationType.PFIZER) + .images(Collections.emptyList()) + .build(); } - @DisplayName("게시글 생성 - 성공") + private void initMockImageFile() { + file1 = mock(File.class); + file2 = mock(File.class); + file3 = mock(File.class); + file4 = mock(File.class); + file5 = mock(File.class); + imageFile1 = mock(ImageFile.class); + imageFile2 = mock(ImageFile.class); + imageFile3 = mock(ImageFile.class); + imageFile4 = mock(ImageFile.class); + imageFile5 = mock(ImageFile.class); + willReturn(file1).given(imageFile1).getFile(); + willReturn(file2).given(imageFile2).getFile(); + willReturn(file3).given(imageFile3).getFile(); + willReturn(file4).given(imageFile4).getFile(); + willReturn(file5).given(imageFile5).getFile(); + willDoNothing().given(imageFile1).delete(); + willDoNothing().given(imageFile2).delete(); + willDoNothing().given(imageFile3).delete(); + willDoNothing().given(imageFile4).delete(); + willDoNothing().given(imageFile5).delete(); + } + + private void initMockImageConverter() { + willReturn(imageFile1).given(imageConverter).convertBytesToImageFile(eq(IMAGE1_BASE_64_DATA), any(ImageType.class)); + willReturn(imageFile2).given(imageConverter).convertBytesToImageFile(eq(IMAGE2_BASE_64_DATA), any(ImageType.class)); + willReturn(imageFile3).given(imageConverter).convertBytesToImageFile(eq(IMAGE3_BASE_64_DATA), any(ImageType.class)); + willReturn(imageFile4).given(imageConverter).convertBytesToImageFile(eq(IMAGE4_BASE_64_DATA), any(ImageType.class)); + willReturn(imageFile5).given(imageConverter).convertBytesToImageFile(eq(IMAGE5_BASE_64_DATA), any(ImageType.class)); + } + + private void initMockAwsS3Uploader() { + willReturn(IMAGE1_S3_URL).given(awsS3Uploader).upload(any(String.class), same(file1)); + willReturn(IMAGE2_S3_URL).given(awsS3Uploader).upload(any(String.class), same(file2)); + willReturn(IMAGE3_S3_URL).given(awsS3Uploader).upload(any(String.class), same(file3)); + willReturn(IMAGE4_S3_URL).given(awsS3Uploader).upload(any(String.class), same(file4)); + willReturn(IMAGE5_S3_URL).given(awsS3Uploader).upload(any(String.class), same(file5)); + } + + private void assertIdAssigned() { + assertThat(comment1.getId()).isNotNull(); + assertThat(comment2.getId()).isNotNull(); + + assertThat(image1.getId()).isNotNull(); + assertThat(image2.getId()).isNotNull(); + + assertThat(like1.getId()).isNotNull(); + assertThat(like2.getId()).isNotNull(); + + assertThat(postWithImages.getId()).isNotNull(); + } + + @DisplayName("게시글 생성 - 성공 - 이미지 포함하지 않음") @Test - void create() { + void createNotWithImages() { //given //when - PostResponse createResponse = postService.create(optionalUser, postRequest); - Post foundPost = postRepository.findById(createResponse.getId()) - .orElseThrow(() -> new NotFoundException("게시글을 찾을 수 없음.")); + PostResponse postResponse = postService.create(optionalUser, postRequestNotWithImages); + resetEntityManager(); + Post foundPost = postRepository.findById(postResponse.getId()) + .orElseThrow(() -> new NotFoundException("게시글을 찾을 수 없음.")); //then - assertThat(createResponse.getWriter().getId()).isEqualTo(user.getId()); - assertThat(createResponse.getContent()).isEqualTo(postRequest.getContent()); + assertThat(postResponse.getWriter().getId()).isEqualTo(user.getId()); + assertThat(postResponse.getContent()).isEqualTo(postRequestNotWithImages.getContent()); + assertThat(postResponse.getImages()).isEmpty(); + + assertThat(foundPost).isNotNull(); + assertThat(foundPost.getUser()).isNotNull(); + assertThat(foundPost.hasImages()).isFalse(); + + verify(awsS3Uploader, times(0)).upload(any(String.class), any(File.class)); + } + + @DisplayName("게시글 생성 - 성공 - 이미지 포함") + @Test + void createWithImages() { + //given + //when + PostResponse postResponse = postService.create(optionalUser, postRequestWithImages); + resetEntityManager(); + Post foundPost = postRepository.findById(postResponse.getId()) + .orElseThrow(() -> new NotFoundException("게시글을 찾을 수 없음.")); + //then + assertThat(postResponse.getWriter().getId()).isEqualTo(user.getId()); + assertThat(postResponse.getContent()).isEqualTo(postRequestWithImages.getContent()); + assertThat(postResponse.getImages()).containsExactly(IMAGE1_S3_URL, IMAGE2_S3_URL, IMAGE3_S3_URL); + assertThat(foundPost).isNotNull(); assertThat(foundPost.getUser()).isNotNull(); + assertThat(foundPost.getImages().getImages()) + .extracting("url").containsExactly(IMAGE1_S3_URL, IMAGE2_S3_URL, IMAGE3_S3_URL); + + verify(awsS3Uploader, times(3)).upload(any(String.class), any(File.class)); } @DisplayName("게시글 생성 - 실패 - 존재하지 않는 유저") @@ -119,8 +367,8 @@ void createFailureWhenWriterIsNull() { //given //when //then - assertThatThrownBy(() -> postService.create(optionalUserNotSignedIn, postRequest)) - .isExactlyInstanceOf(UnAuthorizedException.class); + assertThatThrownBy(() -> postService.create(optionalUserNotSignedIn, postRequestWithImages)) + .isExactlyInstanceOf(UnAuthorizedException.class); } @DisplayName("게시글 단일 조회 - 성공") @@ -128,9 +376,10 @@ void createFailureWhenWriterIsNull() { void findById() { //given //when - PostResponse findResponse = postService.findById(post.getId(), optionalUser); + PostResponse findResponse = postService.findById(postWithImages.getId(), optionalUser); //then - assertThat(findResponse.getId()).isEqualTo(post.getId()); + assertThat(findResponse.getId()).isEqualTo(postWithImages.getId()); + assertThat(findResponse.getImages()).containsExactly(IMAGE1_S3_URL, IMAGE2_S3_URL, IMAGE3_S3_URL); } @DisplayName("게시글 단일 조회 - 실패 - 게시글이 존재하지 않는 경우") @@ -140,7 +389,7 @@ void findByIdFailureWhenPostIsNotExists() { //when //then assertThatThrownBy(() -> postService.findById(Long.MAX_VALUE, optionalUser)) - .isExactlyInstanceOf(NotFoundException.class); + .isExactlyInstanceOf(NotFoundException.class); } @DisplayName("게시글 전체 조회 - 성공") @@ -150,43 +399,76 @@ void findAll() { //when List findResponse = postService.findByVaccineType(VaccinationType.ALL, optionalUser); //then - assertThat(findResponse).hasSize(2); + assertThat(findResponse).hasSize(3); assertThat(findResponse.get(0).getContent()).isEqualTo(post.getContent()); + assertThat(findResponse.get(0).getImages()).containsExactly(IMAGE1_S3_URL, IMAGE2_S3_URL, IMAGE3_S3_URL); } - @DisplayName("게시글 수정 - 성공") + @DisplayName("게시글 수정 - 이미지 모두 제거 - 성공") @Test - void update() { + void updateWhenRemoveAllImages() { //given - PostRequest updateRequest = new PostRequest("updated content", postRequest.getVaccinationType()); + PostRequest updateRequest = new PostRequest("updated content", postRequestNotWithImages.getVaccinationType(), Collections.emptyList()); //when - postService.update(post.getId(), optionalUser, updateRequest); + postService.update(postWithImages.getId(), optionalUser, updateRequest); + resetEntityManager(); + + Post updatedPost = postRepository.findById(postWithImages.getId()) + .orElseThrow(() -> new NotFoundException("게시글을 찾을 수 없음.")); //then - Post updatedPost = postRepository.findById(post.getId()) - .orElseThrow(() -> new NotFoundException("게시글을 찾을 수 없음.")); assertThat(updatedPost.getContent()).isEqualTo(updateRequest.getContent()); + assertThat(updatedPost.hasImages()).isFalse(); + assertThat(imageRepository.findById(image1.getId())).isEmpty(); + assertThat(imageRepository.findById(image2.getId())).isEmpty(); + assertThat(imageRepository.findById(image3.getId())).isEmpty(); + verify(awsS3Uploader, times(3)).delete(any(String.class), any(String.class)); + verify(awsS3Uploader, times(1)).delete(any(String.class), eq(image1.getName())); + verify(awsS3Uploader, times(1)).delete(any(String.class), eq(image2.getName())); + verify(awsS3Uploader, times(1)).delete(any(String.class), eq(image3.getName())); + } + + @DisplayName("게시글 수정 - 이미지 수정 - 성공") + @Test + void updateWithImages() { + //given + PostRequest updateRequest = new PostRequest("updated content", postRequestWithImages.getVaccinationType(), updateImageRequests); + //when + postService.update(postWithImages.getId(), optionalUser, updateRequest); + resetEntityManager(); + Post updatedPost = postRepository.findById(postWithImages.getId()) + .orElseThrow(() -> new NotFoundException("게시글을 찾을 수 없음.")); + //then + assertThat(updatedPost.getContent()).isEqualTo(updateRequest.getContent()); + assertThat(updatedPost.getImages().getImages()) + .extracting("url").containsExactly(IMAGE4_S3_URL, IMAGE5_S3_URL); + assertThat(imageRepository.findAll()).extracting("url").containsExactly(IMAGE4_S3_URL, IMAGE5_S3_URL); + verify(awsS3Uploader, times(3)).delete(any(String.class), any(String.class)); + verify(awsS3Uploader, times(1)).delete(any(String.class), eq(image1.getName())); + verify(awsS3Uploader, times(1)).delete(any(String.class), eq(image2.getName())); + verify(awsS3Uploader, times(1)).delete(any(String.class), eq(image3.getName())); + verify(awsS3Uploader, times(2)).upload(any(String.class), any(File.class)); } @DisplayName("게시글 수정 - 실패 - 찾을 수 없는 게시글") @Test void updateFailureWhenCannotFind() { //given - PostRequest changedContent = new PostRequest("updated content", postRequest.getVaccinationType()); + PostRequest changedContent = new PostRequest("updated content", postRequestWithImages.getVaccinationType()); //when //then assertThatThrownBy(() -> postService.update(Long.MAX_VALUE, optionalUser, changedContent)) - .isExactlyInstanceOf(NotFoundException.class); + .isExactlyInstanceOf(NotFoundException.class); } @DisplayName("게시글 수정 - 실패 - 다른 작성자의 게시글") @Test void updateFailureWhenOthersPost() { //given - PostRequest changedContent = new PostRequest("changed content", postRequest.getVaccinationType()); + PostRequest changedContent = new PostRequest("changed content", postRequestWithImages.getVaccinationType()); //when //then assertThatThrownBy(() -> postService.update(post.getId(), optionalAnotherUser, changedContent)) - .isExactlyInstanceOf(InvalidOperationException.class); + .isExactlyInstanceOf(InvalidOperationException.class); } @DisplayName("게시글 삭제 - 성공") @@ -207,7 +489,7 @@ void deleteFailureWhenPostIsNotExists() { //when //then assertThatThrownBy(() -> postService.delete(Long.MAX_VALUE, optionalUser)) - .isExactlyInstanceOf(NotFoundException.class); + .isExactlyInstanceOf(NotFoundException.class); } @DisplayName("게시글 삭제 - 실패 - 글 작성자가 아님") @@ -217,6 +499,40 @@ void deletePostFailureWhenNotAuthor() { //when //then assertThatThrownBy(() -> postService.delete(post.getId(), optionalAnotherUser)) - .isExactlyInstanceOf(InvalidOperationException.class); + .isExactlyInstanceOf(InvalidOperationException.class); + } + + @DisplayName("Post를 삭제하면, 안에 있는 Comment, Like, Image 들이 모두 삭제된다.") + @Test + void deletePost() { + //given + //when + postService.delete(postWithImages.getId(), optionalUser); + resetEntityManager(); + //then + assertThat(userRepository.findById(user.getId())).isNotEmpty(); + assertThat(userRepository.findById(anotherUser.getId())).isNotEmpty(); + + assertThat(postRepository.findById(postWithImages.getId())).isEmpty(); + + assertThat(commentRepository.findById(comment1.getId())).isEmpty(); + assertThat(commentRepository.findById(comment2.getId())).isEmpty(); + + assertThat(likeRepository.findById(like1.getId())).isEmpty(); + assertThat(likeRepository.findById(like2.getId())).isEmpty(); + + assertThat(imageRepository.findById(image1.getId())).isEmpty(); + assertThat(imageRepository.findById(image2.getId())).isEmpty(); + assertThat(imageRepository.findById(image3.getId())).isEmpty(); + + verify(awsS3Uploader, times(3)).delete(any(String.class), any(String.class)); + verify(awsS3Uploader, times(1)).delete(any(String.class), eq(image1.getName())); + verify(awsS3Uploader, times(1)).delete(any(String.class), eq(image2.getName())); + verify(awsS3Uploader, times(1)).delete(any(String.class), eq(image3.getName())); + } + + private void resetEntityManager() { + entityManager.flush(); + entityManager.clear(); } } diff --git a/backend/app-cvi-api/src/test/java/com/cvi/service/UserServiceTest.java b/backend/app-cvi-api/src/test/java/com/cvi/service/UserServiceTest.java index e9fc581c..b4767d56 100644 --- a/backend/app-cvi-api/src/test/java/com/cvi/service/UserServiceTest.java +++ b/backend/app-cvi-api/src/test/java/com/cvi/service/UserServiceTest.java @@ -1,5 +1,9 @@ package com.cvi.service; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.BDDMockito.willReturn; + import com.cvi.auth.JwtTokenProvider; import com.cvi.dto.UserRequest; import com.cvi.dto.UserResponse; @@ -10,6 +14,8 @@ import com.cvi.user.domain.model.SocialProvider; import com.cvi.user.domain.model.User; import com.cvi.user.domain.repository.UserRepository; +import java.util.Optional; +import javax.transaction.Transactional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -17,18 +23,10 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; -import javax.transaction.Transactional; -import java.util.Optional; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.willReturn; -import static org.mockito.BDDMockito.willThrow; - @SpringBootTest @Transactional @DisplayName("사용자 비즈니스 흐름 테스트") -public class UserServiceTest { +class UserServiceTest { @Autowired private UserService userService; @@ -38,10 +36,6 @@ public class UserServiceTest { @Autowired private UserRepository userRepository; - - @MockBean - private PublicDataScheduler publicDataScheduler; - private UserRequest userRequest; @BeforeEach @@ -57,7 +51,7 @@ void signup() { UserResponse userResponse = userService.signup(userRequest); //then User foundUser = userRepository.findById(userResponse.getId()) - .orElseThrow(() -> new NotFoundException("User 조회 에러")); + .orElseThrow(() -> new NotFoundException("User 조회 에러")); assertThat(foundUser.getNickname()).isEqualTo("인비"); assertThat(foundUser.getAgeRange()).isEqualTo(AgeRange.TEENS); @@ -73,7 +67,7 @@ void signupFailureWhenDuplicateNickname() { //when //then assertThatThrownBy(() -> userService.signup(userRequest)) - .isInstanceOf(DuplicateException.class); + .isInstanceOf(DuplicateException.class); } @DisplayName("Access Token을 이용한 사용자 조회 - 성공") @@ -108,7 +102,7 @@ void findByIdFailureWhenNotExists() { //when //then assertThatThrownBy(() -> userService.findById(lastIndex + 1L)) - .isInstanceOf(NotFoundException.class); + .isInstanceOf(NotFoundException.class); } @DisplayName("사용자 수정 - 성공") @@ -122,7 +116,7 @@ void update() { userService.update(Optional.of(user), updateRequest); //then User updatedUser = userRepository.findById(user.getId()) - .orElseThrow(() -> new NotFoundException("사용자 조회 실패")); + .orElseThrow(() -> new NotFoundException("사용자 조회 실패")); assertThat(updatedUser.getNickname()).isEqualTo(updateRequest.getNickname()); assertThat(updatedUser.getAgeRange()).isEqualTo(AgeRange.THIRTIES); @@ -140,7 +134,7 @@ void updateNicknameToSameNickname() { userService.update(Optional.of(user), updateRequest); //then User updatedUser = userRepository.findById(user.getId()) - .orElseThrow(() -> new NotFoundException("사용자 조회 실패")); + .orElseThrow(() -> new NotFoundException("사용자 조회 실패")); assertThat(updatedUser.getNickname()).isEqualTo(userRequest.getNickname()); } @@ -156,21 +150,21 @@ void updateFailureWhenNicknameDuplicate() { User user2 = userService.findUserById(signupResponse2.getId()); UserRequest updateRequest = UserRequest.builder() - .nickname("인비") - .ageRange(AgeRange.FIFTIES) - .build(); + .nickname("인비") + .ageRange(AgeRange.FIFTIES) + .build(); //when assertThatThrownBy(() -> userService.update(Optional.of(user2), updateRequest)) - .isInstanceOf(DuplicateException.class); + .isInstanceOf(DuplicateException.class); //then User notUpdatedUser1 = userRepository.findById(user1.getId()) - .orElseThrow(() -> new NotFoundException("사용자 조회 실패")); + .orElseThrow(() -> new NotFoundException("사용자 조회 실패")); assertThat(notUpdatedUser1.getNickname()).isEqualTo(userRequest.getNickname()); assertThat(notUpdatedUser1.getAgeRange()).isSameAs(userRequest.getAgeRange()); User notUpdatedUser2 = userRepository.findById(signupResponse2.getId()) - .orElseThrow(() -> new NotFoundException("사용자 조회 실패")); + .orElseThrow(() -> new NotFoundException("사용자 조회 실패")); assertThat(notUpdatedUser2.getNickname()).isEqualTo(signUpRequest2.getNickname()); assertThat(notUpdatedUser2.getAgeRange()).isSameAs(signUpRequest2.getAgeRange()); @@ -185,7 +179,7 @@ void updateFailureWhenNotExists() { UserRequest updateRequest = new UserRequest(null, null, false, null, null, null); //then assertThatThrownBy(() -> userService.update(Optional.empty(), updateRequest)) - .isInstanceOf(UnAuthorizedException.class); + .isInstanceOf(UnAuthorizedException.class); } @DisplayName("사용자 삭제 - 성공") @@ -208,17 +202,17 @@ void deleteFailureWhenNotExists() { //when //then assertThatThrownBy(() -> userService.delete(Optional.empty())) - .isInstanceOf(UnAuthorizedException.class); + .isInstanceOf(UnAuthorizedException.class); } private Long getLastIndex() { User lastUser = User.builder() - .nickname("라이언") - .ageRange(AgeRange.TWENTIES) - .socialProvider(SocialProvider.KAKAO) - .socialId("KAKAO_ID") - .profileUrl("kakao.com/profile") - .build(); + .nickname("라이언") + .ageRange(AgeRange.TWENTIES) + .socialProvider(SocialProvider.KAKAO) + .socialId("KAKAO_ID") + .profileUrl("kakao.com/profile") + .build(); return userRepository.save(lastUser).getId(); } } diff --git a/backend/app-cvi-api/src/test/resources/application.yml b/backend/app-cvi-api/src/test/resources/application.yml index 3cb8465d..6f9a1f78 100644 --- a/backend/app-cvi-api/src/test/resources/application.yml +++ b/backend/app-cvi-api/src/test/resources/application.yml @@ -2,6 +2,14 @@ spring: profiles: active: test + autoconfigure: + exclude: + - org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration + - org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration + - org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration + - org.springframework.cloud.aws.autoconfigure.context.ContextResourceLoaderAutoConfiguration + - org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration + datasource: driver-class-name: org.h2.Driver url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE; @@ -17,9 +25,13 @@ spring: ddl-auto: create-drop properties: hibernate: + default_batch_fetch_size: 500 format_sql: true generate-ddl: true + flyway: + enabled: false + security: jwt: token: @@ -34,6 +46,23 @@ security: data: vaccination: publicdata-secret +aws: + s3: + bucket_name: bucket-name + directory: + path: + posts: + images: dir-path + cloudfront: + url: https://cloudfront.net + +cloud: + aws: + region: + static: ap-northeast-2 + stack: + auto: false + logging: level: org.hibernate.SQL: debug diff --git a/backend/common-cvi/src/main/java/com/cvi/exception/FileConvertException.java b/backend/common-cvi/src/main/java/com/cvi/exception/FileConvertException.java new file mode 100644 index 00000000..5391a1a3 --- /dev/null +++ b/backend/common-cvi/src/main/java/com/cvi/exception/FileConvertException.java @@ -0,0 +1,8 @@ +package com.cvi.exception; + +public class FileConvertException extends CommonException { + + public FileConvertException(String message) { + super(message); + } +} diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/Authorization.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/Authorization.java index 2a6b4723..54327cb8 100644 --- a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/Authorization.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/Authorization.java @@ -9,17 +9,17 @@ public interface Authorization { - UserInformation requestProfile(String code, String state); + UserInformation requestProfile(String code, String state, String requestOrigin); UserInformation parseProfile(OAuthToken oAuthToken); - OAuthToken requestToken(String code, String state); + OAuthToken requestToken(String code, String state, String requestOrigin); OAuthToken mapToOAuthToken(ResponseEntity response); SocialProfile mapToProfile(ResponseEntity response); - HttpEntity> createTokenRequest(String code, String state); + HttpEntity> createTokenRequest(String code, String state, String requestOrigin); HttpEntity> createProfileRequest(OAuthToken oAuthToken); diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/AuthorizationManager.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/AuthorizationManager.java index b5e5996f..fc0a56ef 100644 --- a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/AuthorizationManager.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/AuthorizationManager.java @@ -17,9 +17,9 @@ public class AuthorizationManager { private final Map authorizationMap; - public UserInformation requestUserInfo(SocialProvider provider, String code, String state) { + public UserInformation requestUserInfo(SocialProvider provider, String code, String state, String requestOrigin) { Authorization authorization = extractAuthorization(provider); - return authorization.requestProfile(code, state); + return authorization.requestProfile(code, state, requestOrigin); } private Authorization extractAuthorization(SocialProvider provider) { @@ -39,4 +39,3 @@ private void validateSocialProvider(SocialProvider provider) { } } } - diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/KakaoAuthorization.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/KakaoAuthorization.java index 00694c39..e238a2b5 100644 --- a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/KakaoAuthorization.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/KakaoAuthorization.java @@ -24,15 +24,14 @@ public class KakaoAuthorization implements Authorization { private static final String PROFILE_REQUEST_URL = "https://kapi.kakao.com/v2/user/me"; private static final String TOKEN_REQUEST_URL = "https://kauth.kakao.com/oauth/token"; - private static final String REDIRECT_URL = "https://vaccine-review.com/auth/kakao/callback"; - //private static final String REDIRECT_URL = "https://localhost:9000/auth/kakao/callback"; + private static final String CALLBACK_URL_SUFFIX = "/auth/kakao/callback"; private final RestTemplate restTemplate = new RestTemplate(); private final ObjectMapper objectMapper = new ObjectMapper(); @Override - public UserInformation requestProfile(String code, String state) { - OAuthToken kakaoOAuthToken = requestToken(code, state); + public UserInformation requestProfile(String code, String state, String requestOrigin) { + OAuthToken kakaoOAuthToken = requestToken(code, state, requestOrigin); return parseProfile(kakaoOAuthToken); } @@ -44,8 +43,8 @@ public UserInformation parseProfile(OAuthToken oAuthToken) { } @Override - public OAuthToken requestToken(String code, String state) { - HttpEntity> kakaoTokenRequest = createTokenRequest(code, state); + public OAuthToken requestToken(String code, String state, String requestOrigin) { + HttpEntity> kakaoTokenRequest = createTokenRequest(code, state, requestOrigin); ResponseEntity response = sendRequest(kakaoTokenRequest, TOKEN_REQUEST_URL); return mapToOAuthToken(response); } @@ -71,11 +70,11 @@ public SocialProfile mapToProfile(ResponseEntity response) { } @Override - public HttpEntity> createTokenRequest(String code, String state) { + public HttpEntity> createTokenRequest(String code, String state, String requestOrigin) { MultiValueMap params = new LinkedMultiValueMap<>(); params.add("grant_type", "authorization_code"); params.add("client_id", "1a06cf63be2ce0a6ebd8f49cd534e1c9"); - params.add("redirect_uri", REDIRECT_URL); + params.add("redirect_uri", requestOrigin + CALLBACK_URL_SUFFIX); params.add("code", code); HttpHeaders headers = new HttpHeaders(); @@ -94,10 +93,10 @@ public HttpEntity> createProfileRequest(OAuthToken @Override public ResponseEntity sendRequest(HttpEntity> request, String url) { return restTemplate.exchange( - url, - HttpMethod.POST, - request, - String.class + url, + HttpMethod.POST, + request, + String.class ); } } diff --git a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/NaverAuthorization.java b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/NaverAuthorization.java index 46b20fe2..bd30fb70 100644 --- a/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/NaverAuthorization.java +++ b/backend/domain-cvi-oauth-service/src/main/java/com/cvi/parser/NaverAuthorization.java @@ -21,7 +21,7 @@ @Component @Slf4j -public class NaverAuthorization implements Authorization { +public class NaverAuthorization implements Authorization { private static final String PROFILE_REQUEST_URL = "https://openapi.naver.com/v1/nid/me"; private static final String TOKEN_REQUEST_URL = "https://nid.naver.com/oauth2.0/token"; @@ -33,8 +33,8 @@ public class NaverAuthorization implements Authorization { private String clientSecret; @Override - public UserInformation requestProfile(String code, String state) { - OAuthToken naverOAuthToken = requestToken(code, state); + public UserInformation requestProfile(String code, String state, String requestOrigin) { + OAuthToken naverOAuthToken = requestToken(code, state, requestOrigin); return parseProfile(naverOAuthToken); } @@ -46,8 +46,8 @@ public UserInformation parseProfile(OAuthToken oAuthToken) { } @Override - public OAuthToken requestToken(String code, String state) { - HttpEntity> naverTokenRequest = createTokenRequest(code, state); + public OAuthToken requestToken(String code, String state, String requestOrigin) { + HttpEntity> naverTokenRequest = createTokenRequest(code, state, requestOrigin); ResponseEntity response = sendRequest(naverTokenRequest, TOKEN_REQUEST_URL); return mapToOAuthToken(response); } @@ -73,7 +73,7 @@ public SocialProfile mapToProfile(ResponseEntity response) { } @Override - public HttpEntity> createTokenRequest(String code, String state) { + public HttpEntity> createTokenRequest(String code, String state, String requestOrigin) { MultiValueMap params = new LinkedMultiValueMap<>(); params.add("grant_type", "authorization_code"); params.add("client_id", "nr6cVo7X8bw1cRQCKOQu"); @@ -97,10 +97,10 @@ public HttpEntity> createProfileRequest(OAuthToken @Override public ResponseEntity sendRequest(HttpEntity> request, String url) { return restTemplate.exchange( - url, - HttpMethod.POST, - request, - String.class + url, + HttpMethod.POST, + request, + String.class ); } } diff --git a/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/AuthorizationManagerTest.java b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/AuthorizationManagerTest.java index 91dd4320..8abb45f6 100644 --- a/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/AuthorizationManagerTest.java +++ b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/AuthorizationManagerTest.java @@ -1,5 +1,10 @@ package com.cvi.parser; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.Mockito.spy; + import com.cvi.dto.profile.KakaoProfile; import com.cvi.dto.profile.NaverProfile; import com.cvi.dto.profile.UserInformation; @@ -7,18 +12,12 @@ import com.cvi.user.domain.model.SocialProvider; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.HashMap; +import java.util.Map; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.HashMap; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.willReturn; -import static org.mockito.Mockito.spy; - @DisplayName("Authorization 매니저 도메인 테스트") class AuthorizationManagerTest { @@ -26,6 +25,7 @@ class AuthorizationManagerTest { private static final String KAKAO_PROFILE_RESPONSE = "{\"id\":1816688137,\"connected_at\":\"2021-07-22T05:43:16Z\",\"properties\":{\"nickname\":\"김영빈\"},\"kakao_account\":{\"profile_nickname_needs_agreement\":false,\"profile_image_needs_agreement\":false,\"profile\":{\"nickname\":\"김영빈\",\"thumbnail_image_url\":\"http://k.kakaocdn.net/dn/dpk9l1/btqmGhA2lKL/Oz0wDuJn1YV2DIn92f6DVK/img_110x110.jpg\",\"profile_image_url\":\"http://k.kakaocdn.net/dn/dpk9l1/btqmGhA2lKL/Oz0wDuJn1YV2DIn92f6DVK/img_640x640.jpg\",\"is_default_image\":true}}}"; private static final String STATE = "STATE"; private static final String SOCIAL_CODE = "CODE"; + private static final String REQUEST_ORIGIN = "http://localhost:9000"; private Map authorizationMap = new HashMap<>(); private AuthorizationManager authorizationManager = new AuthorizationManager(authorizationMap); @@ -53,9 +53,9 @@ void setUp() throws JsonProcessingException { @Test void requestNaverUserInfo() { //given - willReturn(naverUserInfo).given(naverAuthorization).requestProfile(SOCIAL_CODE, STATE); + willReturn(naverUserInfo).given(naverAuthorization).requestProfile(SOCIAL_CODE, STATE, REQUEST_ORIGIN); //when - UserInformation expected = authorizationManager.requestUserInfo(SocialProvider.NAVER, SOCIAL_CODE, STATE); + UserInformation expected = authorizationManager.requestUserInfo(SocialProvider.NAVER, SOCIAL_CODE, STATE, REQUEST_ORIGIN); //then assertThat(expected).isEqualTo(naverUserInfo); } @@ -64,9 +64,9 @@ void requestNaverUserInfo() { @Test void requestKakaoUserInfo() { //given - willReturn(kakaoUserInfo).given(kakaoAuthorization).requestProfile(SOCIAL_CODE, null); + willReturn(kakaoUserInfo).given(kakaoAuthorization).requestProfile(SOCIAL_CODE, null, REQUEST_ORIGIN); //when - UserInformation expected = authorizationManager.requestUserInfo(SocialProvider.KAKAO, SOCIAL_CODE, null); + UserInformation expected = authorizationManager.requestUserInfo(SocialProvider.KAKAO, SOCIAL_CODE, null, REQUEST_ORIGIN); //then assertThat(expected).isEqualTo(kakaoUserInfo); } @@ -77,8 +77,8 @@ void requestUserInfoFailureWhenInvalidSocialProviderNaver() { //given //when //then - assertThatThrownBy(() -> authorizationManager.requestUserInfo(null, SOCIAL_CODE, STATE)) - .isExactlyInstanceOf(InvalidOperationException.class) - .hasMessage("해당 OAuth 제공자가 존재하지 않습니다 입력값: null"); + assertThatThrownBy(() -> authorizationManager.requestUserInfo(null, SOCIAL_CODE, STATE, REQUEST_ORIGIN)) + .isExactlyInstanceOf(InvalidOperationException.class) + .hasMessage("해당 OAuth 제공자가 존재하지 않습니다 입력값: null"); } } diff --git a/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/KakaoAuthorizationTest.java b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/KakaoAuthorizationTest.java index 443ab0f5..6c35a2aa 100644 --- a/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/KakaoAuthorizationTest.java +++ b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/KakaoAuthorizationTest.java @@ -1,5 +1,10 @@ package com.cvi.parser; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.Mockito.spy; + import com.cvi.dto.oauthtoken.KakaoOAuthToken; import com.cvi.dto.oauthtoken.OAuthToken; import com.cvi.dto.profile.SocialProfile; @@ -13,11 +18,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.util.MultiValueMap; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.willReturn; -import static org.mockito.Mockito.spy; - @DisplayName("Kakao Authorization 도메인 테스트") class KakaoAuthorizationTest { @@ -33,6 +33,7 @@ class KakaoAuthorizationTest { private static final String REFRESH_TOKEN = "{REFRESH_TOKEN received from Social Provider}"; private static final String TOKEN_EXPIRE_TIME = "25184000"; private static final String SCOPE = "account_email profile"; + private static final String REQUEST_ORIGIN = "http://localhost:9000"; private KakaoAuthorization kakaoAuthorization = spy(new KakaoAuthorization()); private HttpEntity> kakaoTokenRequest; @@ -42,7 +43,7 @@ class KakaoAuthorizationTest { @BeforeEach void beforeEach() { - kakaoTokenRequest = kakaoAuthorization.createTokenRequest(CODE, null); + kakaoTokenRequest = kakaoAuthorization.createTokenRequest(CODE, null, REQUEST_ORIGIN); tokenResponse = ResponseEntity.ok(TOKEN_RESPONSE); profileResponse = ResponseEntity.ok(PROFILE_RESPONSE); @@ -57,7 +58,7 @@ void beforeEach() { void requestProfile() { //given //when - UserInformation userInformation = kakaoAuthorization.requestProfile(CODE, null); + UserInformation userInformation = kakaoAuthorization.requestProfile(CODE, null, REQUEST_ORIGIN); //then assertThat(userInformation.getSocialId()).isEqualTo(KAKAO_SOCIAL_ID); assertThat(userInformation.getSocialProfileUrl()).isEqualTo("http://k.kakaocdn.net/dn/dpk9l1/btqmGhA2lKL/Oz0wDuJn1YV2DIn92f6DVK/img_640x640.jpg"); @@ -68,7 +69,7 @@ void requestProfile() { void requestToken() { //given //when - KakaoOAuthToken expected = (KakaoOAuthToken) kakaoAuthorization.requestToken(CODE, null); + KakaoOAuthToken expected = (KakaoOAuthToken) kakaoAuthorization.requestToken(CODE, null, REQUEST_ORIGIN); //then assertThat(expected.getToken_type()).isEqualTo(BEARER); assertThat(expected.getAccess_token()).isEqualTo(ACCESS_TOKEN); @@ -82,12 +83,12 @@ void requestToken() { @Test void requestTokenFailure() { //given - HttpEntity> invalidToken = kakaoAuthorization.createTokenRequest("INVALID_TOKEN", null); + HttpEntity> invalidToken = kakaoAuthorization.createTokenRequest("INVALID_TOKEN", null, REQUEST_ORIGIN); willReturn(new ResponseEntity<>("{\"ERROR\":\"ERROR\"}", HttpStatus.BAD_REQUEST)).given(kakaoAuthorization).sendRequest(invalidToken, TOKEN_REQUEST_URL); //when //then - assertThatThrownBy(() -> kakaoAuthorization.requestToken("INVALID_TOKEN", null)) - .isExactlyInstanceOf(MappingFailureException.class); + assertThatThrownBy(() -> kakaoAuthorization.requestToken("INVALID_TOKEN", null, REQUEST_ORIGIN)) + .isExactlyInstanceOf(MappingFailureException.class); } @DisplayName("토큰 매핑 테스트 - 성공") @@ -112,7 +113,7 @@ void mapToOAuthTokenFailureWhenNotValidTokenResponse() { //when //then assertThatThrownBy(() -> kakaoAuthorization.mapToOAuthToken(ResponseEntity.ok("NOT_VALID_TOKEN"))) - .isExactlyInstanceOf(MappingFailureException.class); + .isExactlyInstanceOf(MappingFailureException.class); } @DisplayName("프로필 요청 테스트 - 성공") @@ -136,7 +137,7 @@ void parseProfileFailure() { //when //then assertThatThrownBy(() -> kakaoAuthorization.parseProfile(oAuthToken)) - .isExactlyInstanceOf(MappingFailureException.class); + .isExactlyInstanceOf(MappingFailureException.class); } @DisplayName("프로필 매핑 테스트 - 성공") @@ -157,6 +158,6 @@ void mapToProfileFailureWhenInvalidProfileResponse() { //when //then assertThatThrownBy(() -> kakaoAuthorization.mapToProfile(ResponseEntity.ok("NOT_VALID_PROFILE"))) - .isExactlyInstanceOf(MappingFailureException.class); + .isExactlyInstanceOf(MappingFailureException.class); } } diff --git a/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/NaverAuthorizationTest.java b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/NaverAuthorizationTest.java index c236c559..e9aceb90 100644 --- a/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/NaverAuthorizationTest.java +++ b/backend/domain-cvi-oauth-service/src/test/java/com/cvi/parser/NaverAuthorizationTest.java @@ -1,5 +1,10 @@ package com.cvi.parser; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.Mockito.spy; + import com.cvi.dto.oauthtoken.NaverOAuthToken; import com.cvi.dto.oauthtoken.OAuthToken; import com.cvi.dto.profile.SocialProfile; @@ -13,11 +18,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.util.MultiValueMap; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.BDDMockito.willReturn; -import static org.mockito.Mockito.spy; - @DisplayName("Naver Authorization 도메인 테스트") class NaverAuthorizationTest { @@ -33,6 +33,7 @@ class NaverAuthorizationTest { private static final String ACCESS_TOKEN = "{ACCESS_TOKEN received from Social Provider}"; private static final String REFRESH_TOKEN = "{REFRESH_TOKEN received from Social Provider}"; private static final String EXPIRE_TIME = "3600"; + private static final String REQUEST_ORIGIN = "http://localhost:9000"; private NaverAuthorization naverAuthorization = spy(new NaverAuthorization()); private HttpEntity> naverTokenRequest; @@ -42,7 +43,7 @@ class NaverAuthorizationTest { @BeforeEach void beforeEach() { - naverTokenRequest = naverAuthorization.createTokenRequest(CODE, STATE); + naverTokenRequest = naverAuthorization.createTokenRequest(CODE, STATE, REQUEST_ORIGIN); tokenResponse = ResponseEntity.ok(TOKEN_RESPONSE); profileResponse = ResponseEntity.ok(PROFILE_RESPONSE); @@ -57,7 +58,7 @@ void beforeEach() { void requestProfile() { //given //when - UserInformation userInformation = naverAuthorization.requestProfile(CODE, STATE); + UserInformation userInformation = naverAuthorization.requestProfile(CODE, STATE, REQUEST_ORIGIN); //then assertThat(userInformation.getSocialId()).isEqualTo(NAVER_ID); assertThat(userInformation.getSocialProfileUrl()).isEqualTo(NAVER_PROFILE_URL); @@ -68,7 +69,7 @@ void requestProfile() { void requestToken() { //given //when - NaverOAuthToken expected = (NaverOAuthToken) naverAuthorization.requestToken(CODE, STATE); + NaverOAuthToken expected = (NaverOAuthToken) naverAuthorization.requestToken(CODE, STATE, REQUEST_ORIGIN); //then assertThat(expected.getToken_type()).isEqualTo(BEARER); assertThat(expected.getAccess_token()).isEqualTo(ACCESS_TOKEN); @@ -80,12 +81,12 @@ void requestToken() { @Test void requestTokenFailure() { //given - HttpEntity> invalidToken = naverAuthorization.createTokenRequest("INVALID_TOKEN", STATE); + HttpEntity> invalidToken = naverAuthorization.createTokenRequest("INVALID_TOKEN", STATE, REQUEST_ORIGIN); willReturn(new ResponseEntity<>("{\"ERROR\":\"ERROR\"}", HttpStatus.BAD_REQUEST)).given(naverAuthorization).sendRequest(invalidToken, TOKEN_REQUEST_URL); //when //then - assertThatThrownBy(() -> naverAuthorization.requestToken("INVALID_TOKEN", STATE)) - .isExactlyInstanceOf(MappingFailureException.class); + assertThatThrownBy(() -> naverAuthorization.requestToken("INVALID_TOKEN", STATE, REQUEST_ORIGIN)) + .isExactlyInstanceOf(MappingFailureException.class); } @DisplayName("토큰 매핑 테스트 - 성공") @@ -108,7 +109,7 @@ void mapToOAuthTokenFailureWhenNotValidTokenResponse() { //when //then assertThatThrownBy(() -> naverAuthorization.mapToOAuthToken(ResponseEntity.ok("NOT_VALID_TOKEN"))) - .isExactlyInstanceOf(MappingFailureException.class); + .isExactlyInstanceOf(MappingFailureException.class); } @DisplayName("프로필 요청 테스트 - 성공") @@ -132,7 +133,7 @@ void parseProfileFailure() { //when //then assertThatThrownBy(() -> naverAuthorization.parseProfile(oAuthToken)) - .isExactlyInstanceOf(MappingFailureException.class); + .isExactlyInstanceOf(MappingFailureException.class); } @DisplayName("프로필 매핑 테스트 - 성공") @@ -153,6 +154,6 @@ void mapToProfileFailureWhenInvalidProfileResponse() { //when //then assertThatThrownBy(() -> naverAuthorization.mapToProfile(ResponseEntity.ok("NOT_VALID_PROFILE"))) - .isExactlyInstanceOf(MappingFailureException.class); + .isExactlyInstanceOf(MappingFailureException.class); } } diff --git a/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/RegionVaccinationDataFactory.java b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/KoreaVaccinationDataFactory.java similarity index 67% rename from backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/RegionVaccinationDataFactory.java rename to backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/KoreaVaccinationDataFactory.java index 3e159444..c16b13e2 100644 --- a/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/RegionVaccinationDataFactory.java +++ b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/KoreaVaccinationDataFactory.java @@ -2,24 +2,23 @@ import com.cvi.publicdata.domain.model.VaccinationStatistic; import com.cvi.publicdata.domain.model.VaccinationStatistics; - import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -public class RegionVaccinationDataFactory { +public class KoreaVaccinationDataFactory { private final List koreaRegionVaccinationData; - public RegionVaccinationDataFactory(List koreaRegionVaccinationData) { + public KoreaVaccinationDataFactory(List koreaRegionVaccinationData) { this.koreaRegionVaccinationData = new ArrayList<>(koreaRegionVaccinationData); } public VaccinationStatistics toVaccinationStatistics() { List vaccinationStatistics = koreaRegionVaccinationData.stream() - .map(VaccinationStatisticResponse::from) - .map(VaccinationStatisticResponse::toEntity) - .collect(Collectors.toList()); + .map(VaccinationStatisticResponse::from) + .map(VaccinationStatisticResponse::toEntity) + .collect(Collectors.toList()); return new VaccinationStatistics(vaccinationStatistics); } } diff --git a/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/VaccinationStatisticResponse.java b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/VaccinationStatisticResponse.java index faaf5024..5e0deca6 100644 --- a/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/VaccinationStatisticResponse.java +++ b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/VaccinationStatisticResponse.java @@ -26,8 +26,8 @@ public class VaccinationStatisticResponse { private BigDecimal totalSecondRate; public VaccinationStatisticResponse(long accumulatedFirstCnt, long accumulatedSecondCnt, LocalDate baseDate, long firstCnt, - long secondCnt, String sido, long totalFirstCnt, long totalSecondCnt, BigDecimal totalFirstRate, - BigDecimal totalSecondRate) { + long secondCnt, String sido, long totalFirstCnt, long totalSecondCnt, BigDecimal totalFirstRate, + BigDecimal totalSecondRate) { this.accumulatedFirstCnt = accumulatedFirstCnt; this.accumulatedSecondCnt = accumulatedSecondCnt; this.baseDate = baseDate; @@ -42,36 +42,36 @@ public VaccinationStatisticResponse(long accumulatedFirstCnt, long accumulatedSe public static VaccinationStatisticResponse from(KoreaRegionVaccinationData koreaRegionVaccinationData) { return new VaccinationStatisticResponse(koreaRegionVaccinationData.getAccumulatedFirstCnt(), koreaRegionVaccinationData.getAccumulatedSecondCnt(), - DateConverter.convertLocalDateTimeStringToLocalDate(koreaRegionVaccinationData.getBaseDate()), koreaRegionVaccinationData.getFirstCnt(), koreaRegionVaccinationData.getSecondCnt(), - koreaRegionVaccinationData.getSido(), koreaRegionVaccinationData.getTotalFirstCnt(), koreaRegionVaccinationData.getTotalSecondCnt(), - null, null); + DateConverter.convertLocalDateTimeStringToLocalDate(koreaRegionVaccinationData.getBaseDate()), koreaRegionVaccinationData.getFirstCnt(), koreaRegionVaccinationData.getSecondCnt(), + koreaRegionVaccinationData.getSido(), koreaRegionVaccinationData.getTotalFirstCnt(), koreaRegionVaccinationData.getTotalSecondCnt(), + null, null); } public static VaccinationStatisticResponse from(WorldVaccinationData worldVaccinationData) { return new VaccinationStatisticResponse(0L, 0L, DateConverter.toLocalDate(worldVaccinationData.getDate()), 0L, 0L, RegionPopulation.WORLD.getRegion(), - worldVaccinationData.getPeopleVaccinated(), worldVaccinationData.getPeopleFullyVaccinated(), null, null + worldVaccinationData.getPeopleVaccinated(), worldVaccinationData.getPeopleFullyVaccinated(), null, null ); } public static VaccinationStatisticResponse toResponse(VaccinationStatistic vaccinationStatistic) { return new VaccinationStatisticResponse(vaccinationStatistic.getAccumulatedFirstCnt(), vaccinationStatistic.getAccumulatedSecondCnt(), - vaccinationStatistic.getBaseDate(), vaccinationStatistic.getFirstCnt(), vaccinationStatistic.getSecondCnt(), - vaccinationStatistic.getRegionPopulation().getRegion(), vaccinationStatistic.getTotalFirstCnt(), vaccinationStatistic.getTotalSecondCnt(), - vaccinationStatistic.getTotalFirstRate(), vaccinationStatistic.getTotalSecondRate()); + vaccinationStatistic.getBaseDate(), vaccinationStatistic.getFirstCnt(), vaccinationStatistic.getSecondCnt(), + vaccinationStatistic.getRegionPopulation().getRegion(), vaccinationStatistic.getTotalFirstCnt(), vaccinationStatistic.getTotalSecondCnt(), + vaccinationStatistic.getTotalFirstRate(), vaccinationStatistic.getTotalSecondRate()); } public VaccinationStatistic toEntity() { return VaccinationStatistic.builder() - .accumulatedFirstCnt(accumulatedFirstCnt) - .accumulatedSecondCnt(accumulatedSecondCnt) - .baseDate(baseDate) - .firstCnt(firstCnt) - .secondCnt(secondCnt) - .regionPopulation(RegionPopulation.findByRegion(sido)) - .totalFirstCnt(totalFirstCnt) - .totalSecondCnt(totalSecondCnt) - .totalFirstRate(totalFirstRate) - .totalSecondRate(totalSecondRate) - .build(); + .accumulatedFirstCnt(accumulatedFirstCnt) + .accumulatedSecondCnt(accumulatedSecondCnt) + .baseDate(baseDate) + .firstCnt(firstCnt) + .secondCnt(secondCnt) + .regionPopulation(RegionPopulation.findByRegion(sido)) + .totalFirstCnt(totalFirstCnt) + .totalSecondCnt(totalSecondCnt) + .totalFirstRate(totalFirstRate) + .totalSecondRate(totalSecondRate) + .build(); } } diff --git a/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/WorldVaccinationDataFactory.java b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/WorldVaccinationDataFactory.java index 4726645a..274c8d9c 100644 --- a/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/WorldVaccinationDataFactory.java +++ b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/dto/WorldVaccinationDataFactory.java @@ -17,9 +17,9 @@ public WorldVaccinationDataFactory(List worldVaccinationDa public VaccinationStatistics toVaccinationStatistics() { List vaccinationStatistics = worldVaccinationDataGroup.stream() - .map(VaccinationStatisticResponse::from) - .map(VaccinationStatisticResponse::toEntity) - .collect(Collectors.toList()); + .map(VaccinationStatisticResponse::from) + .map(VaccinationStatisticResponse::toEntity) + .collect(Collectors.toList()); return new VaccinationStatistics(vaccinationStatistics); } } diff --git a/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/service/PublicDataService.java b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/service/PublicDataService.java index aa204948..781d440e 100644 --- a/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/service/PublicDataService.java +++ b/backend/domain-cvi-publicdata-service/src/main/java/com/cvi/service/PublicDataService.java @@ -32,14 +32,14 @@ public class PublicDataService { public List saveVaccinationStatistics(LocalDate targetDate) { KoreaVaccineParserResponse koreaVaccineParserResponse = vacinationparser.parseToKoreaPublicData(targetDate, publicDataProperties.getVaccination()); - RegionVaccinationDataFactory regionVaccinationDataFactory = new RegionVaccinationDataFactory(koreaVaccineParserResponse.getData()); - VaccinationStatistics vaccinationStatistics = regionVaccinationDataFactory.toVaccinationStatistics(); + KoreaVaccinationDataFactory koreaVaccinationDataFactory = new KoreaVaccinationDataFactory(koreaVaccineParserResponse.getData()); + VaccinationStatistics vaccinationStatistics = koreaVaccinationDataFactory.toVaccinationStatistics(); List foundByDate = vaccinationStatisticRepository.findByBaseDate(targetDate); List unSavedStatistics = vaccinationStatistics.findUnSavedStatistics(foundByDate, targetDate); return vaccinationStatisticRepository.saveAll(unSavedStatistics) - .stream() - .map(VaccinationStatisticResponse::toResponse) - .collect(Collectors.toList()); + .stream() + .map(VaccinationStatisticResponse::toResponse) + .collect(Collectors.toList()); } @Transactional(readOnly = true) @@ -47,10 +47,10 @@ public List saveVaccinationStatistics(LocalDate ta public List findVaccinationStatistics(LocalDate targetDate) { List foundVaccinationStatistics = vaccinationStatisticRepository.findAll(); VaccinationStatistics vaccinationStatistics = new VaccinationStatistics(foundVaccinationStatistics); - List recentlyStatistics = vaccinationStatistics.findRecentlyStatistics(targetDate); + List recentlyStatistics = vaccinationStatistics.findKoreaRecentlyStatistics(targetDate); return recentlyStatistics.stream() - .map(VaccinationStatisticResponse::toResponse) - .collect(Collectors.toList()); + .map(VaccinationStatisticResponse::toResponse) + .collect(Collectors.toList()); } @Transactional @@ -63,9 +63,9 @@ public List saveWorldVaccinationStatistics(LocalDa List foundByRegionPopulation = vaccinationStatisticRepository.findByRegionPopulation(RegionPopulation.WORLD); List unSavedStatistics = vaccinationStatistics.findUnSavedStatistics(foundByRegionPopulation, targetDate); return vaccinationStatisticRepository.saveAll(unSavedStatistics) - .stream() - .map(VaccinationStatisticResponse::toResponse) - .collect(Collectors.toList()); + .stream() + .map(VaccinationStatisticResponse::toResponse) + .collect(Collectors.toList()); } @Transactional(readOnly = true) @@ -75,7 +75,7 @@ public List findWorldVaccinationStatistics(LocalDa VaccinationStatistics vaccinationStatistics = new VaccinationStatistics(foundVaccinationStatistics); List recentlyStatistics = vaccinationStatistics.findWorldRecentlyStatistics(targetDate); return recentlyStatistics.stream() - .map(VaccinationStatisticResponse::toResponse) - .collect(Collectors.toList()); + .map(VaccinationStatisticResponse::toResponse) + .collect(Collectors.toList()); } } diff --git a/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFacotry.java b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFacotry.java deleted file mode 100644 index 7b365411..00000000 --- a/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFacotry.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.cvi; - -import com.cvi.dto.KoreaRegionVaccinationData; -import com.cvi.dto.KoreaVaccineParserResponse; -import com.cvi.dto.WorldVaccinationData; -import com.cvi.dto.WorldVaccinationParserResponse; -import com.cvi.util.DateConverter; - -import java.time.LocalDate; -import java.util.Arrays; -import java.util.List; - -public class PublicDataFacotry { - public static final List REGIONS = Arrays.asList("전국", "부산광역시", "대구광역시", "대전광역시", "인천광역시", "광주광역시", - "울산광역시", "경기도", "강원도", "세종특별자치시", "충청북도", "충청남도", - "전라북도", "전라남도", "경상북도", "경상남도", "제주특별자치도"); - - public static KoreaVaccineParserResponse toVaccineParserResponse(LocalDate targetDate) { - String expectDateTime = DateConverter.convertDateToContainsZeroTime(targetDate); - return new KoreaVaccineParserResponse(18, Arrays.asList( - new KoreaRegionVaccinationData(19473657, 7146602, expectDateTime, - 473850, 35955, "전국", 19947507, 7182557), - new KoreaRegionVaccinationData(3646765, 1329982, expectDateTime, - 77877, 7123, "서울특별시", 3724642, 1337105), - new KoreaRegionVaccinationData(1352394, 477845, expectDateTime, - 31252, 2628, "부산광역시", 1383646, 480473), - new KoreaRegionVaccinationData(848397, 309317, expectDateTime, - 22726, 2688, "대구광역시", 871123, 312005), - new KoreaRegionVaccinationData(523814, 197608, expectDateTime, - 12990, 959, "대전광역시", 536804, 198567), - new KoreaRegionVaccinationData(1032052, 360923, expectDateTime, - 27394, 1760, "인천광역시", 1059446, 362683), - new KoreaRegionVaccinationData(549706, 204415, expectDateTime, - 13700, 830, "광주광역시", 563406, 205245), - new KoreaRegionVaccinationData(396793, 124839, expectDateTime, - 11275, 471, "울산광역시", 408068, 125310), - new KoreaRegionVaccinationData(4636237, 1636357, expectDateTime, - 118717, 7895, "경기도", 4754954, 1644252), - new KoreaRegionVaccinationData(668422, 273253, expectDateTime, - 14908, 1010, "강원도", 683330, 274263), - new KoreaRegionVaccinationData(109202, 37624, expectDateTime, - 3028, 179, "세종특별자치시", 112230, 37803), - new KoreaRegionVaccinationData(639514, 240704, expectDateTime, - 15886, 1324, "충청북도", 655400, 242028), - new KoreaRegionVaccinationData(849914, 330591, expectDateTime, - 22167, 2054, "충청남도", 872081, 332645), - new KoreaRegionVaccinationData(789017, 311961, expectDateTime, - 17331, 1270, "전라북도", 806348, 313231), - new KoreaRegionVaccinationData(859228, 344275, expectDateTime, - 19083, 1378, "전라남도", 878311, 345653), - new KoreaRegionVaccinationData(1070878, 409752, expectDateTime, - 27263, 2016, "경상북도", 1098141, 411768), - new KoreaRegionVaccinationData(1249910, 464110, expectDateTime, - 31098, 1943, "경상남도", 1281008, 466053), - new KoreaRegionVaccinationData(251414, 93046, expectDateTime, - 7155, 427, "제주특별자치도", 258569, 93473) - ), 18, 1, 20, 2634); - } - - public static WorldVaccinationParserResponse toWorldVaccinationParserResponse(LocalDate targetDate) { - return new WorldVaccinationParserResponse("World", "OWID_WRL", - Arrays.asList(new WorldVaccinationData(targetDate.minusDays(2).toString(), 4327424315L, 2293196690L, 1175939230L, - 43847311L, 42963523L, 55.52, 29.42, 15.09, 5512L), - new WorldVaccinationData(targetDate.minusDays(1).toString(), 4399234109L, 2317353271L, 1181952381L, - 32322341L, 40310055L, 55.93, 29.56, 15.16, 5171L), - new WorldVaccinationData(targetDate.toString(), 4359746656L, 2303769251L, 1191535085L, - 33797364L, 40043557L, 56.44, 29.73, 15.29, 5137L) - ) - ); - } -} diff --git a/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFactory.java b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFactory.java new file mode 100644 index 00000000..a0f32459 --- /dev/null +++ b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/PublicDataFactory.java @@ -0,0 +1,127 @@ +package com.cvi; + +import com.cvi.dto.KoreaRegionVaccinationData; +import com.cvi.dto.KoreaVaccineParserResponse; +import com.cvi.dto.VaccinationStatisticResponse; +import com.cvi.dto.WorldVaccinationData; +import com.cvi.dto.WorldVaccinationParserResponse; +import com.cvi.util.DateConverter; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.Arrays; +import java.util.List; + +public class PublicDataFactory { + public static final List REGIONS = Arrays.asList("전국", "부산광역시", "대구광역시", "대전광역시", "인천광역시", "광주광역시", + "울산광역시", "경기도", "강원도", "세종특별자치시", "충청북도", "충청남도", + "전라북도", "전라남도", "경상북도", "경상남도", "제주특별자치도"); + + public static KoreaVaccineParserResponse toVaccineParserResponse(LocalDate targetDate) { + String expectDateTime = DateConverter.convertDateToContainsZeroTime(targetDate); + return new KoreaVaccineParserResponse(18, Arrays.asList( + new KoreaRegionVaccinationData(19473657, 7146602, expectDateTime, + 473850, 35955, "전국", 19947507, 7182557), + new KoreaRegionVaccinationData(3646765, 1329982, expectDateTime, + 77877, 7123, "서울특별시", 3724642, 1337105), + new KoreaRegionVaccinationData(1352394, 477845, expectDateTime, + 31252, 2628, "부산광역시", 1383646, 480473), + new KoreaRegionVaccinationData(848397, 309317, expectDateTime, + 22726, 2688, "대구광역시", 871123, 312005), + new KoreaRegionVaccinationData(523814, 197608, expectDateTime, + 12990, 959, "대전광역시", 536804, 198567), + new KoreaRegionVaccinationData(1032052, 360923, expectDateTime, + 27394, 1760, "인천광역시", 1059446, 362683), + new KoreaRegionVaccinationData(549706, 204415, expectDateTime, + 13700, 830, "광주광역시", 563406, 205245), + new KoreaRegionVaccinationData(396793, 124839, expectDateTime, + 11275, 471, "울산광역시", 408068, 125310), + new KoreaRegionVaccinationData(4636237, 1636357, expectDateTime, + 118717, 7895, "경기도", 4754954, 1644252), + new KoreaRegionVaccinationData(668422, 273253, expectDateTime, + 14908, 1010, "강원도", 683330, 274263), + new KoreaRegionVaccinationData(109202, 37624, expectDateTime, + 3028, 179, "세종특별자치시", 112230, 37803), + new KoreaRegionVaccinationData(639514, 240704, expectDateTime, + 15886, 1324, "충청북도", 655400, 242028), + new KoreaRegionVaccinationData(849914, 330591, expectDateTime, + 22167, 2054, "충청남도", 872081, 332645), + new KoreaRegionVaccinationData(789017, 311961, expectDateTime, + 17331, 1270, "전라북도", 806348, 313231), + new KoreaRegionVaccinationData(859228, 344275, expectDateTime, + 19083, 1378, "전라남도", 878311, 345653), + new KoreaRegionVaccinationData(1070878, 409752, expectDateTime, + 27263, 2016, "경상북도", 1098141, 411768), + new KoreaRegionVaccinationData(1249910, 464110, expectDateTime, + 31098, 1943, "경상남도", 1281008, 466053), + new KoreaRegionVaccinationData(251414, 93046, expectDateTime, + 7155, 427, "제주특별자치도", 258569, 93473) + ), 18, 1, 20, 2634); + } + + public static List toVaccinationStatisticResponse(LocalDate targetDate) { + return Arrays.asList( + new VaccinationStatisticResponse(19473657, 7146602, targetDate, + 473850, 35955, "전국", 19947507, 7182557, BigDecimal.valueOf(39.2), BigDecimal.valueOf(14.3)), + new VaccinationStatisticResponse(3646765, 1329982, targetDate, + 77877, 7123, "서울특별시", 3724642, 1337105, BigDecimal.valueOf(39.5), BigDecimal.valueOf(14.4)), + new VaccinationStatisticResponse(1352394, 477845, targetDate, + 31252, 2628, "부산광역시", 1383646, 480473, BigDecimal.valueOf(41.8), BigDecimal.valueOf(14.6)), + new VaccinationStatisticResponse(848397, 309317, targetDate, + 22726, 2688, "대구광역시", 871123, 312005, BigDecimal.valueOf(37.0), BigDecimal.valueOf(13.4)), + new VaccinationStatisticResponse(1032052, 360923, targetDate, + 27394, 1760, "인천광역시", 1059446, 362683, BigDecimal.valueOf(39.8), BigDecimal.valueOf(14.7)), + new VaccinationStatisticResponse(549706, 204415, targetDate, + 13700, 830, "광주광역시", 563406, 205245, BigDecimal.valueOf(37.6), BigDecimal.valueOf(14.7)), + new VaccinationStatisticResponse(396793, 124839, targetDate, + 11275, 471, "울산광역시", 408068, 125310, BigDecimal.valueOf(37.6), BigDecimal.valueOf(14.0)), + new VaccinationStatisticResponse(523814, 197608, targetDate, + 12990, 959, "대전광역시", 536804, 198567, BigDecimal.valueOf(36.8), BigDecimal.valueOf(12.7)), + new VaccinationStatisticResponse(4636237, 1636357, targetDate, + 118717, 7895, "경기도", 4754954, 1644252, BigDecimal.valueOf(31.6), BigDecimal.valueOf(10.9)), + new VaccinationStatisticResponse(668422, 273253, targetDate, + 14908, 1010, "강원도", 683330, 274263, BigDecimal.valueOf(36.9), BigDecimal.valueOf(11.5)), + new VaccinationStatisticResponse(109202, 37624, targetDate, + 3028, 179, "세종특별자치시", 112230, 37803, BigDecimal.valueOf(42.7), BigDecimal.valueOf(15.8)), + new VaccinationStatisticResponse(639514, 240704, targetDate, + 15886, 1324, "충청북도", 655400, 242028, BigDecimal.valueOf(42.1), BigDecimal.valueOf(16.1)), + new VaccinationStatisticResponse(849914, 330591, targetDate, + 22167, 2054, "충청남도", 872081, 332645, BigDecimal.valueOf(45.6), BigDecimal.valueOf(17.8)), + new VaccinationStatisticResponse(789017, 311961, targetDate, + 17331, 1270, "전라북도", 806348, 313231, BigDecimal.valueOf(48.4), BigDecimal.valueOf(19.1)), + new VaccinationStatisticResponse(859228, 344275, targetDate, + 19083, 1378, "전라남도", 878311, 345653, BigDecimal.valueOf(42.7), BigDecimal.valueOf(16.0)), + new VaccinationStatisticResponse(1070878, 409752, targetDate, + 27263, 2016, "경상북도", 1098141, 411768, BigDecimal.valueOf(40.4), BigDecimal.valueOf(14.8)), + new VaccinationStatisticResponse(1249910, 464110, targetDate, + 31098, 1943, "경상남도", 1281008, 466053, BigDecimal.valueOf(39.2), BigDecimal.valueOf(14.3)), + new VaccinationStatisticResponse(251414, 93046, targetDate, + 7155, 427, "제주특별자치도", 258569, 93473, BigDecimal.valueOf(42.7), BigDecimal.valueOf(17.8)) + ); + } + + public static WorldVaccinationParserResponse toWorldVaccinationParserResponse(LocalDate targetDate) { + return new WorldVaccinationParserResponse("World", "OWID_WRL", + Arrays.asList(new WorldVaccinationData(targetDate.minusDays(2).toString(), 4327424315L, 2293196690L, 1175939230L, + 43847311L, 42963523L, 55.52, 29.42, 15.09, 5512L), + new WorldVaccinationData(targetDate.minusDays(1).toString(), 4399234109L, 2317353271L, 1181952381L, + 32322341L, 40310055L, 55.93, 29.56, 15.16, 5171L), + new WorldVaccinationData(targetDate.toString(), 4359746656L, 2303769251L, 1191535085L, + 33797364L, 40043557L, 56.44, 29.73, 15.29, 5137L) + ) + ); + } + + public static List toVaccinationStatisticResponseOnlyWorldRegion(LocalDate targetDate) { + return Arrays.asList( + new VaccinationStatisticResponse(0, 0, targetDate, + 0, 0, "World", 2303769251L, 1191535085L, BigDecimal.valueOf(29.3), BigDecimal.valueOf(15.0)), + new VaccinationStatisticResponse(0, 0, targetDate.minusDays(1), + 0, 0, "World", 2293196690L, 1175939230L, BigDecimal.valueOf(28.9), BigDecimal.valueOf(14.7)) + ); + } + + public static VaccinationStatisticResponse toSingleWorldVaccinationStatisticResponse(LocalDate targetDate) { + return new VaccinationStatisticResponse(0, 0, targetDate, + 0, 0, "World", 2303769251L, 1191535085L, BigDecimal.valueOf(29.3), BigDecimal.valueOf(15.0)); + } +} diff --git a/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/service/PublicDataServiceTest.java b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/service/PublicDataServiceTest.java index 12cee3e3..efd68e16 100644 --- a/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/service/PublicDataServiceTest.java +++ b/backend/domain-cvi-publicdata-service/src/test/java/com/cvi/service/PublicDataServiceTest.java @@ -1,12 +1,23 @@ package com.cvi.service; -import com.cvi.PublicDataFacotry; +import static com.cvi.PublicDataFactory.REGIONS; +import static com.cvi.PublicDataFactory.toVaccineParserResponse; +import static com.cvi.PublicDataFactory.toWorldVaccinationParserResponse; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.Mockito.mock; + import com.cvi.dto.VaccinationStatisticResponse; import com.cvi.parser.VaccinationParser; import com.cvi.properties.PublicDataProperties; import com.cvi.publicdata.domain.model.RegionPopulation; import com.cvi.publicdata.domain.model.VaccinationStatistic; import com.cvi.publicdata.domain.repository.VaccinationStatisticRepository; +import java.time.LocalDate; +import java.util.List; +import java.util.stream.Stream; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -14,23 +25,10 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.BDDMockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDate; -import java.util.List; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.BDDMockito.*; -import static org.mockito.BDDMockito.willReturn; -import static org.mockito.Mockito.mock; - @SpringBootTest @DisplayName("공공데이터 요청 서비스 흐름 테스트") @Transactional @@ -47,9 +45,9 @@ class PublicDataServiceTest { public static Stream targetDate() { return Stream.of( - Arguments.of(LocalDate.now()), - Arguments.of(LocalDate.now().minusDays(1)), - Arguments.of(LocalDate.of(2021, 3, 11)) + Arguments.of(LocalDate.now()), + Arguments.of(LocalDate.now().minusDays(1)), + Arguments.of(LocalDate.of(2021, 3, 11)) ); } @@ -73,7 +71,7 @@ void saveVaccinationStatistics(LocalDate targetDate) { List publicData = vaccinationStatisticRepository.findByBaseDate(targetDate); //then assertThat(publicData).extracting(VaccinationStatistic::getBaseDate) - .contains(targetDate); + .contains(targetDate); } @ParameterizedTest(name = "백신 정종률 데이터 조회 - 성공") @@ -86,25 +84,25 @@ void findVaccinationStatistics(LocalDate targetDate) { //then assertThat(vaccinationStatistics).isNotEmpty(); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getAccumulatedFirstCnt) - .isNotEmpty(); + .isNotEmpty(); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getAccumulatedSecondCnt) - .isNotEmpty(); + .isNotEmpty(); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getBaseDate) - .contains(targetDate); + .contains(targetDate); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getSido) - .containsAll(PublicDataFacotry.REGIONS); + .containsAll(REGIONS); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getFirstCnt) - .isNotEmpty(); + .isNotEmpty(); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getSecondCnt) - .isNotEmpty(); + .isNotEmpty(); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getTotalFirstCnt) - .isNotEmpty(); + .isNotEmpty(); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getTotalSecondCnt) - .isNotEmpty(); + .isNotEmpty(); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getTotalSecondCnt) - .isNotEmpty(); + .isNotEmpty(); assertThat(vaccinationStatistics).extracting(VaccinationStatisticResponse::getTotalFirstRate) - .isNotEmpty(); + .isNotEmpty(); } @DisplayName("세계 백신 정좁률 데이터 - 저장 - 성공 ") @@ -115,22 +113,22 @@ void saveWorldVaccinationStatistics() { //when 세계_백신_접종률_저장되어_있음(targetDate); List vaccinationStatistics = - vaccinationStatisticRepository.findByRegionPopulation(RegionPopulation.WORLD); + vaccinationStatisticRepository.findByRegionPopulation(RegionPopulation.WORLD); //then assertThat(vaccinationStatistics).extracting(VaccinationStatistic::getBaseDate) - .contains(targetDate); + .contains(targetDate); assertThat(vaccinationStatistics).extracting(VaccinationStatistic::getRegionPopulation) - .contains(RegionPopulation.WORLD); + .contains(RegionPopulation.WORLD); } private void 백신_접종률_저장되어_있음(LocalDate targetDate) { - willReturn(PublicDataFacotry.toVaccineParserResponse(targetDate)) - .given(vaccinationParser).parseToKoreaPublicData(any(LocalDate.class), anyString()); + willReturn(toVaccineParserResponse(targetDate)) + .given(vaccinationParser).parseToKoreaPublicData(any(LocalDate.class), anyString()); publicDataService.saveVaccinationStatistics(targetDate); } private void 세계_백신_접종률_저장되어_있음(LocalDate targetDate) { - willReturn(PublicDataFacotry.toWorldVaccinationParserResponse(targetDate)).given(vaccinationParser).parseToWorldPublicData(); + willReturn(toWorldVaccinationParserResponse(targetDate)).given(vaccinationParser).parseToWorldPublicData(); publicDataService.saveWorldVaccinationStatistics(targetDate); } } diff --git a/backend/domain-cvi-publicdata-service/src/test/resources/application.yml b/backend/domain-cvi-publicdata-service/src/test/resources/application.yml index 372495fe..1396c529 100644 --- a/backend/domain-cvi-publicdata-service/src/test/resources/application.yml +++ b/backend/domain-cvi-publicdata-service/src/test/resources/application.yml @@ -16,6 +16,9 @@ spring: format_sql: true generate-ddl: true + flyway: + enabled: false + security: public: data: diff --git a/backend/domain-cvi-scheduler/src/main/java/com/cvi/service/PublicDataScheduler.java b/backend/domain-cvi-scheduler/src/main/java/com/cvi/service/PublicDataScheduler.java index cc7c7fa3..9a9998c6 100644 --- a/backend/domain-cvi-scheduler/src/main/java/com/cvi/service/PublicDataScheduler.java +++ b/backend/domain-cvi-scheduler/src/main/java/com/cvi/service/PublicDataScheduler.java @@ -1,14 +1,14 @@ package com.cvi.service; +import java.time.LocalDate; +import java.time.LocalDateTime; +import javax.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Profile; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; -import java.time.LocalDate; - @Slf4j @Component @Profile("!test") @@ -28,16 +28,16 @@ private void initializeVaccinationDate() { @Scheduled(cron = "0 0 10 * * ?") private void scheduleKoreaVaccinationData() { LocalDate today = LocalDate.now(); - log.info("한국 백신접종률 api요청 및 저장 시작:"); + log.info("[스케쥴러] 한국 백신접종률 api요청 및 저장 시작:"); publicDataService.saveVaccinationStatistics(today); - log.info("한국 백신접종률 api요청 완료 및 데이터베이스 저장 완료"); + log.info("[스케쥴러] 한국 백신접종률 api요청 완료 및 데이터베이스 저장 완료"); } @Scheduled(cron = "0 20 05 * * ?") private void scheduleWorldVaccinationData() { - LocalDate today = LocalDate.now(); - log.info("세계 백신접종률 api요청 및 저장 시작:"); - publicDataService.saveWorldVaccinationStatistics(today); - log.info("세계 api요청 완료 및 데이터베이스 저장 완료"); + LocalDateTime today = LocalDateTime.now(); + log.info("[스케쥴러] 세계 백신접종률 api요청 및 저장 시작. 시간: {}", today); + publicDataService.saveWorldVaccinationStatistics(today.toLocalDate()); + log.info("[스케쥴러] 세계 api요청 완료 및 데이터베이스 저장 완료. 시간: {}", today); } } diff --git a/backend/domain-cvi/src/main/resources/db/migration/V20210809__Create_init.sql b/backend/domain-cvi/src/main/resources/db/migration/V20210809__Create_init.sql deleted file mode 100644 index 85fb995d..00000000 --- a/backend/domain-cvi/src/main/resources/db/migration/V20210809__Create_init.sql +++ /dev/null @@ -1,92 +0,0 @@ -drop table if exists comment CASCADE; -drop table if exists likes CASCADE; -drop table if exists post CASCADE; -drop table if exists user CASCADE; -drop table if exists vaccination_statistic; -drop table if exists public_data; - -create table comment -( - comment_id bigint auto_increment not null, - created_at timestamp default CURRENT_TIMESTAMP, - last_modified_at timestamp default CURRENT_TIMESTAMP, - post_id bigint, - user_id bigint, - content text, - primary key (comment_id) -); - -create table likes -( - likes_id bigint auto_increment not null, - created_at timestamp default CURRENT_TIMESTAMP, - last_modified_at timestamp default CURRENT_TIMESTAMP, - post_id bigint, - user_id bigint, - primary key (likes_id) -); - -create table user -( - user_id bigint auto_increment not null, - created_at timestamp default CURRENT_TIMESTAMP, - last_modified_at timestamp default CURRENT_TIMESTAMP, - nickname varchar(255), - age_range varchar(255), - shot_verified boolean not null default false, - social_provider varchar(255), - social_id varchar(255), - profile_url varchar(255), - primary key (user_id), - unique (nickname) -); - -create table post -( - post_id bigint auto_increment not null, - created_at timestamp default CURRENT_TIMESTAMP, - last_modified_at timestamp default CURRENT_TIMESTAMP, - user_id bigint, - content text, - view_count integer not null default 0, - vaccination_type varchar(255), - primary key (post_id) -); - -create table public_data -( - public_data_type varchar(31) not null, - public_data_id bigint auto_increment not null, - created_at timestamp default CURRENT_TIMESTAMP, - last_modified_at timestamp default CURRENT_TIMESTAMP, - region_population varchar(255), - primary key (public_data_id) -); - -create table vaccination_statistic -( - accumulated_first_cnt bigint, - accumulated_second_cnt bigint, - base_date date, - first_cnt bigint, - second_cnt bigint, - total_first_cnt bigint, - total_first_rate decimal(19, 1), - total_second_cnt bigint, - total_second_rate decimal(19, 1), - vaccination_statistic_id bigint not null, - primary key (vaccination_statistic_id) -); - -alter table comment - add constraint fk_comment_post foreign key (post_id) references post (post_id) on delete cascade; -alter table comment - add constraint fk_comment_user foreign key (user_id) references user (user_id) on delete cascade; -alter table likes - add constraint fk_likes_post foreign key (post_id) references post (post_id) on delete cascade; -alter table likes - add constraint fk_likes_user foreign key (user_id) references user (user_id) on delete cascade; -alter table post - add constraint fk_post_user foreign key (user_id) references user (user_id) on delete cascade; -alter table vaccination_statistic - add constraint fk_vaccination_statistic_public_data foreign key (vaccination_statistic_id) references public_data (public_data_id); diff --git a/backend/domain-cvi/src/main/resources/db/migration/V20210810__Column_add.sql b/backend/domain-cvi/src/main/resources/db/migration/V20210810__Column_add.sql new file mode 100644 index 00000000..9541716b --- /dev/null +++ b/backend/domain-cvi/src/main/resources/db/migration/V20210810__Column_add.sql @@ -0,0 +1,43 @@ +drop table if exists vaccination_statistic; +drop table if exists public_data; + +create table public_data +( + public_data_type varchar(31) not null, + public_data_id bigint auto_increment not null, + created_at timestamp default CURRENT_TIMESTAMP, + last_modified_at timestamp default CURRENT_TIMESTAMP, + region_population varchar(255), + primary key (public_data_id) +); + +create table vaccination_statistic +( + accumulated_first_cnt bigint, + accumulated_second_cnt bigint, + base_date date, + first_cnt bigint, + second_cnt bigint, + total_first_cnt bigint, + total_first_rate decimal(19, 1), + total_second_cnt bigint, + total_second_rate decimal(19, 1), + vaccination_statistic_id bigint not null, + primary key (vaccination_statistic_id) +); + +alter table comment + add last_modified_at timestamp default CURRENT_TIMESTAMP; +alter table comment + modify column content text; +alter table likes + add last_modified_at timestamp default CURRENT_TIMESTAMP; +alter table user + add last_modified_at timestamp default CURRENT_TIMESTAMP; +alter table post + add last_modified_at timestamp default CURRENT_TIMESTAMP; +alter table post + modify column content text; + +alter table vaccination_statistic + add constraint fk_vaccination_statistic_public_data foreign key (vaccination_statistic_id) references public_data (public_data_id) on delete cascade on update cascade; diff --git a/backend/domain-cvi/src/main/resources/db/migration/V20210913__Create_image.sql b/backend/domain-cvi/src/main/resources/db/migration/V20210913__Create_image.sql new file mode 100644 index 00000000..d3871650 --- /dev/null +++ b/backend/domain-cvi/src/main/resources/db/migration/V20210913__Create_image.sql @@ -0,0 +1,12 @@ +create table image +( + image_id bigint auto_increment not null, + created_at timestamp default CURRENT_TIMESTAMP, + last_modified_at timestamp default CURRENT_TIMESTAMP, + url varchar(255), + post_id bigint, + primary key (image_id) +); + +alter table image + add constraint fk_image_post foreign key (post_id) references post (post_id) on delete cascade; diff --git a/backend/domain-cvi/src/test/java/com/cvi/image/ImageRepositoryTest.java b/backend/domain-cvi/src/test/java/com/cvi/image/ImageRepositoryTest.java new file mode 100644 index 00000000..2cf663bb --- /dev/null +++ b/backend/domain-cvi/src/test/java/com/cvi/image/ImageRepositoryTest.java @@ -0,0 +1,83 @@ +package com.cvi.image; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.cvi.image.domain.Image; +import com.cvi.image.repository.ImageRepository; +import com.cvi.post.domain.model.Post; +import com.cvi.post.domain.model.VaccinationType; +import com.cvi.post.domain.repository.PostRepository; +import com.cvi.user.domain.model.AgeRange; +import com.cvi.user.domain.model.SocialProvider; +import com.cvi.user.domain.model.User; +import com.cvi.user.domain.repository.UserRepository; +import java.util.Collections; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DisplayName("ImageRepository 테스트") +@DataJpaTest +class ImageRepositoryTest { + + @Autowired + private UserRepository userRepository; + + @Autowired + private PostRepository postRepository; + + @Autowired + private ImageRepository imageRepository; + + private User user1; + private Image image1; + private Post post1; + + @BeforeEach + void setUp() { + user1 = User.builder() + .nickname("인비") + .ageRange(AgeRange.TEENS) + .socialProvider(SocialProvider.KAKAO) + .socialId("1000") + .profileUrl("profile url 1") + .build(); + userRepository.save(user1); + + image1 = Image.builder() + .url("image1_s3_url") + .build(); + imageRepository.save(image1); + + post1 = Post.builder() + .user(user1) + .content("내용 1") + .vaccinationType(VaccinationType.PFIZER) + .build(); + postRepository.save(post1); + } + + @DisplayName("Post에 Image 추가 시 양방향 매핑 테스트") + @Test + void assignImageToPost() { + //given + //when + post1.assignImages(Collections.singletonList(image1)); + //then + assertThat(post1.getImages().getImages().contains(image1)).isTrue(); + assertThat(image1.getPost()).isEqualTo(post1); + } + + @DisplayName("Image에 Post 추가 시 양방향 매핑 테스트") + @Test + void assignPostToImage() { + //given + //when + image1.assignPost(post1); + //then + assertThat(post1.getImages().getImages().contains(image1)).isTrue(); + assertThat(image1.getPost()).isEqualTo(post1); + } +} diff --git a/backend/domain-cvi/src/test/java/com/cvi/image/ImageTest.java b/backend/domain-cvi/src/test/java/com/cvi/image/ImageTest.java new file mode 100644 index 00000000..6481589b --- /dev/null +++ b/backend/domain-cvi/src/test/java/com/cvi/image/ImageTest.java @@ -0,0 +1,31 @@ +package com.cvi.image; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.cvi.image.domain.Image; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("Image 도메인 테스트") +class ImageTest { + + @DisplayName("객체 주소값, 내용이 달라도 id만 같으면 동일한 객체로 본다.") + @Test + void equalsAndHashcode() { + //given + final Image image1 = Image.builder() + .id(1L) + .url("aaaa") + .build(); + final Image image2 = Image.builder() + .id(1L) + .url("bbbb") + .build(); + //when + //then + assertThat(image1) + .isNotSameAs(image2) + .isEqualTo(image2) + .hasSameHashCodeAs(image2); + } +} diff --git a/backend/domain-cvi/src/test/resources/application.yml b/backend/domain-cvi/src/test/resources/application.yml index 3cb8465d..58b27ba3 100644 --- a/backend/domain-cvi/src/test/resources/application.yml +++ b/backend/domain-cvi/src/test/resources/application.yml @@ -20,6 +20,9 @@ spring: format_sql: true generate-ddl: true + flyway: + enabled: false + security: jwt: token: From a35337af6b969fad5dcf1e752a7abf7df91cf0c3 Mon Sep 17 00:00:00 2001 From: jum0 Date: Tue, 28 Sep 2021 17:59:36 +0900 Subject: [PATCH 11/17] =?UTF-8?q?chore:=20build=20=EC=BB=A4=EB=A7=A8?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/front-dev-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/front-dev-deploy.yml b/.github/workflows/front-dev-deploy.yml index 1a3b2e84..6b40c73f 100644 --- a/.github/workflows/front-dev-deploy.yml +++ b/.github/workflows/front-dev-deploy.yml @@ -21,7 +21,7 @@ jobs: run: yarn - name: Build - run: yarn build + run: yarn build:dev - name: S3 Deploy run: aws s3 sync ./dist s3://2021-cvi-dev/ --acl bucket-owner-full-control # s3 이름 2021-cvi-dev From 8b84140a92bb411e4da5354f19f06e34652523ba Mon Sep 17 00:00:00 2001 From: youngbin Date: Wed, 29 Sep 2021 15:11:21 +0900 Subject: [PATCH 12/17] =?UTF-8?q?refactor:=20=EB=A9=80=ED=8B=B0=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=20yml=20=ED=8C=8C=EC=9D=BC=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/cvi/service/EnvSecret.java | 4 ++- .../src/main/resources/application.yml | 13 ++++++++ .../src/main/resources/ehcache.xml | 2 +- backend/build.gradle | 7 +++- backend/deploy/start.sh | 33 +++++++++++-------- .../domain-cvi-aws-s3-service/build.gradle | 2 -- .../application-domain-cvi-aws-s3-service.yml | 12 +++++++ .../application-domain-cvi-publicdata.yml | 10 +++++- .../main/resources/application-domain-cvi.yml | 11 +++++++ 9 files changed, 74 insertions(+), 20 deletions(-) create mode 100644 backend/domain-cvi-aws-s3-service/src/main/resources/application-domain-cvi-aws-s3-service.yml diff --git a/backend/app-cvi-api/src/main/java/com/cvi/service/EnvSecret.java b/backend/app-cvi-api/src/main/java/com/cvi/service/EnvSecret.java index 3943c487..3179b77f 100644 --- a/backend/app-cvi-api/src/main/java/com/cvi/service/EnvSecret.java +++ b/backend/app-cvi-api/src/main/java/com/cvi/service/EnvSecret.java @@ -1,11 +1,12 @@ package com.cvi.service; -import javax.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; +import javax.annotation.PostConstruct; + @Slf4j @Component @RequiredArgsConstructor @@ -17,5 +18,6 @@ public class EnvSecret { public void init() { log.info("naver.client-secret = " + env.getProperty("security.auth.naver.client-secret")); log.info("jwt.secret-key = " + env.getProperty("security.jwt.token.secret-key")); + log.info("inbi.handsome = " + env.getProperty("inbi")); } } diff --git a/backend/app-cvi-api/src/main/resources/application.yml b/backend/app-cvi-api/src/main/resources/application.yml index 4e514610..a19e65f8 100644 --- a/backend/app-cvi-api/src/main/resources/application.yml +++ b/backend/app-cvi-api/src/main/resources/application.yml @@ -4,17 +4,30 @@ spring: - domain-cvi - domain-cvi-oauth - domain-cvi-publicdata + - domain-cvi-aws-s3-service cache: jcache: config: classpath:ehcache.xml + servlet: + multipart: + maxFileSize: 10MB + maxRequestSize: 100MB + security: jwt: token: secret-key: cvi_secret_key expire-length: 3600000 +aws: + s3: + directory: + path: + posts: + images: dir-path + server: shutdown: graceful diff --git a/backend/app-cvi-api/src/main/resources/ehcache.xml b/backend/app-cvi-api/src/main/resources/ehcache.xml index 4536b906..c43a4ca7 100644 --- a/backend/app-cvi-api/src/main/resources/ehcache.xml +++ b/backend/app-cvi-api/src/main/resources/ehcache.xml @@ -9,7 +9,7 @@ - com.backjoongwon.cvi.common.cache.CacheEventLogger + com.cvi.service.CacheEventLogger ASYNCHRONOUS UNORDERED CREATED diff --git a/backend/build.gradle b/backend/build.gradle index 3bff358e..85113de2 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -8,8 +8,13 @@ plugins { id 'application' } +group = 'com.backjoongwon' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '1.8' + + application { - mainClass = 'com.cvi.CentralVaccinationInformationApplication' + mainClassName = 'com.cvi.CentralVaccinationInformationApplication' } subprojects { diff --git a/backend/deploy/start.sh b/backend/deploy/start.sh index e9f08900..1049881b 100644 --- a/backend/deploy/start.sh +++ b/backend/deploy/start.sh @@ -24,18 +24,23 @@ echo "> $JAR_LOCATION 실행" IDLE_PROFILE=$(find_idle_profile) echo "> $JAR_LOCATION 를 profile=$IDLE_PROFILE 로 실행합니다." -if [[ "$1" == prod ]] -then - nohup java -jar \ - -Duser.timezone=Asia/Seoul \ - -Dspring.config.location=classpath:/application.yml,/home/ubuntu/deploy/application-db.yml,/home/ubuntu/deploy/application-jwt.yml,/home/ubuntu/deploy/application-client-secret.yml,/home/ubuntu/deploy/application-publicdata-secret.yml \ - -Dspring.profiles.active=$IDLE_PROFILE,"$1" \ - $JAR_LOCATION > ~/nohup.out 2>&1 & -else - nohup java -jar \ - -Duser.timezone=Asia/Seoul \ - -Dspring.config.location=classpath:/application.yml,/home/ubuntu/deploy/application-jwt.yml,/home/ubuntu/deploy/application-client-secret.yml,/home/ubuntu/deploy/application-publicdata-secret.yml \ - -Dspring.profiles.active=$IDLE_PROFILE,"$1" \ - $JAR_LOCATION > ~/nohup.out 2>&1 & -fi +case $1 in + "dev") + nohup java -jar \ + -Duser.timezone=Asia/Seoul \ + -Dspring.config.location=classpath:/application.yml,/home/ubuntu/deploy/application-db.yml,/home/ubuntu/deploy/application-jwt.yml,/home/ubuntu/deploy/application-auth.yml,/home/ubuntu/deploy/application-publicdata-secret.yml,/home/ubuntu/deploy/application-aws-s3.yml \ + -Dspring.profiles.active=$IDLE_PROFILE,"$1" \ + $JAR_LOCATION > ~/nohup.out 2>&1 & + ;; + "prod") + nohup java -jar \ + -Duser.timezone=Asia/Seoul \ + -Dspring.config.location=classpath:/application.yml,/home/ubuntu/deploy/application-db.yml,/home/ubuntu/deploy/application-jwt.yml,/home/ubuntu/deploy/application-auth.yml,/home/ubuntu/deploy/application-publicdata-secret.yml,/home/ubuntu/deploy/application-aws-s3.yml \ + -Dspring.profiles.active=$IDLE_PROFILE,"$1" \ + $JAR_LOCATION > ~/nohup.out 2>&1 & + ;; + *) + echo "올바르지 않은 배포 환경입니다. 입력된 배포 환경 : $1" + exit 1 +esac diff --git a/backend/domain-cvi-aws-s3-service/build.gradle b/backend/domain-cvi-aws-s3-service/build.gradle index e0da629f..a61d929e 100644 --- a/backend/domain-cvi-aws-s3-service/build.gradle +++ b/backend/domain-cvi-aws-s3-service/build.gradle @@ -3,8 +3,6 @@ jar { enabled = true } dependencies { implementation project(path:':domain-cvi', configuration: 'default') - // implementation 'org.springframework.boot:spring-boot-starter-web' - // aws s3 implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' } diff --git a/backend/domain-cvi-aws-s3-service/src/main/resources/application-domain-cvi-aws-s3-service.yml b/backend/domain-cvi-aws-s3-service/src/main/resources/application-domain-cvi-aws-s3-service.yml new file mode 100644 index 00000000..461607c4 --- /dev/null +++ b/backend/domain-cvi-aws-s3-service/src/main/resources/application-domain-cvi-aws-s3-service.yml @@ -0,0 +1,12 @@ +aws: + s3: + bucket_name: bucket-name + cloudfront: + url: https://cloudfront.net + +cloud: + aws: + region: + static: ap-northeast-2 + stack: + auto: false \ No newline at end of file diff --git a/backend/domain-cvi-publicdata-service/src/main/resources/application-domain-cvi-publicdata.yml b/backend/domain-cvi-publicdata-service/src/main/resources/application-domain-cvi-publicdata.yml index ee19ff04..2b201408 100644 --- a/backend/domain-cvi-publicdata-service/src/main/resources/application-domain-cvi-publicdata.yml +++ b/backend/domain-cvi-publicdata-service/src/main/resources/application-domain-cvi-publicdata.yml @@ -1,4 +1,12 @@ security: public: data: - vaccination: publicdata-secret \ No newline at end of file + vaccination: publicdata-secret + +--- +spring: + config: + activate: + on-profile: local + import: + - file:./cvi-backend-secret/application-publicdata-secret.yml \ No newline at end of file diff --git a/backend/domain-cvi/src/main/resources/application-domain-cvi.yml b/backend/domain-cvi/src/main/resources/application-domain-cvi.yml index 7b360071..7f1fbcf6 100644 --- a/backend/domain-cvi/src/main/resources/application-domain-cvi.yml +++ b/backend/domain-cvi/src/main/resources/application-domain-cvi.yml @@ -11,6 +11,8 @@ spring: logging: level: org.hibernate.SQL: info + +inbi: handsome --- spring: config: @@ -41,3 +43,12 @@ spring: logging: level: org.hibernate.SQL: debug +--- +spring: + config: + activate: + on-profile: dev + +logging: + level: + org.hibernate.SQL: debug From 61d505e12f6a30a705e3ab43ea27e6bd4cdb5d40 Mon Sep 17 00:00:00 2001 From: youngbin Date: Wed, 29 Sep 2021 16:11:38 +0900 Subject: [PATCH 13/17] =?UTF-8?q?refactor:=20=EB=A9=80=ED=8B=B0=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=20yml=20=EC=84=A4=EC=A0=95=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app-cvi-api/src/main/resources/application.yml | 2 ++ backend/build.gradle | 11 ++++------- .../src/main/resources/application-domain-cvi.yml | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/backend/app-cvi-api/src/main/resources/application.yml b/backend/app-cvi-api/src/main/resources/application.yml index a19e65f8..41535ab4 100644 --- a/backend/app-cvi-api/src/main/resources/application.yml +++ b/backend/app-cvi-api/src/main/resources/application.yml @@ -1,5 +1,7 @@ spring: profiles: + active: local + include: - domain-cvi - domain-cvi-oauth diff --git a/backend/build.gradle b/backend/build.gradle index 85113de2..6555c57f 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -8,20 +8,17 @@ plugins { id 'application' } -group = 'com.backjoongwon' -version = '0.0.1-SNAPSHOT' -sourceCompatibility = '1.8' - - application { - mainClassName = 'com.cvi.CentralVaccinationInformationApplication' + mainClass = 'com.cvi.CentralVaccinationInformationApplication' } -subprojects { +allprojects { group = 'com.backjoongwon' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' +} +subprojects { apply plugin: 'java' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' diff --git a/backend/domain-cvi/src/main/resources/application-domain-cvi.yml b/backend/domain-cvi/src/main/resources/application-domain-cvi.yml index 7f1fbcf6..2145c1d8 100644 --- a/backend/domain-cvi/src/main/resources/application-domain-cvi.yml +++ b/backend/domain-cvi/src/main/resources/application-domain-cvi.yml @@ -12,7 +12,6 @@ logging: level: org.hibernate.SQL: info -inbi: handsome --- spring: config: From 06c4c2445c3ca0275edf44dd504cb1eb10f80de4 Mon Sep 17 00:00:00 2001 From: KIM TAE HEE Date: Wed, 29 Sep 2021 16:22:09 +0900 Subject: [PATCH 14/17] =?UTF-8?q?refactor:=20SNAPSHOT=20version=20?= =?UTF-8?q?=EB=AA=85=EC=8B=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app-cvi-api/build.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/app-cvi-api/build.gradle b/backend/app-cvi-api/build.gradle index 324f9608..78e05371 100644 --- a/backend/app-cvi-api/build.gradle +++ b/backend/app-cvi-api/build.gradle @@ -1,5 +1,3 @@ -version = '0.0.1' - dependencies { implementation project(path:':common-cvi', configuration: 'default') implementation project(path:':domain-cvi', configuration: 'default') From ecfcfa4fcf2eaa191e4dda391a7d1d92e02e604f Mon Sep 17 00:00:00 2001 From: KIM TAE HEE Date: Wed, 29 Sep 2021 16:36:19 +0900 Subject: [PATCH 15/17] =?UTF-8?q?fix:=20app-cvi-api=20module=20version=20?= =?UTF-8?q?=EB=AA=85=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app-cvi-api/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/app-cvi-api/build.gradle b/backend/app-cvi-api/build.gradle index 78e05371..56f69e46 100644 --- a/backend/app-cvi-api/build.gradle +++ b/backend/app-cvi-api/build.gradle @@ -1,3 +1,5 @@ +version = '0.0.1-SNAPSHOT' + dependencies { implementation project(path:':common-cvi', configuration: 'default') implementation project(path:':domain-cvi', configuration: 'default') From a0ab32c6fd529f4b51d74c92e6975720230aa1a2 Mon Sep 17 00:00:00 2001 From: KIM TAE HEE Date: Wed, 29 Sep 2021 16:49:57 +0900 Subject: [PATCH 16/17] =?UTF-8?q?fix:=20root=20build.gradle=20allprojects?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/build.gradle | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/backend/build.gradle b/backend/build.gradle index 6555c57f..6e890af5 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -12,11 +12,9 @@ application { mainClass = 'com.cvi.CentralVaccinationInformationApplication' } -allprojects { - group = 'com.backjoongwon' - version = '0.0.1-SNAPSHOT' - sourceCompatibility = '1.8' -} +group = 'com.backjoongwon' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '1.8' subprojects { apply plugin: 'java' @@ -25,6 +23,10 @@ subprojects { apply plugin: 'jacoco' apply plugin: 'org.sonarqube' + group = 'com.backjoongwon' + version = '0.0.1-SNAPSHOT' + sourceCompatibility = '1.8' + dependencies { compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' From 8371b62c3871cc4276b21b2dbedcc3ae5acbad59 Mon Sep 17 00:00:00 2001 From: youngbin Date: Wed, 29 Sep 2021 17:28:20 +0900 Subject: [PATCH 17/17] =?UTF-8?q?refactor:=20Bean=20=EB=93=B1=EB=A1=9D?= =?UTF-8?q?=EC=9A=A9=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...nformationApplication.java => DomainCVITestApplication.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename backend/domain-cvi/src/test/java/com/cvi/{CentralVaccinationInformationApplication.java => DomainCVITestApplication.java} (66%) diff --git a/backend/domain-cvi/src/test/java/com/cvi/CentralVaccinationInformationApplication.java b/backend/domain-cvi/src/test/java/com/cvi/DomainCVITestApplication.java similarity index 66% rename from backend/domain-cvi/src/test/java/com/cvi/CentralVaccinationInformationApplication.java rename to backend/domain-cvi/src/test/java/com/cvi/DomainCVITestApplication.java index c28aa217..2fbebb88 100644 --- a/backend/domain-cvi/src/test/java/com/cvi/CentralVaccinationInformationApplication.java +++ b/backend/domain-cvi/src/test/java/com/cvi/DomainCVITestApplication.java @@ -3,5 +3,5 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class CentralVaccinationInformationApplication { +public class DomainCVITestApplication { }