diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml index c655e89a..85687775 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/server.yml @@ -16,14 +16,12 @@ jobs: AWS_SECRET_KEY: ${{secrets.AWS_SECRET_KEY}} AWS_BUCKET_NAME: ${{secrets.AWS_BUCKET_NAME}} ADMIN_EMAIL: ${{secrets.ADMIN_EMAIL}} - GUEST_EMAIL: ${{secrets.GUEST_EMAIL}} GROWSTORY_EMAIL_USERNAME: ${{secrets.GROWSTORY_EMAIL_USERNAME}} GROWSTORY_EMAIL_PASSWORD: ${{secrets.GROWSTORY_EMAIL_PASSWORD}} G_CLIENT_ID: ${{secrets.G_CLIENT_ID}} G_CLIENT_SECRET: ${{secrets.G_CLIENT_SECRET}} JWT_SECRET_KEY: ${{secrets.JWT_SECRET_KEY}} KEY_STORE_PASSWORD: ${{secrets.KEY_STORE_PASSWORD}} - EVENT_KEY: ${{secrets.EVENT_KEY}} working-directory: ./server steps: @@ -53,14 +51,12 @@ jobs: --build-arg AWS_SECRET_KEY="${{env.AWS_SECRET_KEY}}" \ --build-arg AWS_BUCKET_NAME="${{env.AWS_BUCKET_NAME}}" \ --build-arg ADMIN_EMAIL="${{env.ADMIN_EMAIL}}" \ - --build-arg GUEST_EMAIL="${{env.GUEST_EMAIL}}" \ --build-arg GROWSTORY_EMAIL_USERNAME="${{env.GROWSTORY_EMAIL_USERNAME}}" \ --build-arg GROWSTORY_EMAIL_PASSWORD="${{env.GROWSTORY_EMAIL_PASSWORD}}" \ --build-arg G_CLIENT_ID="${{env.G_CLIENT_ID}}" \ --build-arg G_CLIENT_SECRET="${{env.G_CLIENT_SECRET}}" \ --build-arg JWT_SECRET_KEY="${{env.JWT_SECRET_KEY}}" \ --build-arg KEY_STORE_PASSWORD="${{env.KEY_STORE_PASSWORD}}" \ - --build-arg EVENT_KEY="${{env.EVENT_KEY}}" \ -t growstory-cicd . docker tag growstory-cicd leest/growstory-cicd:${GITHUB_SHA::7} docker push leest/growstory-cicd:${GITHUB_SHA::7} @@ -84,4 +80,4 @@ jobs: sudo docker rm -f server sudo docker pull leest/growstory-cicd:${GITHUB_SHA::7} sudo docker tag leest/growstory-cicd:${GITHUB_SHA::7} growstory-cicd - sudo docker run -d --name server -e TZ=Asia/Seoul -p 443:443 growstory-cicd + sudo docker run -d --name server -e TZ=Asia/Seoul -p 443:443 growstory-cicd \ No newline at end of file diff --git a/server/Dockerfile b/server/Dockerfile index 96503c33..7e1571b5 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -6,7 +6,6 @@ ARG MYSQL_USER \ MYSQL_PASSWORD \ RDS_ENDPOINT \ ADMIN_EMAIL \ - GUEST_EMAIL \ AWS_ACCESS_KEY \ AWS_SECRET_KEY \ AWS_BUCKET_NAME \ @@ -15,15 +14,13 @@ ARG MYSQL_USER \ GROWSTORY_EMAIL_PASSWORD \ GROWSTORY_EMAIL_USERNAME \ JWT_SECRET_KEY \ - KEY_STORE_PASSWORD \ - EVENT_KEY + KEY_STORE_PASSWORD # ⭐ 'ENV' 예약어를 통해 전달받은 값을 실제 값과 매칭시켜야 한다. ENV MYSQL_USER=${MYSQL_USER} \ MYSQL_PASSWORD=${MYSQL_PASSWORD} \ RDS_ENDPOINT=${RDS_ENDPOINT} \ ADMIN_EMAIL=${ADMIN_EMAIL} \ - GUEST_EMAIL=${GUEST_EMAIL} \ AWS_ACCESS_KEY=${AWS_ACCESS_KEY} \ AWS_SECRET_KEY=${AWS_SECRET_KEY} \ AWS_BUCKET_NAME=${AWS_BUCKET_NAME} \ @@ -32,8 +29,7 @@ ENV MYSQL_USER=${MYSQL_USER} \ GROWSTORY_EMAIL_PASSWORD=${GROWSTORY_EMAIL_PASSWORD} \ GROWSTORY_EMAIL_USERNAME=${GROWSTORY_EMAIL_USERNAME} \ JWT_SECRET_KEY=${JWT_SECRET_KEY} \ - KEY_STORE_PASSWORD=${KEY_STORE_PASSWORD} \ - EVENT_KEY=${EVENT_KEY} + KEY_STORE_PASSWORD=${KEY_STORE_PASSWORD} # (2) COPY에서 사용될 경로 변수 ARG JAR_FILE=build/libs/*-SNAPSHOT.jar diff --git a/server/build.gradle b/server/build.gradle index e46d6002..f97425ee 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -62,14 +62,6 @@ dependencies { // spring-security-test 모듈 추가 testImplementation 'org.springframework.security:spring-security-test' - - // websocket - implementation 'org.springframework.boot:spring-boot-starter-websocket' -// implementation 'org.webjars:sockjs-client' -// implementation 'org.webjars:stomp-websocket' - implementation 'org.springframework:spring-messaging' - implementation 'org.springframework.security:spring-security-messaging' - } test { diff --git a/server/server_log b/server/server_log deleted file mode 100644 index bec7e7cb..00000000 --- a/server/server_log +++ /dev/null @@ -1,312 +0,0 @@ -2023-10-15 18:53:26.658 INFO 22224 --- [Test worker] c.g.d.p.c.PlantObjectControllerTest : Starting PlantObjectControllerTest using Java 11.0.18 on DESKTOP-T3EJV1L with PID 22224 (started by LG in C:\Users\LG\Desktop\Main-project\seb45_main_011\seb45_main_011\server) -2023-10-15 18:53:26.730 INFO 22224 --- [Test worker] c.g.d.p.c.PlantObjectControllerTest : The following 1 profile is active: "prod" -2023-10-15 18:53:34.328 INFO 22224 --- [Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. -2023-10-15 18:53:34.973 INFO 22224 --- [Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 578 ms. Found 18 JPA repository interfaces. -2023-10-15 18:53:44.610 WARN 22224 --- [Test worker] com.amazonaws.util.EC2MetadataUtils : Unable to retrieve the requested metadata (/latest/meta-data/instance-id). Failed to connect to service endpoint: - -com.amazonaws.SdkClientException: Failed to connect to service endpoint: - at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:100) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:70) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.internal.InstanceMetadataServiceResourceFetcher.readResource(InstanceMetadataServiceResourceFetcher.java:75) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.internal.EC2ResourceFetcher.readResource(EC2ResourceFetcher.java:66) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.util.EC2MetadataUtils.getItems(EC2MetadataUtils.java:402) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.util.EC2MetadataUtils.getData(EC2MetadataUtils.java:371) ~[aws-java-sdk-core-1.11.792.jar:na] - at org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38) ~[spring-cloud-aws-context-2.2.6.RELEASE.jar:2.2.6.RELEASE] - at org.springframework.cloud.aws.context.annotation.OnAwsCloudEnvironmentCondition.matches(OnAwsCloudEnvironmentCondition.java:38) ~[spring-cloud-aws-context-2.2.6.RELEASE.jar:2.2.6.RELEASE] - at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$TrackedConditionEvaluator.shouldSkip(ConfigurationClassBeanDefinitionReader.java:489) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:140) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:129) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:343) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:748) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.15.jar:2.7.15] - at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.15.jar:2.7.15] - at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.15.jar:2.7.15] - at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:136) ~[spring-boot-test-2.7.15.jar:2.7.15] - at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:141) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:90) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138) ~[spring-test-5.3.29.jar:5.3.29] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$8(ClassBasedTestDescriptor.java:363) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:368) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$9(ClassBasedTestDescriptor.java:363) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[na:na] - at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177) ~[na:na] - at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655) ~[na:na] - at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na] - at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na] - at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312) ~[na:na] - at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) ~[na:na] - at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) ~[na:na] - at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658) ~[na:na] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:362) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:283) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:282) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:272) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at java.base/java.util.Optional.orElseGet(Optional.java:369) ~[na:na] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:271) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:102) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:101) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:66) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) ~[na:na] - at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) ~[na:na] - at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110) ~[na:na] - at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90) ~[na:na] - at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85) ~[na:na] - at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) ~[na:na] - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] - at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] - at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) ~[na:na] - at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) ~[na:na] - at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) ~[na:na] - at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) ~[na:na] - at com.sun.proxy.$Proxy5.stop(Unknown Source) ~[na:na] - at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) ~[na:na] - at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) ~[na:na] - at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) ~[na:na] - at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) ~[na:na] - at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) ~[na:na] - at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113) ~[na:na] - at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65) ~[na:na] - at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) ~[gradle-worker.jar:na] - at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) ~[gradle-worker.jar:na] -Caused by: java.net.SocketTimeoutException: connect timed out - at java.base/java.net.PlainSocketImpl.waitForConnect(Native Method) ~[na:na] - at java.base/java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:107) ~[na:na] - at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412) ~[na:na] - at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255) ~[na:na] - at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237) ~[na:na] - at java.base/java.net.Socket.connect(Socket.java:615) ~[na:na] - at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:177) ~[na:na] - at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:507) ~[na:na] - at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:602) ~[na:na] - at java.base/sun.net.www.http.HttpClient.(HttpClient.java:275) ~[na:na] - at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:374) ~[na:na] - at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:395) ~[na:na] - at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1258) ~[na:na] - at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1237) ~[na:na] - at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1086) ~[na:na] - at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1020) ~[na:na] - at com.amazonaws.internal.ConnectionUtils.connectToEndpoint(ConnectionUtils.java:52) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:80) ~[aws-java-sdk-core-1.11.792.jar:na] - ... 109 common frames omitted - -2023-10-15 18:53:51.096 INFO 22224 --- [Test worker] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] -2023-10-15 18:53:51.431 INFO 22224 --- [Test worker] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.15.Final -2023-10-15 18:53:51.674 INFO 22224 --- [Test worker] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} -2023-10-15 18:53:52.195 INFO 22224 --- [Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... -2023-10-15 18:53:53.832 INFO 22224 --- [Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. -2023-10-15 18:53:53.904 INFO 22224 --- [Test worker] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect -2023-10-15 18:53:54.662 WARN 22224 --- [Test worker] org.hibernate.cfg.AnnotationBinder : HHH000457: Joined inheritance hierarchy [com.growstory.domain.rank.entity.Rank] defined explicit @DiscriminatorColumn. Legacy Hibernate behavior was to ignore the @DiscriminatorColumn. However, as part of issue HHH-6911 we now apply the explicit @DiscriminatorColumn. If you would prefer the legacy behavior, enable the `hibernate.discriminator.ignore_explicit_for_joined` setting (hibernate.discriminator.ignore_explicit_for_joined=true) -2023-10-15 18:53:58.142 INFO 22224 --- [Test worker] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] -2023-10-15 18:53:58.181 INFO 22224 --- [Test worker] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' -2023-10-15 18:54:13.016 INFO 22224 --- [Test worker] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@54c2daa5, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@38a6e207, org.springframework.security.web.context.SecurityContextPersistenceFilter@af1e856, org.springframework.security.web.header.HeaderWriterFilter@4d05f9b7, org.springframework.web.filter.CorsFilter@ac2dde2, org.springframework.security.web.authentication.logout.LogoutFilter@ba1678f, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@573bb6d7, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@4d6a7d58, com.growstory.global.auth.filter.JwtVerificationFilter@4d2b73c5, com.growstory.global.auth.filter.JwtAuthenticationFilter@5fa8c4b8, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5be71883, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@35d20a03, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1dfd2a1a, org.springframework.security.web.session.SessionManagementFilter@4c82fd27, org.springframework.security.web.access.ExceptionTranslationFilter@4784ce56, org.springframework.security.web.access.intercept.AuthorizationFilter@160d925f] -2023-10-15 18:54:14.710 WARN 22224 --- [Test worker] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning -2023-10-15 18:54:21.049 INFO 22224 --- [Test worker] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring TestDispatcherServlet '' -2023-10-15 18:54:21.051 INFO 22224 --- [Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet '' -2023-10-15 18:54:21.057 INFO 22224 --- [Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 4 ms -2023-10-15 18:54:21.523 INFO 22224 --- [Test worker] c.g.d.p.c.PlantObjectControllerTest : Started PlantObjectControllerTest in 56.732 seconds (JVM running for 64.9) -2023-10-15 18:54:23.780 INFO 22224 --- [SpringApplicationShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' -2023-10-15 18:54:23.788 INFO 22224 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... -2023-10-15 18:54:23.822 INFO 22224 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. -2023-10-15 19:04:43.265 INFO 25028 --- [Test worker] c.g.d.p.c.PlantObjectControllerTest : Starting PlantObjectControllerTest using Java 11.0.18 on DESKTOP-T3EJV1L with PID 25028 (started by LG in C:\Users\LG\Desktop\Main-project\seb45_main_011\seb45_main_011\server) -2023-10-15 19:04:43.278 INFO 25028 --- [Test worker] c.g.d.p.c.PlantObjectControllerTest : The following 1 profile is active: "prod" -2023-10-15 19:04:52.334 INFO 25028 --- [Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. -2023-10-15 19:04:53.537 INFO 25028 --- [Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 1162 ms. Found 18 JPA repository interfaces. -2023-10-15 19:05:04.202 WARN 25028 --- [Test worker] com.amazonaws.util.EC2MetadataUtils : Unable to retrieve the requested metadata (/latest/meta-data/instance-id). Failed to connect to service endpoint: - -com.amazonaws.SdkClientException: Failed to connect to service endpoint: - at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:100) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:70) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.internal.InstanceMetadataServiceResourceFetcher.readResource(InstanceMetadataServiceResourceFetcher.java:75) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.internal.EC2ResourceFetcher.readResource(EC2ResourceFetcher.java:66) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.util.EC2MetadataUtils.getItems(EC2MetadataUtils.java:402) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.util.EC2MetadataUtils.getData(EC2MetadataUtils.java:371) ~[aws-java-sdk-core-1.11.792.jar:na] - at org.springframework.cloud.aws.context.support.env.AwsCloudEnvironmentCheckUtils.isRunningOnCloudEnvironment(AwsCloudEnvironmentCheckUtils.java:38) ~[spring-cloud-aws-context-2.2.6.RELEASE.jar:2.2.6.RELEASE] - at org.springframework.cloud.aws.context.annotation.OnAwsCloudEnvironmentCondition.matches(OnAwsCloudEnvironmentCondition.java:38) ~[spring-cloud-aws-context-2.2.6.RELEASE.jar:2.2.6.RELEASE] - at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$TrackedConditionEvaluator.shouldSkip(ConfigurationClassBeanDefinitionReader.java:489) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:140) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:129) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:343) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:748) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.29.jar:5.3.29] - at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) ~[spring-boot-2.7.15.jar:2.7.15] - at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.15.jar:2.7.15] - at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) ~[spring-boot-2.7.15.jar:2.7.15] - at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:136) ~[spring-boot-test-2.7.15.jar:2.7.15] - at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:141) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:90) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248) ~[spring-test-5.3.29.jar:5.3.29] - at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138) ~[spring-test-5.3.29.jar:5.3.29] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$8(ClassBasedTestDescriptor.java:363) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:368) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$9(ClassBasedTestDescriptor.java:363) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[na:na] - at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177) ~[na:na] - at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655) ~[na:na] - at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na] - at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na] - at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312) ~[na:na] - at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) ~[na:na] - at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) ~[na:na] - at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658) ~[na:na] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:362) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:283) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:282) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:272) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at java.base/java.util.Optional.orElseGet(Optional.java:369) ~[na:na] - at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:271) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:102) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:101) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:66) ~[junit-jupiter-engine-5.8.2.jar:5.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) ~[na:na] - at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) ~[na:na] - at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) ~[junit-platform-engine-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) ~[junit-platform-launcher-1.8.2.jar:1.8.2] - at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110) ~[na:na] - at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90) ~[na:na] - at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85) ~[na:na] - at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) ~[na:na] - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] - at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] - at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] - at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] - at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) ~[na:na] - at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) ~[na:na] - at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) ~[na:na] - at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) ~[na:na] - at com.sun.proxy.$Proxy5.stop(Unknown Source) ~[na:na] - at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) ~[na:na] - at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) ~[na:na] - at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) ~[na:na] - at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) ~[na:na] - at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) ~[na:na] - at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113) ~[na:na] - at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65) ~[na:na] - at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) ~[gradle-worker.jar:na] - at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) ~[gradle-worker.jar:na] -Caused by: java.net.SocketTimeoutException: connect timed out - at java.base/java.net.PlainSocketImpl.waitForConnect(Native Method) ~[na:na] - at java.base/java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:107) ~[na:na] - at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:412) ~[na:na] - at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:255) ~[na:na] - at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:237) ~[na:na] - at java.base/java.net.Socket.connect(Socket.java:615) ~[na:na] - at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:177) ~[na:na] - at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:507) ~[na:na] - at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:602) ~[na:na] - at java.base/sun.net.www.http.HttpClient.(HttpClient.java:275) ~[na:na] - at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:374) ~[na:na] - at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:395) ~[na:na] - at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1258) ~[na:na] - at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1237) ~[na:na] - at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1086) ~[na:na] - at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1020) ~[na:na] - at com.amazonaws.internal.ConnectionUtils.connectToEndpoint(ConnectionUtils.java:52) ~[aws-java-sdk-core-1.11.792.jar:na] - at com.amazonaws.internal.EC2ResourceFetcher.doReadResource(EC2ResourceFetcher.java:80) ~[aws-java-sdk-core-1.11.792.jar:na] - ... 109 common frames omitted - -2023-10-15 19:05:10.086 INFO 25028 --- [Test worker] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] -2023-10-15 19:05:10.393 INFO 25028 --- [Test worker] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.15.Final -2023-10-15 19:05:10.540 INFO 25028 --- [Test worker] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final} -2023-10-15 19:05:11.060 INFO 25028 --- [Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... -2023-10-15 19:05:11.908 INFO 25028 --- [Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. -2023-10-15 19:05:11.964 INFO 25028 --- [Test worker] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect -2023-10-15 19:05:12.803 WARN 25028 --- [Test worker] org.hibernate.cfg.AnnotationBinder : HHH000457: Joined inheritance hierarchy [com.growstory.domain.rank.entity.Rank] defined explicit @DiscriminatorColumn. Legacy Hibernate behavior was to ignore the @DiscriminatorColumn. However, as part of issue HHH-6911 we now apply the explicit @DiscriminatorColumn. If you would prefer the legacy behavior, enable the `hibernate.discriminator.ignore_explicit_for_joined` setting (hibernate.discriminator.ignore_explicit_for_joined=true) -2023-10-15 19:05:16.390 INFO 25028 --- [Test worker] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] -2023-10-15 19:05:16.417 INFO 25028 --- [Test worker] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' -2023-10-15 19:05:25.460 INFO 25028 --- [Test worker] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@56a658d0, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@541b5225, org.springframework.security.web.context.SecurityContextPersistenceFilter@71f6eb10, org.springframework.security.web.header.HeaderWriterFilter@4ab52b06, org.springframework.web.filter.CorsFilter@68aa0a5f, org.springframework.security.web.authentication.logout.LogoutFilter@548f1320, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@3f5ca1a1, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@530fa6c8, com.growstory.global.auth.filter.JwtVerificationFilter@67334787, com.growstory.global.auth.filter.JwtAuthenticationFilter@2e3a6d7f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5b93d8c7, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@4e81d32e, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@4abec0b0, org.springframework.security.web.session.SessionManagementFilter@2ed099fd, org.springframework.security.web.access.ExceptionTranslationFilter@5f5a8308, org.springframework.security.web.access.intercept.AuthorizationFilter@2a166e62] -2023-10-15 19:05:27.291 WARN 25028 --- [Test worker] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning -2023-10-15 19:05:33.460 INFO 25028 --- [Test worker] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring TestDispatcherServlet '' -2023-10-15 19:05:33.461 INFO 25028 --- [Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet '' -2023-10-15 19:05:33.466 INFO 25028 --- [Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 4 ms -2023-10-15 19:05:33.940 INFO 25028 --- [Test worker] c.g.d.p.c.PlantObjectControllerTest : Started PlantObjectControllerTest in 54.001 seconds (JVM running for 62.547) -2023-10-15 19:05:36.027 INFO 25028 --- [SpringApplicationShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' -2023-10-15 19:05:36.034 INFO 25028 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... -2023-10-15 19:05:36.071 INFO 25028 --- [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. diff --git a/server/server_log.2023-10-04.0.gz b/server/server_log.2023-10-04.0.gz deleted file mode 100644 index 8ecd26cf..00000000 Binary files a/server/server_log.2023-10-04.0.gz and /dev/null differ diff --git a/server/src/main/java/com/growstory/GrowstoryApplication.java b/server/src/main/java/com/growstory/GrowstoryApplication.java index 10b728f4..8047882b 100644 --- a/server/src/main/java/com/growstory/GrowstoryApplication.java +++ b/server/src/main/java/com/growstory/GrowstoryApplication.java @@ -2,7 +2,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; @@ -10,12 +9,7 @@ @EnableScheduling @EnableJpaAuditing @EnableAsync -@EnableAspectJAutoProxy -@SpringBootApplication(exclude = { - org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration.class, - org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration.class, - org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration.class -}) +@SpringBootApplication public class GrowstoryApplication { public static void main(String[] args) { diff --git a/server/src/main/java/com/growstory/domain/account/constants/AccountGrade.java b/server/src/main/java/com/growstory/domain/account/constants/AccountGrade.java deleted file mode 100644 index f312e33a..00000000 --- a/server/src/main/java/com/growstory/domain/account/constants/AccountGrade.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.growstory.domain.account.constants; - -import lombok.Getter; - -// 식물카드개수에 의한 등급 제도 -// 50개 미만 - 브론즈 가드너 -// 50개 이상 - 실버 가드너 -// 100개 이상 - 골드 가드너 -public enum AccountGrade { - GRADE_BRONZE(1, "브론즈 가드너"), - GRADE_SILVER(2, "실버 가드너"), - GRADE_GOLD(3, "골드 가드너"); - - @Getter - private int stepNumber; - - @Getter - private String stepDescription; - - AccountGrade(int stepNumber, String stepDescription) { - this.stepNumber = stepNumber; - this.stepDescription = stepDescription; - } -} diff --git a/server/src/main/java/com/growstory/domain/account/constants/Status.java b/server/src/main/java/com/growstory/domain/account/constants/Status.java deleted file mode 100644 index a038a398..00000000 --- a/server/src/main/java/com/growstory/domain/account/constants/Status.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.growstory.domain.account.constants; - -import lombok.Getter; - -public enum Status { - ADMIN(1, "ADMIN"), - USER(2, "USER"), - SOCIAL_USER(3, "SOCIAL_USER"), - BANNED_USER(4, "BANNED_USER"), - GUEST_USER(5, "GUEST_USER"); - - @Getter - private int stepNumber; - - @Getter - private String stepDescription; - - Status(int stepNumber, String stepDescription) { - this.stepNumber = stepNumber; - this.stepDescription = stepDescription; - } -} diff --git a/server/src/main/java/com/growstory/domain/account/controller/AccountController.java b/server/src/main/java/com/growstory/domain/account/controller/AccountController.java index 6f095dad..da77b177 100644 --- a/server/src/main/java/com/growstory/domain/account/controller/AccountController.java +++ b/server/src/main/java/com/growstory/domain/account/controller/AccountController.java @@ -7,10 +7,10 @@ import com.growstory.global.response.SingleResponseDto; import com.growstory.global.utils.UriCreator; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -36,26 +36,12 @@ public class AccountController { @Operation(summary = "회원가입", description = "사용자 정보를 입력받아 계정 생성") @PostMapping("/signup") public ResponseEntity postAccount(@Valid @RequestBody AccountDto.Post accountPostDto) { - AccountDto.Response responseDto = accountService.createAccount(accountPostDto); - URI location = UriCreator.createUri(ACCOUNT_DEFAULT_URL, responseDto.getAccountId()); - + AccountDto.Response accountResponseDto = accountService.createAccount(accountPostDto); + URI location = UriCreator.createUri(ACCOUNT_DEFAULT_URL, accountResponseDto.getAccountId()); return ResponseEntity.created(location).build(); } - @Operation(summary = "회원가입", description = "게스트 계정 생성") - @PostMapping("/guest") - public ResponseEntity postAccount() { - List token = accountService.createAccount(); - URI location = UriCreator.createUri(ACCOUNT_DEFAULT_URL, Long.parseLong(token.get(2))); - - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", token.get(0)); - headers.add("Refresh", token.get(1)); - - return ResponseEntity.created(location).headers(headers).build(); - } - @Operation(summary = "프로필 사진 수정", description = "입력받은 프로필 사진으로 정보 수정") @PatchMapping(value = "/profileimage", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity patchProfileImage(@RequestPart MultipartFile profileImage) { @@ -170,12 +156,4 @@ public ResponseEntity deleteAccount() { return ResponseEntity.noContent().build(); } - - @Operation(summary = "게스트 회원 탈퇴", description = "게스트 사용자 계정 삭제") - @DeleteMapping("/guest/{account-id}") - public ResponseEntity deleteAccount(@Positive @PathVariable("account-id") Long accountId){ - accountService.deleteAccount(accountId); - - return ResponseEntity.noContent().build(); - } } diff --git a/server/src/main/java/com/growstory/domain/account/dto/AccountDto.java b/server/src/main/java/com/growstory/domain/account/dto/AccountDto.java index 741e2570..6b715fd7 100644 --- a/server/src/main/java/com/growstory/domain/account/dto/AccountDto.java +++ b/server/src/main/java/com/growstory/domain/account/dto/AccountDto.java @@ -1,7 +1,6 @@ package com.growstory.domain.account.dto; import com.growstory.domain.point.entity.Point; -import com.growstory.global.badwords.dto.TextContainer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -17,7 +16,7 @@ public class AccountDto { @Getter @Builder @Schema(name = "AccountPostDto") - public static class Post implements TextContainer { + public static class Post { @NotBlank private String displayName; @@ -28,17 +27,11 @@ public static class Post implements TextContainer { @NotBlank @Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d).{6,}$" , message = "영문, 숫자 포함 6글자 이상의 패스워드만 허용합니다.") private String password; - - @Override - public String combineText() { - return displayName; - } } - @Getter @NoArgsConstructor - public static class DisplayNamePatch implements TextContainer { + public static class DisplayNamePatch { @NotBlank private String displayName; @@ -46,11 +39,6 @@ public static class DisplayNamePatch implements TextContainer { public DisplayNamePatch(String displayName) { this.displayName = displayName; } - - @Override - public String combineText() { - return this.displayName; - } } @Getter @@ -82,7 +70,6 @@ public static class Response { private Long accountId; private String email; private String displayName; - private String status; private String profileImageUrl; private String grade; private Point point; diff --git a/server/src/main/java/com/growstory/domain/account/entity/Account.java b/server/src/main/java/com/growstory/domain/account/entity/Account.java index 1f0f03ca..5e342dca 100644 --- a/server/src/main/java/com/growstory/domain/account/entity/Account.java +++ b/server/src/main/java/com/growstory/domain/account/entity/Account.java @@ -2,25 +2,15 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonManagedReference; -import com.growstory.domain.account.constants.AccountGrade; -import com.growstory.domain.account.constants.Status; -import com.growstory.domain.alarm.entity.Alarm; import com.growstory.domain.board.entity.Board; import com.growstory.domain.comment.entity.Comment; -import com.growstory.domain.guestbook.entity.GuestBook; import com.growstory.domain.leaf.entity.Leaf; import com.growstory.domain.likes.entity.AccountLike; import com.growstory.domain.likes.entity.BoardLike; import com.growstory.domain.plant_object.entity.PlantObj; import com.growstory.domain.point.entity.Point; -import com.growstory.domain.qnachat.chatmessage.entity.ChatMessage; -import com.growstory.domain.qnachat.chatroom.entity.AccountChatRoom; -import com.growstory.domain.report.entity.Report; import com.growstory.global.audit.BaseTimeEntity; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import lombok.*; import javax.persistence.*; import java.util.ArrayList; @@ -33,10 +23,9 @@ public class Account extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "ACCOUNT_ID") private Long accountId; - @Column(name = "EMAIL", unique = true, nullable = false, length = 100) + @Column(name = "EMAIL", unique = true, nullable = false, length = 50) private String email; @Column(name = "DISPLAY_NAME", nullable = false, length = 50) @@ -48,15 +37,10 @@ public class Account extends BaseTimeEntity { @Column(name = "PROFILE_IMAGE_URL") private String profileImageUrl; - // 신고 받은 횟수 - private int reportNums = 0; - @OneToMany(mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true) @JsonManagedReference private List boards = new ArrayList<>(); - // cascade = 부모를 db에서 delete하면 자식도 지워진다. - // orphan = 부모를 db에서 delete하면 자식도 지워진다. @OneToMany(mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true) private List leaves = new ArrayList<>(); @@ -83,41 +67,31 @@ public class Account extends BaseTimeEntity { @OneToMany(mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true) private List plantObjs; - @OneToMany(mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true) - private List alarms = new ArrayList<>(); - - @OneToMany(mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true) - private List accountChatRooms = new ArrayList<>(); - - @OneToMany(mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true) - private List chatMessages = new ArrayList<>(); - - // 자신이 신고한 목록 - @OneToMany(mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true) - private List reports = new ArrayList<>(); - - // 방명록을 받은 계정 리스트 - @OneToMany(mappedBy = "receiver", cascade = CascadeType.ALL, orphanRemoval = true) - private List receivedGuestBooks = new ArrayList<>(); - - // 방명록을 작성한 계정 리스트 - @OneToMany(mappedBy = "author", cascade = CascadeType.ALL, orphanRemoval = true) - private List writerGuestBooks = new ArrayList<>(); - @ElementCollection(fetch = FetchType.EAGER) private List roles = new ArrayList<>(); @Enumerated(EnumType.STRING) private AccountGrade accountGrade = AccountGrade.GRADE_BRONZE; - @Enumerated(EnumType.STRING) - private Status status = Status.USER; +// 식물카드개수에 의한 등급 제도 +// 50개 미만 - 브론즈 가드너 +// 50개 이상 - 실버 가드너 +// 100개 이상 - 골드 가드너 + public enum AccountGrade { + GRADE_BRONZE(1, "브론즈 가드너"), + GRADE_SILVER(2, "실버 가드너"), + GRADE_GOLD(3, "골드 가드너"); - // 출석 체크 - private Boolean attendance = false; + @Getter + private int stepNumber; - public void updateDisplayName(String displayName) { - this.displayName = displayName; + @Getter + private String stepDescription; + + AccountGrade(int stepNumber, String stepDescription) { + this.stepNumber = stepNumber; + this.stepDescription = stepDescription; + } } public void addLeaf(Leaf leaf) { @@ -132,10 +106,6 @@ public void addReceivingAccountLike(AccountLike accountLike) { receivingAccountLikes.add(accountLike); } - public void addAlarm(Alarm alarm) { - alarms.add(0, alarm); - } - public void updateGrade(AccountGrade accountGrade) { this.accountGrade = accountGrade; } @@ -146,10 +116,6 @@ public void updatePoint(Point point) { point.updateAccount(this); } - public void updateAttendance(Boolean attendance) { - this.attendance = attendance; - } - public void addBoardLike(BoardLike boardLike) { boardLikes.add(boardLike); } @@ -161,14 +127,6 @@ public void addPlantObj(PlantObj plantObj) { } } - public void addReport(Report report) { - reports.add(report); - } - - public void updateReportsNum() { - reportNums += 1; - } - public void removePlantObj(PlantObj plantObj) { this.plantObjs.remove(plantObj); } @@ -186,7 +144,7 @@ public Account(Long accountId, String email, String displayName, String password public Account(Long accountId, String email, String displayName, String password, String profileImageUrl, List boards, List leaves, List givingAccountLikes, List receivingAccountLikes, List boardLikes, List comments, - Point point, List plantObjs, List roles, AccountGrade accountGrade, Status status, int reportNums) { + Point point, List plantObjs, List roles, AccountGrade accountGrade) { this.accountId = accountId; this.email = email; this.displayName = displayName; @@ -202,7 +160,5 @@ public Account(Long accountId, String email, String displayName, String password this.plantObjs = plantObjs; this.roles = roles; this.accountGrade = accountGrade; - this.status = status; - this.reportNums = reportNums; } -} \ No newline at end of file +} diff --git a/server/src/main/java/com/growstory/domain/account/service/AccountService.java b/server/src/main/java/com/growstory/domain/account/service/AccountService.java index 73c1e8c1..68008fa8 100644 --- a/server/src/main/java/com/growstory/domain/account/service/AccountService.java +++ b/server/src/main/java/com/growstory/domain/account/service/AccountService.java @@ -1,33 +1,21 @@ package com.growstory.domain.account.service; -import com.growstory.domain.account.constants.AccountGrade; -import com.growstory.domain.account.constants.Status; import com.growstory.domain.account.dto.AccountDto; import com.growstory.domain.account.entity.Account; import com.growstory.domain.account.repository.AccountRepository; -import com.growstory.domain.alarm.constants.AlarmType; -import com.growstory.domain.alarm.service.AlarmService; import com.growstory.domain.board.entity.Board; -import com.growstory.domain.guest.service.GuestService; import com.growstory.domain.images.entity.BoardImage; -import com.growstory.domain.leaf.entity.Leaf; -import com.growstory.domain.plant_object.dto.PlantObjDto; import com.growstory.domain.point.entity.Point; import com.growstory.domain.point.service.PointService; -import com.growstory.global.auth.jwt.JwtTokenizer; import com.growstory.global.auth.utils.AuthUserUtils; import com.growstory.global.auth.utils.CustomAuthorityUtils; import com.growstory.global.aws.service.S3Uploader; -import com.growstory.global.email.service.EmailService; import com.growstory.global.exception.BusinessLogicException; import com.growstory.global.exception.ExceptionCode; -import com.growstory.global.sse.service.SseService; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -36,10 +24,11 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; -@Slf4j @Transactional @Service @RequiredArgsConstructor @@ -52,145 +41,30 @@ public class AccountService { private final PointService pointService; private final S3Uploader s3Uploader; private final AuthUserUtils authUserUtils; - private final SseService sseService; - private final AlarmService alarmService; - private final EmailService emailService; - // Guest - private final GuestService guestService; - private final JwtTokenizer jwtTokenizer; + public AccountDto.Response createAccount(AccountDto.Post accountPostDto) { + verifyExistsEmail(accountPostDto.getEmail()); - public AccountDto.Response createAccount(AccountDto.Post requestDto) { - if (verifyExistsEmail(requestDto.getEmail())) { - throw new BusinessLogicException(ExceptionCode.ACCOUNT_ALREADY_EXISTS); - } - - Status status = Status.USER; - String encryptedPassword = passwordEncoder.encode(requestDto.getPassword()); - List roles = authorityUtils.createRoles(requestDto.getEmail()); - Point point = pointService.createPoint(requestDto.getEmail()); - - //TODO: if admin@gmail.com 일때 status.admin 추가 - if (requestDto.getEmail().equals("admin@gmail.com")) status = Status.ADMIN; + String encryptedPassword = passwordEncoder.encode(accountPostDto.getPassword()); + List roles = authorityUtils.createRoles(accountPostDto.getEmail()); + Point point = pointService.createPoint(accountPostDto.getEmail()); Account savedAccount = accountRepository.save(Account.builder() - .displayName(requestDto.getDisplayName()) - .email(requestDto.getEmail()) + .displayName(accountPostDto.getDisplayName()) + .email(accountPostDto.getEmail()) .password(encryptedPassword) .point(point) .roles(roles) - .status(status) - .accountGrade(AccountGrade.GRADE_BRONZE) - .reportNums(0) + .accountGrade(Account.AccountGrade.GRADE_BRONZE) .build()); point.updateAccount(savedAccount); - alarmService.createAlarm(savedAccount.getAccountId(), AlarmType.SIGN_UP); return AccountDto.Response.builder() .accountId(savedAccount.getAccountId()) .build(); } - public List createAccount() { - Status status = Status.GUEST_USER; - List roles = authorityUtils.createRoles(" "); - Point point = pointService.createPoint("guest"); - String encryptedPassword = passwordEncoder.encode("gs123!@#"); - - - // Save Account - Account savedAccount = accountRepository.save(Account.builder() - // Guest Email: guest+8자리 난수@gmail.com - .email("guest" + emailService.getAuthCode() + "@gmail.com") - .password(encryptedPassword) - // DisplayName: Guest + 8자리 난수 - .displayName("Guest" + emailService.getAuthCode()) - .leaves(new ArrayList<>()) - .plantObjs(new ArrayList<>()) - .point(point) - .roles(roles) - .status(status) - .accountGrade(AccountGrade.GRADE_BRONZE) - .reportNums(0) - .build()); - - // Update Point - point.updateAccount(savedAccount); - - // 식물 카드 - Leaf leafA = guestService.createGuestLeaf(savedAccount, "귀염둥이 니드몬","사막에서 공수한 선인장입니다.", "https://growstory.s3.ap-northeast-2.amazonaws.com/image/guest/leaves/cactus-1842095_1280.jpg"); - Leaf leafB = guestService.createGuestLeaf(savedAccount, "가시나","예쁜 선인장이에요!! ", "https://growstory.s3.ap-northeast-2.amazonaws.com/image/guest/leaves/cactus-5434469_1280.jpg"); - - // 일지 각각의 image S3에 업로드 후 imageUrl 반환 - guestService.createGuestJournal(leafA, "니드몬 성장 일기 1일차", "물 주기", null); - guestService.createGuestJournal(leafA, "니드몬 성장 일기 2일차", "칭찬해 주기", null); - guestService.createGuestJournal(leafA, "니드몬 성장 일기 3일차", "햇빛 쫴기", null); - guestService.createGuestJournal(leafA, "니드몬 성장 일기 4일차", "반려 식물 병원 가는 날", null); - guestService.createGuestJournal(leafA, "니드몬 성장 일기 5일차", "물 주기", null); - guestService.createGuestJournal(leafA, "니드몬 성장 일기 6일차", "영양 거름 주기", null); - guestService.createGuestJournal(leafA, "니드몬 성장 일기 7일차", "분갈이", null); - guestService.createGuestJournal(leafA, "니드몬 성장 일기 8일차", "물 주기", null); - guestService.createGuestJournal(leafA, "니드몬 성장 일기 9일차", "칭찬해 주기", null); - guestService.createGuestJournal(leafA, "니드몬 성장 일기 10일차", "물 주기", null); - - // Buy Garden Object - PlantObjDto.TradeResponse plantObjA = guestService.buyProduct(savedAccount, 1L); // 벽돌 유적 - guestService.buyProduct(savedAccount, 2L); // 콜로세움 - guestService.buyProduct(savedAccount, 3L); // 잊혀진 연구소 - guestService.buyProduct(savedAccount, 4L); // 대리석 신전 - PlantObjDto.TradeResponse plantObjB = guestService.buyProduct(savedAccount, 5L); // 벚나무 - - - // Batch Garden Object - // 벽돌 유적(2x2): (6, 5) - // 벚나무(1x1): (3, 3) - guestService.saveLocation(plantObjA.getPlantObj(), plantObjB.getPlantObj()); - - - - // Connect Garden Object and Plants Card - // 식물 카드 A와 벽돌 유적 오브젝트 연결 - guestService.updateLeafConnection(1L, leafA.getLeafId()); - - List tokenList = new ArrayList<>(); - // access token, Refresh Token 발급 - String accessToken = delegateAccessToken(savedAccount); - String refreshToken = delegateRefreshToken(savedAccount); - tokenList.add(accessToken); - tokenList.add(refreshToken); - tokenList.add(String.valueOf(savedAccount.getAccountId())); - - return tokenList; - } - - private String delegateAccessToken(Account account) { - Map claims = new HashMap<>(); - claims.put("accountId", account.getAccountId().toString()); - claims.put("username", account.getEmail()); - claims.put("profileImageUrl", account.getProfileImageUrl()); - claims.put("roles", account.getRoles()); - claims.put("displayName", account.getDisplayName()); - - String subject = account.getEmail(); - Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getAccessTokenExpirationMinutes()); - String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); - String acceesToken = jwtTokenizer.generateAccessToken(claims, subject, expiration, base64EncodedSecretKey); - - return "Bearer " + acceesToken; - } - - private String delegateRefreshToken(Account account) { - String subject = account.getEmail(); - Date expiration = jwtTokenizer.getTokenExpiration(jwtTokenizer.getRefreshTokenExpirationMinutes()); - String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); - - String refreshToken = jwtTokenizer.generateRefreshToken(subject, expiration, base64EncodedSecretKey); - - return refreshToken; - } - - public void updateProfileImage(MultipartFile profileImage) { Account findAccount = authUserUtils.getAuthUser(); @@ -202,18 +76,20 @@ public void updateProfileImage(MultipartFile profileImage) { .build()); } - public void updateDisplayName(AccountDto.DisplayNamePatch requestDto) { + public void updateDisplayName(AccountDto.DisplayNamePatch displayNamePatchDto) { Account findAccount = authUserUtils.getAuthUser(); - findAccount.updateDisplayName(requestDto.getDisplayName()); + accountRepository.save(findAccount.toBuilder() + .displayName(displayNamePatchDto.getDisplayName()) + .build()); } - public void updatePassword(AccountDto.PasswordPatch requestDto) { + public void updatePassword(AccountDto.PasswordPatch passwordPatchDto) { Account findAccount = authUserUtils.getAuthUser(); - String encryptedChangedPassword = passwordEncoder.encode(requestDto.getChangedPassword()); + String encryptedChangedPassword = passwordEncoder.encode(passwordPatchDto.getChangedPassword()); - if (!passwordEncoder.matches(requestDto.getPresentPassword(), findAccount.getPassword())) + if (!passwordEncoder.matches(passwordPatchDto.getPresentPassword(), findAccount.getPassword())) throw new BadCredentialsException("현재 비밀번호가 일치하지 않습니다."); if (findAccount.getPassword().equals(encryptedChangedPassword)) @@ -268,7 +144,7 @@ public Page getAccountCommentWrittenBoard(int page, in Account findAccount = findVerifiedAccount(accountId); List commentWrittenBoardList = findAccount.getComments().stream() .map(comment -> getBoardResponse(comment.getBoard())) - .distinct() // 같은 게시글 중복 제거 + .distinct() .collect(Collectors.toList()); int startIdx = page * size; @@ -285,42 +161,17 @@ public void deleteAccount() { accountRepository.delete(findAccount); } - - // 게스트 용 v1/accounts/{account-id} - public void deleteAccount(Long id) { - Account findAccount = findVerifiedAccount(id); - - accountRepository.delete(findAccount); - } - - // 출석 체크 - public void attendanceCheck(Account account) { - if (!account.getAttendance()) { - account.updatePoint(pointService.updatePoint(account.getPoint(), "login")); - account.updateAttendance(true); - accountRepository.save(account); - - sseService.notify(account.getAccountId(), AlarmType.DAILY_LOGIN); - } - } - - // 자정에 초기화 - @Scheduled(cron = "0 0 0 * * *") - public void attendanceReset() { - accountRepository.findAll() - .forEach(account -> account.updateAttendance(false)); - } - - public Boolean verifyPassword(AccountDto.PasswordVerify requestDto) { + public Boolean verifyPassword(AccountDto.PasswordVerify passwordVerifyDto) { Account findAccount = authUserUtils.getAuthUser(); - return passwordEncoder.matches(requestDto.getPassword(), findAccount.getPassword()); + return passwordEncoder.matches(passwordVerifyDto.getPassword(), findAccount.getPassword()); } - public Boolean verifyExistsEmail(String email) { // 입력받은 이메일의 계정이 이미 존재한다면 true + private void verifyExistsEmail(String email) { Optional findAccount = accountRepository.findByEmail(email); - return findAccount.isPresent(); + if(findAccount.isPresent()) + throw new BusinessLogicException(ExceptionCode.ACCOUNT_ALREADY_EXISTS); } @Transactional(readOnly = true) @@ -329,8 +180,7 @@ public Account findVerifiedAccount(Long accountId) { new BusinessLogicException(ExceptionCode.ACCOUNT_NOT_FOUND)); } - //TODO: 리팩토링 -> AuthUserUtil - public void checkAuthIdMatching(Long accountId) { + public void isAuthIdMatching(Long accountId) { Authentication authentication = null; Map claims = null; try { @@ -346,12 +196,8 @@ public void checkAuthIdMatching(Long accountId) { } // 사용자가 일치하지 않으면 405 예외 던지기 - log.info("## login-id = {}", String.valueOf(claims.get("accountId"))); - log.info("## leafAuthorId = {}", String.valueOf(accountId)); - log.info("##" + !String.valueOf(claims.get("accountId")).equals(String.valueOf(accountId))); - if (!String.valueOf(claims.get("accountId")).equals(String.valueOf(accountId))) { + if (Long.valueOf((String) claims.get("accountId")) != accountId) throw new BusinessLogicException(ExceptionCode.ACCOUNT_NOT_ALLOW); - } } private static AccountDto.Response getAccountResponse(Account findAccount) { diff --git a/server/src/main/java/com/growstory/domain/alarm/constants/AlarmType.java b/server/src/main/java/com/growstory/domain/alarm/constants/AlarmType.java deleted file mode 100644 index 2b7837aa..00000000 --- a/server/src/main/java/com/growstory/domain/alarm/constants/AlarmType.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.growstory.domain.alarm.constants; - -import lombok.Getter; - -@Getter -public enum AlarmType { - REPORT_COMMENT(1, "reportComment"), - REPORT_POST(2, "reportPost"), - SIGN_UP(500, "signUp"), - DAILY_LOGIN(10, "dailyLogin"), - DAILY_QUIZ(10, "dailyQuiz"), - WRITE_POST(30, "writePost"), - WRITE_DIARY(10, "writeDiary"); - - private int point; - - private String stepDescription; - - AlarmType(int point, String stepDescription) { - this.point = point; - this.stepDescription = stepDescription; - } -} diff --git a/server/src/main/java/com/growstory/domain/alarm/controller/AlarmController.java b/server/src/main/java/com/growstory/domain/alarm/controller/AlarmController.java deleted file mode 100644 index e6aca4bf..00000000 --- a/server/src/main/java/com/growstory/domain/alarm/controller/AlarmController.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.growstory.domain.alarm.controller; - -import com.growstory.domain.alarm.dto.AlarmDto; -import com.growstory.domain.alarm.service.AlarmService; -import com.growstory.global.constants.HttpStatusCode; -import com.growstory.global.response.SingleResponseDto; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.validation.constraints.Positive; -import java.util.List; - -@Tag(name = "Alarm", description = "Alarm Controller") -@Validated -@RequiredArgsConstructor -@RequestMapping("/v1/alarms") -@RestController -public class AlarmController { - private final AlarmService alarmService; - - @Operation(summary = "알림 전체 조회", description = "입력받은 사용자의 모든 알림 조회") - @GetMapping("/{account-id}") - public ResponseEntity>> getAlarms(@Positive @PathVariable("account-id") Long accountId) { - List responseDtos = alarmService.findAlarms(accountId); - - return ResponseEntity.ok(SingleResponseDto.>builder() - .status(HttpStatusCode.OK.getStatusCode()) - .message(HttpStatusCode.OK.getMessage()) - .data(responseDtos) - .build()); - } - - @Operation(summary = "알림 개별 삭제", description = "입력받은 알림 ID의 알림 삭제") - @DeleteMapping("/{alarm-id}") - public ResponseEntity deleteAlarm(@PathVariable("alarm-id") @Positive Long alarmId) { - alarmService.deleteAlarm(alarmId); - - return ResponseEntity.noContent().build(); - } - - @Operation(summary = "알림 전체 삭제", description = "입력받은 사용자의 알림 전체 삭제") - @DeleteMapping("/all/{account-id}") - public ResponseEntity deleteAlarms(@PathVariable("account-id") @Positive Long accountId) { - alarmService.deleteAlarms(accountId); - - return ResponseEntity.noContent().build(); - } - - @Operation(summary = "알림 읽음 표시", description = "입력받은 사용자의 알림 읽음으로 표시") - @PostMapping("/{account-id}") - public ResponseEntity readAlarms(@PathVariable("account-id") @Positive Long accountId) { - alarmService.readAlarms(accountId); - - return ResponseEntity.noContent().build(); - } -} \ No newline at end of file diff --git a/server/src/main/java/com/growstory/domain/alarm/dto/AlarmDto.java b/server/src/main/java/com/growstory/domain/alarm/dto/AlarmDto.java deleted file mode 100644 index 8ec5675d..00000000 --- a/server/src/main/java/com/growstory/domain/alarm/dto/AlarmDto.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.growstory.domain.alarm.dto; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Builder; -import lombok.Getter; - -import java.time.LocalDateTime; - -public class AlarmDto { - @Getter - @Builder - @Schema(name = "AlarmResponseDto") - public static class Response { - private Long id; - private String type; - private int num; - private Boolean isShow; - } -} diff --git a/server/src/main/java/com/growstory/domain/alarm/entity/Alarm.java b/server/src/main/java/com/growstory/domain/alarm/entity/Alarm.java deleted file mode 100644 index a748ee08..00000000 --- a/server/src/main/java/com/growstory/domain/alarm/entity/Alarm.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.growstory.domain.alarm.entity; - -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.alarm.constants.AlarmType; -import com.growstory.global.audit.BaseTimeEntity; -import lombok.Builder; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import javax.persistence.*; - -@Getter -@RequiredArgsConstructor -@Entity -public class Alarm extends BaseTimeEntity { - // 구현 방법 SSE (server sent event) - - // 포인트 획득, 신고 알림 - // 확인되지 않은 알림이 존재하면 아이콘에 특별하게 표시 - // 아이콘을 클릭했을 경우 확인된 것으로 간주 - - // 포인트 획득은 포인트를 얻는 경우 - // 요청(출석 로그인, 게시글 등록, 일지 작성)의 응답에 알림이 추가되었다고 알려주기 - - // 신고 알림 - // 신고 받은 사람한테 현재 신고 누적 몇 회라는 알림 - - // 알림을 개별, 전체 삭제할 수 있고, 삭제하지 않은 알림은 - // (삭제 방법: 개수 제한 or 알림 생성되고 이후 시간흐름) - - // 알림 확인 api 추가하기 (isShow, true) - -// 알림 전체 조회 요청 -// req - userId -// res - id, type, num, isShow(false) - -// 알림 클릭 했을때 요청 -// 모든 알림의 isShow를 true로만 바꾸는 요청 -// -// 알림 개별 / 전체 삭제 요청 -// req -개별(알림id) / 전체(유저id) -// res - ok - -// "reportComment" num={1} /> -// "reportPost" num={2} /> -// "signup" num={500} /> -// "dailyLogin" num={10} /> -// "dailyQuiz" num={10} /> -// "writePost" num={30} /> -// "writeDiary" num={10} /> - - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long alarmId; - - private AlarmType alarmType; - - private Boolean isShow = false; - - @ManyToOne - @JoinColumn(name = "ACCOUNT_ID") - private Account account; - - public void updateIsShow(Boolean isShow) { - this.isShow = isShow; - } - - @Builder - public Alarm(Long alarmId, AlarmType alarmType, Boolean isShow, Account account) { - this.alarmId = alarmId; - this.alarmType = alarmType; - this.isShow = isShow; - this.account = account; - } -} diff --git a/server/src/main/java/com/growstory/domain/alarm/repository/AlarmRepository.java b/server/src/main/java/com/growstory/domain/alarm/repository/AlarmRepository.java deleted file mode 100644 index 620b61d3..00000000 --- a/server/src/main/java/com/growstory/domain/alarm/repository/AlarmRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.growstory.domain.alarm.repository; - -import com.growstory.domain.alarm.entity.Alarm; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface AlarmRepository extends JpaRepository { -} diff --git a/server/src/main/java/com/growstory/domain/alarm/service/AlarmService.java b/server/src/main/java/com/growstory/domain/alarm/service/AlarmService.java deleted file mode 100644 index 16e9f8a9..00000000 --- a/server/src/main/java/com/growstory/domain/alarm/service/AlarmService.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.growstory.domain.alarm.service; - -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.account.repository.AccountRepository; -import com.growstory.domain.alarm.constants.AlarmType; -import com.growstory.domain.alarm.dto.AlarmDto; -import com.growstory.domain.alarm.entity.Alarm; -import com.growstory.domain.alarm.repository.AlarmRepository; -import com.growstory.global.exception.BusinessLogicException; -import com.growstory.global.exception.ExceptionCode; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.stream.Collectors; - -@Transactional -@RequiredArgsConstructor -@Service -public class AlarmService { - private final AlarmRepository alarmRepository; - private final AccountRepository accountRepository; - - public void createAlarm(Long accountId, AlarmType alarmType) { - Account findAccount = accountRepository.findById(accountId).orElseThrow(() -> - new BusinessLogicException(ExceptionCode.ACCOUNT_NOT_FOUND)); - - Alarm savedAlarm = alarmRepository.save(Alarm.builder() - .alarmType(alarmType) - .isShow(false) - .account(findAccount) - .build()); - - findAccount.addAlarm(savedAlarm); - } - - public List findAlarms(Long accountId) { - Account findAccount = accountRepository.findById(accountId).orElseThrow(() -> - new BusinessLogicException(ExceptionCode.ACCOUNT_NOT_FOUND)); - - return findAccount.getAlarms().stream() - .map(this::getAlarmResponseDto) - .collect(Collectors.toList()); - } - - // 더티체킹 테스트해보기 - public void deleteAlarm(Long alarmId) { - Alarm findAlarm = findVerifiedAlarm(alarmId); - alarmRepository.delete(findAlarm); - - findAlarm.getAccount().getAlarms().remove(findAlarm); - } - - public void deleteAlarms(Long accountId) { - Account findAccount = accountRepository.findById(accountId).orElseThrow(() -> - new BusinessLogicException(ExceptionCode.ACCOUNT_NOT_FOUND)); - - alarmRepository.deleteAll(); - - findAccount.getAlarms().clear(); - } - - @Transactional(readOnly = true) - public Alarm findVerifiedAlarm(Long alarmId) { - return alarmRepository.findById(alarmId).orElseThrow(() -> - new BusinessLogicException(ExceptionCode.ALARM_NOT_FOUND)); - } - - private AlarmDto.Response getAlarmResponseDto(Alarm findAlarm) { - return AlarmDto.Response.builder() - .id(findAlarm.getAlarmId()) - .type(findAlarm.getAlarmType().getStepDescription()) - .num(findAlarm.getAlarmType().getPoint()) - .isShow(findAlarm.getIsShow()) - .build(); - } - - public void readAlarms(Long accountId) { - Account findAccount = accountRepository.findById(accountId).orElseThrow(() -> - new BusinessLogicException(ExceptionCode.ACCOUNT_NOT_FOUND)); - - findAccount.getAlarms().forEach(alarm -> - alarm.updateIsShow(true)); - } -} diff --git a/server/src/main/java/com/growstory/domain/bannedAccount/entity/BannedAccount.java b/server/src/main/java/com/growstory/domain/bannedAccount/entity/BannedAccount.java deleted file mode 100644 index 5945b94b..00000000 --- a/server/src/main/java/com/growstory/domain/bannedAccount/entity/BannedAccount.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.growstory.domain.bannedAccount.entity; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; - - -@Getter -@NoArgsConstructor -@Entity -public class BannedAccount { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long bannedAccountId; - - // 신고 받은 횟수 - private int reportNums; - - // 남은 정지 일수 - private int suspendedDays; - - private Long accountId; -} diff --git a/server/src/main/java/com/growstory/domain/board/controller/BoardController.java b/server/src/main/java/com/growstory/domain/board/controller/BoardController.java index bbdab83a..101ca614 100644 --- a/server/src/main/java/com/growstory/domain/board/controller/BoardController.java +++ b/server/src/main/java/com/growstory/domain/board/controller/BoardController.java @@ -7,6 +7,7 @@ import com.growstory.domain.rank.board_likes.dto.BoardLikesRankDto; import com.growstory.domain.rank.board_likes.service.BoardLikesRankService; import com.growstory.global.constants.HttpStatusCode; +import com.growstory.global.response.MultiResponseDto; import com.growstory.global.response.MultiResponseDto2; import com.growstory.global.response.SingleResponseDto; import com.growstory.global.utils.UriCreator; @@ -26,7 +27,7 @@ import java.net.URI; import java.util.List; -@Tag(name = "Boards API", description = "게시판 API") +@Tag(name = "Boards API", description = "게시판 기능") @Validated @RequiredArgsConstructor @RequestMapping("/v1/boards") @@ -68,7 +69,7 @@ public ResponseEntity> getBoard(@Positive @P public ResponseEntity> getBoards(@Positive @RequestParam(defaultValue = "1") int page, @Positive @RequestParam(defaultValue = "12") int size) { Page responseBoardDtos = boardService.findBoards(page - 1, size); - List responseBoardRankList = boardLikesRankService.findCurrentBoardLikesRanks(); + List responseBoardRankList = boardLikesRankService.findAllBoardLikesRanks(); return ResponseEntity.ok(MultiResponseDto2.builder() @@ -85,7 +86,7 @@ public ResponseEntity responseBoardDtos = boardService.findBoardsByKeyword(page - 1, size, keyword); - List responseBoardRankList = boardLikesRankService.findCurrentBoardLikesRanks(); + List responseBoardRankList = boardLikesRankService.findAllBoardLikesRanks(); return ResponseEntity.ok(MultiResponseDto2.builder() .status(HttpStatusCode.OK.getStatusCode()) diff --git a/server/src/main/java/com/growstory/domain/board/dto/RequestBoardDto.java b/server/src/main/java/com/growstory/domain/board/dto/RequestBoardDto.java index 3a8cf13a..1e497b44 100644 --- a/server/src/main/java/com/growstory/domain/board/dto/RequestBoardDto.java +++ b/server/src/main/java/com/growstory/domain/board/dto/RequestBoardDto.java @@ -2,7 +2,6 @@ import com.growstory.domain.account.entity.Account; import com.growstory.domain.board.entity.Board; -import com.growstory.global.badwords.dto.TextContainer; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -18,7 +17,7 @@ public class RequestBoardDto { @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) - public static class Post implements TextContainer { + public static class Post { @NotBlank private String title; @@ -43,21 +42,11 @@ public Board toEntity(Account account) { .account(account) .build(); } - - @Override - public String combineText() { - StringBuilder sb = new StringBuilder(); - sb.append(title+ " ").append(content+ " "); - for(String hash : hashTags) { - sb.append(hash + " "); - } - return sb.toString(); - } } @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter - public static class Patch implements TextContainer { + public static class Patch { // private Long boardId; @@ -82,15 +71,5 @@ public Patch(@Nullable String title, @Nullable String content, @Nullable List findTop3LikedBoards() { return response; } - // 좋아요 기준 상위 3개의 게시글을 랭킹과 함께 반환 + // 좋아요 기준 상위 3개의 게시글을 랭킹과 함께 반환 (🆘 추후 리팩토링) public List findTop3LikedBoardRanks() { LocalDateTime sevenDaysAgo = LocalDateTime.now().minusDays(7); List topBoardsWithLikes = boardRepository.findTop3LikedBoards(sevenDaysAgo); @@ -302,7 +297,7 @@ public List findTop3LikedBoardRanks() { .board(board) .likeNum(likeCount) .build(); - boardLikesRank.updateRank(uniqueLikeCounts.size()); //차등 등수 업데이트 + boardLikesRank.updateRank(uniqueLikeCounts.size()); boardLikesRanks.add(boardLikesRank); }); @@ -313,10 +308,9 @@ public List findTop3LikedBoardRanks() { private boolean checkSameLikesCondition(List boardLikesRanks) { int boardSize = boardLikesRanks.size(); - //게시글이 4개 이상이고 마지막 두 게시글의 순위가 서로 다르면 마지막 요소를 제거하고 false 반환 if(boardSize>=4 && - (boardLikesRanks.get(boardSize-1).getRankOrders().getPosition() != - boardLikesRanks.get(boardSize-2).getRankOrders().getPosition())) { + (boardLikesRanks.get(boardSize-1).getRankStatus().getRank() != + boardLikesRanks.get(boardSize-2).getRankStatus().getRank())) { boardLikesRanks.remove(boardLikesRanks.get(boardSize-1)); return false; } diff --git a/server/src/main/java/com/growstory/domain/comment/controller/CommentController.java b/server/src/main/java/com/growstory/domain/comment/controller/CommentController.java index 5f5bb17d..195adff3 100644 --- a/server/src/main/java/com/growstory/domain/comment/controller/CommentController.java +++ b/server/src/main/java/com/growstory/domain/comment/controller/CommentController.java @@ -43,7 +43,7 @@ public ResponseEntity postComment(@Positive @PathVariable("boardId") Long boa @PatchMapping("/{commentId}") public ResponseEntity patchComment(@Positive @PathVariable("commentId") Long commentId, @RequestBody CommentDto.Patch commentDto) { - commentService.updateComment(commentId, commentDto); + commentService.editComment(commentId, commentDto); return ResponseEntity.noContent().build(); } diff --git a/server/src/main/java/com/growstory/domain/comment/dto/CommentDto.java b/server/src/main/java/com/growstory/domain/comment/dto/CommentDto.java index 5cacfbd7..246da70d 100644 --- a/server/src/main/java/com/growstory/domain/comment/dto/CommentDto.java +++ b/server/src/main/java/com/growstory/domain/comment/dto/CommentDto.java @@ -3,7 +3,6 @@ import com.growstory.domain.account.entity.Account; import com.growstory.domain.board.entity.Board; import com.growstory.domain.comment.entity.Comment; -import com.growstory.global.badwords.dto.TextContainer; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -16,7 +15,7 @@ public class CommentDto { @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) - public static class Post implements TextContainer { + public static class Post { @NotBlank private String content; @@ -32,27 +31,17 @@ public Comment toEntity(Account account, Board board) { public Post(String content) { this.content = content; } - - @Override - public String combineText() { - return content; - } } @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) - public static class Patch implements TextContainer { + public static class Patch { @NotBlank private String content; public Patch(String content) { this.content = content; } - - @Override - public String combineText() { - return content; - } } diff --git a/server/src/main/java/com/growstory/domain/comment/service/CommentService.java b/server/src/main/java/com/growstory/domain/comment/service/CommentService.java index 072daff1..7224e6d5 100644 --- a/server/src/main/java/com/growstory/domain/comment/service/CommentService.java +++ b/server/src/main/java/com/growstory/domain/comment/service/CommentService.java @@ -60,7 +60,7 @@ private static List getResponseCommentDtoList(List } - public void updateComment(Long commentId, CommentDto.Patch commentDto) { + public void editComment(Long commentId, CommentDto.Patch commentDto) { findCommentsMatchCommentId(commentId); Comment comment = getVerifiedCommentByCommentId(commentId); diff --git a/server/src/main/java/com/growstory/domain/guest/service/GuestService.java b/server/src/main/java/com/growstory/domain/guest/service/GuestService.java deleted file mode 100644 index 5f184a82..00000000 --- a/server/src/main/java/com/growstory/domain/guest/service/GuestService.java +++ /dev/null @@ -1,247 +0,0 @@ -package com.growstory.domain.guest.service; - - -import com.growstory.domain.account.constants.AccountGrade; -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.images.entity.JournalImage; -import com.growstory.domain.images.repository.JournalImageRepository; -import com.growstory.domain.journal.entity.Journal; -import com.growstory.domain.journal.mapper.JournalMapper; -import com.growstory.domain.journal.repository.JournalRepository; -import com.growstory.domain.leaf.entity.Leaf; -import com.growstory.domain.leaf.repository.LeafRepository; -import com.growstory.domain.plant_object.dto.PlantObjDto; -import com.growstory.domain.plant_object.entity.PlantObj; -import com.growstory.domain.plant_object.location.dto.LocationDto; -import com.growstory.domain.plant_object.location.entity.Location; -import com.growstory.domain.plant_object.location.repository.LocationRepository; -import com.growstory.domain.plant_object.location.service.LocationService; -import com.growstory.domain.plant_object.mapper.PlantObjMapper; -import com.growstory.domain.plant_object.repository.PlantObjRepository; -import com.growstory.domain.plant_object.service.PlantObjService; -import com.growstory.domain.point.entity.Point; -import com.growstory.domain.product.entity.Product; -import com.growstory.domain.product.service.ProductService; -import com.growstory.global.exception.BusinessLogicException; -import com.growstory.global.exception.ExceptionCode; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import javax.transaction.Transactional; -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -@Service -@Transactional -@RequiredArgsConstructor -public class GuestService { - - // 식물 카드 - private final LeafRepository leafRepository; - - // 일지 - private final JournalRepository journalRepository; - private final JournalMapper journalMapper; - private final JournalImageRepository journalImageRepository; - - // 정원 - private final ProductService productService; - private final PlantObjMapper plantObjMapper; - private final PlantObjRepository plantObjRepository; - - // 정원 배치 - private final LocationRepository locationRepository; - - - public Leaf createGuestLeaf(Account account, String leafName, String content, String imageUrl) { - Leaf leaf = Leaf.builder() - .leafName(leafName) - .leafImageUrl(imageUrl) - .content(content) - .account(account) - .journals(new ArrayList<>()) - .build(); - - Leaf saveLeaf = leafRepository.save(leaf); - - account.addLeaf(saveLeaf); - account.updateGrade(updateAccountGrade(account)); -// account.updateGrade(updateAccountGrade(account)); - - return Leaf.builder() - .leafId(saveLeaf.getLeafId()) - .build(); - } - - private AccountGrade updateAccountGrade(Account findAccount) { - int leavesNum = findAccount.getLeaves().size(); - if (leavesNum < 50) { - return AccountGrade.GRADE_BRONZE; - } else if (leavesNum < 100) { - return AccountGrade.GRADE_SILVER; - } else { - return AccountGrade.GRADE_GOLD; - } - } - - - public void createGuestJournal(Leaf leaf, String title, String contents, File imageUrl) { - Journal journal = createGuestJournalWithNoImg(leaf, title, contents); - //image가 null이거나 비어있을 경우 ResponseDto로 변환하여 반환 - if(imageUrl==null) { - journalMapper.toResponseFrom(journal); - return; - } - //image가 null이 아닐 경우 이미지 업로드 및 DB 저장 - JournalImage savedJournalImage = createJournalImage(imageUrl, journal); - //imageUrl 정보 Journal에 업데이트 - journal.updateImg(savedJournalImage); - - leaf.getJournals().add(journal); - journal.updateLeaf(leaf); - - journalMapper.toResponseFrom(journalRepository.save(journal)); - } - - - private Journal createGuestJournalWithNoImg(Leaf findLeaf, String title, String contents) { - return journalRepository.save(Journal.builder() - .title(title) - .content(contents) - .leaf(findLeaf) - .journalImage(null) - .build()); - } - - - // 테이블 인스턴스 생성 및 S3 파일 업로드 - private JournalImage createJournalImage(File imageUrl, Journal journal) { - if(imageUrl == null || journal == null) - return null; - JournalImage journalImage = - JournalImage.builder() - .imageUrl("imageUrl.get") - .originName("test1") - .journal(journal) - .build(); - return journalImageRepository.save(journalImage); - } - - // POST : 유저 포인트로 오브젝트 구입 - public PlantObjDto.TradeResponse buyProduct(Account account, Long productId) { - - // 클라이언트에서 전송된 productId 기반으로 product 정보 조회 - Product findProduct = productService.findVerifiedProduct(productId); - - // 조회한 계정, 포인트, 상품정보를 바탕으로 구입 메서드 실행 - buy(account,findProduct); - - // 구입한 오브젝트 객체 생성 - PlantObj boughtPlantObj = PlantObj.builder() - .product(findProduct) - .leaf(null) - .location(new Location()) - .account(account) - .build(); - - //구입한 오브젝트를 DB에 저장 및 findAccount에 추가 - account.addPlantObj( - plantObjRepository.save( - boughtPlantObj - ) - ); - - Point afterPoint = boughtPlantObj.getAccount().getPoint(); - - // 이미 구입한 프로덕트, - return plantObjMapper.toTradeResponse(boughtPlantObj, afterPoint); - } - - private void buy(Account account, Product product) { - Point accountPoint = account.getPoint(); - int price = product.getPrice(); - int userPointScore = account.getPoint().getScore(); - if(price > userPointScore) { - throw new BusinessLogicException(ExceptionCode.NOT_ENOUGH_POINTS); - } else { // price <= userPointScore - int updatedScore = accountPoint.getScore()-price; - accountPoint.updateScore(updatedScore); - } - } - - - // POST : 오브젝트 배치 - public void saveLocation(PlantObjDto.Response plantObjA, PlantObjDto.Response plantObjB) { - List patchLocationList = new ArrayList<>(); - patchLocationList.add(PlantObjDto.PatchLocation.builder() - .plantObjId(plantObjA.getPlantObjId()) - .locationDto(LocationDto.Patch.builder() - .locationId(plantObjA.getLocation().getLocationId()) - .x(6) - .y(5) - .isInstalled(true) - .build()) - .build()); - patchLocationList.add(PlantObjDto.PatchLocation.builder() - .plantObjId(plantObjB.getPlantObjId()) - .locationDto(LocationDto.Patch.builder() - .locationId(plantObjB.getLocation().getLocationId()) - .x(3) - .y(3) - .isInstalled(true) - .build()) - .build()); - - patchLocationList.stream() - .forEach(patchLocationDto -> { - LocationDto.Patch locationPatchDto = patchLocationDto.getLocationDto(); - //프로덕트 id와 로케이션 id가 일치하지 않으면 예외 발생 -// if(patchLocationDto.getPlantObjId()!=locationPatchDto.getLocationId()) { -// throw new BusinessLogicException(ExceptionCode.LOCATION_NOT_ALLOW); -// } - if(locationPatchDto.getX()<0 || locationPatchDto.getX()>11 || - locationPatchDto.getY()<0 || locationPatchDto.getY()>7) { - throw new BusinessLogicException(ExceptionCode.INVALID_LOCATION); - } - // locationPatchDto와 기존 DB의 Location 정보가 일치하는지를 비교하여 다르다면 그 변화를 저장 - updateLocation(locationPatchDto); - }); - } - - private Location updateLocation(LocationDto.Patch locationDto) { - Location findLocation = locationRepository.findById(locationDto.getLocationId()).orElseThrow(()-> new BusinessLogicException(ExceptionCode.LOCATION_NOT_FOUND)); - - boolean isChangged = - findLocation.getX() != locationDto.getX() || findLocation.getY() != locationDto.getY() || findLocation.isInstalled() != locationDto.isInstalled(); - - if (isChangged) { - findLocation.update(locationDto.getX(), locationDto.getY(), locationDto.isInstalled()); - } - return findLocation; - } - - // PATCH : 오브젝트와 식물 카드 연결 / 해제 / 교체 - public void updateLeafConnection(Long plantObjId, Long leafId) { - PlantObj findPlantObj = findVerifiedPlantObj(plantObjId); - - if (leafId != null) { - // leafId가 null이 아닌경우 NPE에 대한 우려 없이 DB에서 조회 - Leaf findLeaf = leafRepository.findById(leafId) - .orElseThrow(()-> new BusinessLogicException(ExceptionCode.LEAF_NOT_FOUND)); - findPlantObj.updateLeaf(findLeaf); - findLeaf.updatePlantObj(findPlantObj); - } else { - Leaf beforeLeaf = findPlantObj.getLeaf(); - if (beforeLeaf != null) { - beforeLeaf.updatePlantObj(null); - } - findPlantObj.updateLeaf(null); - } - } - - private PlantObj findVerifiedPlantObj(long plantObjId) { - return plantObjRepository.findById(plantObjId).orElseThrow(() -> new BusinessLogicException(ExceptionCode.PLANT_OBJ_NOT_FOUND)); - } - -} diff --git a/server/src/main/java/com/growstory/domain/guestbook/controller/GuestBookController.java b/server/src/main/java/com/growstory/domain/guestbook/controller/GuestBookController.java deleted file mode 100644 index e3a6c741..00000000 --- a/server/src/main/java/com/growstory/domain/guestbook/controller/GuestBookController.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.growstory.domain.guestbook.controller; - - -import com.growstory.domain.guestbook.dto.GuestBookRequestDto; -import com.growstory.domain.guestbook.dto.GuestBookResponseDto; -import com.growstory.domain.guestbook.service.GuestBookService; -import com.growstory.global.constants.HttpStatusCode; -import com.growstory.global.response.MultiResponseDto; -import com.growstory.global.utils.UriCreator; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import javax.validation.constraints.Positive; -import java.net.URI; - -@Tag(name = "GuestBook API", description = "방명록 API") -@Validated -@RequiredArgsConstructor -@RequestMapping("/v1/guestbooks") -@RestController -public class GuestBookController { - - private final GuestBookService guestBookService; - - private final static String GUESTBOOK_DEFAULT_URL = "/v1/guestbooks"; - - - @Operation(summary = "Create GuestBook API", description = "방명록 추가 기능") - @PostMapping("/{accountId}") - public ResponseEntity postGuestBook(@Positive @PathVariable("accountId") Long accountId, - @Valid @RequestBody GuestBookRequestDto.Post requestDto) { - Long guestBookId = guestBookService.saveGuestBook(accountId, requestDto); - - URI location = UriCreator.createUri(GUESTBOOK_DEFAULT_URL, guestBookId); - - return ResponseEntity.created(location).build(); - } - - @Operation(summary = "Read Page GuestBook API", description = "방명록 페이지 조회 기능") - @GetMapping("{accountId}") - public ResponseEntity> readGuestBooks(@Positive @PathVariable("accountId") Long accountId, - @Positive @RequestParam(defaultValue = "1") int page, - @Positive @RequestParam(defaultValue = "12") int size) { - Page responseDtoPage = guestBookService.getGuestbookPage(accountId, page - 1, size); - - return ResponseEntity.ok(MultiResponseDto.builder() - .status(HttpStatusCode.OK.getStatusCode()) - .message(HttpStatusCode.OK.getMessage()) - .data(responseDtoPage.getContent()) - .page(responseDtoPage).build()); - } - - - @Operation(summary = "Update GuestBook API", description = "방명록 수정 기능") - @PatchMapping("{guestBookId}") - public ResponseEntity updateGuestBook(@Positive @PathVariable("guestBookId") Long guestBookId, - @Valid @RequestBody GuestBookRequestDto.Patch requestDto) { - guestBookService.updateGuestBook(guestBookId, requestDto); - - return ResponseEntity.noContent().build(); - } - - @Operation(summary = "Delete GuestBook API", description = "방명록 삭제 기능") - @DeleteMapping("/{guestBookId}") - public ResponseEntity deleteGuestBook(@Positive @PathVariable("guestBookId") Long guestBookId) { - guestBookService.deleteGuestbook(guestBookId); - - return ResponseEntity.noContent().build(); - } -} diff --git a/server/src/main/java/com/growstory/domain/guestbook/dto/GuestBookRequestDto.java b/server/src/main/java/com/growstory/domain/guestbook/dto/GuestBookRequestDto.java deleted file mode 100644 index de3dd125..00000000 --- a/server/src/main/java/com/growstory/domain/guestbook/dto/GuestBookRequestDto.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.growstory.domain.guestbook.dto; - -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.guestbook.entity.GuestBook; -import com.growstory.domain.plant_object.entity.PlantObj; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotBlank; - -public class GuestBookRequestDto { - - @Getter - @NoArgsConstructor(access = AccessLevel.PROTECTED) - public static class Post { - @NotBlank - private String content; - - public GuestBook toEntity(Account author, Account receiver) { - return GuestBook.builder() - .content(content) - .author(author) - .receiver(receiver) - .build(); - } - - - public Post(String content) { - this.content = content; - } - } - - @Getter - @NoArgsConstructor(access = AccessLevel.PROTECTED) - public static class Patch { - - @NotBlank - private String content; - } -} diff --git a/server/src/main/java/com/growstory/domain/guestbook/dto/GuestBookResponseDto.java b/server/src/main/java/com/growstory/domain/guestbook/dto/GuestBookResponseDto.java deleted file mode 100644 index 45fc698c..00000000 --- a/server/src/main/java/com/growstory/domain/guestbook/dto/GuestBookResponseDto.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.growstory.domain.guestbook.dto; - - -import lombok.Builder; -import lombok.Getter; - -import java.time.LocalDateTime; - -@Getter -@Builder -public class GuestBookResponseDto { - private Long guestbookId; - private String content; - - // account - private String displayName; - private String imageUrl; - private String accountGrade; - private LocalDateTime createdAt; - private LocalDateTime modifiedAt; -} diff --git a/server/src/main/java/com/growstory/domain/guestbook/entity/GuestBook.java b/server/src/main/java/com/growstory/domain/guestbook/entity/GuestBook.java deleted file mode 100644 index ee180e81..00000000 --- a/server/src/main/java/com/growstory/domain/guestbook/entity/GuestBook.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.growstory.domain.guestbook.entity; - -import com.growstory.domain.account.entity.Account; -import com.growstory.global.audit.BaseTimeEntity; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -public class GuestBook extends BaseTimeEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long guestbookId; - - private String content; - - @ManyToOne - @JoinColumn(name = "WRITER_ACCOUNT_ID") - private Account author; - - @ManyToOne - @JoinColumn(name = "RECEIVE_ACCOUNT_ID") - private Account receiver; - - - @Builder - public GuestBook(Long guestbookId, String content, Account author, Account receiver) { - this.guestbookId = guestbookId; - this.content = content; - this.author = author; - this.receiver = receiver; - } - - public void update(String content){ - this.content = content; - } -} - diff --git a/server/src/main/java/com/growstory/domain/guestbook/repository/GuestBookRepository.java b/server/src/main/java/com/growstory/domain/guestbook/repository/GuestBookRepository.java deleted file mode 100644 index 3608351c..00000000 --- a/server/src/main/java/com/growstory/domain/guestbook/repository/GuestBookRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.growstory.domain.guestbook.repository; - -import com.growstory.domain.guestbook.entity.GuestBook; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; -import java.util.Optional; - -public interface GuestBookRepository extends JpaRepository { -// Optional> findGuestBooksByReceiverAccountId(Long accountId); -} diff --git a/server/src/main/java/com/growstory/domain/guestbook/service/GuestBookService.java b/server/src/main/java/com/growstory/domain/guestbook/service/GuestBookService.java deleted file mode 100644 index 60e9cadb..00000000 --- a/server/src/main/java/com/growstory/domain/guestbook/service/GuestBookService.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.growstory.domain.guestbook.service; - -import com.growstory.domain.account.dto.AccountDto; -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.account.repository.AccountRepository; -import com.growstory.domain.guestbook.dto.GuestBookRequestDto; -import com.growstory.domain.guestbook.dto.GuestBookResponseDto; -import com.growstory.domain.guestbook.entity.GuestBook; -import com.growstory.domain.guestbook.repository.GuestBookRepository; -import com.growstory.global.auth.utils.AuthUserUtils; -import com.growstory.global.exception.BusinessLogicException; -import com.growstory.global.exception.ExceptionCode; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -@Transactional -@RequiredArgsConstructor -@Service -public class GuestBookService { - - private final AccountRepository accountRepository; - private final GuestBookRepository guestbookRepository; - private final AuthUserUtils authUserUtils; - - public Long saveGuestBook(Long accountId, GuestBookRequestDto.Post requestDto) { - // 방명록을 작성하는 사람 - Account author = authUserUtils.getAuthUser(); - - // 방명록을 받을 사용자 - Account receiver = accountRepository.findById(accountId) - .orElseThrow(() -> new BusinessLogicException(ExceptionCode.ACCOUNT_NOT_FOUND)); - - GuestBook guestbook = guestbookRepository.save(requestDto.toEntity(author, receiver)); - - - return guestbook.getGuestbookId(); - } - - public Page getGuestbookPage(Long accountId, int page, int size) { - Account findAccount = accountRepository.findById(accountId).orElseThrow(() -> - new BusinessLogicException(ExceptionCode.ACCOUNT_NOT_FOUND)); - List guestBookResponseDtoList = findAccount.getReceivedGuestBooks().stream() - .map(this::getGuestBookResponse) - .collect(Collectors.toList()); - - int startIdx = page * size; - int endIdx = Math.min(guestBookResponseDtoList.size(), (page + 1) * size); - return new PageImpl<>(guestBookResponseDtoList.subList(startIdx, endIdx), PageRequest.of(page, size), guestBookResponseDtoList.size()); - } - - public GuestBookResponseDto getGuestBookResponse(GuestBook guestBook) { - return GuestBookResponseDto.builder() - .guestbookId(guestBook.getGuestbookId()) - .displayName(guestBook.getAuthor().getDisplayName()) - .imageUrl(guestBook.getAuthor().getProfileImageUrl()) - .accountGrade(guestBook.getAuthor().getAccountGrade().getStepDescription()) - .createdAt(guestBook.getCreatedAt()) - .modifiedAt(guestBook.getModifiedAt()) - .content(guestBook.getContent()) - .build(); - } - - public void updateGuestBook(Long guestBookId, GuestBookRequestDto.Patch requestDto) { - findGuestBooksMatchGuestBookId(guestBookId); - - GuestBook findGuestBook = findVerifedGuestbook(guestBookId); - findGuestBook.update(requestDto.getContent()); - } - - public void deleteGuestbook(Long guestbookId) { - findGuestBooksMatchGuestBookId(guestbookId); - - GuestBook findGuestBook = findVerifedGuestbook(guestbookId); - - guestbookRepository.delete(findGuestBook); - - // 방명록 삭제 후 Account, PlantObj 업데이트 - findGuestBook.getAuthor().getWriterGuestBooks().remove(findGuestBook); - findGuestBook.getReceiver().getReceivedGuestBooks().remove(findGuestBook); - - } - - - private void findGuestBooksMatchGuestBookId(Long guestBookId) { - Account account = authUserUtils.getAuthUser(); - - boolean isGuestBook = account.getWriterGuestBooks().stream() - .map(GuestBook::getGuestbookId) - .anyMatch(id -> Objects.equals(id, guestBookId)); - - if (!isGuestBook) - throw new BusinessLogicException(ExceptionCode.GUESTBOOK_NOT_FOUND); - } - - - @Transactional(readOnly = true) - public GuestBook findVerifedGuestbook(Long guestbookId) { - return guestbookRepository.findById(guestbookId) - .orElseThrow(() -> new BusinessLogicException(ExceptionCode.GUESTBOOK_NOT_FOUND)); - } -} diff --git a/server/src/main/java/com/growstory/domain/images/entity/ChatMessageImage.java b/server/src/main/java/com/growstory/domain/images/entity/ChatMessageImage.java deleted file mode 100644 index 59a96981..00000000 --- a/server/src/main/java/com/growstory/domain/images/entity/ChatMessageImage.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.growstory.domain.images.entity; - -import com.growstory.domain.qnachat.chatmessage.entity.ChatMessage; -import lombok.*; - -import javax.persistence.*; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Entity -public class ChatMessageImage { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private long chatImageId; - - @Column(name ="origin_name", nullable = false) - private String originName; - - @Column(name = "image_url", nullable = false) - private String imageUrl; - - @OneToOne (cascade = CascadeType.ALL) - @JoinColumn(name = "chat_message_id", nullable = false) - private ChatMessage chatMessage; - - @Builder - public ChatMessageImage(long chatImageId, String originName, String imageUrl, ChatMessage chatMessage) { - this.chatImageId = chatImageId; - this.originName = originName; - this.imageUrl = imageUrl; - this.chatMessage = chatMessage; - } - - /** - * 연관관계 메소드 - * @param chatMessage : ChatMessageImage가 참조하는 메시지 객체 - */ - public void updateChatMessage(ChatMessage chatMessage) { - this.chatMessage = chatMessage; - } -} diff --git a/server/src/main/java/com/growstory/domain/images/repository/ChatMessageImageRepository.java b/server/src/main/java/com/growstory/domain/images/repository/ChatMessageImageRepository.java deleted file mode 100644 index be74f7f4..00000000 --- a/server/src/main/java/com/growstory/domain/images/repository/ChatMessageImageRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.growstory.domain.images.repository; - -import com.growstory.domain.images.entity.ChatMessageImage; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ChatMessageImageRepository extends JpaRepository { -} diff --git a/server/src/main/java/com/growstory/domain/images/service/ChatMessageImageService.java b/server/src/main/java/com/growstory/domain/images/service/ChatMessageImageService.java deleted file mode 100644 index cd41d41f..00000000 --- a/server/src/main/java/com/growstory/domain/images/service/ChatMessageImageService.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.growstory.domain.images.service; - -import com.growstory.domain.images.entity.ChatMessageImage; -import com.growstory.domain.images.repository.ChatMessageImageRepository; -import com.growstory.domain.qnachat.chatmessage.entity.ChatMessage; -import com.growstory.global.aws.service.S3Uploader; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -@Transactional -@Slf4j -@RequiredArgsConstructor -@Service -public class ChatMessageImageService { - - private final ChatMessageImageRepository chatMessageImageRepository; - private final S3Uploader s3Uploader; - - // 테이블 인스턴스 생성 및 S3 파일 업로드 - public ChatMessageImage createChatMessageImgWithS3(MultipartFile image, String type, ChatMessage chatMessage) { - if(image.isEmpty() || type == null || chatMessage == null) { - log.info("image:{}, type:{}, chatMessage:{}", image, type, chatMessage); - - throw new NullPointerException("챗 메세지 이미지 생성 중 NPE 발생"); - } - String imgUrl = s3Uploader.uploadImageToS3(image, type); - ChatMessageImage chatMessageImage = - ChatMessageImage.builder() - .imageUrl(imgUrl) - .originName(image.getOriginalFilename()) - .chatMessage(chatMessage) - .build(); - - return chatMessageImageRepository.save(chatMessageImage); - } - - // 테이블 인스턴스 삭제 및 S3 데이터 삭제 - public void deleteChatMessageImageWithS3(ChatMessageImage chatMessageImage, String type) { - if(chatMessageImage == null || type == null) { - log.info("chatMessageImage:{}, type:{}", chatMessageImage, type); - throw new NullPointerException("챗 메세지 이미지 삭제 중 NPE 발생"); - } - - ChatMessage chatMessage = chatMessageImage.getChatMessage(); -// chatMessage.removeChatMessageImage(chatMessageImage); - - s3Uploader.deleteImageFromS3(chatMessageImage.getImageUrl(), type); - - } -} diff --git a/server/src/main/java/com/growstory/domain/images/service/JournalImageService.java b/server/src/main/java/com/growstory/domain/images/service/JournalImageService.java index 3aa76d62..e89ac052 100644 --- a/server/src/main/java/com/growstory/domain/images/service/JournalImageService.java +++ b/server/src/main/java/com/growstory/domain/images/service/JournalImageService.java @@ -3,7 +3,6 @@ import com.growstory.domain.images.entity.JournalImage; import com.growstory.domain.images.repository.JournalImageRepository; import com.growstory.domain.journal.entity.Journal; -import com.growstory.global.auth.utils.AuthUserUtils; import com.growstory.global.aws.service.S3Uploader; import com.growstory.global.exception.BusinessLogicException; import com.growstory.global.exception.ExceptionCode; @@ -22,8 +21,7 @@ public class JournalImageService { // 테이블 인스턴스 생성 및 S3 파일 업로드 public JournalImage createJournalImgWithS3(MultipartFile image, String type, Journal journal) { - if(image.isEmpty() || type == null || journal == null) - throw new NullPointerException("저널 이미지 생성 중 NPE 발생"); + if(image.isEmpty() || type == null || journal == null) return null; String imgUrl = s3Uploader.uploadImageToS3(image, type); JournalImage journalImage = JournalImage.builder() @@ -36,7 +34,7 @@ public JournalImage createJournalImgWithS3(MultipartFile image, String type, Jou // 테이블 인스턴스 삭제 및 S3 데이터 삭제 public void deleteJournalImageWithS3(JournalImage journalImage, String type) { - if(journalImage == null || type == null) throw new NullPointerException("저널 이미지 삭제 중 NPE 발생"); + if(journalImage == null) return; Journal journal = journalImage.getJournal(); journal.removeJournalImage(journalImage); diff --git a/server/src/main/java/com/growstory/domain/journal/controller/JournalController.java b/server/src/main/java/com/growstory/domain/journal/controller/JournalController.java index e6b37839..03617aa1 100644 --- a/server/src/main/java/com/growstory/domain/journal/controller/JournalController.java +++ b/server/src/main/java/com/growstory/domain/journal/controller/JournalController.java @@ -1,11 +1,11 @@ package com.growstory.domain.journal.controller; +import com.growstory.domain.account.service.AccountService; import com.growstory.domain.journal.dto.JournalDto; import com.growstory.domain.journal.service.JournalService; import com.growstory.global.response.SingleResponseDto; import com.growstory.global.utils.UriCreator; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; @@ -17,7 +17,6 @@ import java.net.URI; import java.util.List; -@Slf4j @RestController @RequestMapping("/v1/leaves") @RequiredArgsConstructor @@ -25,7 +24,6 @@ public class JournalController { private final JournalService journalService; - private final UriCreator uriCreator; private static final String DEFAULT_URL = "/v1/leaves"; @@ -45,23 +43,25 @@ public ResponseEntity getJournals( // POST, 식물 일지를 등록 @PostMapping("/{leaf-id}/journals") - public ResponseEntity postJournal(@Positive @PathVariable("leaf-id") Long leafId, - @Valid @RequestPart(value = "postDto") JournalDto.Post postDto, - @RequestPart(required = false, value = "image") MultipartFile image) { - JournalDto.Response journal = journalService.createJournal(leafId, postDto, image); + public ResponseEntity postJournal(@RequestPart JournalDto.LeafAuthor leafAuthor, + @Positive @PathVariable("leaf-id") Long leafId, + @Valid @RequestPart JournalDto.Post postDto, + @RequestPart(required = false) MultipartFile image) { + JournalDto.Response journal = journalService.createJournal(leafAuthor.getAccountId(), leafId, postDto, image); - URI location = uriCreator.createUri_test(DEFAULT_URL, journal.getJournalId()); + URI location = UriCreator.createUri(DEFAULT_URL, journal.getJournalId()); return ResponseEntity.created(location).build(); } // PATCH, 식물 일지를 수정 @PatchMapping("/journals/{journal-id}") - public ResponseEntity patchJournal(@Positive @PathVariable("journal-id") Long journalId, + public ResponseEntity patchJournal(@RequestPart JournalDto.LeafAuthor leafAuthor, + @Positive @PathVariable("journal-id") Long journalId, @Valid @RequestPart JournalDto.Patch patchDto, @RequestPart(required = false) MultipartFile image) { - journalService.updateJournal(journalId, patchDto, image); + journalService.updateJournal(leafAuthor.getAccountId(), journalId, patchDto, image); return ResponseEntity.noContent().build(); } @@ -69,9 +69,9 @@ public ResponseEntity patchJournal(@Positive @PathVariable("journal- // DELETE, 식물 일지를 삭제 @DeleteMapping("/journals/{journal-id}") public ResponseEntity deleteJournal( - @RequestParam("leaf-author-id") long leafAuthorId, + @RequestBody JournalDto.LeafAuthor leafAuthor, @Positive @PathVariable("journal-id") Long journalId) { - journalService.deleteJournal(leafAuthorId, journalId); + journalService.deleteJournal(leafAuthor.getAccountId(), journalId); return ResponseEntity.noContent().build(); } diff --git a/server/src/main/java/com/growstory/domain/journal/dto/JournalDto.java b/server/src/main/java/com/growstory/domain/journal/dto/JournalDto.java index 5f974335..f1b05b25 100644 --- a/server/src/main/java/com/growstory/domain/journal/dto/JournalDto.java +++ b/server/src/main/java/com/growstory/domain/journal/dto/JournalDto.java @@ -1,47 +1,32 @@ package com.growstory.domain.journal.dto; -import com.growstory.global.badwords.dto.TextContainer; -import lombok.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; import org.springframework.lang.Nullable; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import java.time.LocalDate; import java.time.LocalDateTime; public class JournalDto { @Getter - @Builder - @NoArgsConstructor - @AllArgsConstructor - public static class Post implements TextContainer { + public static class Post { @NotBlank String title; @NotBlank String content; - @NotNull - long leafAuthorId; - - @Override - public String combineText() { - StringBuilder sb = new StringBuilder(); - return sb.append(title+ " ").append(content).toString(); - } } @Getter - public static class Patch implements TextContainer { + public static class Patch { @Nullable String title; @Nullable String content; - @NotNull - long leafAuthorId; - - @Override - public String combineText() { - StringBuilder sb = new StringBuilder(); - return sb.append(title+ " ").append(content).toString(); - } } @Getter @@ -54,11 +39,8 @@ public static class Response { LocalDateTime createdAt; } -// @Getter -// @Builder -// @NoArgsConstructor -// @AllArgsConstructor -// public static class LeafAuthor { -// long accountId; -// } + @Getter + public static class LeafAuthor { + long accountId; + } } diff --git a/server/src/main/java/com/growstory/domain/journal/service/JournalService.java b/server/src/main/java/com/growstory/domain/journal/service/JournalService.java index 563a0102..f7c47dea 100644 --- a/server/src/main/java/com/growstory/domain/journal/service/JournalService.java +++ b/server/src/main/java/com/growstory/domain/journal/service/JournalService.java @@ -1,7 +1,6 @@ package com.growstory.domain.journal.service; import com.growstory.domain.account.service.AccountService; -import com.growstory.domain.alarm.constants.AlarmType; import com.growstory.domain.images.entity.JournalImage; import com.growstory.domain.images.service.JournalImageService; import com.growstory.domain.journal.dto.JournalDto; @@ -13,7 +12,6 @@ import com.growstory.domain.point.service.PointService; import com.growstory.global.exception.BusinessLogicException; import com.growstory.global.exception.ExceptionCode; -import com.growstory.global.sse.service.SseService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -35,7 +33,6 @@ public class JournalService { private final JournalMapper journalMapper; private final AccountService accountService; private final PointService pointService; - private final SseService sseService; private static final String JOURNAL_IMAGE_PROCESS_TYPE = "journal_image"; @@ -49,11 +46,10 @@ public List findAllJournals(Long accountId, Long leafId) { .collect(Collectors.toList()); } - public JournalDto.Response createJournal(Long leafId, JournalDto.Post postDto, MultipartFile image) { - accountService.checkAuthIdMatching(postDto.getLeafAuthorId()); + public JournalDto.Response createJournal(Long accountId, Long leafId, JournalDto.Post postDto, MultipartFile image) { + accountService.isAuthIdMatching(accountId); Leaf findLeaf = leafService.findLeafEntityBy(leafId); Journal journal = createJournalWithNoImg(findLeaf, postDto); - sseService.notify(postDto.getLeafAuthorId(), AlarmType.WRITE_DIARY); //image가 null이거나 비어있을 경우 ResponseDto로 변환하여 반환 if(image==null|| image.isEmpty()) { return journalMapper.toResponseFrom(journal); @@ -63,11 +59,9 @@ public JournalDto.Response createJournal(Long leafId, JournalDto.Post postDto, M //image 정보 Journal에 업데이트 journal.updateImg(savedJournalImage); - return journalMapper.toResponseFrom(journalRepository.save(journal)); } - private Journal createJournalWithNoImg(Leaf findLeaf, JournalDto.Post postDto) { pointService.updatePoint(findLeaf.getAccount().getPoint(), "journal"); return journalRepository.save(Journal.builder() @@ -78,9 +72,9 @@ private Journal createJournalWithNoImg(Leaf findLeaf, JournalDto.Post postDto) { .build()); } - public void updateJournal(Long journalId, JournalDto.Patch patchDto, MultipartFile image) { + public void updateJournal(Long accountId, Long journalId, JournalDto.Patch patchDto, MultipartFile image) { Journal findJournal = findVerifiedJournalBy(journalId); - accountService.checkAuthIdMatching(patchDto.getLeafAuthorId()); + accountService.isAuthIdMatching(accountId); Optional.ofNullable(patchDto.getTitle()) .ifPresent(findJournal::updateTitle); @@ -90,6 +84,8 @@ public void updateJournal(Long journalId, JournalDto.Patch patchDto, MultipartFi updateLoadImage(image, findJournal, JOURNAL_IMAGE_PROCESS_TYPE); } + //TODO: S3Uploader로 빼는 리팩토링 작업? (상위 클래스 Image를 이용한 형변환) + // 기존 DB와 S3에 저장된 이미지 정보를 업로드 이미지 여부에 따라 수정 private void updateLoadImage(MultipartFile image, Journal journal, String type) { JournalImage journalImage = journal.getJournalImage(); @@ -107,7 +103,7 @@ private void updateLoadImage(MultipartFile image, Journal journal, String type) } public void deleteJournal(Long accountId, Long journalId) { - accountService.checkAuthIdMatching(accountId); + accountService.isAuthIdMatching(accountId); Journal journal = findVerifiedJournalBy(journalId); //저널에 귀속되어 있는 이미지들도 S3에서 삭제해야 한다. JournalImage journalImage = journal.getJournalImage(); diff --git a/server/src/main/java/com/growstory/domain/leaf/dto/LeafDto.java b/server/src/main/java/com/growstory/domain/leaf/dto/LeafDto.java index f29e8f0d..c3b6071b 100644 --- a/server/src/main/java/com/growstory/domain/leaf/dto/LeafDto.java +++ b/server/src/main/java/com/growstory/domain/leaf/dto/LeafDto.java @@ -1,6 +1,5 @@ package com.growstory.domain.leaf.dto; -import com.growstory.global.badwords.dto.TextContainer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @@ -12,7 +11,7 @@ public class LeafDto { @Getter @Schema(name = "LeafPostDto") - public static class Post implements TextContainer { + public static class Post { @NotBlank private String leafName; @@ -24,17 +23,11 @@ public Post(String leafName, String content) { this.leafName = leafName; this.content = content; } - - @Override - public String combineText() { - StringBuilder sb = new StringBuilder(); - return sb.append(this.leafName).append(" ").append(this.content).toString(); - } } @Getter @Schema(name = "LeafPatchDto") - public static class Patch implements TextContainer { + public static class Patch { @Positive private Long leafId; @@ -53,12 +46,6 @@ public Patch(Long leafId, String leafName, String content, Boolean isImageUpdate this.content = content; this.isImageUpdated = isImageUpdated; } - - @Override - public String combineText() { - StringBuilder sb = new StringBuilder(); - return sb.append(this.leafName).append(" ").append(this.content).toString(); - } } @Getter diff --git a/server/src/main/java/com/growstory/domain/leaf/entity/Leaf.java b/server/src/main/java/com/growstory/domain/leaf/entity/Leaf.java index ab3ec0f1..d5a69737 100644 --- a/server/src/main/java/com/growstory/domain/leaf/entity/Leaf.java +++ b/server/src/main/java/com/growstory/domain/leaf/entity/Leaf.java @@ -33,7 +33,7 @@ public class Leaf extends BaseTimeEntity { @JoinColumn(name = "ACCOUNT_ID") private Account account; - @OneToOne(mappedBy = "leaf", cascade = CascadeType.ALL, orphanRemoval = true) + @OneToOne(mappedBy = "leaf") private PlantObj plantObj; @OneToMany(mappedBy = "leaf", cascade = CascadeType.ALL, orphanRemoval = true) @@ -58,8 +58,6 @@ public void updatePlantObj(PlantObj plantObj) { this.plantObj = plantObj; } - - public void removePlantObj() { this.plantObj = null; } diff --git a/server/src/main/java/com/growstory/domain/leaf/service/LeafService.java b/server/src/main/java/com/growstory/domain/leaf/service/LeafService.java index b7c7b9e4..6bd4dc67 100644 --- a/server/src/main/java/com/growstory/domain/leaf/service/LeafService.java +++ b/server/src/main/java/com/growstory/domain/leaf/service/LeafService.java @@ -1,6 +1,5 @@ package com.growstory.domain.leaf.service; -import com.growstory.domain.account.constants.AccountGrade; import com.growstory.domain.account.entity.Account; import com.growstory.domain.account.service.AccountService; import com.growstory.domain.images.service.JournalImageService; @@ -34,11 +33,11 @@ public class LeafService { private final AuthUserUtils authUserUtils; private final JournalImageService journalImageService; - public LeafDto.Response createLeaf(LeafDto.Post requestDto, MultipartFile leafImage) { + public LeafDto.Response createLeaf(LeafDto.Post leafPostDto, MultipartFile leafImage) { Account findAccount = authUserUtils.getAuthUser(); Leaf leaf = Leaf.builder() - .leafName(requestDto.getLeafName()) - .content(requestDto.getContent()) + .leafName(leafPostDto.getLeafName()) + .content(leafPostDto.getContent()) .account(findAccount) .build(); @@ -55,21 +54,21 @@ public LeafDto.Response createLeaf(LeafDto.Post requestDto, MultipartFile leafIm .build(); } - public void updateLeaf(LeafDto.Patch requestDto, MultipartFile leafImage) { + public void updateLeaf(LeafDto.Patch leafPatchDto, MultipartFile leafImage) { Account findAccount = authUserUtils.getAuthUser(); - Leaf findLeaf = findVerifiedLeafByAccount(findAccount.getAccountId(), requestDto.getLeafId()); + Leaf findLeaf = findVerifiedLeafByAccount(findAccount.getAccountId(), leafPatchDto.getLeafId()); String leafImageUrl = findLeaf.getLeafImageUrl(); - if (requestDto.getIsImageUpdated()) + if (leafPatchDto.getIsImageUpdated()) s3Uploader.deleteImageFromS3(leafImageUrl, LEAF_IMAGE_PROCESS_TYPE); if (Optional.ofNullable(leafImage).isPresent()) leafImageUrl = s3Uploader.uploadImageToS3(leafImage, LEAF_IMAGE_PROCESS_TYPE); leafRepository.save(findLeaf.toBuilder() - .leafName(Optional.ofNullable(requestDto.getLeafName()).orElse(findLeaf.getLeafName())) + .leafName(Optional.ofNullable(leafPatchDto.getLeafName()).orElse(findLeaf.getLeafName())) .leafImageUrl(leafImageUrl) - .content(Optional.ofNullable(requestDto.getContent()).orElse(findLeaf.getContent())) + .content(Optional.ofNullable(leafPatchDto.getContent()).orElse(findLeaf.getContent())) .build()); } @@ -98,7 +97,6 @@ public Leaf findLeafEntityBy(Long leafId) { public void deleteLeaf(Long leafId) { Account findAccount = authUserUtils.getAuthUser(); - Leaf findLeaf = findVerifiedLeafByAccount(findAccount.getAccountId(), leafId); s3Uploader.deleteImageFromS3(findLeaf.getLeafImageUrl(), LEAF_IMAGE_PROCESS_TYPE); @@ -126,14 +124,14 @@ private Leaf findVerifiedLeafByAccount(Long accountId, Long leafId) { else return findLeaf; } - public AccountGrade updateAccountGrade(Account findAccount) { + public Account.AccountGrade updateAccountGrade(Account findAccount) { int leavesNum = findAccount.getLeaves().size(); if (leavesNum < 50) { - return AccountGrade.GRADE_BRONZE; + return Account.AccountGrade.GRADE_BRONZE; } else if (leavesNum < 100) { - return AccountGrade.GRADE_SILVER; + return Account.AccountGrade.GRADE_SILVER; } else { - return AccountGrade.GRADE_GOLD; + return Account.AccountGrade.GRADE_GOLD; } } diff --git a/server/src/main/java/com/growstory/domain/plant_object/entity/PlantObj.java b/server/src/main/java/com/growstory/domain/plant_object/entity/PlantObj.java index fda9f681..a7e6a460 100644 --- a/server/src/main/java/com/growstory/domain/plant_object/entity/PlantObj.java +++ b/server/src/main/java/com/growstory/domain/plant_object/entity/PlantObj.java @@ -2,7 +2,6 @@ import com.growstory.domain.account.entity.Account; -import com.growstory.domain.guestbook.entity.GuestBook; import com.growstory.domain.leaf.entity.Leaf; import com.growstory.domain.plant_object.location.entity.Location; import com.growstory.domain.product.entity.Product; @@ -12,8 +11,6 @@ import lombok.NoArgsConstructor; import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; @Getter diff --git a/server/src/main/java/com/growstory/domain/plant_object/service/PlantObjService.java b/server/src/main/java/com/growstory/domain/plant_object/service/PlantObjService.java index 37ede600..871e8c21 100644 --- a/server/src/main/java/com/growstory/domain/plant_object/service/PlantObjService.java +++ b/server/src/main/java/com/growstory/domain/plant_object/service/PlantObjService.java @@ -73,7 +73,7 @@ public PlantObjDto.GardenInfoResponse findAllGardenInfo(Long accountId) { // POST : 유저 포인트로 오브젝트 구입 public PlantObjDto.TradeResponse buyProduct(Long accountId, Long productId) { // 시큐리티 컨텍스트 인증정보 확인 - accountService.checkAuthIdMatching(accountId); + accountService.isAuthIdMatching(accountId); // 인증 정보를 바탕으로 Account 엔티티 조회 Account findAccount = authUserUtils.getAuthUser(); @@ -105,7 +105,7 @@ public PlantObjDto.TradeResponse buyProduct(Long accountId, Long productId) { // PATCH : 오브젝트 되팔기 public PointDto.Response refundPlantObj(Long accountId, Long plantObjId) { - accountService.checkAuthIdMatching(accountId); + accountService.isAuthIdMatching(accountId); Account findAccount = authUserUtils.getAuthUser(); PlantObj plantObj = findVerifiedPlantObj(plantObjId); @@ -124,15 +124,15 @@ public PointDto.Response refundPlantObj(Long accountId, Long plantObjId) { // POST : 오브젝트 배치 (편집 완료) public void saveLocation(Long accountId, List patchLocationDtos) { - accountService.checkAuthIdMatching(accountId); + accountService.isAuthIdMatching(accountId); patchLocationDtos.stream() .forEach(patchLocationDto -> { LocationDto.Patch locationPatchDto = patchLocationDto.getLocationDto(); //프로덕트 id와 로케이션 id가 일치하지 않으면 예외 발생 -// if(patchLocationDto.getPlantObjId()!=locationPatchDto.getLocationId()) { -// throw new BusinessLogicException(ExceptionCode.LOCATION_NOT_ALLOW); -// } + if(patchLocationDto.getPlantObjId()!=locationPatchDto.getLocationId()) { + throw new BusinessLogicException(ExceptionCode.LOCATION_NOT_ALLOW); + } if(locationPatchDto.getX()<0 || locationPatchDto.getX()>11 || locationPatchDto.getY()<0 || locationPatchDto.getY()>7) { throw new BusinessLogicException(ExceptionCode.INVALID_LOCATION); @@ -144,7 +144,7 @@ public void saveLocation(Long accountId, List patchLo // PATCH : 오브젝트와 식물 카드 연결 / 해제 / 교체 public PlantObjDto.Response updateLeafConnection(Long accountId, Long plantObjId, Long leafId) { - accountService.checkAuthIdMatching(accountId); + accountService.isAuthIdMatching(accountId); boolean isLeafNull = leafId == null; PlantObj findPlantObj = findVerifiedPlantObj(plantObjId); @@ -160,9 +160,10 @@ public PlantObjDto.Response updateLeafConnection(Long accountId, Long plantObjId return plantObjMapper.toPlantObjResponse(findPlantObj); } - public PlantObj findVerifiedPlantObj (long plantObjId) { + private PlantObj findVerifiedPlantObj (long plantObjId) { return plantObjRepository.findById(plantObjId).orElseThrow(() -> new BusinessLogicException(ExceptionCode.PLANT_OBJ_NOT_FOUND)); + } private void buy(Account account, Product product) { diff --git a/server/src/main/java/com/growstory/domain/point/controller/PointController.java b/server/src/main/java/com/growstory/domain/point/controller/PointController.java deleted file mode 100644 index 9dbcff1e..00000000 --- a/server/src/main/java/com/growstory/domain/point/controller/PointController.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.growstory.domain.point.controller; - -import com.growstory.domain.point.service.PointService; -import com.growstory.global.response.SingleResponseDto; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import javax.validation.constraints.Positive; - -@RequiredArgsConstructor -@RequestMapping("/v1/points") -@RestController -public class PointController { - - private final PointService pointService; - - @Operation(summary = "Patch All Event Point", description = "Points awarded through events to everyone") - @PatchMapping("/all") - public ResponseEntity patchAllEventPoints(@Positive @RequestParam("point") int pointScore, - @RequestParam("event-key") String eventKey) { - - pointService.updateAllEventPoint(pointScore, eventKey); - - return ResponseEntity.noContent().build(); - } - - @Operation(summary = "Patch Someone Event Point", description = "Points awarded through events to someone") - @PatchMapping - public ResponseEntity patchEventPoint( - @Positive @RequestParam("account-id") Long accountId, - @Positive @RequestParam("point") int point, - @RequestParam("event-key")String eventKey) { - - pointService.updateEventPoint(accountId, point, eventKey); - - return ResponseEntity.noContent().build(); - } -} diff --git a/server/src/main/java/com/growstory/domain/point/service/PointService.java b/server/src/main/java/com/growstory/domain/point/service/PointService.java index 10f611bc..a296af5d 100644 --- a/server/src/main/java/com/growstory/domain/point/service/PointService.java +++ b/server/src/main/java/com/growstory/domain/point/service/PointService.java @@ -1,44 +1,29 @@ package com.growstory.domain.point.service; -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.account.repository.AccountRepository; -import com.growstory.domain.account.service.AccountService; import com.growstory.domain.point.entity.Point; import com.growstory.domain.point.repository.PointRepository; import com.growstory.global.exception.BusinessLogicException; import com.growstory.global.exception.ExceptionCode; 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; -import java.util.List; - @Transactional -@RequiredArgsConstructor -@Slf4j @Service +@RequiredArgsConstructor public class PointService { @Value("${mail.admin.address}") private String adminMailAddress; - @Value("${mail.guest}") - private String guest; - private static final int ADMIN_POINT = 100000000; - private static final int GUEST_POINT = 12300; // 게스트 시작 시 지급 포인트(10,000 + 2,300) - private static final int REGISTER_POINT = 2500; // 회원 가입시 지급 포인트 + private static final int REGISTER_POINT = 500; // 회원 가입시 지급 포인트 private static final int POSTING_POINT = 30; // 게시글 등록시 지급 포인트 private static final int DAILY_LOGIN_POINT = 10; // 일일 로그인시 지급 포인트 (출석 체크 창이나 버튼이 필요, 로그인을 지속하며 날짜가 갱신되었을 때 판별이 어려워보임) private static final int JOURNAL_WRITTEN_POINT = 10; // 저널 작성 포인트 - @Value("${event.key}") - private String EVENT_KEY; - private final PointRepository pointRepository; - private final AccountRepository accountRepository; public Point createPoint(String email) { // pointRepo.save 없이 account의 cascade로 자동 저장됨(account가 삭제되면 자동 삭제) @@ -46,10 +31,6 @@ public Point createPoint(String email) { return Point.builder() .score(ADMIN_POINT) .build(); - if (email.equals(guest)) - return Point.builder() - .score(GUEST_POINT) - .build(); return Point.builder() .score(REGISTER_POINT) @@ -89,26 +70,4 @@ public Point updatePoint(Point presentPoint, int updateScore) { .score(presentPoint.getScore() + updateScore) .build()); } - - // 계정 전원 포인트 지급 - public void updateAllEventPoint(int updateScore, String eventKey) { - if(!EVENT_KEY.equals(eventKey)) { - log.info("eventError"); - return; - } - - List findPoints = pointRepository.findAll(); - findPoints - .forEach(point -> updatePoint(point, updateScore)); - } - - // 특정 계정 포인트 지급 - public void updateEventPoint(Long accountId, Integer updateScore, String eventKey) { - if(!EVENT_KEY.equals(eventKey)) { - log.info("eventError"); - return; - } - Account findAccount = accountRepository.findById(accountId).get(); - updatePoint(findAccount.getPoint(), updateScore); - } } diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/constant/ChatMessageConstants.java b/server/src/main/java/com/growstory/domain/qnachat/chatmessage/constant/ChatMessageConstants.java deleted file mode 100644 index f492af92..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/constant/ChatMessageConstants.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.growstory.domain.qnachat.chatmessage.constant; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -public class ChatMessageConstants { - - @Getter - @AllArgsConstructor - @NoArgsConstructor - public enum EnumChatMessage { - QNA_ENTERED("님, 문의하신 내용을 자세하게 적어주시면 담당자가 훨씬 빠르게 내용을 파악하고 답변드릴 수 있습니다."); - - private String value; - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/controller/ChatMessageController.java b/server/src/main/java/com/growstory/domain/qnachat/chatmessage/controller/ChatMessageController.java deleted file mode 100644 index f1486764..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/controller/ChatMessageController.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.growstory.domain.qnachat.chatmessage.controller; - -import com.growstory.domain.qnachat.chatmessage.dto.ChatMessageRequestDto; -import com.growstory.domain.qnachat.chatmessage.dto.ChatMessageResponseDto; -import com.growstory.domain.qnachat.chatmessage.service.ChatMessageService; -import com.growstory.domain.qnachat.chatroom.dto.SimpChatRoomRequestDto; -import com.growstory.global.response.PageResponse; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import javax.validation.Valid; -import javax.validation.constraints.Positive; -import java.util.List; - -@Validated -@RequestMapping("v1/chat-messages") -@RequiredArgsConstructor -@RestController -public class ChatMessageController { - - private final ChatMessageService chatMessageService; - - @Operation(summary = "채팅방의 전체 메시지 조회", description = "채팅방의 전체 메시지를 조회합니다.") - @GetMapping("/{chatroom-id}") - public ResponseEntity>> getAllChatMessages(@PageableDefault Pageable pageable, - @Positive @PathVariable("chatroom-id") Long chatRoomId) { - return ResponseEntity.ok(chatMessageService.getAllChatMessage(pageable, chatRoomId)); - } - - @Operation(summary = "입장 메시지 만들기 테스트", description = "메시지 만들기 테스트") - @PostMapping("/enter-test") - public ResponseEntity createEnterMessage(@Valid @RequestBody SimpChatRoomRequestDto chatMessageRequest) { - return ResponseEntity.ok(chatMessageService.createEnterMessage(chatMessageRequest)); - } - - @Operation(summary = "보내는 메시지 만들기 테스트", description = "메시지 만들기 테스트") - @PostMapping("/send-test") - public ResponseEntity createSendMessage(@Valid @RequestPart ChatMessageRequestDto chatMessageRequest, - @RequestPart(required = false, value = "image") MultipartFile image) { - return ResponseEntity.ok(chatMessageService.createSendMessage(chatMessageRequest, image)); - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/controller/ChatMessageStompController.java b/server/src/main/java/com/growstory/domain/qnachat/chatmessage/controller/ChatMessageStompController.java deleted file mode 100644 index 21dda1a4..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/controller/ChatMessageStompController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.growstory.domain.qnachat.chatmessage.controller; - -import com.growstory.domain.qnachat.chatmessage.dto.ChatMessageRequestDto; -import com.growstory.domain.qnachat.chatmessage.dto.ChatMessageResponseDto; -import com.growstory.domain.qnachat.chatmessage.service.ChatMessageService; -import com.growstory.domain.qnachat.chatroom.dto.SimpChatRoomRequestDto; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.messaging.handler.annotation.MessageMapping; -import org.springframework.messaging.simp.SimpMessagingTemplate; -import org.springframework.stereotype.Controller; - -@Slf4j -@Controller -@RequiredArgsConstructor -public class ChatMessageStompController { - - private final SimpMessagingTemplate simpMessagingTemplate; - private final ChatMessageService chatMessageService; - - @MessageMapping(value = "/chatRoom/enter") - public void enterChatRoom(SimpChatRoomRequestDto enterMessageRequest) { - ChatMessageResponseDto chatMessageResponse = chatMessageService.createEnterMessage(enterMessageRequest); - simpMessagingTemplate.convertAndSend("/sub/chatRoom/" + enterMessageRequest.getChatRoomId(), chatMessageResponse); - } - - @MessageMapping(value = "/chatRoom/send") - public void sendMessageToChatRoom(ChatMessageRequestDto chatMessageRequest) { - ChatMessageResponseDto chatMessageResponse = chatMessageService.createSendMessage(chatMessageRequest, null); - simpMessagingTemplate.convertAndSend("/sub/chatRoom/" + chatMessageRequest.getChatRoomId(), chatMessageResponse); - } - - @MessageMapping(value = "/chatRoom/exit") - public void exitChatRoom(SimpChatRoomRequestDto deleteChatRoomRequest) { - ChatMessageResponseDto chatMessageResponse = chatMessageService.sendExitChatRoomMessage(deleteChatRoomRequest); - simpMessagingTemplate.convertAndSend("/sub/chatRoom/"+deleteChatRoomRequest.getChatRoomId(), chatMessageResponse); - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/dto/ChatMessageRequestDto.java b/server/src/main/java/com/growstory/domain/qnachat/chatmessage/dto/ChatMessageRequestDto.java deleted file mode 100644 index d8f33fa7..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/dto/ChatMessageRequestDto.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.growstory.domain.qnachat.chatmessage.dto; - -import com.growstory.domain.qnachat.chatmessage.entity.ChatMessage; -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.springframework.web.multipart.MultipartFile; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; - -@Getter -@NoArgsConstructor -public class ChatMessageRequestDto { - @NotNull @Min(1) - private Long senderId; - @NotNull @Min(1) - private Long chatRoomId; - @NotBlank - private String message; - - @Builder - public ChatMessageRequestDto(Long senderId, String message, Long chatRoomId) { - this.senderId = senderId; - this.message = message; - this.chatRoomId = chatRoomId; - } - - public static ChatMessageRequestDto of(Long chatRoomId, Long senderId, String message) { - return ChatMessageRequestDto.builder() - .chatRoomId(chatRoomId) - .senderId(senderId) - .message(message) - .build(); - } - -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/dto/ChatMessageResponseDto.java b/server/src/main/java/com/growstory/domain/qnachat/chatmessage/dto/ChatMessageResponseDto.java deleted file mode 100644 index 0b513dc9..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/dto/ChatMessageResponseDto.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.growstory.domain.qnachat.chatmessage.dto; - -import com.growstory.domain.qnachat.chatmessage.entity.ChatMessage; -import lombok.*; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -@Getter -@Builder -@AllArgsConstructor -public class ChatMessageResponseDto { - private Long messageId; - private Long senderId; - private String senderName; - private String message; - private String imageUrl; - private LocalDateTime createdAt; - private LocalDateTime modifiedAt; - - public static ChatMessageResponseDto from(ChatMessage chatMessage) { - String chatImgUrl = chatMessage.getChatMessageImage() == null ? null : chatMessage.getChatMessageImage().getImageUrl(); - return ChatMessageResponseDto.builder() - .messageId(chatMessage.getMessageId()) - .senderId(chatMessage.getAccount().getAccountId()) - .senderName(chatMessage.getAccount().getDisplayName()) - .message(chatMessage.getMessage()) - .imageUrl(chatImgUrl) - .createdAt(chatMessage.getCreatedAt().withNano(0)) - .modifiedAt(chatMessage.getModifiedAt().withNano(0)) - .build(); - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/entity/ChatMessage.java b/server/src/main/java/com/growstory/domain/qnachat/chatmessage/entity/ChatMessage.java deleted file mode 100644 index 7374f22b..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/entity/ChatMessage.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.growstory.domain.qnachat.chatmessage.entity; - -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.images.entity.ChatMessageImage; -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import com.growstory.global.audit.BaseTimeEntity; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - -@NoArgsConstructor -@Getter -@Entity -public class ChatMessage extends BaseTimeEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long messageId; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "sender_id", nullable = false) - Account account; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "chat_room_id", nullable = false) - private ChatRoom chatRoom; - - @Lob - @Column(nullable = false) - private String message; - - @OneToOne(mappedBy = "chatMessage", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, orphanRemoval = true) - private ChatMessageImage chatMessageImage; - - /** - * 생성자 - */ - - @Builder - public ChatMessage(Account account, String message, ChatMessageImage chatMessageImage, ChatRoom chatRoom) { - this.account = account; - this.message = message; - this.chatMessageImage = chatMessageImage; - this.chatRoom = chatRoom; - } - - /** - * 연관관계 메서드 - */ - public void updateChatMessageImage(ChatMessageImage chatMessageImage) { - this.chatMessageImage = chatMessageImage; - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/mapper/ChatMessageMapper.java b/server/src/main/java/com/growstory/domain/qnachat/chatmessage/mapper/ChatMessageMapper.java deleted file mode 100644 index 0ba6d99c..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/mapper/ChatMessageMapper.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.growstory.domain.qnachat.chatmessage.mapper; - -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.account.service.AccountService; -import com.growstory.domain.qnachat.chatmessage.dto.ChatMessageRequestDto; -import com.growstory.domain.qnachat.chatmessage.entity.ChatMessage; -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import com.growstory.domain.qnachat.chatroom.service.ChatRoomService; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; - -@RequiredArgsConstructor -@Component -public class ChatMessageMapper { - - private final AccountService accountService; - private final ChatRoomService chatRoomService; - - public ChatMessage toEntityFrom(ChatMessageRequestDto requestDto) { - if(requestDto == null) return null; - - Account findAccount = accountService.findVerifiedAccount(requestDto.getSenderId()); - ChatRoom findChatRoom = chatRoomService.findVerifiedChatRoom(requestDto.getChatRoomId()); - - return ChatMessage.builder() - .account(findAccount) - .chatRoom(findChatRoom) - .message(requestDto.getMessage()) - .build(); - }; -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/repository/ChatMessageRepository.java b/server/src/main/java/com/growstory/domain/qnachat/chatmessage/repository/ChatMessageRepository.java deleted file mode 100644 index df97f248..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/repository/ChatMessageRepository.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.growstory.domain.qnachat.chatmessage.repository; - -import com.growstory.domain.qnachat.chatmessage.entity.ChatMessage; -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface ChatMessageRepository extends JpaRepository { - //채팅방 페이지 조회 - Page findByChatRoom(Pageable pageable, ChatRoom chatRoom); - - - //채팅방 조건 메시지 조회 - List findAllByChatRoom(ChatRoom chatRoom); - - List findAllByChatRoom(ChatRoom chatRoom, Sort sort); - - //메시지 내용 조건 메시지 조회 - List findAllByMessageContaining(String message); - - List findAllByMessageContaining(String message, Sort sort); -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/service/ChatMessageService.java b/server/src/main/java/com/growstory/domain/qnachat/chatmessage/service/ChatMessageService.java deleted file mode 100644 index 52213da4..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/service/ChatMessageService.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.growstory.domain.qnachat.chatmessage.service; - -import com.growstory.domain.qnachat.chatmessage.dto.ChatMessageRequestDto; -import com.growstory.domain.qnachat.chatmessage.dto.ChatMessageResponseDto; -import com.growstory.domain.qnachat.chatroom.dto.SimpChatRoomRequestDto; -import com.growstory.global.response.PageResponse; -import org.springframework.data.domain.Pageable; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; - -public interface ChatMessageService { - PageResponse> getAllChatMessage(Pageable pageable, Long chatRoomId); - ChatMessageResponseDto createSendMessage(ChatMessageRequestDto chatMessageRequest, MultipartFile image); - ChatMessageResponseDto createEnterMessage(SimpChatRoomRequestDto chatMessageRequest); - ChatMessageResponseDto sendExitChatRoomMessage(SimpChatRoomRequestDto deleteChatRoomRequest); -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/service/ChatMessageServiceImpl.java b/server/src/main/java/com/growstory/domain/qnachat/chatmessage/service/ChatMessageServiceImpl.java deleted file mode 100644 index 247111b8..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatmessage/service/ChatMessageServiceImpl.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.growstory.domain.qnachat.chatmessage.service; - -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.account.service.AccountService; -import com.growstory.domain.images.entity.ChatMessageImage; -import com.growstory.domain.images.service.ChatMessageImageService; -import com.growstory.domain.qnachat.chatmessage.constant.ChatMessageConstants; -import com.growstory.domain.qnachat.chatmessage.dto.ChatMessageRequestDto; -import com.growstory.domain.qnachat.chatmessage.dto.ChatMessageResponseDto; -import com.growstory.domain.qnachat.chatmessage.entity.ChatMessage; -import com.growstory.domain.qnachat.chatmessage.repository.ChatMessageRepository; -import com.growstory.domain.qnachat.chatroom.constants.ChatRoomConstants; -import com.growstory.domain.qnachat.chatroom.dto.SimpChatRoomRequestDto; -import com.growstory.domain.qnachat.chatroom.entity.AccountChatRoom; -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import com.growstory.domain.qnachat.chatroom.service.ChatRoomService; -import com.growstory.global.exception.BusinessLogicException; -import com.growstory.global.exception.ExceptionCode; -import com.growstory.global.response.PageResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; -import java.util.stream.Collectors; - -@RequiredArgsConstructor -@Transactional -@Service -public class ChatMessageServiceImpl implements ChatMessageService{ - private final ChatRoomService chatRoomService; - private final ChatMessageRepository chatMessageRepository; - private final AccountService accountService; - private final ChatMessageImageService chatMessageImageService; - - private static final String CHAT_MESSAGE_IMAGE_PROCESS_TYPE = "chat_message_image"; - - // chatRoomId -> 메시지응답 페이지 반환 - @Override - @Transactional(readOnly = true) - public PageResponse> getAllChatMessage(Pageable pageable, Long chatRoomId) { - ChatRoom chatRoom = this.chatRoomService.findVerifiedChatRoom(chatRoomId); - Page page = this.chatMessageRepository.findByChatRoom(pageable, chatRoom); - List data = page.get().map(ChatMessageResponseDto::from).collect(Collectors.toList()); - return PageResponse.of(page, data); - } - - // 메시지 전송 요청 -> Account, ChatRoom과 매핑 후 저장 및 응답 - @Override - public ChatMessageResponseDto createSendMessage(ChatMessageRequestDto chatMessageRequest, MultipartFile image) { - Account account = accountService.findVerifiedAccount(chatMessageRequest.getSenderId()); - ChatRoom chatRoom = chatRoomService.findVerifiedChatRoom(chatMessageRequest.getChatRoomId()); - ChatMessage chatMessage = - ChatMessage.builder() - .account(account) - .chatRoom(chatRoom) - .message(chatMessageRequest.getMessage()) - .build(); - chatMessageRepository.save(chatMessage); - - // image가 null이 아닐 경우 이미지 업로드 및 DB 저장 - if(image!=null && !image.isEmpty()) { - mapChatMessageWithImage(image, chatMessage); - } - - return ChatMessageResponseDto.from(chatMessage); - } - - // 채팅방 입장 메시지 매핑 및 저장, 응답 - @Override - public ChatMessageResponseDto createEnterMessage(SimpChatRoomRequestDto chatMessageRequest) { - Long questionerId = chatMessageRequest.getSenderId(); - Long chatRoomId = chatMessageRequest.getChatRoomId(); - Account questioner = accountService.findVerifiedAccount(questionerId); - ChatRoom chatRoom = chatRoomService.findVerifiedChatRoom(chatRoomId); - AccountChatRoom accountChatRoom = chatRoomService.validateIsEntered(questionerId, chatRoomId); - chatRoomService.validateAlreadyEnter(questionerId, chatRoomId); - accountChatRoom.updateEntryCheck(true); - - // 대화 상대방 (관리자) 매핑 - AccountChatRoom reviewerChatRoom = chatRoom.getAccountChatRooms().stream() - .filter(accChatRoom -> accChatRoom.getAccount().getAccountId() != questionerId) - .filter(accChatRoom -> accChatRoom.getAccount().getRoles().contains("ADMIN")) - .findFirst() - .orElseThrow(() -> new BusinessLogicException(ExceptionCode.ACCOUNT_UNAUTHORIZED)); - - ChatMessage chatMessage = - ChatMessage.builder() - .message(setEntryMessage(questioner.getDisplayName())) - .account(reviewerChatRoom.getAccount()) - .chatRoom(chatRoom) - .build(); - - chatMessageRepository.save(chatMessage); - - return ChatMessageResponseDto.from(chatMessage); - } - - private void mapChatMessageWithImage(MultipartFile image, ChatMessage chatMessage) { - ChatMessageImage chatMessageImage - = chatMessageImageService.createChatMessageImgWithS3(image, CHAT_MESSAGE_IMAGE_PROCESS_TYPE, chatMessage); - chatMessage.updateChatMessageImage(chatMessageImage); - } - - private String setEntryMessage(String displayName) { - StringBuilder sb = new StringBuilder(); - return sb.append("안녕하세요 ") - .append(displayName) - .append(ChatMessageConstants.EnumChatMessage.QNA_ENTERED.getValue()) - .toString(); - } - - // 채팅방 삭제 메시지 전송 & 채팅방 떠나기 - @Override - public ChatMessageResponseDto sendExitChatRoomMessage(SimpChatRoomRequestDto deleteChatRoomRequest) { - Account account = accountService.findVerifiedAccount(deleteChatRoomRequest.getSenderId()); - ChatRoom chatRoom = chatRoomService.findVerifiedChatRoom(deleteChatRoomRequest.getChatRoomId()); - AccountChatRoom accountChatRoom = chatRoomService.getAccountChatRoomByAccountIdAndChatRoomId(account.getAccountId(), chatRoom.getChatRoomId()); - // 채팅방 떠나기 - chatRoomService.deleteChatRoom(accountChatRoom); - return createSendMessage(ChatMessageRequestDto.of(chatRoom.getChatRoomId(), account.getAccountId(), - account.getDisplayName() + ChatRoomConstants.EnumChatRoomMessage.enumExitChatRoomMessage.getValue()), null); - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/constants/ChatRoomConstants.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/constants/ChatRoomConstants.java deleted file mode 100644 index f8e2c75b..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/constants/ChatRoomConstants.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.constants; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -public class ChatRoomConstants { - - @Getter - @AllArgsConstructor - @NoArgsConstructor - public enum EnumChatRoomMessage { - enumExitChatRoomMessage("님이 채팅방을 퇴장하셨습니다."); - private String value; - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/controller/ChatRoomController.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/controller/ChatRoomController.java deleted file mode 100644 index 7c4a779a..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/controller/ChatRoomController.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.controller; - -import com.growstory.domain.qnachat.chatmessage.dto.ChatMessageResponseDto; -import com.growstory.domain.qnachat.chatmessage.service.ChatMessageService; -import com.growstory.domain.qnachat.chatroom.dto.*; -import com.growstory.domain.qnachat.chatroom.service.ChatRoomService; -import com.growstory.global.response.PageResponse; -import com.growstory.global.utils.UriCreator; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.web.PageableDefault; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.net.URI; -import java.util.List; - -@RequiredArgsConstructor -@RequestMapping("v1/chat-rooms") -@RestController -public class ChatRoomController { - private final ChatRoomService chatRoomService; - private final ChatMessageService chatMessageService; - - private static final String DEFAULT_URL = "/v1/chat-rooms"; - - @Operation(summary = "유저의 모든 채팅방 조회", description = "특정 유저의 모든 채팅방을 조회합니다.") - @GetMapping("/{account-id}") - public ResponseEntity>> getAllChatRooms( - @PathVariable("account-id") Long accountId, - @PageableDefault Pageable pageable) { - return ResponseEntity.ok(chatRoomService.getAllChatRooms(accountId, pageable)); - } - - @Operation(summary = "qna 채팅방 생성", description = "관리자와 문의자의 1:1 문의 채팅방을 생성합니다.") - @PostMapping - public ResponseEntity createQnaChatRoom(@RequestBody CreateQnaChatRequest createQnaChatRequest) { - Long chatRoomId = chatRoomService.createQnaChatRoom(createQnaChatRequest); - URI location = UriCreator.createUri(DEFAULT_URL, chatRoomId); - return ResponseEntity.created(location).body(CreateQnaChatResponse.builder().chatRoomId(chatRoomId).build()); - } - - @Operation(summary = "유저의 채팅방 입장 여부 조회", description = "특정 유저가 채팅방에 입장했는지 여부를 조회합니다.") - @PostMapping("/entry-check") - public ResponseEntity checkEntry(@RequestBody EntryCheckRequestDto entryCheckRequest) { - return ResponseEntity.ok(chatRoomService.checkEntry(entryCheckRequest)); - } - - - @Operation(summary = "채팅방 나가기", description = "특정 유저의 채팅방을 삭제 상태로 변경 합니다.") - @DeleteMapping("/out") - public ResponseEntity deleteChatRoom(@RequestBody SimpChatRoomRequestDto deleteChatRoomRequest) { - return ResponseEntity.ok(chatMessageService.sendExitChatRoomMessage(deleteChatRoomRequest)); - } - - @Operation(summary = "문의 답변 여부 갱신", description = "해당 채팅방의 답변 여부를 최신 상태로 갱신합니다.") - @PatchMapping("/qna-answer-renewal") - public ResponseEntity patchAnswer(@RequestBody SimpChatRoomRequestDto answerRenewalRequest) { - chatRoomService.updateAnswer(answerRenewalRequest); - return ResponseEntity.ok().build(); - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/ChatRoomRequestDto.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/ChatRoomRequestDto.java deleted file mode 100644 index 18422d8a..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/ChatRoomRequestDto.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.dto; - -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class ChatRoomRequestDto { - private String roomName; - - @Builder - public ChatRoomRequestDto(String roomName) { - this.roomName = roomName; - } - - public ChatRoom toEntity() { - return ChatRoom.builder() - .roomName(this.roomName) - .build(); - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/ChatRoomResponseDto.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/ChatRoomResponseDto.java deleted file mode 100644 index 7cec337d..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/ChatRoomResponseDto.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.dto; - -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.qnachat.chatmessage.entity.ChatMessage; -import com.growstory.domain.qnachat.chatroom.entity.AccountChatRoom; -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Comparator; -import java.util.List; -import java.util.Set; - -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Getter -public class ChatRoomResponseDto implements Comparable { - private Long chatRoomId; - private String roomName; - private Long otherAccountId; - private String otherAccountName; - private String createdAt; - private String status; - private Boolean isAnswered; - private String latestMessage; - private String latestTime; - - public static ChatRoomResponseDto from(AccountChatRoom accountChatRoom, AccountChatRoom otherAccountChatRoom) { - - List chatMessages = accountChatRoom.getChatRoom().getChatMessages(); - LocalDateTime tempLatestTime = LocalDateTime.of(2000, 1, 1, 1, 1, 1); - String tempLatestMessage = null; - for (ChatMessage chatMessage : chatMessages) { - if (chatMessage.getCreatedAt().isAfter(tempLatestTime)) { - tempLatestTime = chatMessage.getCreatedAt().withNano(0); - tempLatestMessage = chatMessage.getMessage(); - } - } - return ChatRoomResponseDto.builder() - .chatRoomId(accountChatRoom.getChatRoom().getChatRoomId()) - .roomName(accountChatRoom.getChatRoom().getRoomName()) - .otherAccountId(otherAccountChatRoom.getAccount().getAccountId()) - .otherAccountName(otherAccountChatRoom.getAccount().getDisplayName()) - .status(accountChatRoom.getChatRoom().getStatus().getMessage()) - .createdAt(accountChatRoom.getChatRoom().getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) - .isAnswered(accountChatRoom.getChatRoom().getIsAnswered()) - .latestMessage(tempLatestMessage) - .latestTime(tempLatestTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))) - .build(); - } - - public static ChatRoomResponseDto from(AccountChatRoom accountChatRoom) { - - List chatMessages = accountChatRoom.getChatRoom().getChatMessages(); - LocalDateTime tempLatestTime = LocalDateTime.of(2000, 1, 1, 1, 1, 1); - String tempLatestMessage = null; - - for(ChatMessage chatMessage : chatMessages) { - if(chatMessage.getCreatedAt().isAfter(tempLatestTime)) { - tempLatestTime = chatMessage.getCreatedAt().withNano(0); - tempLatestMessage = chatMessage.getMessage(); - } - } - return ChatRoomResponseDto.builder() - .chatRoomId(accountChatRoom.getChatRoom().getChatRoomId()) - .latestMessage(tempLatestMessage) - .latestTime(tempLatestTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) - .build(); - - } - - public void trimLatestTime() { - this.latestTime = this.latestTime.split(" ")[0]; -// return this; - } - - - @Override - public int compareTo(ChatRoomResponseDto other) { - // latestTime을 기준으로 내림차순 정렬 - return Comparator.comparing(ChatRoomResponseDto::getLatestTime, Comparator.nullsLast(Comparator.reverseOrder())) - .compare(this, other); - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/CreateQnaChatRequest.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/CreateQnaChatRequest.java deleted file mode 100644 index e4268e87..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/CreateQnaChatRequest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.dto; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; - -@Getter -@AllArgsConstructor -@NoArgsConstructor -public class CreateQnaChatRequest { - @NotNull @Min(1) - private Long questionerId; - @NotNull @Min(1) - private Long reviewerId; - @NotNull - private String qnaTitle; -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/CreateQnaChatResponse.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/CreateQnaChatResponse.java deleted file mode 100644 index 68f3c552..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/CreateQnaChatResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; - -@Getter -@NoArgsConstructor -public class CreateQnaChatResponse { - private Long chatRoomId; - - @Builder - public CreateQnaChatResponse(Long chatRoomId) { - this.chatRoomId = chatRoomId; - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/EntryCheckRequestDto.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/EntryCheckRequestDto.java deleted file mode 100644 index 31513039..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/EntryCheckRequestDto.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.dto; - -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; - -@Getter -@NoArgsConstructor -public class EntryCheckRequestDto { - @NotNull(message = "채팅방id를 입력해주세요.") @Min(1) - private Long chatRoomId; - @NotNull(message = "메시지를 전송할 계정 id를 입력해주세요.") @Min(1) - private Long accountId; - - @Builder - public EntryCheckRequestDto(Long chatRoomId, Long accountId) { - this.chatRoomId = chatRoomId; - this.accountId = accountId; - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/EntryCheckResponseDto.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/EntryCheckResponseDto.java deleted file mode 100644 index 27d2b5be..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/EntryCheckResponseDto.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.dto; - -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -@Getter -public class EntryCheckResponseDto { - - private boolean entryCheck; - - @Builder - public EntryCheckResponseDto(boolean entryCheck) { - this.entryCheck = entryCheck; - } - - public EntryCheckResponseDto from(boolean entryCheck) { - return EntryCheckResponseDto - .builder() - .entryCheck(entryCheck) - .build(); - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/SimpChatRoomRequestDto.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/SimpChatRoomRequestDto.java deleted file mode 100644 index 394dd283..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/dto/SimpChatRoomRequestDto.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.dto; - -import lombok.*; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class SimpChatRoomRequestDto { - @NotNull @Min(1) - private Long chatRoomId; - - @NotNull @Min(1) - private Long senderId; -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/entity/AccountChatRoom.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/entity/AccountChatRoom.java deleted file mode 100644 index dcb51278..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/entity/AccountChatRoom.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.entity; - - -import com.growstory.domain.account.entity.Account; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - -@NoArgsConstructor -@Getter -@Entity -public class AccountChatRoom { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "account_chat_room_id") - private Long accountChatRoomId; - - @ManyToOne - @JoinColumn(name = "account_id") - private Account account; - - @ManyToOne - @JoinColumn(name = "chatroom_id") - private ChatRoom chatRoom; - - @Column(nullable = false) - private boolean entryCheck; - - /** - * 생성자 - */ - @Builder - public AccountChatRoom(Long accountChatRoomId, Account account, ChatRoom chatRoom, boolean entryCheck) { - this.accountChatRoomId = accountChatRoomId; - this.account = account; - this.chatRoom = chatRoom; - this.entryCheck = entryCheck; - } - - /** - * 연관관계 메서드 - */ - - public void updateAccount(Account account) { - this.account = account; - account.getAccountChatRooms().add(this); - } - - public void updateChatRoom(ChatRoom chatRoom) { - this.chatRoom = chatRoom; - chatRoom.getAccountChatRooms().add(this); - } - - public void updateEntryCheck(boolean check) { - this.entryCheck = check; - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/entity/ChatRoom.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/entity/ChatRoom.java deleted file mode 100644 index 5425902a..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/entity/ChatRoom.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.entity; - -import com.growstory.domain.qnachat.chatmessage.entity.ChatMessage; -import com.growstory.domain.qnachat.chatroom.dto.ChatRoomRequestDto; -import com.growstory.global.audit.BaseTimeEntity; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; - -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Getter -@Entity -public class ChatRoom extends BaseTimeEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long chatRoomId; - - @Column(nullable = false) - private String roomName; - - @OneToMany(mappedBy = "chatRoom", cascade = CascadeType.ALL, orphanRemoval = true) - private List accountChatRooms = new ArrayList<>(); - - @OneToMany(mappedBy = "chatRoom", cascade = CascadeType.ALL, orphanRemoval = true) - private List chatMessages = new ArrayList<>(); - - @Enumerated(EnumType.STRING) - private ChatRoomStatus status; - - @Column(nullable = false) - private Boolean isAnswered; - - @Builder - public ChatRoom(String roomName) { - this.roomName = roomName; - this.status = ChatRoomStatus.EXISTS; - this.isAnswered = false; - } - - /** - * 연관관계 매핑 - */ - - public Long updateRoomName(ChatRoomRequestDto requestDto) { - this.roomName = requestDto.getRoomName(); - return this.chatRoomId; - } - - public void updateAnswered(boolean answered) { - this.isAnswered = answered; - } - - /** - * enum 타입 : 채팅방 상태 - */ - - @Getter - public enum ChatRoomStatus { - EXISTS(1, "EXISTS"), - DELETED(2, "DELETED"), - ANSWER_COMPLETED(3, "ANSWER COMPLETED"); - private final int status; - private final String message; - - ChatRoomStatus(int status, String message) { - this.status = status; - this.message = message; - } - } - public void updateStatus(ChatRoomStatus chatRoomStatus) { - this.status = chatRoomStatus; - } -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/repository/AccountChatRoomRepository.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/repository/AccountChatRoomRepository.java deleted file mode 100644 index da46937f..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/repository/AccountChatRoomRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.repository; - -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.qnachat.chatroom.entity.AccountChatRoom; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; -import java.util.Optional; - -public interface AccountChatRoomRepository extends JpaRepository { - List findAllByAccount(Account account); -// List findAllByChatRoomId(Long chatRoomId); - //TODO: 리팩토링 - Optional findOneByAccountAccountIdAndChatRoomChatRoomId(Long accountId, Long chatRoomId); -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/repository/ChatRoomRepository.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/repository/ChatRoomRepository.java deleted file mode 100644 index 039d2930..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/repository/ChatRoomRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.repository; - -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; - -public interface ChatRoomRepository extends JpaRepository { - // ChatRoom 상세 조회 - ChatRoom findByRoomName(String roomName); - - // ChatRoom 목록 조회 - List findAllByRoomName(String roomName); - - List findAllByRoomName(String roomName, Sort sort); - - // ChatRoom 목록 조회, 포함 일치 - List findAllByRoomNameContaining(String roomName); - - List findAllByRoomNameContaining(String roomName, Sort sort); -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/service/ChatRoomService.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/service/ChatRoomService.java deleted file mode 100644 index cdd53f66..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/service/ChatRoomService.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.service; - -import com.growstory.domain.qnachat.chatroom.dto.*; -import com.growstory.domain.qnachat.chatroom.entity.AccountChatRoom; -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import com.growstory.global.response.PageResponse; -import org.springframework.data.domain.Pageable; - -import java.util.List; - -public interface ChatRoomService { - PageResponse> getAllChatRooms(Long accountId, Pageable pageable); - ChatRoom findVerifiedChatRoom(Long chatRoomId); - Long createQnaChatRoom(CreateQnaChatRequest chatRoomRequestDto); - EntryCheckResponseDto checkEntry(EntryCheckRequestDto entryCheckRequestDto); - AccountChatRoom validateIsEntered(Long accountId, Long chatRoomId); - void validateAlreadyEnter(Long accountId, Long chatRoomId); - void deleteChatRoom(AccountChatRoom deleteAccChatRoomRequest); - void completeChatRoom(AccountChatRoom completeAccChatRoomRequest); - AccountChatRoom getAccountChatRoomByAccountIdAndChatRoomId(Long accountId, Long chatRoomId); - void updateAnswer(SimpChatRoomRequestDto answerRenewalRequest); -} diff --git a/server/src/main/java/com/growstory/domain/qnachat/chatroom/service/ChatRoomServiceImpl.java b/server/src/main/java/com/growstory/domain/qnachat/chatroom/service/ChatRoomServiceImpl.java deleted file mode 100644 index cc85d026..00000000 --- a/server/src/main/java/com/growstory/domain/qnachat/chatroom/service/ChatRoomServiceImpl.java +++ /dev/null @@ -1,188 +0,0 @@ -package com.growstory.domain.qnachat.chatroom.service; - -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.account.service.AccountService; -import com.growstory.domain.images.service.ChatMessageImageService; -import com.growstory.domain.qnachat.chatroom.dto.*; -import com.growstory.domain.qnachat.chatroom.entity.AccountChatRoom; -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import com.growstory.domain.qnachat.chatroom.repository.AccountChatRoomRepository; -import com.growstory.domain.qnachat.chatroom.repository.ChatRoomRepository; -import com.growstory.global.exception.BusinessLogicException; -import com.growstory.global.exception.ExceptionCode; -import com.growstory.global.response.PageResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.*; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - -@RequiredArgsConstructor -@Transactional -@Service -public class ChatRoomServiceImpl implements ChatRoomService { - private final ChatRoomRepository chatRoomRepository; - private final ChatMessageImageService chatMessageImageService; - private final AccountChatRoomRepository accountChatRoomRepository; - private final AccountService accountService; - - private static final String CHAT_MESSAGE_IMAGE_PROCESS_TYPE = "chat_message_image"; - - // GET, 계정 아이디로 전체 채팅방 조회 - @Override - @Transactional(readOnly = true) - public PageResponse> getAllChatRooms(Long accountId, Pageable pageable) { - Account findAccount = accountService.findVerifiedAccount(accountId); - List accountChatRoomList = accountChatRoomRepository.findAllByAccount(findAccount); - validateCountIsNotZero(accountChatRoomList); - List chatRoomResponses = new ArrayList<>(); - for (AccountChatRoom accountChatRoom : accountChatRoomList) { - // 일대일 채팅일 경우 - if(accountChatRoom.getChatRoom().getAccountChatRooms().size()==2) { - accountChatRoom.getChatRoom().getAccountChatRooms().stream() - .filter(tempAccountChatRoom -> !accountChatRoom.equals(tempAccountChatRoom)) - .filter(tempAccountChatRoom -> isValidateStatus(tempAccountChatRoom.getChatRoom())) - .forEach(tempAccountChatRoom ->chatRoomResponses.add(ChatRoomResponseDto.from(accountChatRoom, tempAccountChatRoom))); - } else // 그룹 채팅의 경우 - { - accountChatRoom.getChatRoom().getAccountChatRooms().stream() - .filter(tempAccountChatRoom -> isValidateStatus(tempAccountChatRoom.getChatRoom())) - .forEach(tempAccountChatRoom -> chatRoomResponses.add(ChatRoomResponseDto.from(accountChatRoom))); - } - } - - //최근 메시지 수신일을 기준으로 내림차순정렬 -// Collections.sort(chatRoomResponses, Comparator.comparing(ChatRoomResponseDto::getLatestTime).reversed()); - Collections.sort(chatRoomResponses); - - // 페이지네이션 처리 - int start = (int) pageable.getOffset(); - int end = Math.min((start + pageable.getPageSize()), chatRoomResponses.size()); - Page page = new PageImpl<>(chatRoomResponses.subList(start, end), pageable, chatRoomResponses.size()); - - page.getContent().forEach(content -> content.trimLatestTime()); - - return PageResponse.of(page, page.getContent()); - } - - //채팅방 id와 계정 id를 이용해 입장 여부를 조회 - @Override - public EntryCheckResponseDto checkEntry(EntryCheckRequestDto entryCheckRequestDto) { - Long accountId = entryCheckRequestDto.getAccountId(); - Long chatRoomId = entryCheckRequestDto.getChatRoomId(); - AccountChatRoom accountChatRoom = validateAccountIdAndChatRoomId(accountId, chatRoomId); - if(accountChatRoom.isEntryCheck()) return EntryCheckResponseDto.builder().entryCheck(true).build(); - else // 해당 계정이 채팅방에 입장하지 않았을 경우 - return EntryCheckResponseDto.builder().entryCheck(false).build(); - } - - - // 질문자 id와 검토자 id를 이용해 채팅방 및 어카운트 채팅방 생성 - @Override - public Long createQnaChatRoom(CreateQnaChatRequest createQnaChatRequest) { - Long questionerId = createQnaChatRequest.getQuestionerId(); - Long reviewerId = createQnaChatRequest.getReviewerId(); - - Account questioner = accountService.findVerifiedAccount(questionerId); - Account reviewer = accountService.findVerifiedAccount(reviewerId); - - ChatRoom chatRoom = ChatRoom.builder().roomName(createQnaChatRequest.getQnaTitle()).build(); - ChatRoom createdChatRoom = chatRoomRepository.save(chatRoom); - - AccountChatRoom accountChatRoomByQuestioner = AccountChatRoom.builder().account(questioner).chatRoom(createdChatRoom).build(); - AccountChatRoom accountChatRoomByReviewer = AccountChatRoom.builder().account(reviewer).chatRoom(createdChatRoom).build(); - - accountChatRoomByQuestioner.updateChatRoom(chatRoom); - accountChatRoomByReviewer.updateChatRoom(chatRoom); - - accountChatRoomRepository.save(accountChatRoomByQuestioner); - accountChatRoomRepository.save(accountChatRoomByReviewer); - - return createdChatRoom.getChatRoomId(); - } - - - @Override - public AccountChatRoom validateIsEntered(Long accountId, Long chatRoomId) { - return this.accountChatRoomRepository.findOneByAccountAccountIdAndChatRoomChatRoomId(accountId, chatRoomId).orElseThrow( - () -> new BusinessLogicException(ExceptionCode.ACCOUNT_CHATROOM_NOT_FOUND) - ); - } - - @Override - public void validateAlreadyEnter(Long accountId, Long chatRoomId) { - if(accountChatRoomRepository.findOneByAccountAccountIdAndChatRoomChatRoomId(accountId, chatRoomId).get().isEntryCheck()) { - throw new BusinessLogicException(ExceptionCode.ALREADY_CHATROOM_ENTERED); - } - } - - // ChatRoom 삭제 - @Override - public void deleteChatRoom(AccountChatRoom deleteAccChatRoomRequest) { - ChatRoom chatRoom = deleteAccChatRoomRequest.getChatRoom(); - chatRoom.getChatMessages().stream() - .forEach(chatMessage -> chatMessageImageService.deleteChatMessageImageWithS3(chatMessage.getChatMessageImage(),CHAT_MESSAGE_IMAGE_PROCESS_TYPE)); - - chatRoomRepository.delete(chatRoom); - } - - // ChatRoom 상태 completed 업데이트 - @Override - public void completeChatRoom(AccountChatRoom completeAccChatRoomRequest) { - ChatRoom chatRoom = completeAccChatRoomRequest.getChatRoom(); - chatRoom.updateStatus(ChatRoom.ChatRoomStatus.ANSWER_COMPLETED); - completeAccChatRoomRequest.updateChatRoom(chatRoom); - } - - // accountId와 chatRoomId를 통해 AccountChatRoom 조회 - @Override - public AccountChatRoom getAccountChatRoomByAccountIdAndChatRoomId(Long accountId, Long chatRoomId) { - return validateAccountIdAndChatRoomId(accountId, chatRoomId); - } - - // 답변 여부 업데이트 - @Override - public void updateAnswer(SimpChatRoomRequestDto answerRenewalRequest) { - Long lastSenderId = answerRenewalRequest.getSenderId(); - Long chatRoomId = answerRenewalRequest.getChatRoomId(); - - Account findAccount = accountService.findVerifiedAccount(lastSenderId); - ChatRoom findChatRoom = findVerifiedChatRoom(chatRoomId); - - boolean answered = false; - if(findAccount.getRoles().contains("ADMIN")) - answered = true; - - findChatRoom.updateAnswered(answered); - } - - // chatRoomId로 채팅방 조회 - @Override - public ChatRoom findVerifiedChatRoom(Long chatRoomId) { - return chatRoomRepository.findById(chatRoomId).orElseThrow(() -> - new BusinessLogicException(ExceptionCode.CHATROOM_NOT_FOUND)); - } - - - private AccountChatRoom validateAccountIdAndChatRoomId(Long accountId, Long chatRoomId) { - return this.accountChatRoomRepository.findOneByAccountAccountIdAndChatRoomChatRoomId(accountId, chatRoomId) - .orElseThrow(() -> new BusinessLogicException(ExceptionCode.ALREADY_CHATROOM_ENTERED)); - } - - // accountChatRoom의 인원이 0이면 예외 던지기 - private void validateCountIsNotZero(List accountChatRoomList) { - if (accountChatRoomList.size() == 0) - throw new BusinessLogicException(ExceptionCode.ACCOUNT_CHATROOM_NOT_FOUND); - } - - // 채팅방 상태가 유효(존재 || 답변 완료)한지 체크 - private boolean isValidateStatus(ChatRoom chatRoom) { - return chatRoom.getStatus().equals(ChatRoom.ChatRoomStatus.EXISTS) || - chatRoom.getStatus().equals(ChatRoom.ChatRoomStatus.ANSWER_COMPLETED); - } -} diff --git a/server/src/main/java/com/growstory/domain/rank/RankService.java b/server/src/main/java/com/growstory/domain/rank/RankService.java index 6cba0264..4c533097 100644 --- a/server/src/main/java/com/growstory/domain/rank/RankService.java +++ b/server/src/main/java/com/growstory/domain/rank/RankService.java @@ -24,7 +24,7 @@ public void compensateWeeklyPoints(Rank rank) { // 주간 랭킹별 포인트 보상액 산정 private int calculateWeeklyPoints(Rank rank) { int score; - switch (rank.getRankOrders().getPosition()) { + switch (rank.getRankStatus().getRank()) { case 1: score = 3000; break; diff --git a/server/src/main/java/com/growstory/domain/rank/board_likes/entity/BoardLikesRank.java b/server/src/main/java/com/growstory/domain/rank/board_likes/entity/BoardLikesRank.java index cb3f3b86..29cbbe46 100644 --- a/server/src/main/java/com/growstory/domain/rank/board_likes/entity/BoardLikesRank.java +++ b/server/src/main/java/com/growstory/domain/rank/board_likes/entity/BoardLikesRank.java @@ -4,6 +4,8 @@ import com.growstory.domain.board.entity.Board; import com.growstory.domain.rank.board_likes.dto.BoardLikesRankDto; import com.growstory.domain.rank.entity.Rank; +import com.growstory.global.exception.BusinessLogicException; +import com.growstory.global.exception.ExceptionCode; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -29,13 +31,12 @@ public BoardLikesRank(Board board, Long likeNum, Account account) { super(account); this.board = board; this.likeNum = likeNum; - super.updateRankStat(RankStat.CURRENT); } public BoardLikesRankDto.Response toResponseDto() { return BoardLikesRankDto.Response .builder() - .rank(this.getRankOrders().getPosition()) //Rank 에서 상속 받은 rank, account 정보 활용 + .rank(this.getRankStatus().getRank()) //Rank 에서 상속 받은 rank, account 정보 활용 .displayName(this.getAccount().getDisplayName()) .boardId(this.board.getBoardId()) .title(this.board.getTitle()) diff --git a/server/src/main/java/com/growstory/domain/rank/board_likes/service/BoardLikesRankService.java b/server/src/main/java/com/growstory/domain/rank/board_likes/service/BoardLikesRankService.java index 072a4ecb..7e42f4b8 100644 --- a/server/src/main/java/com/growstory/domain/rank/board_likes/service/BoardLikesRankService.java +++ b/server/src/main/java/com/growstory/domain/rank/board_likes/service/BoardLikesRankService.java @@ -4,9 +4,9 @@ import com.growstory.domain.rank.RankService; import com.growstory.domain.rank.board_likes.dto.BoardLikesRankDto; import com.growstory.domain.rank.board_likes.entity.BoardLikesRank; +import com.growstory.domain.rank.board_likes.history.entity.BoardLikesRankHistory; import com.growstory.domain.rank.board_likes.history.repository.BoardLikesRankHistoryRepository; import com.growstory.domain.rank.board_likes.repository.BoardLikesRankRepository; -import com.growstory.domain.rank.entity.Rank; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -32,55 +32,48 @@ public class BoardLikesRankService { @Value("${my.scheduled.cron}") private String cronExpression; - // 현재 주간 랭킹 조회 - public List findCurrentBoardLikesRanks() { - return repository.findAll().stream() - //이번 주의 유효한 랭킹만 조회 - .filter(boardLikesRank -> boardLikesRank.getRankStat()== Rank.RankStat.CURRENT) + // 주간 랭킹 조회 + public List findAllBoardLikesRanks() { + List boardLikesRanks = repository.findAll(); + return boardLikesRanks.stream() .map(BoardLikesRank::toResponseDto) .collect(Collectors.toList()); } - //TODO: 이력 테이블 삭제 - // 주 1회 랭킹 업데이트 및 이력 관리, 포인트 보상 @Scheduled(cron = "${my.scheduled.cron}") public void updateFindTop3LikedBoards() { log.info("# Scheduled task findTop3LikedBoards started at {}", LocalDateTime.now()); log.info("# and Cron expression is: {}", cronExpression); - // 기존 랭킹 데이터 상태 Previous로 전환 - repository.findAll() - .forEach(boardLikesRank -> boardLikesRank.updateRankStat(Rank.RankStat.PREVIOUS)); - // 좋아요 개수 상위 3등 까지의 게시글 조회 List boardLikesRanks = boardService.findTop3LikedBoardRanks(); - // 해당 게시글의 유저에게 보상 포인트 제공 + // 이전 주의 랭킹 이력 테이블에 저장 + saveHistories(boardLikesRanks); + + // 유저에게 보상 포인트 제공 boardLikesRanks .forEach(rankService::compensateWeeklyPoints); - // 이번 주 랭킹 저장 - repository.saveAll(boardLikesRanks); - // 이전 주의 랭킹 삭제 및 이번 주 랭킹 저장 -// repository.deleteAll(); -// List newBoardLikesRanks = boardService.findTop3LikedBoardRanks(); -// repository.saveAll(newBoardLikesRanks); + repository.deleteAll(); + List newBoardLikesRanks = boardService.findTop3LikedBoardRanks(); + repository.saveAll(newBoardLikesRanks); } // 이전 게시글 좋아요 랭킹을 이력 테이블로서 저장 -// private void saveHistories(List boardLikesRanks) { -// List histories -// = boardLikesRanks.stream() -// .map(rank -> { -// return BoardLikesRankHistory.builder() -// .accountId(rank.getAccount().getAccountId()) -// .boardId(rank.getBoard().getBoardId()) -// .likesNum(rank.getLikeNum()) -// .build(); -// }).collect(Collectors.toList()); -// historyRepository.saveAll(histories); -// } + private void saveHistories(List boardLikesRanks) { + List histories + = boardLikesRanks.stream() + .map(rank -> { + return BoardLikesRankHistory.builder() + .accountId(rank.getAccount().getAccountId()) + .boardId(rank.getBoard().getBoardId()) + .likesNum(rank.getLikeNum()) + .build(); + }).collect(Collectors.toList()); + historyRepository.saveAll(histories); + } } diff --git a/server/src/main/java/com/growstory/domain/rank/controller/RankController.java b/server/src/main/java/com/growstory/domain/rank/controller/RankController.java index 63071ddd..3c355d05 100644 --- a/server/src/main/java/com/growstory/domain/rank/controller/RankController.java +++ b/server/src/main/java/com/growstory/domain/rank/controller/RankController.java @@ -25,7 +25,7 @@ public class RankController { @GetMapping("/weekly-board-likes") public ResponseEntity getWeeklyBoardLikesRanks() { - List responseDto = boardLikesRankService.findCurrentBoardLikesRanks(); + List responseDto = boardLikesRankService.findAllBoardLikesRanks(); return ResponseEntity.ok(SingleResponseDto.builder() .data(responseDto) diff --git a/server/src/main/java/com/growstory/domain/rank/entity/Rank.java b/server/src/main/java/com/growstory/domain/rank/entity/Rank.java index 742cde25..34b128cb 100644 --- a/server/src/main/java/com/growstory/domain/rank/entity/Rank.java +++ b/server/src/main/java/com/growstory/domain/rank/entity/Rank.java @@ -25,74 +25,52 @@ public abstract class Rank extends BaseTimeEntity { private Account account; @Enumerated(EnumType.STRING) - private RankOrders rankOrders; - - @Enumerated(EnumType.STRING) - private RankStat rankStat; + private RankStatus rankStatus; public Rank(Account account) { this.account = account; } - protected void updateRank(RankOrders rankOrders) { - this.rankOrders = rankOrders; + protected void updateRank(RankStatus rankStatus) { + this.rankStatus = rankStatus; } @Getter - public enum RankOrders { - FIRST("rank_no_1", 1), - SECOND("rank_no_2", 2), - THIRD("rank_no_3", 3), - FOURTH("rank_no_4", 4), - FIFTH("rank_no_5", 5); - - private final String name; - private final int position; - - RankOrders(String name, int position) { - this.name = name; - this.position = position; + public enum RankStatus { + RANK_NO_1("rank_no_1", 1), + RANK_NO_2("rank_no_2", 2), + RANK_NO_3("rank_no_3", 3), + RANK_NO_4("rank_no_4", 4), + RANK_NO_5("rank_no_5", 5); + + private String status; + private int rank; + + RankStatus(String status, int rank) { + this.status = status; + this.rank = rank; } } - @Getter - public enum RankStat { - CURRENT("Current Record", 1), - PREVIOUS("Previous Record", 2); - - private final String recordLabel; - private final int typeCode; - - RankStat(String recordLabel, int typeCode) { - this.recordLabel = recordLabel; - this.typeCode = typeCode; - } - } - - public void updateRank(int rank) { switch (rank) { case 1 : - updateRank(RankOrders.FIRST); + updateRank(RankStatus.RANK_NO_1); break; case 2 : - updateRank(RankOrders.SECOND); + updateRank(RankStatus.RANK_NO_2); break; case 3 : - updateRank(RankOrders.THIRD); + updateRank(RankStatus.RANK_NO_3); break; case 4 : - updateRank(RankOrders.FOURTH); + updateRank(RankStatus.RANK_NO_4); break; case 5 : - updateRank(RankOrders.FIFTH); + updateRank(RankStatus.RANK_NO_5); break; default: throw new BusinessLogicException(ExceptionCode.RANK_NOT_FOUND); } } - - public void updateRankStat(RankStat rankStat) { - this.rankStat = rankStat; - } } diff --git a/server/src/main/java/com/growstory/domain/report/controller/ReportController.java b/server/src/main/java/com/growstory/domain/report/controller/ReportController.java deleted file mode 100644 index 1baefd35..00000000 --- a/server/src/main/java/com/growstory/domain/report/controller/ReportController.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.growstory.domain.report.controller; - -import com.growstory.domain.report.dto.ReportDto; -import com.growstory.domain.report.service.ReportService; -import com.growstory.global.constants.HttpStatusCode; -import com.growstory.global.response.MultiResponseDto; -import com.growstory.global.utils.UriCreator; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import javax.validation.constraints.Positive; -import java.net.URI; - -@Tag(name = "Report", description = "Report Controller") -@Validated -@RequiredArgsConstructor -@RequestMapping("/v1/reports") -@RestController -public class ReportController { - private static final String REPORT_DEFAULT_URL = "/v1/reports"; - - private final ReportService reportService; - - @Operation(summary = "신고 기능", description = "사용자 정보를 입력받아 그 사용자에 대한 신고 기능") - @PostMapping - public ResponseEntity postReport(@Valid @RequestBody ReportDto.Post reportPostDto) { - ReportDto.Response responseDto = reportService.createReport(reportPostDto); - URI location = UriCreator.createUri(REPORT_DEFAULT_URL, responseDto.getReportId()); - - return ResponseEntity.created(location).build(); - } - - @Operation(summary = "전체 신고 조회", description = "전체 신고 조회") - @GetMapping("/all") - public ResponseEntity> getReports(@Positive @RequestParam(defaultValue = "1") int page, - @Positive @RequestParam(defaultValue = "10") int size) { - Page responseDto = reportService.getReports(page - 1, size); - - return ResponseEntity.ok(MultiResponseDto.builder() - .status(HttpStatusCode.OK.getStatusCode()) - .message(HttpStatusCode.OK.getMessage()) - .data(responseDto.getContent()) - .page(responseDto) - .build()); - } -} diff --git a/server/src/main/java/com/growstory/domain/report/dto/ReportDto.java b/server/src/main/java/com/growstory/domain/report/dto/ReportDto.java deleted file mode 100644 index e9901d58..00000000 --- a/server/src/main/java/com/growstory/domain/report/dto/ReportDto.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.growstory.domain.report.dto; - -import com.growstory.domain.point.entity.Point; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Builder; -import lombok.Getter; - -import javax.validation.constraints.NotBlank; -import java.time.LocalDateTime; - -public class ReportDto { - @Getter - @Builder - @Schema(name = "ReportPostDto") - public static class Post { - @NotBlank - private Long accountId; - - @NotBlank - private Long reportedAccountId; - - @NotBlank - private String title; - - @NotBlank - private String content; - } - - @Getter - @Builder - @Schema(name = "ReportResponseDto") - public static class Response { - private Long reportId; - private String displayName; - private String reportedDisplayName; - private String content; - private LocalDateTime createdAt; - } -} diff --git a/server/src/main/java/com/growstory/domain/report/entity/Report.java b/server/src/main/java/com/growstory/domain/report/entity/Report.java deleted file mode 100644 index 9f1208ca..00000000 --- a/server/src/main/java/com/growstory/domain/report/entity/Report.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.growstory.domain.report.entity; - -import com.growstory.domain.account.entity.Account; -import com.growstory.global.audit.BaseTimeEntity; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - -@Getter -@NoArgsConstructor -@Entity -public class Report extends BaseTimeEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long reportId; - - @Lob - @Column(nullable = false) - private String content; - - @ManyToOne - @JoinColumn(name = "ACCOUNT_ID") - private Account account; - - private Long reportedAccountId; - - @Builder - public Report(Long reportId, String content, Account account, Long reportedAccountId) { - this.reportId = reportId; - this.content = content; - this.account = account; - this.reportedAccountId = reportedAccountId; - } -} diff --git a/server/src/main/java/com/growstory/domain/report/repository/ReportRepository.java b/server/src/main/java/com/growstory/domain/report/repository/ReportRepository.java deleted file mode 100644 index 7328aa8f..00000000 --- a/server/src/main/java/com/growstory/domain/report/repository/ReportRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.growstory.domain.report.repository; - -import com.growstory.domain.report.entity.Report; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface ReportRepository extends JpaRepository { -} diff --git a/server/src/main/java/com/growstory/domain/report/service/ReportService.java b/server/src/main/java/com/growstory/domain/report/service/ReportService.java deleted file mode 100644 index 71f9cda0..00000000 --- a/server/src/main/java/com/growstory/domain/report/service/ReportService.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.growstory.domain.report.service; - -import com.growstory.domain.account.dto.AccountDto; -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.account.service.AccountService; -import com.growstory.domain.report.dto.ReportDto; -import com.growstory.domain.report.entity.Report; -import com.growstory.domain.report.repository.ReportRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.stream.Collectors; - -@Transactional -@RequiredArgsConstructor -@Service -public class ReportService { - private final ReportRepository reportRepository; - private final AccountService accountService; - - public ReportDto.Response createReport(ReportDto.Post requestDto) { - Account findAccount = accountService.findVerifiedAccount(requestDto.getAccountId()); - Account findReportedAccount = accountService.findVerifiedAccount(requestDto.getReportedAccountId()); - - Report savedReport = reportRepository.save(Report.builder() - .account(findAccount) - .reportedAccountId(requestDto.getReportedAccountId()) - .content(requestDto.getContent()) - .build()); - findAccount.addReport(savedReport); - findReportedAccount.updateReportsNum(); - - return ReportDto.Response.builder() - .reportId(savedReport.getReportId()) - .build(); - } - - @Transactional(readOnly = true) - public Page getReports(int page, int size) { - List reports = reportRepository.findAll(); - List responses = reports.stream() - .map(report -> { - Account findReportedAccount = accountService.findVerifiedAccount(report.getReportedAccountId()); - - return ReportDto.Response.builder() - .reportId(report.getReportId()) - .displayName(report.getAccount().getDisplayName()) - .reportedDisplayName(findReportedAccount.getDisplayName()) - .content(report.getContent()) - .createdAt(report.getCreatedAt()) - .build(); - }) - .collect(Collectors.toList()); - - int startIdx = page * size; - int endIdx = Math.min(responses.size(), (page + 1) * size); - return new PageImpl<>(responses.subList(startIdx, endIdx), PageRequest.of(page, size), responses.size()); - } -} diff --git a/server/src/main/java/com/growstory/global/advice/GlobalExceptionAdvice.java b/server/src/main/java/com/growstory/global/advice/GlobalExceptionAdvice.java index c7328ec3..b0f37f6d 100644 --- a/server/src/main/java/com/growstory/global/advice/GlobalExceptionAdvice.java +++ b/server/src/main/java/com/growstory/global/advice/GlobalExceptionAdvice.java @@ -1,7 +1,6 @@ package com.growstory.global.advice; import com.growstory.global.exception.BusinessLogicException; -import com.growstory.global.exception.ExceptionCode; import com.growstory.global.response.ErrorResponse; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -11,7 +10,6 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.validation.ConstraintViolationException; -import java.util.Objects; @RestControllerAdvice public class GlobalExceptionAdvice { @@ -32,11 +30,10 @@ public ErrorResponse handleConstraintViolationException(ConstraintViolationExcep @ExceptionHandler(BusinessLogicException.class) // BusinessLogicException 처리 public ResponseEntity handleBusinessLogicException(BusinessLogicException e) { - ErrorResponse response = ErrorResponse.of(e.getExceptionCode()); - if(!Objects.isNull(e.getProfanityDto())) { - response = ErrorResponse.of(e.getExceptionCode(), e.getProfanityDto()); - } - final ErrorResponse errorResponse = response; + final ErrorResponse errorResponse = ErrorResponse.of(e.getExceptionCode()); + +// HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse(); +// ErrorResponder.sendErrorResponse(response, e.getExceptionCode().getStatus() ,e.getExceptionCode().getMessage()); return new ResponseEntity(errorResponse, HttpStatus.valueOf(e.getExceptionCode().getStatus())); } diff --git a/server/src/main/java/com/growstory/global/auth/config/PasswordEncoderConfig.java b/server/src/main/java/com/growstory/global/auth/config/PasswordEncoderConfig.java deleted file mode 100644 index a466bc54..00000000 --- a/server/src/main/java/com/growstory/global/auth/config/PasswordEncoderConfig.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.growstory.global.auth.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.crypto.factory.PasswordEncoderFactories; -import org.springframework.security.crypto.password.PasswordEncoder; - -@Configuration -public class PasswordEncoderConfig { - @Bean - public PasswordEncoder passwordEncoder() { - return PasswordEncoderFactories.createDelegatingPasswordEncoder(); - } -} diff --git a/server/src/main/java/com/growstory/global/auth/config/SecurityConfiguration.java b/server/src/main/java/com/growstory/global/auth/config/SecurityConfiguration.java index 78cc6fa1..805fcffa 100644 --- a/server/src/main/java/com/growstory/global/auth/config/SecurityConfiguration.java +++ b/server/src/main/java/com/growstory/global/auth/config/SecurityConfiguration.java @@ -1,7 +1,6 @@ package com.growstory.global.auth.config; import com.growstory.domain.account.repository.AccountRepository; -import com.growstory.domain.account.service.AccountService; import com.growstory.domain.point.repository.PointRepository; import com.growstory.domain.point.service.PointService; import com.growstory.global.auth.filter.JwtAuthenticationFilter; @@ -18,6 +17,8 @@ import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.factory.PasswordEncoderFactories; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter; import org.springframework.security.web.SecurityFilterChain; @@ -26,7 +27,6 @@ @RequiredArgsConstructor public class SecurityConfiguration { private final JwtTokenizer jwtTokenizer; - private final AccountService accountService; private final AccountRepository accountRepository; private final CustomAuthorityUtils authorityUtils; private final SecurityCorsConfig corsConfig; @@ -57,19 +57,15 @@ public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Excepti .anyRequest().permitAll()) .oauth2Login(oauth2 -> { oauth2.failureHandler(new OAuth2AccountFailureHandler()); - oauth2.successHandler(new OAuth2AccountSuccessHandler(jwtTokenizer, authorityUtils, accountService, accountRepository, pointService, pointRepository)); + oauth2.successHandler(new OAuth2AccountSuccessHandler(jwtTokenizer, authorityUtils, accountRepository, pointService, pointRepository)); }) .build(); } - // securityConfiguration 내부에서 passwordEncoder를 Bean으로 등록하기 때문에 - // accountService와 순환참조 발생 - // 따라서 PasswordEncoderConfig파일을 따로 만들어 - // 외부에서 passwordEncoder를 Bean으로 등록 -// @Bean -// public PasswordEncoder passwordEncoder() { -// return PasswordEncoderFactories.createDelegatingPasswordEncoder(); -// } + @Bean + public PasswordEncoder passwordEncoder() { + return PasswordEncoderFactories.createDelegatingPasswordEncoder(); + } public class CustomFilterConfigurer extends AbstractHttpConfigurer { @Override @@ -80,7 +76,7 @@ public void configure(HttpSecurity builder) throws Exception { JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager, jwtTokenizer); // JwtAuthenticationFilter 객체 생성하며 DI하기 // AbstractAuthenticationProcessingFilter에서 상속받은 filterProcessurl을 설정 (설정하지 않으면 default 값인 /Login) jwtAuthenticationFilter.setFilterProcessesUrl("/v1/accounts/authentication"); - jwtAuthenticationFilter.setAuthenticationSuccessHandler(new AccountAuthenticationSuccessHandler(accountRepository, accountService)); + jwtAuthenticationFilter.setAuthenticationSuccessHandler(new AccountAuthenticationSuccessHandler()); jwtAuthenticationFilter.setAuthenticationFailureHandler(new AccountAuthenticationFailureHandler()); JwtVerificationFilter jwtVerificationFilter = new JwtVerificationFilter(jwtTokenizer, authorityUtils); diff --git a/server/src/main/java/com/growstory/global/auth/config/SecurityCorsConfig.java b/server/src/main/java/com/growstory/global/auth/config/SecurityCorsConfig.java index c5650600..aa491020 100644 --- a/server/src/main/java/com/growstory/global/auth/config/SecurityCorsConfig.java +++ b/server/src/main/java/com/growstory/global/auth/config/SecurityCorsConfig.java @@ -23,6 +23,7 @@ public CorsFilter corsFilter() { config.addAllowedOriginPattern("http://localhost:80"); // 로컬 아파치 환경에서 접근하는 CORS 허용 config.addAllowedOriginPattern("http://localhost:3000"); // 로컬 프론트 환경에서 접근하는 CORS 허용 config.addAllowedOriginPattern("https://growstory.vercel.app"); // 배포 환경 + config.addAllowedOriginPattern("https://grows-tory.vercel.app"); // 배포 환경 // //응답 헤더에 Authorization 헤더를 노출하도록 설정 config.addExposedHeader("Authorization"); @@ -30,7 +31,6 @@ public CorsFilter corsFilter() { config.addExposedHeader("DisplayName"); config.addExposedHeader("AccountId"); config.addExposedHeader("ProfileImageUrl"); - config.addExposedHeader("Location"); config.addAllowedHeader("*"); //모든 header 허용 diff --git a/server/src/main/java/com/growstory/global/auth/dto/LoginDto.java b/server/src/main/java/com/growstory/global/auth/dto/LoginDto.java index 0c6b3cf0..c7767786 100644 --- a/server/src/main/java/com/growstory/global/auth/dto/LoginDto.java +++ b/server/src/main/java/com/growstory/global/auth/dto/LoginDto.java @@ -17,6 +17,5 @@ public static class Response { private String email; private String displayName; private String profileImageUrl; - private String status; } } diff --git a/server/src/main/java/com/growstory/global/auth/filter/JwtAuthenticationFilter.java b/server/src/main/java/com/growstory/global/auth/filter/JwtAuthenticationFilter.java index fbf80951..d419b972 100644 --- a/server/src/main/java/com/growstory/global/auth/filter/JwtAuthenticationFilter.java +++ b/server/src/main/java/com/growstory/global/auth/filter/JwtAuthenticationFilter.java @@ -74,7 +74,6 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR .email(account.getEmail()) .displayName(URLEncoder.encode(account.getDisplayName(), "UTF-8")) .profileImageUrl(account.getProfileImageUrl()) - .status(account.getStatus().getStepDescription()) .build(); // response body에 유저 정보 저장 diff --git a/server/src/main/java/com/growstory/global/auth/filter/JwtVerificationFilter.java b/server/src/main/java/com/growstory/global/auth/filter/JwtVerificationFilter.java index e81b4cc7..68b4bf47 100644 --- a/server/src/main/java/com/growstory/global/auth/filter/JwtVerificationFilter.java +++ b/server/src/main/java/com/growstory/global/auth/filter/JwtVerificationFilter.java @@ -2,6 +2,9 @@ import com.growstory.global.auth.jwt.JwtTokenizer; import com.growstory.global.auth.utils.CustomAuthorityUtils; +import com.growstory.global.exception.BusinessLogicException; +import com.growstory.global.exception.ExceptionCode; +import com.growstory.global.response.ErrorResponder; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.SignatureException; @@ -9,6 +12,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.json.BasicJsonParser; import org.springframework.boot.json.JsonParser; +import org.springframework.http.HttpStatus; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; @@ -22,6 +26,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -64,8 +69,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse // 이걸 저장할 때 설정 Date accessTokenExpiration = new Date((Long) accessTokenClaims.get("exp") * 1000L); Date refreshTokenExpiration = new Date((Long) refreshTokenClaims.get("exp") * 1000L); -// System.out.println("before:" + accessTokenExpiration); -// System.out.println("before:" + refreshTokenExpiration); + System.out.println("before:" + accessTokenExpiration); + System.out.println("before:" + refreshTokenExpiration); Date now = new Date(); // accessToken 만료시간이 지금보다 이전이면(accessToken 만료 O), refreshToken 만료시간이 지금보다 이후라면(refreshToken 만료 X) @@ -83,6 +88,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse Map recreatedAccessTokenClaims = verifyJws(accessToken); // JWT 검증 verifyJws(refreshToken); setAuthenticationToContext(recreatedAccessTokenClaims); + //jwt 검증에 실패할 경우 발생하는 예외를 HttpServletRequest의 속성(Attribute)으로 추가 } catch (SignatureException se) { request.setAttribute("exception", se); diff --git a/server/src/main/java/com/growstory/global/auth/handler/AccountAuthenticationSuccessHandler.java b/server/src/main/java/com/growstory/global/auth/handler/AccountAuthenticationSuccessHandler.java index e9512e5e..3cbfd1f4 100644 --- a/server/src/main/java/com/growstory/global/auth/handler/AccountAuthenticationSuccessHandler.java +++ b/server/src/main/java/com/growstory/global/auth/handler/AccountAuthenticationSuccessHandler.java @@ -1,10 +1,5 @@ package com.growstory.global.auth.handler; -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.account.repository.AccountRepository; -import com.growstory.domain.account.service.AccountService; -import com.growstory.global.exception.BusinessLogicException; -import com.growstory.global.exception.ExceptionCode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; @@ -14,22 +9,13 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.Map; @Slf4j @RequiredArgsConstructor public class AccountAuthenticationSuccessHandler implements AuthenticationSuccessHandler { - private final AccountRepository accountRepository; - private final AccountService accountService; - @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { log.info("# Authenticated successfully !"); - - Account account = accountRepository.findById(((Account) authentication.getPrincipal()).getAccountId()).orElseThrow(() -> - new BusinessLogicException(ExceptionCode.ACCOUNT_NOT_FOUND)); - - accountService.attendanceCheck(account); } } diff --git a/server/src/main/java/com/growstory/global/auth/handler/OAuth2AccountSuccessHandler.java b/server/src/main/java/com/growstory/global/auth/handler/OAuth2AccountSuccessHandler.java index 3081eb64..8150d719 100644 --- a/server/src/main/java/com/growstory/global/auth/handler/OAuth2AccountSuccessHandler.java +++ b/server/src/main/java/com/growstory/global/auth/handler/OAuth2AccountSuccessHandler.java @@ -1,9 +1,7 @@ package com.growstory.global.auth.handler; -import com.growstory.domain.account.constants.Status; import com.growstory.domain.account.entity.Account; import com.growstory.domain.account.repository.AccountRepository; -import com.growstory.domain.account.service.AccountService; import com.growstory.domain.point.entity.Point; import com.growstory.domain.point.repository.PointRepository; import com.growstory.domain.point.service.PointService; @@ -11,15 +9,21 @@ import com.growstory.global.auth.utils.CustomAuthorityUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseCookie; +import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.springframework.web.util.UriComponentsBuilder; import org.yaml.snakeyaml.util.UriEncoder; import javax.servlet.ServletException; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.*; @@ -31,7 +35,6 @@ public class OAuth2AccountSuccessHandler extends SimpleUrlAuthenticationSuccessH private final JwtTokenizer jwtTokenizer; private final CustomAuthorityUtils authorityUtils; - private final AccountService accountService; private final AccountRepository accountRepository; private final PointService pointService; private final PointRepository pointRepository; @@ -57,14 +60,11 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo .profileImageUrl(profileImageUrl) .point(point) .roles(authorities) - //status social로 추가 - .status(Status.SOCIAL_USER) + .accountGrade(Account.AccountGrade.GRADE_BRONZE) .build()); point.updateAccount(savedAccount); pointRepository.save(point); - } else { - accountService.attendanceCheck(optionalAccount.get()); } redirect(request, response, optionalAccount.orElse(savedAccount), authorities); @@ -135,6 +135,9 @@ private Object createURI(String accessToken, String refreshToken, Account accoun .newInstance() .scheme("https") .host("growstory.vercel.app") +// .port(3000) +// .host("growstory.s3-website.ap-northeast-2.amazonaws.com") +// .port(80) //S3는 80포트 .port(443) .path("/signin") .queryParam("access_token", accessToken) @@ -142,29 +145,28 @@ private Object createURI(String accessToken, String refreshToken, Account accoun .queryParam("accountId", account.getAccountId()) .queryParam("displayName", UriEncoder.encode(account.getDisplayName())) .queryParam("profileIamgeUrl", account.getProfileImageUrl()) - .queryParam("status", account.getStatus().getStepDescription()) .build() .toUri(); } -// private HttpServletResponse addCookies(HttpServletResponse response, Account account, String accessToken, String refreshToken) { -// response.addHeader("Set-Cookie", createCookie("access_token", accessToken).toString()); -// response.addHeader("Set-Cookie", createCookie("refresh_token", refreshToken).toString()); -// response.addHeader("Set-Cookie", createCookie("account_id", account.getAccountId().toString()).toString()); -// response.addHeader("Set-Cookie", createCookie("displayName", UriEncoder.encode(account.getDisplayName())).toString()); -// response.addHeader("Set-Cookie", createCookie("profileImageUrl", account.getProfileImageUrl()).toString()); -// -// return response; -// } -// -// private ResponseCookie createCookie(String key, String value) { -// ResponseCookie cookie = ResponseCookie.from(key, value) -// .sameSite("") -//// .domain("seb45-main-011.vercel.app") -// .path("/") -//// .secure(true) -// .build(); -// -// return cookie; -// } + private HttpServletResponse addCookies(HttpServletResponse response, Account account, String accessToken, String refreshToken) { + response.addHeader("Set-Cookie", createCookie("access_token", accessToken).toString()); + response.addHeader("Set-Cookie", createCookie("refresh_token", refreshToken).toString()); + response.addHeader("Set-Cookie", createCookie("account_id", account.getAccountId().toString()).toString()); + response.addHeader("Set-Cookie", createCookie("displayName", UriEncoder.encode(account.getDisplayName())).toString()); + response.addHeader("Set-Cookie", createCookie("profileImageUrl", account.getProfileImageUrl()).toString()); + + return response; + } + + private ResponseCookie createCookie(String key, String value) { + ResponseCookie cookie = ResponseCookie.from(key, value) + .sameSite("") +// .domain("seb45-main-011.vercel.app") + .path("/") +// .secure(true) + .build(); + + return cookie; + } } diff --git a/server/src/main/java/com/growstory/global/auth/jwt/JwtTokenizer.java b/server/src/main/java/com/growstory/global/auth/jwt/JwtTokenizer.java index 462a6bbf..53a9f5ce 100644 --- a/server/src/main/java/com/growstory/global/auth/jwt/JwtTokenizer.java +++ b/server/src/main/java/com/growstory/global/auth/jwt/JwtTokenizer.java @@ -71,7 +71,7 @@ public Jws getClaims(String jws, String base64EncodedSecretKey) { .build() .parseClaimsJws(jws); // 토큰의 유효성 검사 -// System.out.println("after:" + claims.getBody().getExpiration()); + System.out.println("after:" + claims.getBody().getExpiration()); return claims; } diff --git a/server/src/main/java/com/growstory/global/auth/utils/CustomAuthorityUtils.java b/server/src/main/java/com/growstory/global/auth/utils/CustomAuthorityUtils.java index 3d283555..12d8ddfc 100644 --- a/server/src/main/java/com/growstory/global/auth/utils/CustomAuthorityUtils.java +++ b/server/src/main/java/com/growstory/global/auth/utils/CustomAuthorityUtils.java @@ -12,13 +12,8 @@ public class CustomAuthorityUtils { @Value("${mail.admin.address}") private String adminMailAddress; - - @Value("${mail.guest}") - private String guest; - private final List ADMIN_ROLES_STRING = List.of("ADMIN", "USER"); private final List USER_ROLES_STRING = List.of("USER"); - private final List GUEST_ROLE_STRING = List.of("GUEST", "USER"); // DB 저장된 Role 기반 권한 정보 생성 public List createAuthorities(List roles) { @@ -33,8 +28,6 @@ public List createRoles(String email) { if(email.equals(adminMailAddress)) { return ADMIN_ROLES_STRING; } - if (email.equals(guest)) return GUEST_ROLE_STRING; - return USER_ROLES_STRING; } } diff --git a/server/src/main/java/com/growstory/global/aws/config/S3Config.java b/server/src/main/java/com/growstory/global/aws/config/S3Config.java index c0ad3517..ab600427 100644 --- a/server/src/main/java/com/growstory/global/aws/config/S3Config.java +++ b/server/src/main/java/com/growstory/global/aws/config/S3Config.java @@ -3,7 +3,7 @@ import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @@ -21,10 +21,10 @@ public class S3Config { private String region; @Bean - public AmazonS3Client amazonS3Client() { + public AmazonS3 amazonS3Client() { AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey); - return (AmazonS3Client) AmazonS3ClientBuilder + return AmazonS3ClientBuilder .standard() .withCredentials(new AWSStaticCredentialsProvider(credentials)) .withRegion(region) diff --git a/server/src/main/java/com/growstory/global/aws/service/S3Uploader.java b/server/src/main/java/com/growstory/global/aws/service/S3Uploader.java index 6ed90037..cbf49214 100644 --- a/server/src/main/java/com/growstory/global/aws/service/S3Uploader.java +++ b/server/src/main/java/com/growstory/global/aws/service/S3Uploader.java @@ -1,6 +1,6 @@ package com.growstory.global.aws.service; -import com.amazonaws.services.s3.AmazonS3Client; +import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.CannedAccessControlList; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; @@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; @@ -18,7 +19,7 @@ @Service @RequiredArgsConstructor public class S3Uploader { - private final AmazonS3Client amazonS3Client; + private final AmazonS3 amazonS3; @Value("${cloud.aws.s3.bucket}") private String bucket; @@ -33,7 +34,7 @@ public String uploadImageToS3(MultipartFile image, String type) { metadata.setContentType(ext); try { - PutObjectResult putObjectRequest = amazonS3Client.putObject(new PutObjectRequest( + PutObjectResult putObjectRequest = amazonS3.putObject(new PutObjectRequest( bucket + "/" + type, changedName, image.getInputStream(), metadata) .withCannedAcl(CannedAccessControlList.PublicRead) ); @@ -41,14 +42,14 @@ public String uploadImageToS3(MultipartFile image, String type) { throw new RuntimeException(e); } - String imageUrl = amazonS3Client.getUrl(bucket + "/" + type, changedName).toString(); + String imageUrl = amazonS3.getUrl(bucket + "/" + type, changedName).toString(); return imageUrl; } public void deleteImageFromS3(String imageUrl, String type) { if (imageUrl.contains("https://s3.ap-northeast-2.amazonaws.com/"+ bucket)) - amazonS3Client.deleteObject(bucket + "/" + type, imageUrl.split("/")[6]); + amazonS3.deleteObject(bucket + "/" + type, imageUrl.split("/")[6]); } // 이미지 이름 변경 diff --git a/server/src/main/java/com/growstory/global/badwords/aspect/BadWordsAspect.java b/server/src/main/java/com/growstory/global/badwords/aspect/BadWordsAspect.java deleted file mode 100644 index 04e05e26..00000000 --- a/server/src/main/java/com/growstory/global/badwords/aspect/BadWordsAspect.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.growstory.global.badwords.aspect; - -import com.growstory.global.badwords.dto.ProfanityDto; -import com.growstory.global.badwords.dto.TextContainer; -import com.growstory.global.badwords.service.BlackListService; -import com.growstory.global.exception.BusinessLogicException; -import com.growstory.global.exception.ExceptionCode; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; -import org.aspectj.lang.annotation.Pointcut; -import org.springframework.stereotype.Component; - -import java.util.Set; - -@Slf4j -@RequiredArgsConstructor -@Component -@Aspect -public class BadWordsAspect { - - private final BlackListService badWordsService; - - @Pointcut("execution(public * com.growstory..journal.controller.*.postJournal(..)) || " + - "execution(public * com.growstory..journal.controller.*.patchJournal(..)) || " + - "execution(public * com.growstory..board.controller.*.postBoard(..)) || " + - "execution(public * com.growstory..board.controller.*.patchBoard(..)) || " + - "execution(public * com.growstory..comment.controller.*.postComment(..)) || " + - "execution(public * com.growstory..comment.controller.*.patchComment(..)) || " + - "execution(public * com.growstory..leaf.controller.*.postLeaf(..)) || " + - "execution(public * com.growstory..leaf.controller.*.patchLeaf(..)) || " + - "execution(public * com.growstory..account.controller.*.postAccount(..)) || " + - "execution(public * com.growstory..account.controller.*.patchDisplayName(..)) " ) - public void beforeWritten() { - } - - @Before("beforeWritten()") - public void badWordsFiltering(JoinPoint joinPoint) throws Throwable { - log.info("# 욕설 필터링 동작"); - Object[] args = joinPoint.getArgs(); - - String content = ""; - for(Object container : args) { - if(container instanceof TextContainer) { - TextContainer dto = (TextContainer) container; - content = dto.combineText(); - break; - } - } - - ProfanityDto profanityDto = badWordsService.getProfanityWords(content); - Set profanityWords = profanityDto.getInputProfanityWords(); - //욕설이 포함되어 있다면 - if(!profanityWords.isEmpty()) { - throw new BusinessLogicException(ExceptionCode.BAD_WORD_INCLUDED, profanityDto); - } - } - -} diff --git a/server/src/main/java/com/growstory/global/badwords/dto/ProfanityDto.java b/server/src/main/java/com/growstory/global/badwords/dto/ProfanityDto.java deleted file mode 100644 index 17532efc..00000000 --- a/server/src/main/java/com/growstory/global/badwords/dto/ProfanityDto.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.growstory.global.badwords.dto; - -import lombok.Builder; -import lombok.Getter; - -import java.util.HashSet; -import java.util.Set; - -@Getter -@Builder -public class ProfanityDto { - Set inputProfanityWords = new HashSet<>(); - Set bannedWords = new HashSet<>(); - - @Override - public String toString() { - StringBuilder response = new StringBuilder(); - - String inputProfanityWords = this.getInputProfanityWords().toString(); - String bannedWords = this.getBannedWords().toString(); - - return response.append(inputProfanityWords.substring(1, inputProfanityWords.length()-1)) - .append("/") - .append(bannedWords.substring(1, bannedWords.length()-1)).toString(); - } -} diff --git a/server/src/main/java/com/growstory/global/badwords/dto/TextContainer.java b/server/src/main/java/com/growstory/global/badwords/dto/TextContainer.java deleted file mode 100644 index 9ac0be35..00000000 --- a/server/src/main/java/com/growstory/global/badwords/dto/TextContainer.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.growstory.global.badwords.dto; - -public interface TextContainer { - // 유저 작성글 내용을 하나의 텍스트로 통합 - public String combineText(); -} diff --git a/server/src/main/java/com/growstory/global/badwords/filterlist/BlackList.java b/server/src/main/java/com/growstory/global/badwords/filterlist/BlackList.java deleted file mode 100644 index c057ba17..00000000 --- a/server/src/main/java/com/growstory/global/badwords/filterlist/BlackList.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.growstory.global.badwords.filterlist; - -public interface BlackList { - String[] koreanSlangs = { - "ㅅㅂ", "씨발", "씨바", "개세끼", "18년", "18놈", "18새끼", "ㄱㅐㅅㅐㄲl", "ㄱㅐㅈㅏ", "가슴만져", "가슴빨아", "가슴빨어", "가슴조물락", "가슴주물럭", "가슴쪼물딱", - "가슴쪼물락", "가슴핧아", "가슴핧어", "강간", "개가튼년", "개가튼뇬", "개같은년", "개걸레", "개고치", "개너미", "개넘", "개년", "개놈", "개늠", "개똥", "개떵", "개떡", - "개라슥", "개보지", "개부달", "개부랄", "개불랄", "개붕알", "개새", "개세", "개쓰래기", "개쓰레기", "개씁년", "개씁블", "개씁자지", "개씨발", "개씨블", "개자식", "개자지", - "개잡년", "개젓가튼넘", "개좆", "개지랄", "개후라년", "개후라들놈", "개후라새끼", "걔잡년", "거시기", "걸래년", "걸레같은년", "걸레년", "걸레핀년", "게부럴", "게세끼", "게이", - "게새끼", "게늠", "게자식", "게지랄놈", "고환", "공지", "공지사항", "귀두", "깨쌔끼", "난자마셔", "난자먹어", "난자핧아", "내꺼빨아", "내꺼핧아", "내버지", "내자지", "내잠지", - "내조지", "너거애비", "노옴", "누나강간", "니기미", "니뿡", "니뽕", "니씨브랄", "니아범", "니아비", "니애미", "니애뷔", "니애비", "니할애비", "닝기미", "닌기미", "니미", - "닳은년", "덜은새끼", "돈새끼", "돌으년", "돌은넘", "돌은새끼", "동생강간", "동성애자", "딸딸이", "똥구녁", "똥꾸뇽", "똥구뇽", "똥", "띠발뇬", "띠팔", "띠펄", "띠풀", "띠벌", - "띠벨", "띠빌", "마스터", "막간년", "막대쑤셔줘", "막대핧아줘", "맛간년", "맛없는년", "맛이간년", "멜리스", "미친구녕", "미친구멍", "미친넘", "미친년", "미친놈", "미친눔", - "미친새끼", "미친쇄리", "미친쇠리", "미친쉐이", "미친씨부랄", "미튄", "미티넘", "미틴", "미틴넘", "미틴년", "미틴놈", "미틴것", "백보지", "버따리자지", "버지구녕", "버지구멍", - "버지냄새", "버지따먹기", "버지뚫어", "버지뜨더", "버지물마셔", "버지벌려", "버지벌료", "버지빨아", "버지빨어", "버지썰어", "버지쑤셔", "버지털", "버지핧아", "버짓물", "버짓물마셔", - "벌창같은년", "벵신", "병닥", "병딱", "병신", "보쥐", "보지", "보지핧어", "보짓물", "보짓물마셔", "봉알", "부랄", "불알", "붕알", "붜지", "뷩딱", "븅쉰", "븅신", "빙띤", - "빙신", "빠가십새", "빠가씹새", "빠구리", "빠굴이", "뻑큐", "뽕알", "뽀지", "뼝신", "사까시", "상년", "새꺄", "새뀌", "새끼", "색갸", "색끼", "색스", "색키", "샤발", - "써글", "써글년", "성교", "성폭행", "세꺄", "세끼", "섹스", "섹스하자", "섹스해", "섹쓰", "섹히", "수셔", "쑤셔", "쉐끼", "쉑갸", "쉑쓰", "쉬발", "쉬방", "쉬밸년", "쉬벌", - "쉬불", "쉬붕", "쉬빨", "쉬이발", "쉬이방", "쉬이벌", "쉬이불", "쉬이붕", "쉬이빨", "쉬이팔", "쉬이펄", "쉬이풀", "쉬팔", "쉬펄", "쉬풀", "쉽쌔", "시댕이", "시발", "시발아", "시발이", "시발년", - "시발놈", "시발새끼", "시방새", "시밸", "시벌", "시불", "시붕", "시이발", "시이벌", "시이불", "시이붕", "시이팔", "시이펄", "시이풀", "시팍새끼", "시팔", "시팔넘", "시팔년", - "시팔놈", "시팔새끼", "시펄", "실프", "십8", "십때끼", "십떼끼", "십버지", "십부랄", "십부럴", "십새", "십세이", "십셰리", "십쉐", "십자석", "십자슥", "십지랄", "십창녀", - "십창", "십탱", "십탱구리", "십탱굴이", "십팔새끼", "ㅆㅂ", "ㅆㅂㄹㅁ", "ㅆㅂㄻ", "ㅆㅣ", "쌍넘", "쌍년", "쌍놈", "쌍눔", "쌍보지", - "쌔끼", "쌔리", "쌕스", "쌕쓰", "썅년", "썅놈", "썅뇬", "썅늠", "쓉새", "쓰바새끼", "쓰브랄쉽세", "씌발", "씌팔", "씨가랭넘", "씨가랭년", "씨가랭놈", "씨발", - "씨발년", "씨발롬", "씨발병신", "씨방새", "씨방세", "씨밸", "씨뱅가리", "씨벌", "씨벌년", "씨벌쉐이", "씨부랄", "씨부럴", "씨불", "씨불알", "씨붕", "씨브럴", "씨블", - "씨블년", "씨븡새끼", "씨빨", "씨이발", "씨이벌", "씨이불", "씨이붕", "씨이팔", "씨파넘", "씨팍새끼", "씨팍세끼", "씨팔", "씨펄", "씨퐁넘", "씨퐁뇬", "씨퐁보지", - "씨퐁자지", "씹년", "씹물", "씹미랄", "씹버지", "씹보지", "씹부랄", "씹브랄", "씹빵구", "씹뽀지", "씹새", "씹새끼", "씹세", "씹쌔끼", "씹자석", "씹자슥", "씹자지", - "씹지랄", "씹창", "씹창녀", "씹탱", "씹탱굴이", "씹탱이", "씹팔", "아가리", "애무", "애미", "애미랄", "애미보지", "애미씨뱅", "애미자지", "애미잡년", "애미좃물", - "애비", "애자", "양아치", "어미강간", "어미따먹자", "어미쑤시자", "영자", "엄창", "에미", "에비", "엔플레버", "엠플레버", "염병", "염병할", "염뵹", "엿먹어라", "오랄", - "오르가즘", "왕버지", "왕자지", "왕잠지", "왕털버지", "왕털보지", "왕털자지", "왕털잠지", "우미쑤셔", "운디네", "운영자", "유두", "유두빨어", "유두핧어", "유방", "유방만져", - "유방빨아", "유방주물럭", "유방쪼물딱", "유방쪼물럭", "유방핧아", "유방핧어", "육갑", "이그니스", "이년", "이프리트", "자기핧아", "자지", "자지구녕", "자지구멍", "자지꽂아", - "자지넣자", "자지뜨더", "자지뜯어", "자지박어", "자지빨아", "자지빨아줘", "자지빨어", "자지쑤셔", "자지쓰레기", "자지정개", "자지짤라", "자지털", "자지핧아", "자지핧아줘", - "자지핧어", "작은보지", "잠지", "잠지뚫어", "잠지물마셔", "잠지털", "잠짓물마셔", "잡년", "잡놈", "저년", "점물", "젓가튼", "젓가튼쉐이", "젓같내", "젓같은", "젓까", "젓나", - "젓냄새", "젓대가리", "젓떠", "젓마무리", "젓만이", "젓물", "젓물냄새", "젓밥", "정액마셔", "정액먹어", "정액발사", "정액짜", "정액핧아", "정자마셔", "정자먹어", "정자핧아", - "젖같은", "젖까", "젖밥", "젖탱이", "조개넓은년", "조개따조", "조개마셔줘", "조개벌려조", "조개속물", "조개쑤셔줘", "조개핧아줘", "조까", "조또", "족같내", "족까", "족까내", - "존나", "존나게", "존니", "졸라", "좀마니", "좀물", "좀쓰레기", "좁빠라라", "좃가튼뇬", "좃간년", "좃까", "좃까리", "좃깟네", "좃냄새", "좃넘", "좃대가리", "좃도", "좃또", - "좃만아", "좃만이", "좃만한것", "좃만한쉐이", "좃물", "좃물냄새", "좃보지", "좃부랄", "좃빠구리", "좃빠네", "좃빠라라", "좃털", "좆같은놈", "좆같은새끼", "좆까", "좆까라", - "좆나", "좆년", "좆도", "좆만아", "좆만한년", "좆만한놈", "좆만한새끼", "좆먹어", "좆물", "좆밥", "좆빨아", "좆새끼", "좆털", "좋만한것", "주글년", "주길년", "쥐랄", "지랄", - "지랼", "지럴", "지뢀", "쪼까튼", "쪼다", "쪼다새끼", "찌랄", "찌질이", "창남", "창녀", "창녀버지", "창년", "처먹고", "처먹을", "쳐먹고", "쳐쑤셔박어", "촌씨브라리", - "촌씨브랑이", "촌씨브랭이", "크리토리스", "큰보지", "클리토리스", "트랜스젠더", "페니스", "항문수셔", "항문쑤셔", "허덥", "허버리년", "허벌년", "허벌보지", "허벌자식", "허벌자지", - "허접", "허젚", "허졉", "허좁", "헐렁보지", "혀로보지핧기", "호냥년", "호로", "호로새끼", "호로자슥", "호로자식", "호로짜식", "호루자슥", "호모", "호졉", "호좁", "후라덜넘", - "후장", "후장꽂아", "후장뚫어", "흐접", "흐젚", "흐졉", "bitch", "fuck", "fuckyou", "nflavor", "penis", "pennis", "pussy", "sex" - }; -} diff --git a/server/src/main/java/com/growstory/global/badwords/filterlist/WhiteList.java b/server/src/main/java/com/growstory/global/badwords/filterlist/WhiteList.java deleted file mode 100644 index c376c0ec..00000000 --- a/server/src/main/java/com/growstory/global/badwords/filterlist/WhiteList.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.growstory.global.badwords.filterlist; - -public interface WhiteList { - String[] whiteList = { - "시발점" - }; -} diff --git a/server/src/main/java/com/growstory/global/badwords/service/BlackListService.java b/server/src/main/java/com/growstory/global/badwords/service/BlackListService.java deleted file mode 100644 index 113ec9ab..00000000 --- a/server/src/main/java/com/growstory/global/badwords/service/BlackListService.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.growstory.global.badwords.service; - -import com.growstory.global.badwords.dto.ProfanityDto; -import com.growstory.global.badwords.filterlist.BlackList; -import com.growstory.global.badwords.filterlist.WhiteList; -import org.springframework.stereotype.Service; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -@Service -public class BlackListService implements BlackList, WhiteList { - - private HashSet blackSet = new HashSet<>(); //블랙 리스트 - private HashSet whiteSet = new HashSet<>(); //화이트 리스트 - private HashSet bannedWords = new HashSet<>(); // 포함된 금지 단어 목록 - - //대체 문자 지정 - //기본값 : * - private String substituteValue = "*"; - - public BlackListService() { - //블랙 리스트 포함 - blackSet.addAll(List.of(koreanSlangs)); - //화이트 리스트 포함 - whiteSet.addAll(List.of(whiteList)); - } - - public BlackListService(String substituteValue) { - this.substituteValue = substituteValue; - } - - //비속어 있다면 대체 - public String change(String text) { - String[] words = blackSet.stream().filter(text::contains).toArray(String[]::new); - for (String v : words) { - String sub = this.substituteValue.repeat(v.length()); - text = text.replace(v, sub); - } - return text; - } - -// public String change(String text, String[] sings) { -// StringBuilder singBuilder = new StringBuilder("["); -// for (String sing : sings) singBuilder.append(Pattern.quote(sing)); -// singBuilder.append("]*"); -// String patternText = singBuilder.toString(); -// -// for (String word : this) { -// if (word.length() == 1) text = text.replace(word, substituteValue); -// String[] chars = word.chars().mapToObj(Character::toString).toArray(String[]::new); -// text = Pattern.compile(String.join(patternText, chars)) -// .matcher(text) -// .replaceAll(v -> substituteValue.repeat(v.group().length())); -// } -// -// return text; -// } - - //금지된 욕설인지 여부 - public boolean isForbidden(String text) { - boolean isWhite = whiteSet.stream().anyMatch(text::contains); - boolean isBlack = blackSet.stream().anyMatch(blackWord -> { - // contains, 블랙 리스트에 포함되어 있으면서 화이트 리스트에서 제외되었는지 여부 판단 - boolean contains = text.contains(blackWord) && !isWhite; - if (contains) { - bannedWords.add(blackWord); // anyMatch가 true일 때 해당 단어를 추가 - } - return contains; - }); - - return isBlack && !isWhite; - } - - //사용자가 입력한 욕설 리스트 반환 - public ProfanityDto getProfanityWords(String text) { - String[] contents = text.split(" "); - bannedWords.clear(); - - Set inputProfanityWords = Arrays.stream(contents) - .filter(this::isForbidden) - .collect(Collectors.toSet()); - - return ProfanityDto.builder() - .inputProfanityWords(inputProfanityWords) - .bannedWords(bannedWords).build(); - - //TODO: findFirst()를 이용해 속도 효율을 증가 시키는 방법도 고려할 수 있다 - } - - //공백이 없는 상태에서 욕설 인식 및 반환 - public ProfanityDto getProfanityWordsWithNoBlanks(String text) { - return getProfanityWords(text.replace(" ", "")); - } -} diff --git a/server/src/main/java/com/growstory/global/config/S3Config.java b/server/src/main/java/com/growstory/global/config/S3Config.java new file mode 100644 index 00000000..968ce203 --- /dev/null +++ b/server/src/main/java/com/growstory/global/config/S3Config.java @@ -0,0 +1,31 @@ +package com.growstory.global.config; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; + +public class S3Config { + @Value("${cloud.aws.credentials.accessKey}") + private String accessKey; + + @Value("${cloud.aws.credentials.secretKey}") + private String secretKey; + + @Value("${cloud.aws.region.static}") + private String region; + + @Bean + public AmazonS3 amazonS3Client() { + AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey); + + return AmazonS3ClientBuilder + .standard() + .withCredentials(new AWSStaticCredentialsProvider(credentials)) + .withRegion(region) + .build(); + } +} diff --git a/server/src/main/java/com/growstory/global/email/controller/EmailController.java b/server/src/main/java/com/growstory/global/email/controller/EmailController.java index d6b276cb..7cbfae90 100644 --- a/server/src/main/java/com/growstory/global/email/controller/EmailController.java +++ b/server/src/main/java/com/growstory/global/email/controller/EmailController.java @@ -1,6 +1,5 @@ package com.growstory.global.email.controller; -import com.growstory.domain.account.service.AccountService; import com.growstory.global.constants.HttpStatusCode; import com.growstory.global.email.dto.EmailDto; import com.growstory.global.email.service.EmailService; @@ -23,17 +22,11 @@ @RequestMapping("/v1/emails") public class EmailController { private final EmailService emailService; - private final AccountService accountService; @Operation(summary = "회원가입 시 메일 인증", description = "회원가입 시 입력받은 이메일로 메일 전송") @PostMapping("/signup") public ResponseEntity> postAuthCodeMail(@Valid @RequestBody EmailDto.Post emailPostDto) { - Boolean isDuplicated = accountService.verifyExistsEmail(emailPostDto.getEmail()); - EmailDto.SignUpResponse responseDto = EmailDto.SignUpResponse.builder().isDuplicated(isDuplicated).build(); - - if (!isDuplicated) { - responseDto = emailService.sendAuthCodeMail(emailPostDto); - } + EmailDto.SignUpResponse responseDto = emailService.sendAuthCodeMail(emailPostDto); return ResponseEntity.ok(SingleResponseDto.builder() .status(HttpStatusCode.OK.getStatusCode()) @@ -53,16 +46,4 @@ public ResponseEntity> postPassword .data(responseDto) .build()); } - - @Operation(summary = "QnA 답변 여부 전송" , description = "QnA 관리자 답변 완료 여부 안내") - @PostMapping("/qna-answer") - public ResponseEntity> postQnaAnswerMail(@Valid @RequestBody EmailDto.QnaAnswer emailQnaDto) { - EmailDto.QnaAnswerResponse responseDto = emailService.sendQnaAnswerMail(emailQnaDto); - - return ResponseEntity.ok(SingleResponseDto.builder() - .status(HttpStatusCode.OK.getStatusCode()) - .message(HttpStatusCode.OK.getMessage()) - .data(responseDto) - .build()); - } } diff --git a/server/src/main/java/com/growstory/global/email/dto/EmailDto.java b/server/src/main/java/com/growstory/global/email/dto/EmailDto.java index 0fea784b..c3eedefe 100644 --- a/server/src/main/java/com/growstory/global/email/dto/EmailDto.java +++ b/server/src/main/java/com/growstory/global/email/dto/EmailDto.java @@ -20,7 +20,6 @@ public static class Post { @Getter @Builder public static class SignUpResponse { - private Boolean isDuplicated; private String authCode; } @@ -28,20 +27,5 @@ public static class SignUpResponse { @Builder(toBuilder = true) public static class PasswordResponse { private Boolean isMatched; - private Boolean isSocial; - } - - @Getter - @Builder - public static class QnaAnswer { - private Long chatRoomId; - private Long questionerId; - private String mailSubject; - } - - @Getter - @Builder - public static class QnaAnswerResponse { - private String receiverEmail; } } diff --git a/server/src/main/java/com/growstory/global/email/service/EmailService.java b/server/src/main/java/com/growstory/global/email/service/EmailService.java index b379685b..a68d74bc 100644 --- a/server/src/main/java/com/growstory/global/email/service/EmailService.java +++ b/server/src/main/java/com/growstory/global/email/service/EmailService.java @@ -2,12 +2,7 @@ import com.growstory.domain.account.entity.Account; import com.growstory.domain.account.repository.AccountRepository; -import com.growstory.domain.qnachat.chatroom.entity.ChatRoom; -import com.growstory.domain.qnachat.chatroom.repository.ChatRoomRepository; -import com.growstory.domain.qnachat.chatroom.service.ChatRoomService; import com.growstory.global.email.dto.EmailDto; -import com.growstory.global.exception.BusinessLogicException; -import com.growstory.global.exception.ExceptionCode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.mail.javamail.JavaMailSender; @@ -33,10 +28,8 @@ public class EmailService { private final SpringTemplateEngine templateEngine; private final AccountRepository accountRepository; private final PasswordEncoder passwordEncoder; - private final ChatRoomRepository chatRoomRepository; - // 부하 테스트 때 비동기 처리 - public EmailDto.SignUpResponse sendAuthCodeMail(EmailDto.Post requsetDto) { + public EmailDto.SignUpResponse sendAuthCodeMail(EmailDto.Post emailPostDto) { try { String authCode = getAuthCode(); @@ -46,7 +39,7 @@ public EmailDto.SignUpResponse sendAuthCodeMail(EmailDto.Post requsetDto) { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "UTF-8"); - mimeMessageHelper.setTo(requsetDto.getEmail()); // 수신 이메일 + mimeMessageHelper.setTo(emailPostDto.getEmail()); // 수신 이메일 mimeMessageHelper.setSubject("[GrowStory] 회원가입 인증번호 안내"); // 이메일 제목 mimeMessageHelper.setText(finalText, true); // 이메일 본문 @@ -57,7 +50,6 @@ public EmailDto.SignUpResponse sendAuthCodeMail(EmailDto.Post requsetDto) { }); return EmailDto.SignUpResponse.builder() - .isDuplicated(false) .authCode(authCode) .build(); } catch (Exception e) { @@ -66,17 +58,12 @@ public EmailDto.SignUpResponse sendAuthCodeMail(EmailDto.Post requsetDto) { } } - public EmailDto.PasswordResponse sendPasswordMail(EmailDto.Post requestDto) { - Optional optionalAccount = accountRepository.findByEmail(requestDto.getEmail()); + public EmailDto.PasswordResponse sendPasswordMail(EmailDto.Post emailPostDto) { + Optional optionalAccount = accountRepository.findByEmail(emailPostDto.getEmail()); if (optionalAccount.isEmpty()) { return EmailDto.PasswordResponse.builder() .isMatched(false) - .isSocial(false) - .build(); - } else if (optionalAccount.get().getStatus().getStepDescription().equals("SOCIAL_USER")) { - return EmailDto.PasswordResponse.builder() - .isSocial(true) .build(); } @@ -89,7 +76,7 @@ public EmailDto.PasswordResponse sendPasswordMail(EmailDto.Post requestDto) { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "UTF-8"); - mimeMessageHelper.setTo(requestDto.getEmail()); // 수신 이메일 + mimeMessageHelper.setTo(emailPostDto.getEmail()); // 수신 이메일 mimeMessageHelper.setSubject("[GrowStory] 임시 비밀번호 안내"); // 이메일 제목 mimeMessageHelper.setText(setContext(password, "password"), true); // 이메일 본문 mailSender.send(mimeMessage); @@ -105,43 +92,14 @@ public EmailDto.PasswordResponse sendPasswordMail(EmailDto.Post requestDto) { return EmailDto.PasswordResponse.builder() .isMatched(true) - .isSocial(false) .build(); } - // Qna 답변 여부 이메일 발송 - public EmailDto.QnaAnswerResponse sendQnaAnswerMail(EmailDto.QnaAnswer emailQnaDto) { - Account findAccount = accountRepository.findById(emailQnaDto.getQuestionerId()) - .orElseThrow(() -> new BusinessLogicException(ExceptionCode.ACCOUNT_NOT_FOUND)); - ChatRoom findChatRoom = chatRoomRepository.findById(emailQnaDto.getChatRoomId()) - .orElseThrow(() -> new BusinessLogicException(ExceptionCode.CHATROOM_NOT_FOUND)); - - String chatRoomLink = "https://growstory.vercel.app/"; - - CompletableFuture.runAsync(() -> { - try { - MimeMessage mimeMessage = mailSender.createMimeMessage(); - MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "UTF-8"); - - mimeMessageHelper.setTo(findAccount.getEmail()); // 수신 이메일 - mimeMessageHelper.setSubject(findChatRoom.getRoomName() + "에 대한 답변이 작성되었습니다."); - mimeMessageHelper.setText(setContext(chatRoomLink, "qnaResponse"), true); - - mailSender.send(mimeMessage); - - } catch (MessagingException e) { - throw new RuntimeException(e); - } - }); - - return EmailDto.QnaAnswerResponse.builder() - .receiverEmail(findAccount.getEmail()).build(); - } // 인증 번호 겸 임시 비밀번호 - public String getAuthCode() { + private String getAuthCode() { Random random = new Random(); - StringBuilder authCode = new StringBuilder(); + StringBuffer authCode = new StringBuffer(); for (int i = 0; i < 8; i++) { int index = random.nextInt(4); @@ -161,6 +119,4 @@ private String setContext(String code, String type) { context.setVariable(type, code); return templateEngine.process(type, context); } - - } \ No newline at end of file diff --git a/server/src/main/java/com/growstory/global/exception/BusinessLogicException.java b/server/src/main/java/com/growstory/global/exception/BusinessLogicException.java index d8ac3539..3707c98f 100644 --- a/server/src/main/java/com/growstory/global/exception/BusinessLogicException.java +++ b/server/src/main/java/com/growstory/global/exception/BusinessLogicException.java @@ -1,24 +1,13 @@ package com.growstory.global.exception; -import com.growstory.global.badwords.dto.ProfanityDto; import lombok.Getter; -import java.util.List; - @Getter public class BusinessLogicException extends RuntimeException { private ExceptionCode exceptionCode; - private ProfanityDto profanityDto; public BusinessLogicException(ExceptionCode exceptionCode) { super(exceptionCode.getMessage()); this.exceptionCode = exceptionCode; } - - //비속어 필터링 관련 BLE - public BusinessLogicException(ExceptionCode exceptionCode, ProfanityDto profanityDto) { - super(exceptionCode.getMessage()); - this.exceptionCode = exceptionCode; - this.profanityDto = profanityDto; - } } diff --git a/server/src/main/java/com/growstory/global/exception/ExceptionCode.java b/server/src/main/java/com/growstory/global/exception/ExceptionCode.java index b4ecd29a..b0226495 100644 --- a/server/src/main/java/com/growstory/global/exception/ExceptionCode.java +++ b/server/src/main/java/com/growstory/global/exception/ExceptionCode.java @@ -1,7 +1,6 @@ package com.growstory.global.exception; import lombok.Getter; -import org.springframework.http.HttpStatus; @Getter public enum ExceptionCode { @@ -22,10 +21,6 @@ public enum ExceptionCode { COMMENT_NOT_ALLOW(405, "That Comment doesn't have authority"), COMMENT_ALREADY_EXISTS(409, "Comment already exists"), - GUESTBOOK_NOT_FOUND(404, "Guestbook not found"), - GUESTBOOK_NOT_ALLOW(405, "That Guestbook doesn't have authority"), - GUESTBOOK_ALREADY_EXISTS(409, "Guestbook already exists"), - PLANT_OBJECT_NOT_FOUND(404, "Plant Object not found"), PLANT_OBJECT_NOT_ALLOW(405, "That Plant Object doesn't have authority"), PLANT_OBJECT_ALREADY_EXISTS(409, "Plant Object already exists"), @@ -50,16 +45,7 @@ public enum ExceptionCode { NOT_ENOUGH_POINTS(403, "Not Enough Points"), - RANK_NOT_FOUND(404, "Rank not found"), - - BAD_WORD_INCLUDED(406, "Bad word Included"), - - ALARM_NOT_FOUND(404, "Alarm not found"), - - CHATROOM_NOT_FOUND(404, "ChatRoom does not Found"), - ACCOUNT_CHATROOM_NOT_FOUND(404, "AccountChatRoom does not Found"), - ALREADY_CHATROOM_ENTERED(409, "Already entered this ChatRoom"), - WEBSOCKET_EXCEPTION(HttpStatus.UNAUTHORIZED.value(), "Exception occurred at Websocket Process"); + RANK_NOT_FOUND(404, "Rank not found"); private final int status; private final String message; diff --git a/server/src/main/java/com/growstory/global/response/ErrorResponse.java b/server/src/main/java/com/growstory/global/response/ErrorResponse.java index bc7d80c9..546e3edf 100644 --- a/server/src/main/java/com/growstory/global/response/ErrorResponse.java +++ b/server/src/main/java/com/growstory/global/response/ErrorResponse.java @@ -1,7 +1,6 @@ package com.growstory.global.response; -import com.growstory.global.badwords.dto.ProfanityDto; import com.growstory.global.exception.ExceptionCode; import lombok.Getter; import org.springframework.http.HttpStatus; @@ -42,11 +41,6 @@ public static ErrorResponse of(ExceptionCode exceptionCode) { return new ErrorResponse(exceptionCode.getStatus(), exceptionCode.getMessage()); } - // 비속어 필터링 관련 예외 응답 처리 - public static ErrorResponse of(ExceptionCode exceptionCode, ProfanityDto profanityDto) { - return new ErrorResponse(exceptionCode.getStatus(), profanityDto.toString()); - } - public static ErrorResponse of(HttpStatus httpStatus) { return new ErrorResponse(httpStatus.value(), httpStatus.getReasonPhrase()); } diff --git a/server/src/main/java/com/growstory/global/response/PageResponse.java b/server/src/main/java/com/growstory/global/response/PageResponse.java deleted file mode 100644 index 246f8bec..00000000 --- a/server/src/main/java/com/growstory/global/response/PageResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.growstory.global.response; - -import lombok.Builder; -import lombok.Getter; -import org.springframework.data.domain.Page; - -@Getter -@Builder -public class PageResponse { - private int totalPage; - private int currentPage; - private Long totalElements; - private int currentElements; - private boolean hasPrevious; - private boolean hasNext; - private boolean isLast; - private T data; - - // 정적 팩토리 메서드, page와 data로부터 ResponseDto 생성 - public static PageResponse of(Page page, T data) { - return PageResponse.builder() - .totalPage(page.getTotalPages()) - .currentPage(page.getNumber()) - .totalElements(page.getTotalElements()) - .currentElements(page.getNumberOfElements()) - .hasPrevious(page.hasPrevious()) - .hasNext(page.hasNext()) - .isLast(page.isLast()) - .data(data) - .build(); - } -} diff --git a/server/src/main/java/com/growstory/global/sse/controller/SseController.java b/server/src/main/java/com/growstory/global/sse/controller/SseController.java deleted file mode 100644 index 43a77d03..00000000 --- a/server/src/main/java/com/growstory/global/sse/controller/SseController.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.growstory.global.sse.controller; - -import com.growstory.domain.alarm.constants.AlarmType; -import com.growstory.global.sse.service.SseService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; - -@Tag(name = "Server-Sent-Event", description = "SSE Controller") -@Validated -@RequiredArgsConstructor -@RequestMapping("/v1/sse") -@RestController -public class SseController { - private final SseService sseService; - - @Operation(summary = "구독 연결", description = "클라이언트 측과 서버 연결") - @GetMapping(value = "/subscribe/{account-id}", produces = "text/event-stream") // text/event-stream => sse 형식 - public SseEmitter subscribe(@PathVariable("account-id") Long accountId, - @RequestHeader(value = "Last-Event-ID", required = false, defaultValue = "") String lastEventId) { // lastEventId는 타임아웃 이후 재연결 요청을 할 때 헤더로 들어오는 값 - return sseService.subscribe(accountId, lastEventId); - } - -// const eventSource = new EventSource('http://localhost:8888/v1/sse/subscribe/1'); -// eventSource.addEventListener('sse', event => { -// console.log(event); -// }); - - - // 테스트 용 - @Operation(summary = "알림 전송", description = "클라이언트 측으로 알림 전송") - @PostMapping("/send/{account-id}") - public void sendAlarm(@PathVariable("account-id") Long accountId) { - sseService.notify(accountId, AlarmType.DAILY_QUIZ); - } -} diff --git a/server/src/main/java/com/growstory/global/sse/repository/SseEmitterRepository.java b/server/src/main/java/com/growstory/global/sse/repository/SseEmitterRepository.java deleted file mode 100644 index 41e71379..00000000 --- a/server/src/main/java/com/growstory/global/sse/repository/SseEmitterRepository.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.growstory.global.sse.repository; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Repository; -import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -@RequiredArgsConstructor -@Repository -public class SseEmitterRepository { - // 동시성 문제 thread-safe한 concurrentHashMap 사용 - private final Map emitters = new ConcurrentHashMap<>(); - - public void save(Long accountId, SseEmitter emitter) { - emitters.put(accountId, emitter); - } - - public void deleteById(Long accountId) { - emitters.remove(accountId); - } - - public SseEmitter get(Long accountId) { - return emitters.get(accountId); - } -} diff --git a/server/src/main/java/com/growstory/global/sse/service/SseService.java b/server/src/main/java/com/growstory/global/sse/service/SseService.java deleted file mode 100644 index 333eb546..00000000 --- a/server/src/main/java/com/growstory/global/sse/service/SseService.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.growstory.global.sse.service; - -import com.growstory.domain.alarm.constants.AlarmType; -import com.growstory.domain.alarm.service.AlarmService; -import com.growstory.global.sse.repository.SseEmitterRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; - -import java.io.IOException; - -// 추가로, SSE 서비스단에 트랜잭션이 걸려있다면 SSE연결 동안 트랜잭션을 계속 물고 있어 -// 커넥션 낭비가 일어날 수 있으니 SSE 서비스로직에는 트랜잭션을 걸지 않아야 합니다. -@RequiredArgsConstructor -@Service -public class SseService { - // 연결 타임아웃(ms) - private static final Long DEFAULT_TIMEOUT = 60 * 60 * 1000L; -// private static final Long DEFAULT_TIMEOUT = 60L; - - private final SseEmitterRepository sseEmitterRepository; - private final AlarmService alarmService; - - // 클라이언트와 서버 연결(구독) - public SseEmitter subscribe(Long accountId, String lastEventId) { - SseEmitter emitter = createEmitter(accountId); - - sendToClient(accountId, "서버와 연결 완료"); - -// if (hasLostData(lastEventId)) { -// sendLostData(lastEventId, memberId, emitterId, emitter); -// } - - return emitter; - } - -// private boolean hasLostData(String lastEventId) { -// return !lastEventId.isEmpty(); -// } - -// private void sendLostData(String lastEventId, Long memberId, String emitterId, SseEmitter emitter) { -// Map eventCaches = sseEmitterRepository.findAllEventCacheStartWithByMemberId(String.valueOf(memberId)); -// eventCaches.entrySet().stream() -// .filter(entry -> lastEventId.compareTo(entry.getKey()) < 0) -// .forEach(entry -> sendNotification(emitter, entry.getKey(), emitterId, entry.getValue())); -// } - - // 서버의 이벤트를 클라이언트 측으로 전송하기 위해 - // 서버의 다른 서비스에서 호출 - public void notify(Long accountId, AlarmType alarmType) { - alarmService.createAlarm(accountId, alarmType); - - sendToClient(accountId, alarmType.getStepDescription()); - } - - // 클라이언트 측으로 데이터 전송 - private void sendToClient(Long accountId, String data) { - SseEmitter emitter = sseEmitterRepository.get(accountId); - - if (emitter != null) { - try { - emitter.send(SseEmitter.event() - .id(String.valueOf(accountId)) - .name("sse") - .data(data)); - } catch (IOException exception) { - sseEmitterRepository.deleteById(accountId); - emitter.completeWithError(exception); - } - } - } - - private SseEmitter createEmitter(Long accountId) { - SseEmitter emitter = new SseEmitter(DEFAULT_TIMEOUT); - sseEmitterRepository.save(accountId, emitter); - - emitter.onCompletion(() -> sseEmitterRepository.deleteById(accountId)); - emitter.onTimeout(() -> sseEmitterRepository.deleteById(accountId)); - - return emitter; - } -} diff --git a/server/src/main/java/com/growstory/global/utils/UriCreator.java b/server/src/main/java/com/growstory/global/utils/UriCreator.java index b7d0bfc5..16b9c516 100644 --- a/server/src/main/java/com/growstory/global/utils/UriCreator.java +++ b/server/src/main/java/com/growstory/global/utils/UriCreator.java @@ -1,11 +1,9 @@ package com.growstory.global.utils; -import org.springframework.stereotype.Component; import org.springframework.web.util.UriComponentsBuilder; import java.net.URI; -@Component public class UriCreator { public static URI createUri(String defaultUrl, long resourceId) { return UriComponentsBuilder @@ -22,13 +20,4 @@ public static URI creatUri(String defaultUrl, long resourceId1, String anotherRe .buildAndExpand(resourceId1, resourceId2) .toUri(); } - - // 테스트용 - public URI createUri_test(String defaultUrl, long resourceId) { - return UriComponentsBuilder - .newInstance() - .path(defaultUrl+ "/{resource-id}") - .buildAndExpand(resourceId) - .toUri(); - } } \ No newline at end of file diff --git a/server/src/main/java/com/growstory/global/websocket/FilterChannelInterceptor.java b/server/src/main/java/com/growstory/global/websocket/FilterChannelInterceptor.java deleted file mode 100644 index affce50d..00000000 --- a/server/src/main/java/com/growstory/global/websocket/FilterChannelInterceptor.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.growstory.global.websocket; - -import com.growstory.global.auth.filter.JwtVerificationFilter; -import com.growstory.global.auth.jwt.JwtTokenizer; -import com.growstory.global.exception.BusinessLogicException; -import com.growstory.global.exception.ExceptionCode; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.security.SignatureException; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageChannel; -import org.springframework.messaging.simp.stomp.StompCommand; -import org.springframework.messaging.simp.stomp.StompHeaderAccessor; -import org.springframework.messaging.support.ChannelInterceptor; -import org.springframework.stereotype.Component; - -import java.util.Map; -import java.util.Objects; - -@Order(Ordered.HIGHEST_PRECEDENCE + 99) -@Slf4j -@RequiredArgsConstructor -@Component -public class FilterChannelInterceptor implements ChannelInterceptor { - private final JwtTokenizer jwtTokenizer; - private final JwtVerificationFilter jwtVerificationFilter; - - @Override - public Message preSend(Message message, MessageChannel channel) { - StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message); - log.info("## StompHeaderAccessor: " + headerAccessor); - - if(StompCommand.CONNECT.equals(headerAccessor.getCommand())) { // 웹소켓 연결 요청 -> JWT 인증 - log.info("## CONNECT : 소켓 연결 "); - String accessToken = getAccessTokenFrom(headerAccessor); - String refreshToken = getRefreshTokenFrom(headerAccessor); - //TODO: refresh 토큰 관련 로직 개선 - try { - Map claims = verifyJws(accessToken); - putValue(headerAccessor, "senderId", claims.get("accountId")); - putValue(headerAccessor, "displayName", claims.get("displayName")); - log.info("## Claims : {}", claims); - } catch (SignatureException | MalformedJwtException sme) { - log.info("잘못된 JWT 서명입니다."); - putValue(headerAccessor, "exception", sme); - } catch (ExpiredJwtException ee) { - log.info("만료된 JWT 토큰입니다."); - putValue(headerAccessor, "exception", ee); - } catch (Exception e) { - putValue(headerAccessor, "exception", e); - } - } else if (StompCommand.SEND == (headerAccessor.getCommand())) { - String payload = new String((byte[]) message.getPayload()); - log.info("Message Payload : "+ payload); - } else if (StompCommand.SUBSCRIBE == (headerAccessor.getCommand())) { - String chatRoomId = getChatRoomIdFrom(headerAccessor); - putValue(headerAccessor, "chatRoomId", chatRoomId); - log.info("## SUBSCRIBE: accountId ({})번, ({})님이 ({})번 채팅방을 구독하셨습니다." + headerAccessor - , getValue(headerAccessor, "senderId"), getValue(headerAccessor, "displayName") - , getValue(headerAccessor, "chatRoomId")); - } else if (StompCommand.DISCONNECT == (headerAccessor.getCommand())) { - log.info("## DISCONNECT: accountId ({})번, ({})님이 ({})번 채팅방을 떠났습니다." + headerAccessor - , getValue(headerAccessor, "senderId"), getValue(headerAccessor, "displayName") - , getValue(headerAccessor, "chatRoomId")); - } - - return message; - } - - - private String getAccessTokenFrom(StompHeaderAccessor headerAccessor) { - String accessToken = headerAccessor.getNativeHeader("Authorization").toString(); - accessToken = accessToken.substring(1, accessToken.length()-1).replace("Bearer ", ""); - putValue(headerAccessor, "Authorization", accessToken); - log.info("## accessToken: " + accessToken); - return accessToken; - } - private String getRefreshTokenFrom(StompHeaderAccessor headerAccessor) { - String refreshToken = headerAccessor.getNativeHeader("refresh").toString(); - refreshToken = refreshToken.substring(1, refreshToken.length()-1); - putValue(headerAccessor, "refresh", refreshToken); - log.info("## refreshToken: " + refreshToken); - return refreshToken; - } - private static String getChatRoomIdFrom(StompHeaderAccessor headerAccessor) { - String destination = headerAccessor.getDestination(); - String chatRoomId = destination.substring(destination.lastIndexOf('/')+1); - return chatRoomId; - } - - private Map verifyJws(String token) { - //request의 header에서 JWT 얻기 - // String jws = request.getHeader("Authorization").replace("Bearer ", ""); - //서버에 저장된 비밀키 호출 - String base64EncodedSecretKey = jwtTokenizer.encodeBase64SecretKey(jwtTokenizer.getSecretKey()); - //Claims (JWT의 Payload, 사용자 정보인 username, roles 얻기) < - 내부적으로 서명(Signature) 검증에 성공한 상태 - Map claims = jwtTokenizer.getClaims(token, base64EncodedSecretKey).getBody(); - - return claims; - } - - private void putValue(StompHeaderAccessor accessor, String key, Object value) { - Map sessionAttributes = getSessionAttributes(accessor); - sessionAttributes.put(key, value); - } - - private Object getValue(StompHeaderAccessor accessor, String key) { - Map sessionAttributes = getSessionAttributes(accessor); - Object value = sessionAttributes.get(key); - - if(Objects.isNull(value)) { - log.info("sessionAttributes doesnt has a key named {}", key); - throw new BusinessLogicException(ExceptionCode.WEBSOCKET_EXCEPTION); - } - return value; - } - - private Map getSessionAttributes(StompHeaderAccessor accessor) { - Map sessionAttributes = accessor.getSessionAttributes(); - - if (Objects.isNull(sessionAttributes)) { - log.info("SessionAttributes is Null"); - throw new BusinessLogicException(ExceptionCode.WEBSOCKET_EXCEPTION); - } - return sessionAttributes; - } - -} diff --git a/server/src/main/java/com/growstory/global/websocket/WebSocketConfig.java b/server/src/main/java/com/growstory/global/websocket/WebSocketConfig.java deleted file mode 100644 index 279fb5aa..00000000 --- a/server/src/main/java/com/growstory/global/websocket/WebSocketConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.growstory.global.websocket; - -import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Configuration; -import org.springframework.messaging.simp.config.ChannelRegistration; -import org.springframework.messaging.simp.config.MessageBrokerRegistry; -import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; -import org.springframework.web.socket.config.annotation.StompEndpointRegistry; -import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; - -@Configuration -@RequiredArgsConstructor -@EnableWebSocketMessageBroker -public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { - - private final FilterChannelInterceptor filterChannelInterceptor; - - // 엔드 포인트 및 CORS 설정 - @Override - public void registerStompEndpoints(StompEndpointRegistry registry) { - // STOMP 접속 주소 - registry.addEndpoint("/v1/wss") - // CORS 설정 - .setAllowedOrigins("https://growstory.vercel.app", "http://localhost:3000", "http://localhost:8888") - // SockJS 라이브러리 사용 - .withSockJS(); - } - - // 메시지 브로커 설정 - @Override - public void configureMessageBroker(MessageBrokerRegistry registry) { - // 서버 -> 클라이언트, '/sub'이 prefix로 붙은 destination의 클라이언트에게 메시지 전송 - registry.enableSimpleBroker("/sub"); - // 클라이언트 -> 서버, '/pub'이 prefix로 붙은 메시지들은 @MessageMapping이 붙은 메소드로 바운드 된다. - registry.setApplicationDestinationPrefixes("/pub"); - } - - @Override - public void configureClientInboundChannel(ChannelRegistration registration) { - registration.interceptors(filterChannelInterceptor); - } -} diff --git a/server/src/main/resources/application-prod.yml b/server/src/main/resources/application-prod.yml index cf062f25..606af3e3 100644 --- a/server/src/main/resources/application-prod.yml +++ b/server/src/main/resources/application-prod.yml @@ -87,15 +87,11 @@ springdoc: mail: admin: address: ${ADMIN_EMAIL} - guest: ${GUEST_EMAIL} my: scheduled: cron: 0 0 0 ? * MON -event: - key: ${EVENT_KEY} - server: port: 443 ssl: diff --git a/server/src/main/resources/images/test1.jpg b/server/src/main/resources/images/test1.jpg deleted file mode 100644 index 5d4800a3..00000000 Binary files a/server/src/main/resources/images/test1.jpg and /dev/null differ diff --git a/server/src/main/resources/images/test2.jpg b/server/src/main/resources/images/test2.jpg deleted file mode 100644 index ebe0e2ad..00000000 Binary files a/server/src/main/resources/images/test2.jpg and /dev/null differ diff --git a/server/src/main/resources/templates/qnaResponse.html b/server/src/main/resources/templates/qnaResponse.html deleted file mode 100644 index f7e2f8d1..00000000 --- a/server/src/main/resources/templates/qnaResponse.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - Grow Story 문의 답변 안내 - - - - - - - - - - - - - - - -
- Grow Story Logo -
- - - - - - - - - - - - - - - - -
안녕하세요.
- 자신이 키우는 식물에 대해 얘기하고 가상의 정원을 가꿔보는 - 플랫폼
- Grow Story입니다. -
 
- 문의하신 내용에 대한 답변이 작성되었습니다. -
- 아래의 링크에서 상세 답변 내용을 확인해주세요. -
-
- -
- Copyright@Team Grow Story -
- - diff --git a/server/src/test/java/com/growstory/GrowstoryApplicationTests.java b/server/src/test/java/com/growstory/GrowstoryApplicationTests.java deleted file mode 100644 index c12ebb06..00000000 --- a/server/src/test/java/com/growstory/GrowstoryApplicationTests.java +++ /dev/null @@ -1,9 +0,0 @@ -//package com.growstory; -// -//import org.junit.jupiter.api.Test; -//import org.springframework.boot.test.context.SpringBootTest; -// -//@SpringBootTest -//class GrowstoryApplicationTests { -// -//} diff --git a/server/src/test/java/com/growstory/domain/account/controller/AccountControllerTest.java b/server/src/test/java/com/growstory/domain/account/controller/AccountControllerTest.java deleted file mode 100644 index b3166709..00000000 --- a/server/src/test/java/com/growstory/domain/account/controller/AccountControllerTest.java +++ /dev/null @@ -1,339 +0,0 @@ -//package com.growstory.domain.account.controller; -// -//import com.google.gson.Gson; -//import com.growstory.domain.account.dto.AccountDto; -//import com.growstory.domain.account.service.AccountService; -//import com.growstory.domain.point.entity.Point; -//import org.junit.jupiter.api.Test; -//import org.mockito.Mockito; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -//import org.springframework.boot.test.context.SpringBootTest; -//import org.springframework.boot.test.mock.mockito.MockBean; -//import org.springframework.data.domain.Page; -//import org.springframework.data.domain.PageImpl; -//import org.springframework.data.domain.PageRequest; -//import org.springframework.http.HttpMethod; -//import org.springframework.http.MediaType; -//import org.springframework.mock.web.MockMultipartFile; -//import org.springframework.test.web.servlet.MockMvc; -//import org.springframework.test.web.servlet.ResultActions; -//import org.springframework.web.multipart.MultipartFile; -// -//import java.io.FileInputStream; -//import java.util.ArrayList; -//import java.util.List; -// -//import static org.hamcrest.Matchers.is; -//import static org.hamcrest.Matchers.not; -//import static org.mockito.BDDMockito.given; -//import static org.mockito.BDDMockito.willDoNothing; -//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.*; -// -//@SpringBootTest -//@AutoConfigureMockMvc -//public class AccountControllerTest { -// @Autowired -// private MockMvc mockMvc; -// -// @Autowired -// private Gson gson; -// -// @MockBean -// private AccountService accountService; -// -// @Test -// void 회원가입() throws Exception { -// // given -// AccountDto.Post requestDto = AccountDto.Post.builder() -// .email("user1@gmail.com") -// .displayName("user1") -// .password("user1234") -// .build(); -// -// AccountDto.Response responseDto = getResponseDto(1L, "user1@gmail.com", "user1"); -// -// given(accountService.createAccount(Mockito.any(AccountDto.Post.class))) -// .willReturn(responseDto); -// -// // when -// ResultActions actions = mockMvc.perform( -// post("/v1/accounts/signup") -// .contentType(MediaType.APPLICATION_JSON) // contentType은 default가 application/octet-stream -// .content(gson.toJson(requestDto))); -// -// // then -// actions -// .andExpect(status().isCreated()) -// .andExpect(header().string("Location", is("/v1/accounts/" + responseDto.getAccountId().toString()))) -// .andDo(print()); -// } -// -// @Test -// void 프로필_사진_변경() throws Exception { -// // given -// MockMultipartFile testImage = new MockMultipartFile("profileImage", -// "testImage.jpg", -// "jpg", -// new FileInputStream("src/test/resources/images/testImage.jpg")); -// -// willDoNothing().given(accountService).updateProfileImage(Mockito.any(MultipartFile.class)); -// -// // when -// ResultActions actions = mockMvc.perform( -// multipart(HttpMethod.PATCH, "/v1/accounts/profileimage") -// .file(testImage)); -// -// // then -// actions -// .andExpect(status().isNoContent()) -// .andDo(print()); -// } -// -// @Test -// void 닉네임_수정() throws Exception { -// // given -// AccountDto.DisplayNamePatch requestDto = AccountDto.DisplayNamePatch.builder() -// .displayName("user2") -// .build(); -// -// willDoNothing().given(accountService).updateDisplayName(Mockito.any(AccountDto.DisplayNamePatch.class)); -// -// // when -// ResultActions actions = mockMvc.perform( -// patch("/v1/accounts/displayname") -// .contentType("application/json") -// .content(gson.toJson(requestDto))); -// -// // then -// actions -// .andExpect(status().isNoContent()) -// .andDo(print()); -// } -// -// @Test -// void 비밀번호_수정() throws Exception { -// // given -// AccountDto.PasswordPatch requestDto = AccountDto.PasswordPatch.builder() -// .presentPassword("user1234") -// .changedPassword("user4321") -// .build(); -// -// willDoNothing().given(accountService).updatePassword(Mockito.any(AccountDto.PasswordPatch.class)); -// -// // when -// ResultActions actions = mockMvc.perform( -// patch("/v1/accounts/password") -// .contentType("application/json") -// .content(gson.toJson(requestDto))); -// -// // then -// actions -// .andExpect(status().isNoContent()) -// .andDo(print()); -// } -// -// @Test -// void 나의_계정_조회() throws Exception { -// // given -// Long accountId = 1L; -// -// AccountDto.Response responseDto = getResponseDto(accountId, "user1@gmail.com", "user1"); -// -// given(accountService.getAccount(Mockito.anyLong())) -// .willReturn(responseDto); -// -// // when -// ResultActions actions = mockMvc.perform( -// get("/v1/accounts/" + accountId)); -// -// // then -// actions -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.data.email", is("user1@gmail.com"))) -// .andDo(print()); -// } -// -// @Test -// void 전체_계정_조회() throws Exception { -// // given -// List responseDtos = getResponseDtos(); -// -// given(accountService.getAccounts()) -// .willReturn(responseDtos); -// -// // when -// ResultActions actions = mockMvc.perform( -// get("/v1/accounts/all")); -// -// // then -// actions -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.data[0].email", is("user1@gmail.com"))) -// .andExpect(jsonPath("$.data[1].email", is("user2@gmail.com"))) -// .andDo(print()); -// } -// -// @Test -// void 계정이_작성한_게시글_조회() throws Exception { -// // given -// Long accountId = 1L; -// int page = 1; -// -// List responseDtos = getBoardResponseDtos(); -// -// Page responsePage = new PageImpl<>(responseDtos, PageRequest.of(page - 1,12), responseDtos.size()); -// -// given(accountService.getAccountBoardWritten(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyLong())) -// .willReturn(responsePage); -// -// // when -// ResultActions actions = mockMvc.perform( -// get("/v1/accounts/boardWritten/" + accountId)); -// -// // then -// actions -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.data[0].title", is("제목1"))) -// .andExpect(jsonPath("$.data[1].title", is("제목2"))) -// .andExpect(jsonPath("$.pageInfo.page", is(page))) -// .andExpect(jsonPath("$.pageInfo.totalElements", is(responseDtos.size()))) -// .andDo(print()); -// } -// -// @Test -// void 계정이_좋아요_누른_게시글_조회() throws Exception { -// // given -// Long accountId = 1L; -// int page = 1; -// -// List responseDtos = getBoardResponseDtos(); -// -// Page responsePage = new PageImpl<>(responseDtos, PageRequest.of(page - 1,12), responseDtos.size()); -// -// given(accountService.getAccountBoardLiked(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyLong())) -// .willReturn(responsePage); -// -// // when -// ResultActions actions = mockMvc.perform( -// get("/v1/accounts/boardLiked/" + accountId)); -// -// // then -// actions -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.data[*]..likes[?(1 == @)]").exists()) -// .andExpect(jsonPath("$.pageInfo.page", is(page))) -// .andExpect(jsonPath("$.pageInfo.totalElements", is(responseDtos.size()))) -// .andDo(print()); -// } -// -// @Test -// void 계정이_댓글_작성한_게시글_조회() throws Exception { -// // given -// Long accountId = 1L; -// int page = 1; -// -// List responseDtos = getBoardResponseDtos(); -// -// Page responsePage = new PageImpl<>(responseDtos, PageRequest.of(page - 1,12), responseDtos.size()); -// -// given(accountService.getAccountCommentWrittenBoard(Mockito.anyInt(), Mockito.anyInt(), Mockito.anyLong())) -// .willReturn(responsePage); -// -// // when -// ResultActions actions = mockMvc.perform( -// get("/v1/accounts/commentWritten/" + accountId)); -// -// // then -// actions -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.data[*].commentNums", is(not(0)))) -// .andExpect(jsonPath("$.pageInfo.page", is(page))) -// .andExpect(jsonPath("$.pageInfo.totalElements", is(responseDtos.size()))) -// .andDo(print()); -// } -// -// @Test -// void 비밀번호_검증() throws Exception { -// // given -// AccountDto.PasswordVerify requestDto = AccountDto.PasswordVerify.builder() -// .password("user1234") -// .build(); -// -// Boolean isMatched = true; -// -// given(accountService.verifyPassword(Mockito.any(AccountDto.PasswordVerify.class))) -// .willReturn(isMatched); -// -// // when -// ResultActions actions = mockMvc.perform( -// post("/v1/accounts/password/verification") -// .contentType("application/json") -// .content(gson.toJson(requestDto))); -// -// // then -// actions -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.data", is(isMatched))) -// .andDo(print()); -// } -// -// @Test -// void 회원탈퇴() throws Exception { -// // given -// willDoNothing().given(accountService).deleteAccount(); -// -// // when -// ResultActions actions = mockMvc.perform( -// delete("/v1/accounts")); -// -// // then -// actions -// .andExpect(status().isNoContent()) -// .andDo(print()); -// } -// -// private static AccountDto.Response getResponseDto(Long accountId, String email, String displayName) { -// return AccountDto.Response.builder() -// .accountId(accountId) -// .email(email) -// .displayName(displayName) -// .point(Point.builder().score(500).build()) -// .build(); -// } -// -// private static List getResponseDtos() { -// List responseDtos = new ArrayList<>(); -// -// AccountDto.Response responseDto1 = getResponseDto(1L, "user1@gmail.com", "user1"); -// AccountDto.Response responseDto2 = getResponseDto(2L, "user2@gmail.com", "user2"); -// -// responseDtos.add(responseDto1); -// responseDtos.add(responseDto2); -// -// return responseDtos; -// } -// -// private static AccountDto.BoardResponse getBoardResponseDto(Long boardId, String title, List likes, int commentNums) { -// return AccountDto.BoardResponse.builder() -// .boardId(boardId) -// .title(title) -// .likes(likes) -// .commentNums(commentNums) -// .build(); -// } -// -// private static List getBoardResponseDtos() { -// List responseDtos = new ArrayList<>(); -// -// AccountDto.BoardResponse responseDto1 = getBoardResponseDto(1L, "제목1", List.of(1L), 1); -// AccountDto.BoardResponse responseDto2 = getBoardResponseDto(2L, "제목2", List.of(1L, 2L), 2); -// -// responseDtos.add(responseDto1); -// responseDtos.add(responseDto2); -// -// return responseDtos; -// } -//} diff --git a/server/src/test/java/com/growstory/domain/account/service/AccountServiceTest.java b/server/src/test/java/com/growstory/domain/account/service/AccountServiceTest.java deleted file mode 100644 index 8461d43b..00000000 --- a/server/src/test/java/com/growstory/domain/account/service/AccountServiceTest.java +++ /dev/null @@ -1,617 +0,0 @@ -//package com.growstory.domain.account.service; -// -//import com.growstory.domain.account.dto.AccountDto; -//import com.growstory.domain.account.entity.Account; -//import com.growstory.domain.account.repository.AccountRepository; -//import com.growstory.domain.board.entity.Board; -//import com.growstory.domain.comment.entity.Comment; -//import com.growstory.domain.likes.entity.BoardLike; -//import com.growstory.domain.point.entity.Point; -//import com.growstory.domain.point.service.PointService; -//import com.growstory.global.auth.utils.AuthUserUtils; -//import com.growstory.global.auth.utils.CustomAuthorityUtils; -//import com.growstory.global.aws.service.S3Uploader; -//import com.growstory.global.exception.BusinessLogicException; -//import com.growstory.global.exception.ExceptionCode; -//import org.junit.jupiter.api.*; -//import org.junit.jupiter.api.extension.ExtendWith; -//import org.mockito.InjectMocks; -//import org.mockito.Mock; -//import org.mockito.Mockito; -//import org.mockito.junit.jupiter.MockitoExtension; -//import org.springframework.data.domain.Page; -//import org.springframework.mock.web.MockMultipartFile; -//import org.springframework.security.authentication.BadCredentialsException; -//import org.springframework.security.core.Authentication; -//import org.springframework.security.core.context.SecurityContext; -//import org.springframework.security.core.context.SecurityContextHolder; -//import org.springframework.security.crypto.password.PasswordEncoder; -// -//import java.io.FileInputStream; -//import java.io.IOException; -//import java.util.*; -// -//import static org.hamcrest.MatcherAssert.assertThat; -//import static org.hamcrest.Matchers.contains; -//import static org.hamcrest.Matchers.is; -//import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -//import static org.junit.jupiter.api.Assertions.assertThrows; -//import static org.mockito.BDDMockito.*; -// -//@ExtendWith(MockitoExtension.class) -//public class AccountServiceTest { -// @InjectMocks // @Mock으로 만들어진 객체를 의존성 주입받는 객체 -// private AccountService accountService; -// @Mock -// private PasswordEncoder passwordEncoder; -// @Mock -// private CustomAuthorityUtils customAuthorityUtils; -// @Mock -// private PointService pointService; -// @Mock -// private S3Uploader s3Uploader; -// @Mock -// private AuthUserUtils authUserUtils; -// @Mock -// private static Authentication authentication; -// @Mock -// private AccountRepository accountRepository; -// @Mock -// private static SecurityContext securityContext = mock(SecurityContext.class); -// @Mock -// private Point point = mock(Point.class); -// -// @Nested -// @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -// class 회원가입 { -// // given -// AccountDto.Post requestDto = AccountDto.Post.builder() -// .email("user@gmail.com") -// .displayName("user1") -// .password("user1234") -// .build(); -// List roles = List.of("USER"); -// -// @Test -// @Order(1) -// public void 중복된_이메일이면_회원가입_실패() { -// given(accountRepository.findByEmail(Mockito.anyString())) -// .willReturn(Optional.of(Account.builder().build())); -// -// // when, then -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> accountService.createAccount(requestDto)); -// assertThat(exception.getExceptionCode().getStatus(), is(409)); -// assertThat(exception.getExceptionCode().getMessage(), is("Account already exists")); -// } -// -// @Test -// @Order(2) -// public void 아니면_회원가입_성공() { -// given(accountRepository.findByEmail(Mockito.anyString())) -// .willReturn(Optional.empty()); -// -// given(passwordEncoder.encode(Mockito.anyString())) -// .willReturn(requestDto.getPassword()); -// given(customAuthorityUtils.createRoles(Mockito.anyString())) -// .willReturn(roles); -// given(pointService.createPoint(Mockito.anyString())) -// .willReturn(point); -// -// Account savedAccount = getAccount(1L, requestDto.getEmail(), requestDto.getDisplayName(), -// requestDto.getPassword(), "path", point, roles, Account.AccountGrade.GRADE_BRONZE); -// -// given(accountRepository.save(Mockito.any(Account.class))) -// .willReturn(savedAccount); -// -// willDoNothing().given(point).updateAccount(Mockito.any(Account.class)); -// -// // when -// AccountDto.Response responseDto = accountService.createAccount(requestDto); -// -// // then -// assertThat(responseDto.getAccountId(), is(savedAccount.getAccountId())); -// } -// } -// -// @Nested -// class 이미지_수정 { -// // given -// String s3ImageUrl = "s3/path"; -// -// MockMultipartFile testImage = new MockMultipartFile("profileImage", -// "testImage.jpg", -// "jpg", -// new FileInputStream("src/test/resources/images/testImage.jpg")); -// -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// 이미지_수정() throws IOException { -// } -// -// private void uploadImage() { -// given(s3Uploader.uploadImageToS3(Mockito.any(MockMultipartFile.class), Mockito.anyString())) -// .willReturn(s3ImageUrl); -// given(accountRepository.save(Mockito.any(Account.class))) -// .willReturn(account.toBuilder().profileImageUrl(s3ImageUrl).build()); -// } -// -// @Test -// public void 기존_이미지가_존재할_때() { -// given(authUserUtils.getAuthUser()) -// .willReturn(account); -// -// willDoNothing().given(s3Uploader).deleteImageFromS3(Mockito.anyString(), Mockito.anyString()); -// -// uploadImage(); -// -// // when , then -// assertDoesNotThrow(() -> accountService.updateProfileImage(testImage)); -// verify(s3Uploader, times(1)).deleteImageFromS3(Mockito.anyString(), Mockito.anyString()); -// } -// -// @Test -// public void 기존_이미지가_없을_때() { -// given(authUserUtils.getAuthUser()) -// .willReturn(account.toBuilder().profileImageUrl(null).build()); -// -// uploadImage(); -// -// // when, then -// assertDoesNotThrow(() -> accountService.updateProfileImage(testImage)); -// verify(s3Uploader, times(0)).deleteImageFromS3(Mockito.anyString(), Mockito.anyString()); -// } -// } -// -// @Test -// public void 닉네임_수정() { -// // given -// String updatedDisplayName = "updatedDisplayName"; -// -// AccountDto.DisplayNamePatch displayNamePatchDto = AccountDto.DisplayNamePatch.builder().displayName(updatedDisplayName).build(); -// -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// given(authUserUtils.getAuthUser()) -// .willReturn(account); -// -// given(accountRepository.save(Mockito.any(Account.class))) -// .willReturn(account.toBuilder().displayName(displayNamePatchDto.getDisplayName()).build()); -// -// // when, then -// assertDoesNotThrow(() -> accountService.updateDisplayName(displayNamePatchDto)); -// } -// -// @Nested -// @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -// class 비밀번호_수정 { -// // given -// String updatedPassword = "updatedPassword"; -// String samePassword = "user1234"; -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// AccountDto.PasswordPatch passwordPatchDto = AccountDto.PasswordPatch.builder() -// .presentPassword(account.getPassword()) -// .changedPassword(updatedPassword) -// .build(); -// -// private void init(String updatedPassword) { -// given(authUserUtils.getAuthUser()) -// .willReturn(account); -// given(passwordEncoder.encode(Mockito.anyString())) -// .willReturn(updatedPassword); -// } -// -// @Test -// @Order(1) -// public void 현재_비밀번호가_일치하지_않으면_실패() { -// init(updatedPassword); -// given(passwordEncoder.matches(Mockito.anyString(), Mockito.anyString())) -// .willReturn(false); -// -// // when, then -// BadCredentialsException exception = assertThrows(BadCredentialsException.class, -// () -> accountService.updatePassword(passwordPatchDto)); -// assertThat(exception.getMessage(), is("현재 비밀번호가 일치하지 않습니다.")); -// } -// -// @Test -// @Order(2) -// public void 새로운_비밀번호가_현재와_같으면_실패() { -// init(samePassword); -// given(passwordEncoder.matches(Mockito.anyString(), Mockito.anyString())) -// .willReturn(true); -// -// // when, then -// BadCredentialsException exception = assertThrows(BadCredentialsException.class, -// () -> accountService.updatePassword(passwordPatchDto)); -// assertThat(exception.getMessage(), is("새로운 비밀번호와 현재 비밀번호가 일치합니다.")); -// } -// -// @Test -// @Order(3) -// public void 아니면_수정_성공() { -// init(updatedPassword); -// given(passwordEncoder.matches(Mockito.anyString(), Mockito.anyString())) -// .willReturn(true); -// -// given(accountRepository.save(Mockito.any(Account.class))) -// .willReturn(account.toBuilder().password(updatedPassword).build()); -// // when, then -// assertDoesNotThrow(() -> accountService.updatePassword(passwordPatchDto)); -// } -// } -// -// @Nested -// @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -// class 단일_사용자_조회 { -// // given -// Long accountId = 1L; -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// @Test -// @Order(1) -// public void 입력한_ID의_사용자가_존재하지_않으면_실패() { -// accountVerification(accountId); -// } -// -// @Test -// @Order(2) -// public void 존재한다면_성공() { -// given(accountRepository.findById(accountId)) -// .willReturn(Optional.of(account)); -// -// // when -// AccountDto.Response responseDto = accountService.getAccount(accountId); -// -// // then -// assertThat(responseDto.getAccountId(), is(accountId)); -// } -// } -// -// @Test -// public void 전체_사용자_조회() { -// // given -// Account account1 = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// Account account2 = getAccount(2L, "user2@gmail.com", "user2", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// Account account3 = getAccount(3L, "user3@gmail.com", "user3", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// given(accountRepository.findAll()) -// .willReturn(List.of(account1, account2, account3)); -// -// // when -// List responseDtos = accountService.getAccounts(); -// -// // then -// assertThat(responseDtos.size(), is(3)); -// assertThat(responseDtos.get(0).getAccountId(), is(1L)); -// assertThat(responseDtos.get(1).getAccountId(), is(2L)); -// assertThat(responseDtos.get(2).getAccountId(), is(3L)); -// } -// -// @Nested -// class 사용자_관련_게시글_조회 { -// // given -// int page = 1; -// int size = 12; -// Long accountId = 1L; -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// BoardLike boardLike = BoardLike.builder().account(account).build(); -// Comment comment1 = Comment.builder().account(account).build(); -// Comment comment2 = Comment.builder().account(account).build(); -// Board board1 = getBoard(1L, account, List.of(comment1), new ArrayList<>()); -// Board board2 = getBoard(2L, account, List.of(comment2), List.of(boardLike)); -// Board board3 = getBoard(3L, account, new ArrayList<>(), new ArrayList<>()); -// -// -// -// @Nested -// @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -// class 사용자가_쓴_게시글_조회 { -// @Test -// @Order(1) -// public void 입력한_ID의_사용자가_존재하지_않으면_실패() { -// accountVerification(accountId); -// } -// -// @Test -// @Order(2) -// public void 존재한다면_성공() { -// given(accountRepository.findById(accountId)) -// .willReturn(Optional.of(account.toBuilder() -// .boards(List.of(board1, board2, board3)) -// .build())); -// -// // when -// Page boardResponsePages = accountService.getAccountBoardWritten(page - 1, size, accountId); -// -// // then -// assertThat(boardResponsePages.getContent().size(), is(3)); -// assertThat(boardResponsePages.getNumber(), is(page - 1)); -// } -// } -// -// @Nested -// @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -// class 사용자가_좋아요_누른_게시글_조회 { -// @Test -// @Order(1) -// public void 입력한_ID의_사용자가_존재하지_않으면_실패() { -// accountVerification(accountId); -// } -// -// @Test -// @Order(2) -// public void 존재한다면_성공() { -// given(accountRepository.findById(accountId)) -// .willReturn(Optional.of(account.toBuilder() -// .boards(List.of(board2)) -// .boardLikes(List.of(boardLike.toBuilder().board(board2).build())) -// .build())); -// -// // when -// Page boardResponsePages = accountService.getAccountBoardLiked(page - 1, size, accountId); -// -// // then -// assertThat(boardResponsePages.getContent().size(), is(1)); -// assertThat(boardResponsePages.getNumber(), is(page - 1)); -// assertThat(boardResponsePages.getContent().get(0).getLikes(), contains(1L)); -// } -// } -// -// @Nested -// @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -// class 사용자가_댓글_쓴_게시글_조회 { -// @Test -// @Order(1) -// public void 입력한_ID의_사용자가_존재하지_않으면_실패() { -// accountVerification(accountId); -// } -// -// @Test -// @Order(2) -// public void 존재한다면_성공() { -// given(accountRepository.findById(accountId)) -// .willReturn(Optional.of(account.toBuilder() -// .boards(List.of(board1, board2)) -// .comments(List.of( -// comment1.toBuilder().board(board1).build(), -// comment2.toBuilder().board(board2).build())) -// .build())); -// -// // when -// Page boardResponsePages = accountService.getAccountCommentWrittenBoard(page - 1, size, accountId); -// -// // then -// assertThat(boardResponsePages.getContent().size(), is(2)); -// assertThat(boardResponsePages.getNumber(), is(page - 1)); -// assertThat(boardResponsePages.getContent().get(0).getCommentNums(), is(1)); -// assertThat(boardResponsePages.getContent().get(1).getCommentNums(), is(1)); -// } -// } -// } -// -// @Nested -// class 회원탈퇴 { -// // given -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// @Test -// public void 기존_이미지가_존재할_때() { -// given(authUserUtils.getAuthUser()) -// .willReturn(account); -// -// willDoNothing().given(s3Uploader).deleteImageFromS3(Mockito.anyString(), Mockito.anyString()); -// -// // when , then -// assertDoesNotThrow(() -> accountService.deleteAccount()); -// verify(s3Uploader, times(1)).deleteImageFromS3(Mockito.anyString(), Mockito.anyString()); -// } -// -// @Test -// public void 기존_이미지가_없을_때() { -// given(authUserUtils.getAuthUser()) -// .willReturn(account.toBuilder().profileImageUrl(null).build()); -// -// // when, then -// assertDoesNotThrow(() -> accountService.deleteAccount()); -// verify(s3Uploader, times(0)).deleteImageFromS3(Mockito.anyString(), Mockito.anyString()); -// } -// } -// -// @Nested -// class 회원탈퇴_시_비밀번호_검증 { -// // given -// String password = "user1234"; -// String diffPassword = "admin1234"; -// -// AccountDto.PasswordVerify passwordVerifyDto = AccountDto.PasswordVerify -// .builder() -// .password(password) -// .build(); -// -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// password, "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// @Test -// public void 입력이_현재_비밀번호와_같을_때() { -// given(authUserUtils.getAuthUser()) -// .willReturn(account); -// -// given(passwordEncoder.matches(Mockito.anyString(), Mockito.anyString())) -// .willReturn(passwordVerifyDto.getPassword().equals(account.getPassword())); -// -// // when -// Boolean response = accountService.verifyPassword(passwordVerifyDto); -// -// // then -// assertThat(response, is(true)); -// } -// -// @Test -// public void 입력이_현재_비밀번호와_다를_때() { -// passwordVerifyDto = passwordVerifyDto.toBuilder().password(diffPassword).build(); -// -// given(authUserUtils.getAuthUser()) -// .willReturn(account); -// -// given(passwordEncoder.matches(Mockito.anyString(), Mockito.anyString())) -// .willReturn(passwordVerifyDto.getPassword().equals(account.getPassword())); -// -// // when -// Boolean response = accountService.verifyPassword(passwordVerifyDto); -// -// // then -// assertThat(response, is(false));} -// } -// -// @Nested -// @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -// class 사용자_검증 { -// // given -// Map claims = new HashMap<>(); -// Long accountId = 1L; -// -// @BeforeEach -// private void securityInit() { -// SecurityContextHolder.setContext(securityContext); -// securityContext.setAuthentication(authentication); -// -// given(SecurityContextHolder.getContext().getAuthentication()) -// .willReturn(authentication); -// } -// -// @Test -// @Order(1) -// public void 로그인된_사용자가_없다면_실패() { -// given(SecurityContextHolder.getContext().getAuthentication()) -// .willReturn(null); -// -// //when, then -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> accountService.isAuthIdMatching(accountId)); -// assertThat(exception.getExceptionCode().getStatus(), is(404)); -// assertThat(exception.getExceptionCode().getMessage(), is("Account not found")); -// } -// -// @Test -// @Order(2) -// public void 인증되지_않은_사용자라면_실패() { -// given(authentication.getPrincipal()) -// .willReturn(claims); -// -// given(authentication.getName()) -// .willReturn(null); -// -// //when, then -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> accountService.isAuthIdMatching(accountId)); -// assertThat(exception.getExceptionCode().getStatus(), is(401)); -// assertThat(exception.getExceptionCode().getMessage(), is("Account unauthorized")); -// } -// -// @Test -// @Order(3) -// public void 익명_사용자라면_실패() { -// given(authentication.getPrincipal()) -// .willReturn(claims); -// -// given(authentication.getName()) -// .willReturn("anonymousUser"); -// -// //when, then -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> accountService.isAuthIdMatching(accountId)); -// assertThat(exception.getExceptionCode().getStatus(), is(401)); -// assertThat(exception.getExceptionCode().getMessage(), is("Account unauthorized")); -// } -// -// @Test -// @Order(4) -// public void 로그인된_사용자와_입력된_사용자가_다르면_실패() { -// given(authentication.getPrincipal()) -// .willReturn(claims); -// -// claims.put("accountId", "999"); -// -// given(authentication.getName()) -// .willReturn("SeungTaeLee"); -// -// //when, then -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> accountService.isAuthIdMatching(accountId)); -// assertThat(exception.getExceptionCode().getStatus(), is(405)); -// assertThat(exception.getExceptionCode().getMessage(), is("That Account doesn't have authority")); -// } -// -// @Test -// @Order(5) -// public void 로그인된_사용자가_입력과_동일하면_성공() { -// given(authentication.getPrincipal()) -// .willReturn(claims); -// -// claims.put("accountId", "1"); -// -// given(authentication.getName()) -// .willReturn("SeungTaeLee"); -// -// //when, then -// assertDoesNotThrow(() -> accountService.isAuthIdMatching(accountId)); -// } -// } -// -// private static Account getAccount(Long accountId, String email, String displayName, String password, -// String profileImageUrl, Point point, List roles, Account.AccountGrade accountGrade) { -// return Account.builder() -// .accountId(accountId) -// .email(email) -// .displayName(displayName) -// .password(password) -// .profileImageUrl(profileImageUrl) -// .point(point) -// .roles(roles) -// .accountGrade(accountGrade) -// .build(); -// } -// -// private static Board getBoard(Long boardId, Account account, List boardComments, List boardLikes) { -// return Board.builder() -// .boardId(boardId) -// .boardImages(new ArrayList<>()) -// .account(account) -// .boardComments(boardComments) -// .boardLikes(boardLikes) -// .build(); -// } -// -// private void accountVerification(Long accountId) { -// given(accountRepository.findById(accountId)) -// .willReturn(Optional.empty()); -// -// // when, then -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> accountService.getAccount(accountId)); -// assertThat(exception.getExceptionCode().getStatus(), is(404)); -// assertThat(exception.getExceptionCode().getMessage(), is("Account not found")); -// } -//} diff --git a/server/src/test/java/com/growstory/domain/board/controller/BoardControllerTest.java b/server/src/test/java/com/growstory/domain/board/controller/BoardControllerTest.java deleted file mode 100644 index 9b6db6d2..00000000 --- a/server/src/test/java/com/growstory/domain/board/controller/BoardControllerTest.java +++ /dev/null @@ -1,77 +0,0 @@ -//package com.growstory.domain.board.controller; -// -//import com.google.gson.Gson; -//import com.growstory.domain.board.service.BoardService; -//import org.junit.jupiter.api.DisplayName; -//import org.junit.jupiter.api.Test; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -//import org.springframework.boot.test.context.SpringBootTest; -//import org.springframework.boot.test.mock.mockito.MockBean; -//import org.springframework.test.web.servlet.MockMvc; -// -//import java.util.ArrayList; -//import java.util.Arrays; -//import java.util.List; -// -//import static org.junit.jupiter.api.Assertions.*; -// -// -//@SpringBootTest -//@AutoConfigureMockMvc -//class BoardControllerTest { -// -// // CICD plz -// @Autowired -// private MockMvc mockMvc; -// -// @Autowired -// private Gson gson; -// -// @MockBean -// private BoardService boardService; -// -// private final String BOARD_DEFAULT_URL = "/v1/boards"; -// -// -// @DisplayName("게시판 등록") -// @Test -// void 게시판_등록() throws Exception { -// -// // given -// String title = "게시글 제목"; -// String content = "게시글 본문"; -// List hashTagList = new ArrayList<>(); -// hashTagList.add("tag1"); -// hashTagList.add("tag2"); -// -// // when -// -// // then -// -// } -// -// @Test -// void getBoard() { -// } -// -// @Test -// void getBoards() { -// } -// -// @Test -// void getBoardsByKeyword() { -// } -// -// @Test -// void patchBoard() { -// } -// -// @Test -// void deleteBoard() { -// } -// -// @Test -// void getTop3LikedBoardsOfWeek() { -// } -//} \ No newline at end of file diff --git a/server/src/test/java/com/growstory/domain/board/service/BoardRankingTest.java b/server/src/test/java/com/growstory/domain/board/service/BoardRankingTest.java deleted file mode 100644 index dacf2061..00000000 --- a/server/src/test/java/com/growstory/domain/board/service/BoardRankingTest.java +++ /dev/null @@ -1,192 +0,0 @@ -//package com.growstory.domain.board.service; -// -//import com.growstory.domain.board.repository.BoardHashTagRepository; -//import com.growstory.domain.board.repository.BoardRepository; -//import com.growstory.domain.comment.service.CommentService; -//import com.growstory.domain.hashTag.repository.HashTagRepository; -//import com.growstory.domain.hashTag.service.HashTagService; -//import com.growstory.domain.images.service.BoardImageService; -//import com.growstory.domain.rank.board_likes.entity.BoardLikesRank; -//import com.growstory.domain.stubdata.Stub; -//import com.growstory.global.auth.utils.AuthUserUtils; -//import org.junit.jupiter.api.*; -//import org.junit.jupiter.api.extension.ExtendWith; -//import org.mockito.InjectMocks; -//import org.mockito.Mock; -//import org.mockito.Mockito; -//import org.mockito.junit.jupiter.MockitoExtension; -// -//import java.time.LocalDateTime; -//import java.util.ArrayList; -//import java.util.List; -// -//import static org.hamcrest.MatcherAssert.assertThat; -//import static org.hamcrest.Matchers.is; -//import static org.mockito.BDDMockito.given; -// -//@ExtendWith(MockitoExtension.class) -//public class BoardRankingTest { -// -// @InjectMocks -// private BoardService boardService; -// @Mock -// private BoardRepository boardRepository; -// @Mock -// private HashTagService hashTagService; -// @Mock -// private BoardImageService boardImageService; -// @Mock -// private AuthUserUtils authUserUtils; -// @Mock -// private HashTagRepository hashTagRepository; -// @Mock -// private BoardHashTagRepository boardHashtagRepository; -// @Mock -// private CommentService commentService; -// -// -// @DisplayName("좋아요 기준 상위 3개의 게시글 랭킹과 함께 반환") -// @Nested -// @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -// class FindTop3LikedBoardRanksTest { -// -// //given -// List mockTopBoardsWithLikes = new ArrayList<>(); -// Object[] mockObjectsLike3_1 = {Stub.MockBoard.getMockBoard1(), 3L}; -// Object[] mockObjectsLike3_2 = {Stub.MockBoard.getMockBoard2(), 3L}; -// Object[] mockObjectsLike3_3 = {Stub.MockBoard.getMockBoard3(), 3L}; -// Object[] mockObjectsLike3_4 = {Stub.MockBoard.getMockBoard4(), 3L}; -// Object[] mockObjectsLike3_5 = {Stub.MockBoard.getMockBoard5(), 3L}; -// Object[] mockObjectsLike2_1 = {Stub.MockBoard.getMockBoard2(), 2L}; -// Object[] mockObjectsLike2_2 = {Stub.MockBoard.getMockBoard4(), 2L}; -// Object[] mockObjectsLike2_3 = {Stub.MockBoard.getMockBoard3(), 2L}; -// Object[] mockObjectsLike2_4 = {Stub.MockBoard.getMockBoard5(), 2L}; -// Object[] mockObjectsLike2_5 = {Stub.MockBoard.getMockBoard1(), 2L}; -// Object[] mockObjectsLike1_1 = {Stub.MockBoard.getMockBoard3(), 1L}; -// Object[] mockObjectsLike1_2 = {Stub.MockBoard.getMockBoard5(), 1L}; -// @BeforeEach -// public void setUp() { -// mockTopBoardsWithLikes.add(mockObjectsLike3_1); -// } -// -//// @AfterEach -//// public void tearDown() { -//// mockTopBoardsWithLikes.clear(); -//// } -// -// @Test -// @Order(1) -// void 동점자_없는_상위_3개_게시글() { -// //given -// // 좋아요 3, 2, 1 -// mockTopBoardsWithLikes.add(mockObjectsLike2_1); -// mockTopBoardsWithLikes.add(mockObjectsLike1_1); -// given(boardRepository.findTop3LikedBoards(Mockito.any(LocalDateTime.class))) -// .willReturn(mockTopBoardsWithLikes); -// -// //when -// List responses = boardService.findTop3LikedBoardRanks(); -// -// //then -// assertThat(responses.get(0).getLikeNum(), is(3L)); -// assertThat(responses.get(2).getLikeNum(), is(1L)); -// assertThat(responses.get(responses.size()-1).getRankOrders().getPosition(), is(3)); -// assertThat(responses.size(), is(3)); -// } -// -// @Test -// @Order(2) -// void 일등1_이등2_삼등1() { -// //given -// // 좋아요 3, 2, 2, 1 -// mockTopBoardsWithLikes.add(mockObjectsLike2_1); -// mockTopBoardsWithLikes.add(mockObjectsLike2_2); -// mockTopBoardsWithLikes.add(mockObjectsLike1_2); -// given(boardRepository.findTop3LikedBoards(Mockito.any(LocalDateTime.class))) -// .willReturn(mockTopBoardsWithLikes); -// -// //when -// List responses = boardService.findTop3LikedBoardRanks(); -// -// //then -// assertThat(responses.get(0).getLikeNum(), is(3L)); -// assertThat(responses.get(2).getLikeNum(), is(2L)); -// assertThat(responses.get(responses.size()-1).getRankOrders().getPosition(), is(2)); -// assertThat(responses.size(), is(3)); -// } -// -// @Test -// @Order(3) -// void 일등3_이등1() { -// //given -// // 좋아요 3, 3, 3, 1 -// mockTopBoardsWithLikes.add(mockObjectsLike3_2); -// mockTopBoardsWithLikes.add(mockObjectsLike3_3); -// mockTopBoardsWithLikes.add(mockObjectsLike1_1); -// given(boardRepository.findTop3LikedBoards(Mockito.any(LocalDateTime.class))) -// .willReturn(mockTopBoardsWithLikes); -// -// //when -// List responses = boardService.findTop3LikedBoardRanks(); -// -// //then -// assertThat(responses.get(0).getLikeNum(), is(3L)); -// assertThat(responses.get(2).getLikeNum(), is(3L)); -// assertThat(responses.get(0).getRankOrders().getPosition(), is(1)); -// assertThat(responses.get(responses.size()-1).getRankOrders().getPosition(), is(1)); -// assertThat(responses.size(), is(3)); -// } -// @Test -// @Order(4) -// void 일등5_이등2() { -// //given -// // 좋아요 3, 3, 3, 3, 3, 1, 1 -// mockTopBoardsWithLikes.add(mockObjectsLike3_2); -// mockTopBoardsWithLikes.add(mockObjectsLike3_3); -// mockTopBoardsWithLikes.add(mockObjectsLike3_4); -// mockTopBoardsWithLikes.add(mockObjectsLike3_5); -// mockTopBoardsWithLikes.add(mockObjectsLike1_1); -// mockTopBoardsWithLikes.add(mockObjectsLike1_2); -// given(boardRepository.findTop3LikedBoards(Mockito.any(LocalDateTime.class))) -// .willReturn(mockTopBoardsWithLikes); -// -// //when -// List responses = boardService.findTop3LikedBoardRanks(); -// -// //then -// assertThat(responses.get(0).getLikeNum(), is(3L)); -// assertThat(responses.get(responses.size()-1).getLikeNum(), is(3L)); -// assertThat(responses.get(0).getRankOrders().getPosition(), is(1)); -// assertThat(responses.get(responses.size()-1).getRankOrders().getPosition(), is(1)); -// assertThat(responses.size(), is(5)); -// } -// @Test -// @Order(5) -// void 일등1_이등5_삼등1() { -// //given -// // 좋아요 3, 2, 2, 2, 2, 2, 1 -// mockTopBoardsWithLikes.add(mockObjectsLike2_1); -// mockTopBoardsWithLikes.add(mockObjectsLike2_2); -// mockTopBoardsWithLikes.add(mockObjectsLike2_3); -// mockTopBoardsWithLikes.add(mockObjectsLike2_4); -// mockTopBoardsWithLikes.add(mockObjectsLike2_5); -// mockTopBoardsWithLikes.add(mockObjectsLike1_1); -// given(boardRepository.findTop3LikedBoards(Mockito.any(LocalDateTime.class))) -// .willReturn(mockTopBoardsWithLikes); -// -// //when -// List responses = boardService.findTop3LikedBoardRanks(); -// -// //then -// assertThat(responses.get(0).getLikeNum(), is(3L)); -// assertThat(responses.get(responses.size()-1).getLikeNum(), is(2L)); -// assertThat(responses.get(0).getRankOrders().getPosition(), is(1)); -// assertThat(responses.get(responses.size()-1).getRankOrders().getPosition(), is(2)); -// assertThat(responses.size(), is(6)); -// } -// -// -// -// -// } -//} diff --git a/server/src/test/java/com/growstory/domain/board/service/BoardServiceTest.java b/server/src/test/java/com/growstory/domain/board/service/BoardServiceTest.java deleted file mode 100644 index d07ca0ec..00000000 --- a/server/src/test/java/com/growstory/domain/board/service/BoardServiceTest.java +++ /dev/null @@ -1,62 +0,0 @@ -//package com.growstory.domain.board.service; -// -//import com.growstory.domain.account.entity.Account; -//import com.growstory.domain.board.entity.Board; -//import com.growstory.domain.board.repository.BoardRepository; -//import com.growstory.domain.rank.board_likes.dto.BoardLikesRankDto; -//import com.growstory.domain.stubdata.Stub; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.api.extension.ExtendWith; -//import org.mockito.InjectMocks; -//import org.mockito.Mock; -//import org.mockito.Mockito; -//import org.mockito.junit.jupiter.MockitoExtension; -//import org.springframework.test.context.TestPropertySource; -// -//import java.time.LocalDateTime; -//import java.util.ArrayList; -//import java.util.List; -// -//import static org.junit.jupiter.api.Assertions.assertEquals; -//import static org.mockito.BDDMockito.given; -// -//@ExtendWith(MockitoExtension.class) -//@TestPropertySource(properties = { -// "my.scheduled.cron=0 0 0 * * ?" // 예제 크론 표현식 -//}) -//public class BoardServiceTest { -// -// @InjectMocks -// private BoardService boardService; -// -// @Mock -// private BoardRepository boardRepository; -// -// @Test -// void testFindTop3LikedBoards() { -// // given, 가짜 데이터 생성 -// List fakeTopBoardsWithLikes = new ArrayList<>(); -// fakeTopBoardsWithLikes.add(new Object[] { Board.builder().boardId(1L).title("제목1").account(Account.builder().displayName("빵빵스").build()).boardLikes(Stub.MockBoardLikes.getBoardLikes1()).build(), 3L}); -// fakeTopBoardsWithLikes.add(new Object[] { Board.builder().boardId(2L).title("제목2").account(Account.builder().displayName("김크크").build()).boardLikes(Stub.MockBoardLikes.getBoardLikes2()).build(), 2L}); -// fakeTopBoardsWithLikes.add(new Object[] { Board.builder().boardId(3L).title("제목3").account(Account.builder().displayName("박크크").build()).boardLikes(Stub.MockBoardLikes.getBoardLikes3()).build(), 1L}); -// -// // 가짜 데이터를 반환하도록 Mock 설정 -// given(boardRepository.findTop3LikedBoards(Mockito.any(LocalDateTime.class))) -// .willReturn(fakeTopBoardsWithLikes); -// -// //when, 테스트 대상 메서드 호출 -// List response = boardService.findTop3LikedBoards(); -// -// //then, 결과 검증 -// assertEquals(3, response.size()); -// -// assertEquals(1L, response.get(0).getBoardId()); -// assertEquals(3, response.get(0).getLikeNum()); -// -// assertEquals(2L, response.get(1).getBoardId()); -// assertEquals(2, response.get(1).getLikeNum()); -// -// assertEquals(3L, response.get(2).getBoardId()); -// assertEquals(1, response.get(2).getLikeNum()); -// } -//} diff --git a/server/src/test/java/com/growstory/domain/comment/controller/CommentControllerTest.java b/server/src/test/java/com/growstory/domain/comment/controller/CommentControllerTest.java deleted file mode 100644 index 07618b5e..00000000 --- a/server/src/test/java/com/growstory/domain/comment/controller/CommentControllerTest.java +++ /dev/null @@ -1,127 +0,0 @@ -//package com.growstory.domain.comment.controller; -// -//import com.google.gson.Gson; -//import com.growstory.domain.comment.dto.CommentDto; -//import com.growstory.domain.comment.service.CommentService; -//import org.junit.jupiter.api.Test; -//import org.mockito.Mockito; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -//import org.springframework.boot.test.context.SpringBootTest; -//import org.springframework.boot.test.mock.mockito.MockBean; -//import org.springframework.http.MediaType; -//import org.springframework.security.test.context.support.WithMockUser; -//import org.springframework.test.web.servlet.MockMvc; -//import org.springframework.test.web.servlet.ResultActions; -//import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -//import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -// -//import static org.hamcrest.Matchers.is; -//import static org.hamcrest.Matchers.startsWith; -//import static org.mockito.BDDMockito.given; -//import static org.mockito.Mockito.doNothing; -//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; -//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.header; -//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -// -// -//@SpringBootTest -//@AutoConfigureMockMvc -//class CommentControllerTest { -// -// @Autowired -// private MockMvc mockMvc; -// -// -// @Autowired -// private Gson gson; -// -// @MockBean -// private CommentService commentService; -// -// -// @Test -// void postComment() throws Exception { -// -// // given -// String content = "Comment Test"; -// Long boardId = 1L; -// Long commentId = 1L; -// -// CommentDto.Post commentDto = new CommentDto.Post(content); -// -// -// // when -// given(commentService.saveComment(Mockito.eq(boardId), Mockito.any(CommentDto.Post.class))) -// .willReturn(commentId); -// -// String content1 = gson.toJson(boardId); -// String content2 = gson.toJson(commentDto); -// -// // then -// ResultActions actions = -// mockMvc.perform( -// post("/v1/comments/boards/{boardId}", boardId) -// .accept(MediaType.APPLICATION_JSON) // 요청에서 받을 응답 데이터 타입을 JSON으로 설정합니다. 이것은 클라이언트가 JSON 형식의 응답을 기대한다고 나타냅니다. -// .contentType(MediaType.APPLICATION_JSON) // 요청 데이터의 타입을 JSON으로 설정합니다. 이것은 요청의 본문(content)이 JSON 형식임을 나타냅니다. -// .content(content1) -// .content(content2) -// ); -// -// actions -// .andExpect(status().isCreated()) -// .andExpect(header().string("Location", is(startsWith("/v1/comments/")))) -// .andDo(print()); -// } -// -// @Test -// @WithMockUser(username = "testuser", roles = "USER") // 사용자 권한으로 요청 보내기 -// void patchComment() throws Exception{ -// // given -// Long commentId = 1L; -// String content = "TestContent"; -// CommentDto.Patch commentDto = new CommentDto.Patch(content); -// -// -// // when -// doNothing().when(commentService).editComment(commentId, commentDto); -// -// String content1 = gson.toJson(commentId); -// String content2 = gson.toJson(commentDto); -// -// -// // then -// ResultActions actions = -// mockMvc.perform( -// patch("/v1/comments/{commentId}", commentId) -// .accept(MediaType.APPLICATION_JSON) // 요청에서 받을 응답 데이터 타입을 JSON으로 설정합니다. 이것은 클라이언트가 JSON 형식의 응답을 기대한다고 나타냅니다. -// .contentType(MediaType.APPLICATION_JSON) // 요청 데이터의 타입을 JSON으로 설정합니다. 이것은 요청의 본문(content)이 JSON 형식임을 나타냅니다 -// .content(content1) -// .content(content2) -// ); -// -// actions -// .andExpect(MockMvcResultMatchers.status().isNoContent()) -// .andDo(print()); -// } -// -// @Test -// @WithMockUser(username = "testuser", roles = "USER") // 사용자 권한으로 요청 보내기 -// void deleteComment() throws Exception { -// // given -// Long commentId = 1L; -// -// // when -// doNothing().when(commentService).deleteComment(commentId); -// -// // then -// ResultActions actions = mockMvc.perform( -// MockMvcRequestBuilders.delete("/v1/comments/{commentId}", commentId) -// ); -// actions -// .andExpect(MockMvcResultMatchers.status().isNoContent()) -// .andDo(print()); -// } -//} \ No newline at end of file diff --git a/server/src/test/java/com/growstory/domain/journal/JournalControllerTest.java b/server/src/test/java/com/growstory/domain/journal/JournalControllerTest.java deleted file mode 100644 index 2d277818..00000000 --- a/server/src/test/java/com/growstory/domain/journal/JournalControllerTest.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.growstory.domain.journal; - -import com.google.gson.Gson; -import com.growstory.domain.journal.dto.JournalDto; -import com.growstory.domain.journal.service.JournalService; -import com.growstory.domain.stubdata.Stub; -import com.growstory.global.utils.UriCreator; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.mock.web.MockMultipartFile; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.ResultActions; -import org.springframework.web.multipart.MultipartFile; - -import java.io.IOException; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; - -import static org.hamcrest.Matchers.*; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.BDDMockito.given; -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.*; -@SpringBootTest -@AutoConfigureMockMvc -public class JournalControllerTest { - - @Autowired - private MockMvc mockMvc; - - @Autowired - private Gson gson; - - @MockBean - private JournalService journalService; - - @MockBean - private UriCreator uriCreator; - - private final String DEFAULT_URL = "/v1/leaves"; - - @DisplayName("식물 일지 전체 조회") - @Test - void getJournalsTest() throws Exception { - //given - Long accountId = 1L; - Long leafId = 1L; - List journals = Stub.MockJournal.getStubJournalResponseDtos(); - given(journalService.findAllJournals(anyLong(), anyLong())) - .willReturn(journals); - //when - ResultActions actions = mockMvc.perform( - get(DEFAULT_URL + "/{leaf-id}/journals", leafId) - .param("accountId", accountId.toString()) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON) - ); - - //then - actions.andExpect(status().isOk()) - .andExpect(jsonPath("$.data[0].journalId", is(1))) - .andExpect(jsonPath("$.data[0].title", is(journals.get(0).getTitle()))) - .andDo(print()); - } - - @DisplayName("식물 일지 등록 기능") - @Nested - class PostJournalTest { - - long leafId; -// JournalDto.LeafAuthor leafAuthor; - JournalDto.Post requestDto; - MockMultipartFile leafAuthorPart; - MockMultipartFile requestDtoPart; - MockMultipartFile imagePart; - JournalDto.Response mockJournalResponse; - - @BeforeEach - void init() { - leafId = 1L; -// leafAuthor = JournalDto.LeafAuthor.builder().accountId(1L).build(); - requestDto = JournalDto.Post.builder().title("식물 일지 제목").content("내용").build(); - - // MockMultipartFile 객체화 -// leafAuthorPart = createMockMultipartFile("leafAuthor", gson.toJson(leafAuthor), "application/json"); - requestDtoPart = createMockMultipartFile("postDto", gson.toJson(requestDto), "application/json"); - imagePart = createImageMockFile("src/test/resources/images/testImage.jpg"); - - //given - mockJournalResponse = Stub.MockJournal.getStubJournalResponse1(); - given(journalService.createJournal(anyLong(), Mockito.any(JournalDto.Post.class), Mockito.any(MultipartFile.class))) - .willReturn(mockJournalResponse); - - URI stubUri = URI.create("/v1/leaves/1/journals/1"); - given(uriCreator.createUri_test(Mockito.any(String.class), Mockito.anyLong())).willReturn(stubUri); - } - - private MockMultipartFile createMockMultipartFile(String name, String content, String contentType) { - return new MockMultipartFile(name, name + ".json", contentType, content.getBytes(StandardCharsets.UTF_8)); - } - - private MockMultipartFile createImageMockFile(String pathString) { - Path path = Paths.get(pathString); - byte[] content; - try { - content = Files.readAllBytes(path); - } catch (IOException e) { - throw new RuntimeException(e); - } - return new MockMultipartFile("image", "testImage.jpg", "image/jpeg", content); - } - - @Test - void 이미지_있는_식물_일지_등록() throws Exception { - - //when - ResultActions actions = mockMvc.perform( - multipart(DEFAULT_URL + "/{leaf-id}/journals", leafId) -// .file(leafAuthorPart) - .file(requestDtoPart) - .file(imagePart) - .contentType("multipart/form-data") - .accept(MediaType.APPLICATION_JSON) - .characterEncoding("UTF-8") - ); - - //then - URI expectedLocation = UriCreator.createUri(DEFAULT_URL + "/1/journals/", mockJournalResponse.getJournalId()); - actions - .andExpect(status().isCreated()) - .andExpect(header().string("Location", is(expectedLocation.toString()))) - .andDo(print()); - } - -// @Test -// void 이미지가_없는_식물_일지_등록() throws Exception { -// // given, imagePart를 null로 설정 -// MockMultipartFile imagePart = null; -// -// ResultActions actions = mockMvc.perform( -// multipart(DEFAULT_URL + "/{leaf-id}/journals", leafId) -// .file(leafAuthorPart) -// .file(requestDtoPart) -// // image part를 추가하지 않음 -// .file(imagePart) -// .contentType("multipart/form-data") -// .accept(MediaType.APPLICATION_JSON) -// .characterEncoding("UTF-8") -// ); -// -// // then -// actions -// .andExpect(status().isCreated()) // or isBadRequest(), depending on the expected outcome -// .andDo(print()); -// } - - @Test - void 이미지가_빈_식물_일지_등록() throws Exception { - // given, imagePart를 빈 내용으로 설정 - MockMultipartFile imagePart = new MockMultipartFile("image", "testImage.jpg", "image/jpeg", new byte[0]); - - // when - ResultActions actions = mockMvc.perform( - multipart(DEFAULT_URL + "/{leaf-id}/journals", leafId) -// .file(leafAuthorPart) - .file(requestDtoPart) - .file(imagePart) // empty image part - .contentType("multipart/form-data") - .accept(MediaType.APPLICATION_JSON) - .characterEncoding("UTF-8") - ); - - // then - actions - .andExpect(status().isCreated()) // or isBadRequest(), depending on the expected outcome - .andDo(print()); - } - } - - -} diff --git a/server/src/test/java/com/growstory/domain/leaf/controller/LeafControllerTest.java b/server/src/test/java/com/growstory/domain/leaf/controller/LeafControllerTest.java deleted file mode 100644 index 29f85263..00000000 --- a/server/src/test/java/com/growstory/domain/leaf/controller/LeafControllerTest.java +++ /dev/null @@ -1,191 +0,0 @@ -//package com.growstory.domain.leaf.controller; -// -//import com.google.gson.Gson; -//import com.growstory.domain.account.dto.AccountDto; -//import com.growstory.domain.leaf.dto.LeafDto; -//import com.growstory.domain.leaf.service.LeafService; -//import com.growstory.domain.point.entity.Point; -//import org.junit.jupiter.api.Test; -//import org.mockito.Mockito; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -//import org.springframework.boot.test.context.SpringBootTest; -//import org.springframework.boot.test.mock.mockito.MockBean; -//import org.springframework.http.HttpMethod; -//import org.springframework.http.MediaType; -//import org.springframework.mock.web.MockMultipartFile; -//import org.springframework.mock.web.MockPart; -//import org.springframework.test.web.servlet.MockMvc; -//import org.springframework.test.web.servlet.ResultActions; -//import org.springframework.web.multipart.MultipartFile; -// -//import javax.servlet.http.Part; -//import java.io.FileInputStream; -//import java.util.ArrayList; -//import java.util.List; -// -//import static org.hamcrest.Matchers.is; -//import static org.mockito.BDDMockito.given; -//import static org.mockito.BDDMockito.willDoNothing; -//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -//import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -// -//@SpringBootTest -//@AutoConfigureMockMvc -//public class LeafControllerTest { -// @Autowired -// private MockMvc mockMvc; -// -// @Autowired -// private Gson gson; -// -// @MockBean -// private LeafService leafService; -// -// @Test -// void 식물카드_생성() throws Exception { -// // given -// Long leafId = 1L; -// -// LeafDto.Post requestDto = LeafDto.Post.builder() -// .leafName("식물1") -// .content("본문1") -// .build(); -// -// LeafDto.Response responseDto = getResponseDto("김별명", leafId, requestDto.getLeafName(), requestDto.getContent(), "s3/path"); -// -// MockMultipartFile testImage = new MockMultipartFile("leafImage", -// "testImage.jpg", -// "jpg", -// new FileInputStream("src/test/resources/images/testImage.jpg")); -// -// -// given(leafService.createLeaf(Mockito.any(LeafDto.Post.class), Mockito.any(MultipartFile.class))) -// .willReturn(responseDto); -// -// // when -// ResultActions actions = mockMvc.perform( -// multipart(HttpMethod.POST, "/v1/leaves") -// .file(testImage) -// .file(new MockMultipartFile("leafPostDto", "", "application/json", gson.toJson(requestDto).getBytes()))); -// -// // then -// actions -// .andExpect(status().isCreated()) -// .andExpect(header().string("Location", is("/v1/leaves/" + responseDto.getLeafId().toString()))) -// .andDo(print()); -// } -// -// @Test -// void 식물카드_수정() throws Exception { -// // given -// LeafDto.Patch requestDto = LeafDto.Patch.builder() -// .leafId(1L) -// .leafName("식물1") -// .content("본문1") -// .build(); -// -// MockMultipartFile testImage = new MockMultipartFile("leafImage", -// "testImage.jpg", -// "jpg", -// new FileInputStream("src/test/resources/images/testImage.jpg")); -// -// willDoNothing().given(leafService).updateLeaf(Mockito.any(LeafDto.Patch.class), Mockito.any(MultipartFile.class)); -// -// // when -// ResultActions actions = mockMvc.perform( -// multipart(HttpMethod.PATCH, "/v1/leaves") -// .file(testImage) -// .file(new MockMultipartFile("leafPatchDto", "", "application/json", gson.toJson(requestDto).getBytes()))); -// -// // then -// actions -// .andExpect(status().isNoContent()) -// .andDo(print()); -// } -// -// @Test -// void 나의_식물카드_조회() throws Exception { -// // given -// Long accountId = 1L; -// -// List responseDtos = getResponseDtos(); -// -// given(leafService.findLeaves(Mockito.anyLong())) -// .willReturn(responseDtos); -// -// // when -// ResultActions actions = mockMvc.perform( -// get("/v1/leaves/account/" + accountId)); -// -// // then -// actions -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.data[0].leafName", is("식물1"))) -// .andExpect(jsonPath("$.data[1].leafName", is("식물2"))) -// .andDo(print()); -// } -// -// @Test -// void 식물카드_단일_조회() throws Exception { -// // given -// Long leafId = 1L; -// -// LeafDto.Response responseDto = getResponseDto("김별명", 1L, "식물1", "본문1", "s3/path1"); -// -// given(leafService.findLeaf(Mockito.anyLong())) -// .willReturn(responseDto); -// -// // when -// ResultActions actions = mockMvc.perform( -// get("/v1/leaves/" + leafId)); -// -// // then -// actions -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.data.leafName", is("식물1"))) -// .andDo(print()); -// } -// -// @Test -// void 식물카드_삭제() throws Exception { -// // given -// Long leafId = 1L; -// -// willDoNothing().given(leafService).deleteLeaf(Mockito.anyLong()); -// -// // when -// ResultActions actions = mockMvc.perform( -// delete("/v1/leaves/" + leafId)); -// -// // then -// actions -// .andExpect(status().isNoContent()) -// .andDo(print()); -// } -// -// private static LeafDto.Response getResponseDto(String displayName, Long leafId, String leafName, String content, String leafImageUrl) { -// return LeafDto.Response.builder() -// .displayName(displayName) -// .leafId(leafId) -// .leafName(leafName) -// .content(content) -// .leafImageUrl(leafImageUrl) -// .build(); -// } -// -// private static List getResponseDtos() { -// List responseDtos = new ArrayList<>(); -// -// LeafDto.Response responseDto1 = getResponseDto("김별명", 1L, "식물1", "본문1", "s3/path1"); -// LeafDto.Response responseDto2 = getResponseDto("김별명", 2L, "식물2", "본문2", "s3/path2"); -// -// responseDtos.add(responseDto1); -// responseDtos.add(responseDto2); -// -// return responseDtos; -// } -//} diff --git a/server/src/test/java/com/growstory/domain/leaf/service/LeafServiceTest.java b/server/src/test/java/com/growstory/domain/leaf/service/LeafServiceTest.java deleted file mode 100644 index c730cd88..00000000 --- a/server/src/test/java/com/growstory/domain/leaf/service/LeafServiceTest.java +++ /dev/null @@ -1,408 +0,0 @@ -//package com.growstory.domain.leaf.service; -// -//import com.growstory.domain.account.entity.Account; -//import com.growstory.domain.account.service.AccountService; -//import com.growstory.domain.images.entity.JournalImage; -//import com.growstory.domain.images.service.JournalImageService; -//import com.growstory.domain.journal.entity.Journal; -//import com.growstory.domain.leaf.dto.LeafDto; -//import com.growstory.domain.leaf.entity.Leaf; -//import com.growstory.domain.leaf.repository.LeafRepository; -//import com.growstory.domain.plant_object.entity.PlantObj; -//import com.growstory.domain.point.entity.Point; -//import com.growstory.global.auth.utils.AuthUserUtils; -//import com.growstory.global.aws.service.S3Uploader; -//import com.growstory.global.exception.BusinessLogicException; -//import com.growstory.global.exception.ExceptionCode; -//import org.junit.jupiter.api.*; -//import org.junit.jupiter.api.extension.ExtendWith; -//import org.mockito.InjectMocks; -//import org.mockito.Mock; -//import org.mockito.Mockito; -//import org.mockito.junit.jupiter.MockitoExtension; -//import org.springframework.mock.web.MockMultipartFile; -//import org.springframework.security.authentication.BadCredentialsException; -//import org.springframework.web.multipart.MultipartFile; -// -//import java.io.FileInputStream; -//import java.io.FileNotFoundException; -//import java.io.IOException; -//import java.util.ArrayList; -//import java.util.Arrays; -//import java.util.List; -//import java.util.Optional; -// -//import static org.hamcrest.MatcherAssert.assertThat; -//import static org.hamcrest.Matchers.contains; -//import static org.hamcrest.Matchers.is; -//import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -//import static org.junit.jupiter.api.Assertions.assertThrows; -//import static org.mockito.BDDMockito.*; -// -//@ExtendWith(MockitoExtension.class) -//public class LeafServiceTest { -// @InjectMocks -// private LeafService leafService; -// @Mock -// private LeafRepository leafRepository; -// @Mock -// private AccountService accountService; -// @Mock -// private S3Uploader s3Uploader; -// @Mock -// private AuthUserUtils authUserUtils; -// @Mock -// private JournalImageService journalImageService; -// -// @Nested -// @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -// class 식물카드_생성 { -// // given -// String s3ImageUrl = "s3/path"; -// -// LeafDto.Post leafPostDto = LeafDto.Post.builder() -// .leafName("식물1") -// .content("본문1") -// .build(); -// -// MockMultipartFile testImage = new MockMultipartFile("profileImage", -// "testImage.jpg", -// "jpg", -// new FileInputStream("src/test/resources/images/testImage.jpg")); -// -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// Leaf leaf = getLeaf(1L, leafPostDto.getLeafName(), leafPostDto.getContent(), s3ImageUrl); -// -// private List getLeaves(int size) { -// List leaves = new ArrayList<>(); -// for (int i = 0; i < size; i++) leaves.add(leaf); -// -// return leaves; -// } -// private void uploadImage() { -// given(s3Uploader.uploadImageToS3(Mockito.any(MockMultipartFile.class), Mockito.anyString())) -// .willReturn(s3ImageUrl); -// given(leafRepository.save(Mockito.any(Leaf.class))) -// .willReturn(leaf.toBuilder().leafImageUrl(s3ImageUrl).build()); -// } -// -// 식물카드_생성() throws IOException { -// } -// -// @Test -// @Order(1) -// public void 사용자의_식물카드가_50개_미만이면() { -// int leafSize = 1; -// List leaves = getLeaves(leafSize); -// -// // when -// Account.AccountGrade grade = leafService.updateAccountGrade(account.toBuilder().leaves(leaves).build()); -// -// // then -// assertThat(grade.getStepDescription(), is("브론즈 가드너")); -// } -// -// @Test -// @Order(2) -// public void 사용자의_식물카드가_50개_이상_100개_미만이면() { -// int leafSize = 50; -// List leaves = getLeaves(leafSize); -// -// // when -// Account.AccountGrade grade = leafService.updateAccountGrade(account.toBuilder().leaves(leaves).build()); -// -// // then -// assertThat(grade.getStepDescription(), is("실버 가드너")); -// } -// -// @Test -// @Order(3) -// public void 사용자의_식물카드가_100개_이상이면() { -// int leafSize = 100; -// List leaves = getLeaves(leafSize); -// -// // when -// Account.AccountGrade grade = leafService.updateAccountGrade(account.toBuilder().leaves(leaves).build()); -// -// // then -// assertThat(grade.getStepDescription(), is("골드 가드너")); -// } -// -// @Test -// @Order(4) -// public void 생성_성공() { -// given(authUserUtils.getAuthUser()) -// .willReturn(account.toBuilder().leaves(new ArrayList<>()).build()); -// -// uploadImage(); -// -// // when -// LeafDto.Response responseDto = leafService.createLeaf(leafPostDto, testImage); -// -// // then -// assertThat(responseDto.getLeafId(), is(leaf.getLeafId())); -// } -// } -// -// @Nested -// @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -// class 식물카드_수정 { -// // given -// String s3ImageUrl = "s3/path"; -// -// LeafDto.Patch leafPatchDto = LeafDto.Patch.builder() -// .leafId(1L) -// .leafName("식물1") -// .content("본문1") -// .build(); -// -// MockMultipartFile testImage = new MockMultipartFile("profileImage", -// "testImage.jpg", -// "jpg", -// new FileInputStream("src/test/resources/images/testImage.jpg")); -// -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// Leaf leaf = getLeaf(leafPatchDto.getLeafId(), leafPatchDto.getLeafName(), leafPatchDto.getContent(), s3ImageUrl); -// -// 식물카드_수정() throws IOException { -// } -// -// @Test -// @Order(1) -// public void 입력받은_식물카드가_존재하지_않으면_실패() { -// given(authUserUtils.getAuthUser()) -// .willReturn(account); -// -// given(leafRepository.findById(Mockito.anyLong())) -// .willReturn(Optional.empty()); -// -// // when, then -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> leafService.updateLeaf(leafPatchDto, testImage)); -// assertThat(exception.getExceptionCode().getStatus(), is(404)); -// assertThat(exception.getExceptionCode().getMessage(), is("Leaf not found")); -// } -// -// @Test -// @Order(2) -// public void 입력받은_사용자와_식물카드의_주인이_다르면_실패() { -// given(authUserUtils.getAuthUser()) -// .willReturn(account.toBuilder().accountId(2L).build()); -// -// given(leafRepository.findById(Mockito.anyLong())) -// .willReturn(Optional.of(leaf.toBuilder().account(account).build())); -// -// // when, then -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> leafService.updateLeaf(leafPatchDto, testImage)); -// assertThat(exception.getExceptionCode().getStatus(), is(405)); -// assertThat(exception.getExceptionCode().getMessage(), is("That Account doesn't have authority")); -// } -// -//// @Test -//// @Order(3) -//// public void 입력받은_이미지가_없으면() { -//// given(authUserUtils.getAuthUser()) -//// .willReturn(account); -//// -//// given(leafRepository.findById(Mockito.anyLong())) -//// .willReturn(Optional.of(leaf.toBuilder().account(account).build())); -//// -//// willDoNothing().given(s3Uploader).deleteImageFromS3(Mockito.anyString(), Mockito.anyString()); -//// -//// // when, then -//// assertDoesNotThrow(() -> leafService.updateLeaf(leafPatchDto, null)); -//// verify(s3Uploader, times(0)).uploadImageToS3(Mockito.any(MultipartFile.class), Mockito.anyString()); -//// } -//// -//// @Test -//// @Order(4) -//// public void 입력받은_이미지가_있으면() { -//// given(authUserUtils.getAuthUser()) -//// .willReturn(account); -//// -//// given(leafRepository.findById(Mockito.anyLong())) -//// .willReturn(Optional.of(leaf.toBuilder().account(account).build())); -//// -//// willDoNothing().given(s3Uploader).deleteImageFromS3(Mockito.anyString(), Mockito.anyString()); -//// -//// // when, then -//// assertDoesNotThrow(() -> leafService.updateLeaf(leafPatchDto, testImage)); -//// verify(s3Uploader, times(1)).uploadImageToS3(Mockito.any(MultipartFile.class), Mockito.anyString()); -//// } -// } -// -// @Nested -// class 식물카드_단일_조회 { -// // given -// Long leafId = 1L; -// -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// Leaf leaf = getLeaf(leafId, "식물1", "본문1", "s3/path"); -// -// @Test -// public void 입력받은_식물카드가_존재할_때_성공() { -// given(leafRepository.findById(Mockito.anyLong())) -// .willReturn(Optional.of(leaf.toBuilder() -// .account(account) -// .build())); -// -// // when -// LeafDto.Response responseDto = leafService.findLeaf(leafId); -// -// // then -// assertThat(responseDto.getLeafId(), is(leafId)); -// assertThat(responseDto.getLeafName(), is(leaf.getLeafName())); -// } -// -// @Test -// public void 입력받은_식물카드가_존재하지_않을_때_실패() { -// given(leafRepository.findById(Mockito.anyLong())) -// .willReturn(Optional.empty()); -// -// // when, then -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> leafService.findLeaf(leafId)); -// assertThat(exception.getExceptionCode().getStatus(), is(404)); -// assertThat(exception.getExceptionCode().getMessage(), is("Leaf not found")); -// } -// } -// -// @Test -// public void 전체_식물카드_조회() { -// // given -// Long accountId = 1L; -// -// Account account = getAccount(accountId, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// Leaf leaf1 = getLeaf(1L, "식물1", "본문1", "s3ImageUrl"); -// Leaf leaf2 = getLeaf(2L, "식물2", "본문1", "s3ImageUrl2"); -// -// -// given(accountService.findVerifiedAccount(Mockito.anyLong())) -// .willReturn(account); -// -// given(leafRepository.findByAccount(Mockito.any(Account.class))) -// .willReturn(List.of( -// leaf1.toBuilder().account(account).build(), -// leaf2.toBuilder().account(account).build())); -// -// // when -// List responseDtos = leafService.findLeaves(accountId); -// -// // then -// assertThat(responseDtos.size(), is(2)); -// assertThat(responseDtos.get(0).getLeafId(), is(1L)); -// assertThat(responseDtos.get(1).getLeafId(), is(2L)); -// } -// -// @Test -// public void findLeafEntityByTest() { -// // given -// Long leafId = 1L; -// -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// Leaf leaf = getLeaf(leafId, "식물1", "본문1", "s3ImageUrl"); -// -// given(authUserUtils.getAuthUser()) -// .willReturn(account); -// -// given(leafRepository.findById(leafId)) -// .willReturn(Optional.of(leaf.toBuilder().account(account).build())); -// -// // when -// Leaf findLeaf = leafService.findLeafEntityBy(leafId); -// -// // then -// assertThat(findLeaf.getLeafId(), is(leafId)); -// } -// -// @Nested -// class 식물카드_삭제 { -// // given -// Long leafId = 1L; -// -// Account account = getAccount(1L, "user1@gmail.com", "user1", -// "user1234", "image/path", Point.builder().build(), -// List.of("USER"), Account.AccountGrade.GRADE_BRONZE); -// -// Leaf leaf = getLeaf(leafId, "식물1", "본문1", "s3ImageUrl"); -// -// Journal journal1 = Journal.builder().journalImage(JournalImage.builder().build()).build(); -// Journal journal2 = Journal.builder().build(); -// -// PlantObj plantObj = PlantObj.builder().build(); -// -// @BeforeEach -// private void init() { -// given(authUserUtils.getAuthUser()) -// .willReturn(account.toBuilder().leaves(new ArrayList<>(List.of(leaf))).build()); -// -// willDoNothing().given(journalImageService).deleteJournalImageWithS3(Mockito.any(JournalImage.class), Mockito.anyString()); -// } -// -// @Test -// public void 연결된_plantObj가_없으면(){ -// given(leafRepository.findById(Mockito.anyLong())) -// .willReturn(Optional.of(leaf.toBuilder() -// .account(account) -// .journals(new ArrayList<>(List.of(journal1, journal2))) -// .build())); -// -// // when, then -// assertDoesNotThrow(() -> leafService.deleteLeaf(leafId)); -// } -// -// @Test -// public void 연결된_plantObj가_있으면(){ -// given(leafRepository.findById(Mockito.anyLong())) -// .willReturn(Optional.of(leaf.toBuilder() -// .account(account) -// .journals(new ArrayList<>(List.of(journal1, journal2))) -// .plantObj(plantObj) -// .build())); -// // when -// leafService.deleteLeaf(leafId); -// -// // then -// assertThat(Optional.ofNullable(plantObj.getLeaf()), is(Optional.empty())); -// } -// } -// -// private static Account getAccount(Long accountId, String email, String displayName, String password, -// String profileImageUrl, Point point, List roles, Account.AccountGrade accountGrade) { -// return Account.builder() -// .accountId(accountId) -// .email(email) -// .displayName(displayName) -// .password(password) -// .profileImageUrl(profileImageUrl) -// .point(point) -// .roles(roles) -// .accountGrade(accountGrade) -// .build(); -// } -// -// private Leaf getLeaf(Long leafId, String leafName, String content, String leafImageUrl) { -// return Leaf.builder() -// .leafId(leafId) -// .leafName(leafName) -// .content(content) -// .leafImageUrl(leafImageUrl) -// .build(); -// } -//} diff --git a/server/src/test/java/com/growstory/domain/plant_object/controller/PlantObjectControllerTest.java b/server/src/test/java/com/growstory/domain/plant_object/controller/PlantObjectControllerTest.java deleted file mode 100644 index 47e5aa09..00000000 --- a/server/src/test/java/com/growstory/domain/plant_object/controller/PlantObjectControllerTest.java +++ /dev/null @@ -1,158 +0,0 @@ -//package com.growstory.domain.plant_object.controller; -// -//import com.google.gson.Gson; -//import com.growstory.domain.plant_object.dto.PlantObjDto; -//import com.growstory.domain.plant_object.service.PlantObjService; -//import com.growstory.domain.point.dto.PointDto; -//import com.growstory.domain.stubdata.Stub; -//import org.junit.jupiter.api.DisplayName; -//import org.junit.jupiter.api.Test; -//import org.mockito.Mockito; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -//import org.springframework.boot.test.context.SpringBootTest; -//import org.springframework.boot.test.mock.mockito.MockBean; -//import org.springframework.http.MediaType; -//import org.springframework.test.web.servlet.MockMvc; -//import org.springframework.test.web.servlet.ResultActions; -// -//import java.util.List; -// -//import static org.hamcrest.Matchers.is; -//import static org.mockito.BDDMockito.anyLong; -//import static org.mockito.BDDMockito.given; -//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.jsonPath; -//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -// -//@SpringBootTest -//@AutoConfigureMockMvc -//public class PlantObjectControllerTest { -// -// @Autowired -// private MockMvc mockMvc; -// -// @Autowired -// private Gson gson; -// -// @MockBean -// private PlantObjService plantObjService; -// -// private final String DEFAULT_URL = "/v1/gardens"; -// -// @DisplayName("정원 전체 정보 조회 API 테스트") -// @Test -// void getGardenInfoTest() throws Exception { -// //given -// Long accountId = 1L; -// PlantObjDto.GardenInfoResponse response = Stub.MockPlantObj.getStubGardenInfo(); -// given(plantObjService.findAllGardenInfo(Mockito.anyLong())) -// .willReturn(response); -// //when -// ResultActions actions = mockMvc.perform( -// get(DEFAULT_URL +"/{account-id}" ,accountId)); -// //then -// actions -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.data.plantObjs[0].plantObjId", is(1))) -// .andExpect(jsonPath("$.data.plantObjs[1].plantObjId", is(2))) -// .andDo(print()); -// } -// -// @DisplayName("유저 포인트로 오브젝트 구입 API 테스트") -// @Test -// void postPurchaseObjTest() throws Exception { -// //given -// Long accountId = 1L; -// Long productId = 1L; -// PlantObjDto.TradeResponse response = Stub.MockPlantObj.getStubTradeResponse(); -// given(plantObjService.buyProduct(Mockito.anyLong(), Mockito.anyLong())) -// .willReturn(response); -// -// //when -// ResultActions actions = mockMvc.perform( -// post(DEFAULT_URL +"/{account-id}/purchase", accountId) -// .param("product-id", productId.toString()) -// .contentType(MediaType.APPLICATION_JSON) -// .accept(MediaType.APPLICATION_JSON) -// ); -// -// //then -// actions.andExpect(status().isCreated()) -// .andExpect(jsonPath("$.data.plantObj.productId", is(productId.intValue()))) -// .andDo(print()); -// } -// -// @DisplayName("오브젝트 되팔기 API 테스트") -// @Test -// void deleteRefundObj() throws Exception { -// //given -// Long accountId = 1L; -// Long plantObjId = 1L; -// PointDto.Response response = PointDto.Response.builder().score(500).build(); -// given(plantObjService.refundPlantObj(anyLong(), anyLong())) -// .willReturn(response); -// -// //when -// ResultActions actions = mockMvc.perform( -// delete(DEFAULT_URL+"/{account-id}/refund", accountId) -// .param("plantobj-id", plantObjId.toString()) -// .contentType(MediaType.APPLICATION_JSON) -// .accept(MediaType.APPLICATION_JSON) -// ); -// -// //then -// actions.andExpect(status().isOk()) -// .andExpect(jsonPath("$.data.score", is(500))); -// } -// -// @DisplayName("오브젝트 배치 (편집 완료) API 테스트") -// @Test -// void patchLocationsTest() throws Exception { -// //given -// Long accountId = 1L; -// List patchLocations -// = Stub.MockLocation.getStubPatchLocationResponses(); -// //gardenInfo, patchLocations의 위치 정보를 포함하고 있는 plantObjs를 목 데이터로 가지고 있음. -// PlantObjDto.GardenInfoResponse gardenInfo -// = Stub.MockPlantObj.getStubGardenInfo(); -// given(plantObjService.findAllGardenInfo(anyLong())).willReturn(gardenInfo); -// //when -// ResultActions actions = mockMvc.perform( -// patch(DEFAULT_URL+"/{account-id}/location", accountId) -// .contentType(MediaType.APPLICATION_JSON) -// .accept(MediaType.APPLICATION_JSON) -// .content(gson.toJson(patchLocations)) -// ); -// //then -// actions.andExpect(status().isOk()) -// .andExpect(jsonPath("$.data.plantObjs[0].location.locationId", -// is(accountId.intValue()))) -// .andDo(print()); -// } -// -// @DisplayName("오브젝트와 식물 카드 연결 / 해제 / 교체") -// @Test -// void patchObjConnectionToLeafTest() throws Exception { -// //given -// Long accountId = 1L; -// Long plantObjId = 1L; -// Long leafId = 1L; -// PlantObjDto.Response response = Stub.MockPlantObj.getStubPlantObjResponseDto1(); -// given(plantObjService.updateLeafConnection(anyLong(), anyLong(), anyLong())) -// .willReturn(response); -// //when -// ResultActions actions = mockMvc.perform( -// patch(DEFAULT_URL+"/{account-id}/connection", accountId) -// .param("plantobj-id", String.valueOf(plantObjId)) -// .param("leaf-id", String.valueOf(leafId)) -// .contentType(MediaType.APPLICATION_JSON) -// .accept(MediaType.APPLICATION_JSON) -// ); -// //then -// actions.andExpect(status().isOk()) -// .andExpect(jsonPath("$.data.leafDto.id", is(leafId.intValue()))) -// .andDo(print()); -// } -//} diff --git a/server/src/test/java/com/growstory/domain/plant_object/service/PlantObjServiceTest.java b/server/src/test/java/com/growstory/domain/plant_object/service/PlantObjServiceTest.java deleted file mode 100644 index 70ffd2e1..00000000 --- a/server/src/test/java/com/growstory/domain/plant_object/service/PlantObjServiceTest.java +++ /dev/null @@ -1,407 +0,0 @@ -//package com.growstory.domain.plant_object.service; -// -//import com.growstory.domain.account.entity.Account; -//import com.growstory.domain.account.service.AccountService; -//import com.growstory.domain.leaf.dto.LeafDto; -//import com.growstory.domain.leaf.entity.Leaf; -//import com.growstory.domain.leaf.service.LeafService; -//import com.growstory.domain.plant_object.dto.PlantObjDto; -//import com.growstory.domain.plant_object.entity.PlantObj; -//import com.growstory.domain.plant_object.location.dto.LocationDto; -//import com.growstory.domain.plant_object.location.entity.Location; -//import com.growstory.domain.plant_object.location.service.LocationService; -//import com.growstory.domain.plant_object.mapper.PlantObjMapper; -//import com.growstory.domain.plant_object.repository.PlantObjRepository; -//import com.growstory.domain.point.entity.Point; -//import com.growstory.domain.product.dto.ProductDto; -//import com.growstory.domain.product.entity.Product; -//import com.growstory.domain.product.service.ProductService; -//import com.growstory.domain.stubdata.Stub; -//import com.growstory.global.auth.utils.AuthUserUtils; -//import com.growstory.global.customUser.annotation.WithMockCustomUser; -//import com.growstory.global.exception.BusinessLogicException; -//import com.growstory.global.exception.ExceptionCode; -//import org.junit.jupiter.api.BeforeEach; -//import org.junit.jupiter.api.DisplayName; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.api.extension.ExtendWith; -//import org.mockito.InjectMocks; -//import org.mockito.Mock; -//import org.mockito.Mockito; -//import org.mockito.junit.jupiter.MockitoExtension; -// -//import java.util.ArrayList; -//import java.util.List; -//import java.util.Optional; -// -//import static org.hamcrest.MatcherAssert.assertThat; -//import static org.hamcrest.Matchers.*; -//import static org.junit.jupiter.api.Assertions.assertThrows; -//import static org.mockito.BDDMockito.*; -// -// -//@ExtendWith(MockitoExtension.class) -//public class PlantObjServiceTest { -// -// @InjectMocks -// private PlantObjService plantObjService; -// @Mock -// private PlantObjRepository plantObjRepository; -// @Mock -// private ProductService productService; -// @Mock -// private AccountService accountService; -// @Mock -// private LocationService locationService; -// @Mock -// private LeafService leafService; -// @Mock -// private PlantObjMapper plantObjMapper; -// @Mock -// private AuthUserUtils authUserUtils; -// -// @BeforeEach -// public void init() { -// System.out.println("=".repeat(10) +"PlantObjServiceTest init"+"=".repeat(10)); -// } -// -// @DisplayName("buyProduct Test : 구매 금액이 충분하지 않을 때") -// @WithMockCustomUser(accountId = 1L, displayName = "관리자", email = "admin@gmail.com", password = "1234", profileImageUrl = "112", roles = "{ADMIN, USER}") -// @Test -// public void testBuyProduct_구매금액_불충분() { -// //given -// Long gardenAccountId = 1L; -// Long productId = 1L; -// // 물건을 구입할 계정은 0 포인트를 가지고 있음 -// Account findAccount = Stub.MockAccount.getStubAccount(); -// Point mockPoint = Stub.MockPoint.getStubPointResponseDtoWithNoScore(); -// findAccount.updatePoint(mockPoint); -// // 가격이 500원인 Product -// Product boughtProduct = Stub.MockProduct.getStubProduct1(); -// PlantObj boughtPlantObj = Stub.MockPlantObj.getStubPlantObj1(); -// // 스텁 데이터 -// given(authUserUtils.getAuthUser()).willReturn(findAccount); -// given(productService.findVerifiedProduct(Mockito.anyLong())) -// .willReturn(boughtProduct); -// // given(plantObjRepository.save(Mockito.any(PlantObj.class))) -// // .willReturn(boughtPlantObj); -// -// //when -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> plantObjService.buyProduct(gardenAccountId, productId)); -// int httpStatusCode = exception.getExceptionCode().getStatus(); -// -// //then -// assertThat(exception.getClass(), is(BusinessLogicException.class)); -// assertThat(httpStatusCode, is(403)); -// } -// -// @DisplayName("buyProduct Test : 성공") -//// @WithMockCustomUser(accountId = 3L, displayName = "관리자", email = "admin@gmail.com", password = "1234", profileImageUrl = "112", roles = "{ADMIN, USER}") -// @Test -// public void testBuyProduct_구매금액_충분_성공() { -// //given -// Long gardenAccountId = 1L; -// Long productId = 1L; -// // 물건을 구입할 계정은 500 포인트를 가지고 있음 -// Account findAccount = Stub.MockAccount.getStubAccount(); -// Point mockPoint = Stub.MockPoint.getStubPointResponseDtoWith500Score(); -// findAccount.updatePoint(mockPoint); -// // 가격이 500원인 Product -// Product boughtProduct = Stub.MockProduct.getStubProduct1(); -// PlantObj boughtPlantObj = Stub.MockPlantObj.getStubPlantObj1(); -// -// // Mock 리턴 -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// given(authUserUtils.getAuthUser()).willReturn(findAccount); -// given(productService.findVerifiedProduct(Mockito.anyLong())) -// .willReturn(boughtProduct); -// given(plantObjRepository.save(Mockito.any(PlantObj.class))) -// .willReturn(boughtPlantObj); -// -// //when -// plantObjService.buyProduct(gardenAccountId, productId); -// -// //then -// verify(plantObjRepository).save(Mockito.any(PlantObj.class)); -// assertThat(findAccount.getPlantObjs(), hasItem(boughtPlantObj)); -// assertThat(findAccount.getPoint().getScore(), is(0)); -// } -// -// @DisplayName("refundPlantObj test : 사용자 소유의 환불 가능 품목이 없을 때") -//// @WithMockUser -// @Test -// public void testRefundPlantObj_환불_가능_품목_없음() { -// //given -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// -// Long accountId = 1L; -// Long plantObjId = 1L; -// Account findAccount = Stub.MockAccount.getStubAccount(); -// // 0 Point 매핑 (이미 물건을 구입 했다고 가정) -// Point point = Stub.MockPoint.getStubPointResponseDtoWithNoScore(); -// findAccount.updatePoint(point); -// PlantObj plantObj = Stub.MockPlantObj.getStubPlantObj1(); -// // findAccount.addPlantObj(plantObj)를 실행하지 않는다. -// // 목 데이터 리턴 -// given(authUserUtils.getAuthUser()).willReturn(findAccount); -// given(plantObjRepository.findById(Mockito.anyLong())) -// .willReturn(Optional.of(plantObj)); -// //when -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> plantObjService.refundPlantObj(accountId, plantObjId)); -// //then -// //환불 가능 품목이 존재하지 않을 때 PLANT_OBJ_NOT_FOUND 반환 -// assertThat(exception.getExceptionCode(), is(ExceptionCode.PLANT_OBJ_NOT_FOUND)); -// } -// -// @DisplayName("refundPlantObj test : 사용자 소유의 환불 가능 품목이 존재할 때") -// @Test -// public void testRefundPlantObj_환불_성공() { -// //given -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// -// Long accountId = 1L; -// Account findAccount = Stub.MockAccount.getStubAccount(); -// // 0 Point 매핑 (이미 물건을 구입 했다고 가정) -// Point point = Stub.MockPoint.getStubPointResponseDtoWithNoScore(); -// findAccount.updatePoint(point); -// PlantObj plantObj1 = Stub.MockPlantObj.getStubPlantObj1(); -// PlantObj plantObj2 = Stub.MockPlantObj.getStubPlantObj2(); -// findAccount.addPlantObj(plantObj1); -// findAccount.addPlantObj(plantObj2); -// // 목 데이터 리턴 -// given(authUserUtils.getAuthUser()).willReturn(findAccount); -// given(plantObjRepository.findById(Mockito.anyLong())) -// .willReturn(Optional.of(plantObj2)); -// //when -// plantObjService.refundPlantObj(accountId, plantObj2.getPlantObjId()); -// //then -// assertThat(findAccount.getPoint().getScore(), is(plantObj2.getProduct().getPrice())); -// } -// -// -// @DisplayName("findAllGardenInfo Test : 전체 정원 정보 조회 성공") -// @Test -// public void testFindAllGardenInfo_전체_정원_정보조회_성공() { -// //given -// //정원 소유주 accountId -// Long gardenAccountId = 1L; -// //정원 소유자와 Point 목 데이터 매핑 -// Account findAccount = Stub.MockAccount.getStubAccount(); -// Point userPoint = Stub.MockPoint.getStubPointResponseDtoWith500Score(); -// findAccount.updatePoint(userPoint); -// //소유 PlantObjs 목 데이터 매핑 -// List plantObjList = Stub.MockPlantObj.getStubPlantObjs(); -// plantObjList.stream().forEach(findAccount::addPlantObj); -// List plantObjResponseList = Stub.MockPlantObj.getStubPlantObjsResponseDtos(); -// //상품 리스트 -// List products = Stub.MockProduct.getStubProductResponses(); -// //스텁 데이터 동작 지정 -// given(accountService.findVerifiedAccount(Mockito.anyLong())).willReturn(findAccount); -// given(productService.findAllProducts()).willReturn(products); -// given(plantObjMapper.toPlantObjResponseList(Mockito.anyList())).willReturn(plantObjResponseList); -// -// //when -// PlantObjDto.GardenInfoResponse gardenInfo = plantObjService.findAllGardenInfo(gardenAccountId); -// -// //then -// assertThat(gardenInfo.getPoint().getScore(), is(userPoint.getScore())); -// assertThat(gardenInfo.getDisplayName(), is(findAccount.getDisplayName())); -// assertThat(gardenInfo.getProducts(), is(products)); -// assertThat(gardenInfo.getPlantObjs().get(0).getPlantObjId(), is(plantObjList.get(0).getPlantObjId())); -// } -// -//// @DisplayName("saveLocation Test : 프로덕트 id와 로케이션 id 불일치") -//// @Test -//// public void testSaveLocation_프로덕트id_로케이션id_불일치() { -//// //given -//// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -//// Long accountId = 1L; -//// List patchLocations = Stub.MockLocation.getStubPatchLocationResponses(); -//// patchLocations.add(PlantObjDto.PatchLocation.builder() -//// .plantObjId(3L) -//// .locationDto(LocationDto.Patch.builder() -//// .locationId(99L).x(0).y(0).isInstalled(false) -//// .build()) -//// .build()); -//// //when -//// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -//// () -> plantObjService.saveLocation(accountId, patchLocations)); -//// //then -//// assertThat(exception.getExceptionCode(), is(ExceptionCode.LOCATION_NOT_ALLOW)); -//// } -// -// @DisplayName("saveLocation Test : X축에 부적절한 위치 삽입1 (+좌표)") -// @Test -// public void testSaveLocation_X축_부적절한_위치_삽입() { -// //given -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// Long accountId = 1L; -// List patchLocations = Stub.MockLocation.getStubPatchLocationResponses(); -// patchLocations.add(PlantObjDto.PatchLocation.builder() -// .plantObjId(3L) -// .locationDto(LocationDto.Patch.builder() -// .locationId(3L).x(12).y(0).isInstalled(false) -// .build()) -// .build()); -// //when -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> plantObjService.saveLocation(accountId, patchLocations)); -// //then -// assertThat(exception.getExceptionCode(), is(ExceptionCode.INVALID_LOCATION)); -// } -// -// @DisplayName("saveLocation Test : X축에 부적절한 위치 삽입 (-좌표)") -// @Test -// public void testSaveLocation_X축_부적절한_위치_삽입2() { -// //given -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// Long accountId = 1L; -// List patchLocations = Stub.MockLocation.getStubPatchLocationResponses(); -// patchLocations.add(PlantObjDto.PatchLocation.builder() -// .plantObjId(3L) -// .locationDto(LocationDto.Patch.builder() -// .locationId(3L).x(-1).y(0).isInstalled(false) -// .build()) -// .build()); -// //when -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> plantObjService.saveLocation(accountId, patchLocations)); -// //then -// assertThat(exception.getExceptionCode(), is(ExceptionCode.INVALID_LOCATION)); -// } -// -// @DisplayName("saveLocation Test : Y축에 부적절한 위치 삽입 (+좌표)") -// @Test -// public void testSaveLocation_Y축_부적절한_위치_삽입1() { -// //given -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// Long accountId = 1L; -// List patchLocations = Stub.MockLocation.getStubPatchLocationResponses(); -// patchLocations.add(PlantObjDto.PatchLocation.builder() -// .plantObjId(3L) -// .locationDto(LocationDto.Patch.builder() -// .locationId(3L).x(0).y(99).isInstalled(false) -// .build()) -// .build()); -// //when -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> plantObjService.saveLocation(accountId, patchLocations)); -// //then -// assertThat(exception.getExceptionCode(), is(ExceptionCode.INVALID_LOCATION)); -// } -// -// @DisplayName("saveLocation Test : Y축에 부적절한 위치 삽입 (-좌표)") -// @Test -// public void testSaveLocation_Y축_부적절한_위치_삽입2() { -// //given -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// Long accountId = 1L; -// List patchLocations = Stub.MockLocation.getStubPatchLocationResponses(); -// patchLocations.add(PlantObjDto.PatchLocation.builder() -// .plantObjId(3L) -// .locationDto(LocationDto.Patch.builder() -// .locationId(3L).x(0).y(-1).isInstalled(false) -// .build()) -// .build()); -// //when -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> plantObjService.saveLocation(accountId, patchLocations)); -// //then -// assertThat(exception.getExceptionCode(), is(ExceptionCode.INVALID_LOCATION)); -// } -// -// @DisplayName("saveLocation Test : 성공") -// @Test -// public void testSaveLocation_성공() { -// //given -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// Long accountId = 1L; -// List patchLocations = new ArrayList<>(); -// PlantObjDto.PatchLocation patchLocation = Stub.MockLocation.getStubPatchLocation1(); -// patchLocations.add(patchLocation); -// // PatchLocation 객체에 의해 저장된 Location 엔티티 객체 -// Location savedLocation = Stub.MockLocation.getStubLocation(); -// given(locationService.updateLocation(Mockito.any())).willReturn(savedLocation); -// //when -// plantObjService.saveLocation(accountId,patchLocations); -// //then -// assertThat(savedLocation.getLocationId(), is(patchLocation.getLocationDto().getLocationId())); -// assertThat(savedLocation.getX(), is(patchLocation.getLocationDto().getX())); -// assertThat(savedLocation.getY(), is(patchLocation.getLocationDto().getY())); -// assertThat(savedLocation.isInstalled(), is(patchLocation.getLocationDto().isInstalled())); -// } -// -// @DisplayName("updateLeafConnection Test : leafId가 null일 경우 연결해제") -// @Test -// public void testUpdateLeafConnection_Leaf_연결해제() { -// //given -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// Long accountId = 1L; -// Long plantObjId = 1L; -// Long leafId = null; -// PlantObj findPlantObj = Stub.MockPlantObj.getStubPlantObj1(); -// findPlantObj.updateLeaf(Stub.MockLeaf.getStubLeaf()); -// given(plantObjRepository.findById(Mockito.anyLong())).willReturn(Optional.of(findPlantObj)); -// given(plantObjMapper.toPlantObjResponse(Mockito.any(PlantObj.class))) -// .willReturn(PlantObjDto.Response.builder() -// .plantObjId(findPlantObj.getPlantObjId()) -// .leafDto(null) -// .build()); -// //when -// PlantObjDto.Response response = plantObjService.updateLeafConnection(accountId, plantObjId, leafId); -// -// //then -// verify(leafService, never()).findLeafEntityBy(Mockito.anyLong()); -//// verify(mock(findPlantObj.getClass()), times(1)).updateLeaf(null); -// assertThat(response, is(notNullValue())); -// } -// -// @DisplayName("updateLeafConnection Test : plantObj 미확인 예외발생") -// @Test -// public void testUpdateLeafConnection_Leaf_PlantObj_미확인() { -// //given -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// Long accountId = 1L; -// Long plantObjId = 99L; -// Long leafId = 1L; -// given(plantObjRepository.findById(Mockito.anyLong())) -// .willReturn(Optional.empty()); -// -// //when -// BusinessLogicException exception = assertThrows(BusinessLogicException.class, -// () -> plantObjService.updateLeafConnection(accountId, plantObjId, leafId)); -// -// //then -// assertThat(exception.getExceptionCode(), is(ExceptionCode.PLANT_OBJ_NOT_FOUND)); -// } -// -// @DisplayName("updateLeafConnection Test : leafId가 null이 아닐 경우 연결 성공") -// @Test -// public void testUpdateLeafConnection_Leaf_연결성공() { -// //given -// willDoNothing().given(accountService).isAuthIdMatching(Mockito.anyLong()); -// Long accountId = 1L; -// Long plantObjId = 1L; -// Long leafId = 1L; -// PlantObj findPlantObj = Stub.MockPlantObj.getStubPlantObj1(); -// Leaf findLeaf = Stub.MockLeaf.getStubLeaf(); -// findPlantObj.updateLeaf(findLeaf); -// LeafDto.ResponseForGardenInfo leafResponseDto = Stub.MockLeaf.getStubLeafResponseDto(); -// given(plantObjRepository.findById(Mockito.anyLong())).willReturn(Optional.of(findPlantObj)); -// given(leafService.findLeafEntityBy(leafId)).willReturn(findLeaf); -// given(plantObjMapper.toPlantObjResponse(Mockito.any(PlantObj.class))) -// .willReturn(PlantObjDto.Response.builder() -// .plantObjId(findPlantObj.getPlantObjId()) -// .leafDto(leafResponseDto) -// .build()); -// //when -// PlantObjDto.Response response = plantObjService.updateLeafConnection(accountId, plantObjId, leafId); -// -// //then -// verify(leafService).findLeafEntityBy(Mockito.anyLong()); -// assertThat(response, is(notNullValue())); -// assertThat(response.getLeafDto().getId(), is(leafId)); -// } -//} diff --git a/server/src/test/java/com/growstory/domain/stubdata/Stub.java b/server/src/test/java/com/growstory/domain/stubdata/Stub.java deleted file mode 100644 index deb86635..00000000 --- a/server/src/test/java/com/growstory/domain/stubdata/Stub.java +++ /dev/null @@ -1,499 +0,0 @@ -package com.growstory.domain.stubdata; - -import com.growstory.domain.account.dto.AccountDto; -import com.growstory.domain.account.entity.Account; -import com.growstory.domain.board.entity.Board; -import com.growstory.domain.images.entity.JournalImage; -import com.growstory.domain.journal.dto.JournalDto; -import com.growstory.domain.journal.entity.Journal; -import com.growstory.domain.leaf.dto.LeafDto; -import com.growstory.domain.leaf.entity.Leaf; -import com.growstory.domain.likes.entity.BoardLike; -import com.growstory.domain.plant_object.dto.PlantObjDto; -import com.growstory.domain.plant_object.entity.PlantObj; -import com.growstory.domain.plant_object.location.dto.LocationDto; -import com.growstory.domain.plant_object.location.entity.Location; -import com.growstory.domain.point.entity.Point; -import com.growstory.domain.product.dto.ProductDto; -import com.growstory.domain.product.entity.Product; -import org.springframework.http.HttpMethod; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class Stub { - - public static class MockAccount { - private static Map stubRequestBody; - static { - stubRequestBody = new HashMap<>(); - stubRequestBody.put(HttpMethod.POST, AccountDto.Post.builder() - .displayName("관리자") - .email("admin@gmail.com") - .password("1111") - .build()); - } - - public static Object getRequestBody(HttpMethod method) { - return stubRequestBody.get(method); - } - - public static Account getStubAccount() { - return Account.builder() - .accountId(1L) - .displayName("김닉네임") - .profileImageUrl("https://growstory.s3.ap-northeast-2.amazonaws.com/image/profiles/" + - "e617d918-a5e4-479b-9e3d-386e5346c184book-1822474__340.jpg") -// .point(MockPoint.getStubPointResponseDtoWith500Score()) - .plantObjs(new ArrayList<>()) - .build(); - } - - public static AccountDto.Response getSingleResponseBody() { - return AccountDto.Response - .builder() - .accountId(1L) -// .boardLiked(boardLikes) -// .boardWritten(boardWrittens) - .displayName("김닉네임") - .profileImageUrl("https://growstory.s3.ap-northeast-2.amazonaws.com/image/profiles/" + - "e617d918-a5e4-479b-9e3d-386e5346c184book-1822474__340.jpg") -// .commentWritten(commentWrittens) - .point(Point.builder().pointId(1L).score(500).build()) - .build(); - } - } - - public static class MockGarden { - public static PlantObjDto.GardenInfoResponse getStubGardenInfo() { - return PlantObjDto.GardenInfoResponse.builder() - .displayName(MockAccount.getSingleResponseBody().getDisplayName()) - .products(MockProduct.getStubProductResponses()) -// .plantObjs(MockPlantObj.getStubPlantObjsResponseDtos()) -// .point(MockPoint.getStubPointResponseDto()) - .build(); - } - } - - public static class MockProduct { - public static Product getStubProduct1() { - return Product.builder() - .productId(1L) - .name("building_brown") - .korName("벽돌 유적") - .price(500) - .imageUrlSmall("https://growstory.s3.ap-northeast-2.amazonaws.com/image/products/building_brown_sm.svg") - .imageUrlLarge("https://growstory.s3.ap-northeast-2.amazonaws.com/image/products/building_brown_lg.svg") - .build(); - } - - public static Product getStubProduct2() { - return Product.builder() - .productId(2L) - .name("building_yellow") - .korName("콜로세움") - .price(500) - .imageUrlSmall("https://growstory.s3.ap-northeast-2.amazonaws.com/image/products/building_yellow_sm.svg") - .imageUrlLarge("https://growstory.s3.ap-northeast-2.amazonaws.com/image/products/building_yellow_lg.svg") - .build(); - } - - public static ProductDto.ImageUrlTable getStubImageUrlTable1() { - return new ProductDto.ImageUrlTable( - getStubProduct1().getImageUrlSmall(), - getStubProduct1().getImageUrlLarge()); - } - - public static ProductDto.ImageUrlTable getStubImageUrlTable2() { - return new ProductDto.ImageUrlTable( - getStubProduct2().getImageUrlSmall(), - getStubProduct2().getImageUrlLarge()); - } - - public static List getStubProductResponses() { - List productResponseDtos = new ArrayList<>(); - productResponseDtos.add( - ProductDto.Response.builder() - .productId(getStubProduct1().getProductId()) - .imageUrlTable(getStubImageUrlTable1()) - .price(getStubProduct1().getPrice()) - .korName(getStubProduct1().getKorName()) - .name(getStubProduct1().getName()) - .build()); - productResponseDtos.add( - ProductDto.Response.builder() - .productId(getStubProduct2().getProductId()) - .imageUrlTable(getStubImageUrlTable2()) - .price(getStubProduct2().getPrice()) - .korName(getStubProduct2().getKorName()) - .name(getStubProduct2().getName()) - .build()); - return productResponseDtos; - } - } - - public static class MockPlantObj { - - public static PlantObj getStubPlantObj1() { - return PlantObj.builder() - .plantObjId(1L) - .product(MockProduct.getStubProduct1()) -// .account(MockAccount.getStubAccount()) -// .leaf(MockLeaf.getStubLeaf()) - .build(); - } - - public static PlantObj getStubPlantObj2() { - return PlantObj.builder() - .plantObjId(2L) - .product(MockProduct.getStubProduct2()) - .build(); - } - - public static List getStubPlantObjs() { - ArrayList plantObjs = new ArrayList<>(); - plantObjs.add(getStubPlantObj1()); - plantObjs.add(getStubPlantObj2()); - return plantObjs; - } - - public static PlantObjDto.Response getStubPlantObjResponseDto1() { - PlantObjDto.PatchLocation location1 = MockLocation.getStubPatchLocation1(); - LeafDto.ResponseForGardenInfo leaf1 = MockLeaf.getStubLeafResponseDto(); - return PlantObjDto.Response.builder() - .productId(MockAccount.getStubAccount().getAccountId()) - .plantObjId(MockProduct.getStubProduct1().getProductId()) - .productName(MockProduct.getStubProduct1().getName()) - .korName(MockProduct.getStubProduct1().getKorName()) - .price(MockProduct.getStubProduct1().getPrice()) - .location(LocationDto.Response.builder() - .locationId(location1.getLocationDto().getLocationId()) // 1 - .x(location1.getLocationDto().getX()) //5 - .y(location1.getLocationDto().getY()) //6 - .isInstalled(location1.getLocationDto().isInstalled()) //true - .build()) - .leafDto(LeafDto.ResponseForGardenInfo.builder() - .id(leaf1.getId()) - .build()) - .imageUrlTable(MockProduct.getStubImageUrlTable1()) - .build(); - } - public static PlantObjDto.Response getStubPlantObjResponseDto2() { - PlantObjDto.PatchLocation location2 = MockLocation.getStubPatchLocation2(); - return PlantObjDto.Response.builder() - .productId(MockAccount.getStubAccount().getAccountId()) - .plantObjId(MockProduct.getStubProduct2().getProductId()) - .productName(MockProduct.getStubProduct2().getName()) - .korName(MockProduct.getStubProduct2().getKorName()) - .price(MockProduct.getStubProduct2().getPrice()) - .location(LocationDto.Response.builder() - .locationId(location2.getLocationDto().getLocationId()) // 2 - .x(location2.getLocationDto().getX()) //0 - .y(location2.getLocationDto().getY()) //0 - .isInstalled(location2.getLocationDto().isInstalled()) //false - .build()) -// .leafDto(MockLeaf.getStubLeafResponseDto()) - .imageUrlTable(MockProduct.getStubImageUrlTable2()) - .build(); - } - - public static List getStubPlantObjsResponseDtos() { - - return List.of(getStubPlantObjResponseDto1(), - getStubPlantObjResponseDto2()); - } - - public static PlantObjDto.GardenInfoResponse getStubGardenInfo() { - return PlantObjDto.GardenInfoResponse.builder() - .plantObjs(getStubPlantObjsResponseDtos()) - .build(); - } - - public static PlantObjDto.TradeResponse getStubTradeResponse() { - return PlantObjDto.TradeResponse.builder() - .plantObj(getStubPlantObjResponseDto1()) - .build(); - } - } - - public static class MockLocation { - public static LocationDto.Response getStubLocationResponseDto1() { - return LocationDto.Response.builder() - .locationId(1L) - .x(0) - .y(0) - .isInstalled(false) - .build(); - } - public static LocationDto.Response getStubLocationResponseDto2() { - return LocationDto.Response.builder() - .locationId(2L) - .x(4) - .y(8) - .isInstalled(true) - .build(); - } - public static PlantObjDto.PatchLocation getStubPatchLocation1() { - return PlantObjDto.PatchLocation.builder() - .plantObjId(1L) - .locationDto(LocationDto.Patch.builder() - .locationId(1L).x(5).y(6).isInstalled(true).build()) - .build(); - } - public static PlantObjDto.PatchLocation getStubPatchLocation2() { - return PlantObjDto.PatchLocation.builder() - .plantObjId(2L) - .locationDto(LocationDto.Patch.builder() - .locationId(2L).x(0).y(0).isInstalled(false).build()) - .build(); - } - public static List getStubPatchLocationResponses() { - List patchLocations = new ArrayList<>(); - patchLocations.add(getStubPatchLocation1()); - patchLocations.add(getStubPatchLocation2()); - - return patchLocations; - } - - public static Location getStubLocation() { - PlantObjDto.PatchLocation patchLocation = getStubPatchLocation1(); - - return Location.builder() - .locationId(patchLocation.getLocationDto().getLocationId()) - .x(patchLocation.getLocationDto().getX()) - .y(patchLocation.getLocationDto().getY()) - .isInstalled(patchLocation.getLocationDto().isInstalled()) - .build(); - } - } - - public static class MockLeaf { - public static Leaf getStubLeaf() { - return Leaf.builder() - .leafId(1L) - .leafName("월동자 선인장") - .leafImageUrl("https://growstory.s3.ap-northeast-2.amazonaws.com/image/leaves/4b8b4998-bf12-4c1c-a6ec-dfcaa1dcd339book-1822474__340.jpg") - .content("나의 월동자 선인장은 귀엽다.") -// .account(MockAccount.getStubAccount()) - .journals(null) -// .plantObj(MockPlantObj.getStubPlantObj()) - .build(); - } - public static LeafDto.ResponseForGardenInfo getStubLeafResponseDto() { - return LeafDto.ResponseForGardenInfo.builder() - .id(getStubLeaf().getLeafId()) - .name(getStubLeaf().getLeafName()) - .imageUrl(getStubLeaf().getLeafImageUrl()) - .journalCount(MockJournal.getStubJournalResponseDtos().size()) - .build(); - } - } - - public static class MockJournal { - public static Journal getStubJournal1() { - return Journal.builder() - .journalId(1L) - .title("230909 일지") - .content("오늘은 물을 줬다.") -// .journalImage(MockJournalImage.getStubJournalImage1()) - .leaf(MockLeaf.getStubLeaf()) - .build(); - } - public static Journal getStubJournal2() { - return Journal.builder() - .journalId(2L) - .title("230910 일지") - .content("오늘은 물을 안줬다.") -// .journalImage(MockJournalImage.getStubJournalImage2()) - .leaf(MockLeaf.getStubLeaf()) - .build(); - } - public static JournalDto.Response getStubJournalResponse1() { - LocalDateTime dateTime = LocalDateTime.of(2023, 9, 9, 14, 30, 0); - return JournalDto.Response.builder() - .journalId(getStubJournal1().getJournalId()) - .title(getStubJournal1().getTitle()) - .content(getStubJournal1().getContent()) - .imageUrl(MockJournalImage.getStubJournalImage1().getImageUrl()) - .createdAt(dateTime) - .build(); - } - public static JournalDto.Response getStubJournalResponse2() { - LocalDateTime dateTime = LocalDateTime.of(2023, 9, 10, 14, 30, 0); - return JournalDto.Response.builder() - .journalId(getStubJournal2().getJournalId()) - .title(getStubJournal2().getTitle()) - .content(getStubJournal2().getContent()) - .imageUrl(MockJournalImage.getStubJournalImage2().getImageUrl()) - .createdAt(dateTime) - .build(); - } - public static List getStubJournalResponseDtos() { - return List.of(getStubJournalResponse1(), getStubJournalResponse2()); - } - } - - public static class MockJournalImage { - public static JournalImage getStubJournalImage1() { - return JournalImage.builder() - .journalImageId(1L) - .journal(MockJournal.getStubJournal1()) - .originName("cdde9ac4bc61logo") - .imageUrl("https://growstory.s3.ap-northeast-2.amazonaws.com/image/journal_image/1a4ee5d0-3f55-40c6-aff9-cdde9ac4bc61logo.png") - .build(); - } - public static JournalImage getStubJournalImage2() { - return JournalImage.builder() - .journalImageId(2L) - .journal(MockJournal.getStubJournal2()) - .originName("cdde9ac4bc61logo") - .imageUrl("https://growstory.s3.ap-northeast-2.amazonaws.com/image/journal_image/1a4ee5d0-3f55-40c6-aff9-cdde9ac4bc61logo.png") - .build(); - } - - - } - - public static class MockPoint { - public static Point getStubPointResponseDtoWith500Score() { - return Point.builder() - .score(500) - .build(); - } - public static Point getStubPointResponseDtoWithNoScore() { - return Point.builder() - .score(0) - .build(); - } - } - - public static class MockBoardLikes { - public static BoardLike getBoardLike1_1() { - Account account1 = Account.builder() - .accountId(1L).displayName("김별명1").build(); - return BoardLike.builder() - .boardLikeId(1L) - .account(account1) - .board(Board.builder().boardId(1L).build()) - .build(); - } - public static BoardLike getBoardLike1_2() { - Account account1 = Account.builder() - .accountId(2L).displayName("김별명2").build(); - return BoardLike.builder() - .boardLikeId(2L) - .account(account1) - .board(Board.builder().boardId(1L).build()) - .build(); - } - public static BoardLike getBoardLike1_3() { - Account account1 = Account.builder() - .accountId(3L).displayName("김별명3").build(); - return BoardLike.builder() - .boardLikeId(3L) - .account(account1) - .board(Board.builder().boardId(1L).build()) - .build(); - } - - public static BoardLike getBoardLike2_1() { - Account account1 = Account.builder() - .accountId(1L).displayName("김별명1").build(); - return BoardLike.builder() - .boardLikeId(1L) - .account(account1) - .board(Board.builder().boardId(2L).build()) - .build(); - } - public static BoardLike getBoardLike2_2() { - Account account1 = Account.builder() - .accountId(2L).displayName("김별명2").build(); - return BoardLike.builder() - .boardLikeId(2L) - .account(account1) - .board(Board.builder().boardId(2L).build()) - .build(); - } - - public static BoardLike getBoardLike3_1() { - Account account1 = Account.builder() - .accountId(1L).displayName("김별명1").build(); - return BoardLike.builder() - .boardLikeId(1L) - .account(account1) - .board(Board.builder().boardId(3L).build()) - .build(); - } - - public static List getBoardLikes1() { - List boardLikes = new ArrayList<>(); - boardLikes.add(getBoardLike1_1()); - boardLikes.add(getBoardLike1_2()); - boardLikes.add(getBoardLike1_3()); - return boardLikes; - } - - public static List getBoardLikes2() { - List boardLikes = new ArrayList<>(); - boardLikes.add(getBoardLike2_1()); - boardLikes.add(getBoardLike2_2()); - return boardLikes; - } - - public static List getBoardLikes3() { - List boardLikes = new ArrayList<>(); - boardLikes.add(getBoardLike3_1()); - return boardLikes; - } - } - - public static class MockBoard { - - public static Board getMockBoard1() { - return Board.builder() - .account(Account.builder().accountId(1L).displayName("김별명1").build()) - .boardId(1L) - .title("제목1") - .content("내용1") - .build(); - } - - public static Board getMockBoard2() { - return Board.builder() - .account(Account.builder().accountId(2L).displayName("김별명2").build()) - .boardId(2L) - .title("제목2") - .content("내용2") - .build(); - } - - public static Board getMockBoard3() { - return Board.builder() - .account(Account.builder().accountId(3L).displayName("김별명3").build()) - .boardId(3L) - .title("제목3") - .content("내용3") - .build(); - } - public static Board getMockBoard4() { - return Board.builder() - .account(Account.builder().accountId(4L).displayName("김별명4").build()) - .boardId(4L) - .title("제목4") - .content("내용4") - .build(); - } - public static Board getMockBoard5() { - return Board.builder() - .account(Account.builder().accountId(5L).displayName("김별명5").build()) - .boardId(5L) - .title("제목4") - .content("내용4") - .build(); - } - - } -} diff --git a/server/src/test/java/com/growstory/global/customUser/annotation/WithMockCustomUser.java b/server/src/test/java/com/growstory/global/customUser/annotation/WithMockCustomUser.java deleted file mode 100644 index d6167f3d..00000000 --- a/server/src/test/java/com/growstory/global/customUser/annotation/WithMockCustomUser.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.growstory.global.customUser.annotation; - -import com.growstory.global.customUser.factory.WithMockCustomUserSecurityContextFactory; -import org.springframework.security.test.context.support.WithSecurityContext; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -@WithSecurityContext(factory = WithMockCustomUserSecurityContextFactory.class) -public @interface WithMockCustomUser { - long accountId() default 1L; - String email() default "admin@gmail.com"; - String displayName() default "관리자"; - String password() default "admin1234"; - String profileImageUrl() default ""; - String[] roles() default {"USER", "ADMIN"}; - -} diff --git a/server/src/test/java/com/growstory/global/customUser/factory/WithMockCustomUserSecurityContextFactory.java b/server/src/test/java/com/growstory/global/customUser/factory/WithMockCustomUserSecurityContextFactory.java deleted file mode 100644 index bc444564..00000000 --- a/server/src/test/java/com/growstory/global/customUser/factory/WithMockCustomUserSecurityContextFactory.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.growstory.global.customUser.factory; - -import com.growstory.global.auth.utils.CustomAuthorityUtils; -import com.growstory.global.customUser.annotation.WithMockCustomUser; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.test.context.support.WithSecurityContextFactory; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory { - private static CustomAuthorityUtils authorityUtils; - private static PasswordEncoder passwordEncoder; - - public WithMockCustomUserSecurityContextFactory(CustomAuthorityUtils authorityUtils, PasswordEncoder passwordEncoder) { - this.authorityUtils = authorityUtils; - this.passwordEncoder = passwordEncoder; - } - - @Override - public SecurityContext createSecurityContext(WithMockCustomUser customUser) { - SecurityContext context = SecurityContextHolder.createEmptyContext(); - - Map claims = new HashMap<>(); - claims.put("accountId", customUser.accountId()); - claims.put("username", customUser.email()); - claims.put("displayName", customUser.displayName()); - claims.put("profileImageUrl", customUser.profileImageUrl()); - claims.put("roles", customUser.roles()); - System.out.println(Arrays.asList((String[]) claims.get("roles"))); - List authorities = authorityUtils.createAuthorities(Arrays.asList((String[]) claims.get("roles"))); - // 인증 토큰을 만들어 authentication으로 어퍼 캐스팅하여 SecurityContextHolder에 저장한다. - Authentication authentication = new UsernamePasswordAuthenticationToken(claims, passwordEncoder.encode(customUser.password()), authorities); - context.setAuthentication(authentication); - - return context; - } -}