From 8f54ea43dc58a8f197d8206961eb9b0d02a3b994 Mon Sep 17 00:00:00 2001 From: ssunnykku <108388578+ssunnykku@users.noreply.github.com> Date: Mon, 26 Aug 2024 13:19:58 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20post=20=EC=83=81=EC=84=B8=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + .../content/controller/ContentController.java | 9 -- .../content/repository/ContentRepository.java | 7 -- .../media/content/service/ContentService.java | 7 -- .../exception/PostNotFoundException.java | 11 +++ .../handler/GlobalExceptionHandler.java | 24 ++++-- .../media/post/controller/PostController.java | 28 ++++++ .../Content.java => post/domain/Post.java} | 30 ++++--- .../media/{content => post}/domain/Type.java | 2 +- .../wanted/media/post/dto/DetailResponse.java | 30 +++++++ .../media/post/repository/PostRepository.java | 7 ++ .../media/post/service/PostService.java | 44 ++++++++++ .../post/repository/PostRepositoryTest.java | 85 +++++++++++++++++++ .../media/post/service/PostServiceTest.java | 67 +++++++++++++++ 14 files changed, 312 insertions(+), 41 deletions(-) delete mode 100644 src/main/java/wanted/media/content/controller/ContentController.java delete mode 100644 src/main/java/wanted/media/content/repository/ContentRepository.java delete mode 100644 src/main/java/wanted/media/content/service/ContentService.java create mode 100644 src/main/java/wanted/media/exception/PostNotFoundException.java create mode 100644 src/main/java/wanted/media/post/controller/PostController.java rename src/main/java/wanted/media/{content/domain/Content.java => post/domain/Post.java} (70%) rename src/main/java/wanted/media/{content => post}/domain/Type.java (63%) create mode 100644 src/main/java/wanted/media/post/dto/DetailResponse.java create mode 100644 src/main/java/wanted/media/post/repository/PostRepository.java create mode 100644 src/main/java/wanted/media/post/service/PostService.java create mode 100644 src/test/java/wanted/media/post/repository/PostRepositoryTest.java create mode 100644 src/test/java/wanted/media/post/service/PostServiceTest.java diff --git a/.gitignore b/.gitignore index cf4d44f..d15dcb2 100644 --- a/.gitignore +++ b/.gitignore @@ -267,3 +267,5 @@ gradle-app.setting # End of https://www.toptal.com/developers/gitignore/api/macos,intellij,windows,java,gradle src/main/resources/application-secret.yml +src/main/resources/application-dev.yml +src/main/resources/application-test.yml diff --git a/src/main/java/wanted/media/content/controller/ContentController.java b/src/main/java/wanted/media/content/controller/ContentController.java deleted file mode 100644 index 00583de..0000000 --- a/src/main/java/wanted/media/content/controller/ContentController.java +++ /dev/null @@ -1,9 +0,0 @@ -package wanted.media.content.controller; - -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/contents") -public class ContentController { -} diff --git a/src/main/java/wanted/media/content/repository/ContentRepository.java b/src/main/java/wanted/media/content/repository/ContentRepository.java deleted file mode 100644 index 510a593..0000000 --- a/src/main/java/wanted/media/content/repository/ContentRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package wanted.media.content.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import wanted.media.content.domain.Content; - -public interface ContentRepository extends JpaRepository { -} diff --git a/src/main/java/wanted/media/content/service/ContentService.java b/src/main/java/wanted/media/content/service/ContentService.java deleted file mode 100644 index b505adc..0000000 --- a/src/main/java/wanted/media/content/service/ContentService.java +++ /dev/null @@ -1,7 +0,0 @@ -package wanted.media.content.service; - -import org.springframework.stereotype.Service; - -@Service -public class ContentService { -} diff --git a/src/main/java/wanted/media/exception/PostNotFoundException.java b/src/main/java/wanted/media/exception/PostNotFoundException.java new file mode 100644 index 0000000..7ed3177 --- /dev/null +++ b/src/main/java/wanted/media/exception/PostNotFoundException.java @@ -0,0 +1,11 @@ +package wanted.media.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class PostNotFoundException extends RuntimeException { + private final ErrorCode errorCode; + +} \ No newline at end of file diff --git a/src/main/java/wanted/media/exception/handler/GlobalExceptionHandler.java b/src/main/java/wanted/media/exception/handler/GlobalExceptionHandler.java index c96a472..ee159c1 100644 --- a/src/main/java/wanted/media/exception/handler/GlobalExceptionHandler.java +++ b/src/main/java/wanted/media/exception/handler/GlobalExceptionHandler.java @@ -1,18 +1,30 @@ package wanted.media.exception.handler; import org.apache.coyote.BadRequestException; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; - +import wanted.media.exception.ErrorCode; import wanted.media.exception.ErrorResponse; +import wanted.media.exception.PostNotFoundException; @RestControllerAdvice public class GlobalExceptionHandler { - @ExceptionHandler(BadRequestException.class) - public ResponseEntity handleBadRequestException(BadRequestException e) { - return ResponseEntity.badRequest() - .body(new ErrorResponse(400, e.getMessage())); - } + @ExceptionHandler(BadRequestException.class) + public ResponseEntity handleBadRequestException(BadRequestException e) { + return ResponseEntity.badRequest() + .body(new ErrorResponse(400, e.getMessage())); + } + + @ExceptionHandler(PostNotFoundException.class) + public ResponseEntity handlePostNotFound(PostNotFoundException e) { + ErrorCode errorCode = e.getErrorCode(); + ErrorResponse errorResponse = new ErrorResponse( + errorCode.getStatus().value(), + errorCode.getMessage() + ); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); + } } diff --git a/src/main/java/wanted/media/post/controller/PostController.java b/src/main/java/wanted/media/post/controller/PostController.java new file mode 100644 index 0000000..509cce0 --- /dev/null +++ b/src/main/java/wanted/media/post/controller/PostController.java @@ -0,0 +1,28 @@ +package wanted.media.post.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import wanted.media.post.dto.DetailResponse; +import wanted.media.post.service.PostService; + +@RestController +@RequestMapping("/api/posts") +@RequiredArgsConstructor +public class PostController { + + private final PostService contentService; + + /** + * @param postId + * @return + */ + @GetMapping("/{postId}") + public ResponseEntity getPost(@PathVariable String postId) { + return ResponseEntity.ok(contentService.getPost(postId)); + } + +} diff --git a/src/main/java/wanted/media/content/domain/Content.java b/src/main/java/wanted/media/post/domain/Post.java similarity index 70% rename from src/main/java/wanted/media/content/domain/Content.java rename to src/main/java/wanted/media/post/domain/Post.java index fed9efd..7906803 100644 --- a/src/main/java/wanted/media/content/domain/Content.java +++ b/src/main/java/wanted/media/post/domain/Post.java @@ -1,9 +1,10 @@ -package wanted.media.content.domain; +package wanted.media.post.domain; import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.*; +import org.hibernate.annotations.ColumnDefault; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -13,19 +14,15 @@ @Entity @Getter -@Table(name = "contents") +@Table(name = "posts") @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Builder @EntityListeners(AuditingEntityListener.class) -public class Content { +public class Post { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "content_id", nullable = false) - private Long id; - - @Column(name = "like_count") - private Long likeCount; + @Column(name = "post_id", nullable = false) + private String id; @Enumerated(EnumType.STRING) @Column(nullable = false) @@ -35,12 +32,16 @@ public class Content { @Column(nullable = false) private String title; - private String content; - + private String post; private String hashtags; + @ColumnDefault("0") + private Long likeCount; + + @ColumnDefault("0") private Long viewCount; + @ColumnDefault("0") private Long shareCount; @LastModifiedDate @@ -54,4 +55,11 @@ public class Content { @NotNull private User user; + public void incrementViewCount() { + if (this.viewCount == null) { + this.viewCount = 0L; + } + this.viewCount += 1; + } + } diff --git a/src/main/java/wanted/media/content/domain/Type.java b/src/main/java/wanted/media/post/domain/Type.java similarity index 63% rename from src/main/java/wanted/media/content/domain/Type.java rename to src/main/java/wanted/media/post/domain/Type.java index 539f7fa..55a18e9 100644 --- a/src/main/java/wanted/media/content/domain/Type.java +++ b/src/main/java/wanted/media/post/domain/Type.java @@ -1,4 +1,4 @@ -package wanted.media.content.domain; +package wanted.media.post.domain; public enum Type { FACEBOOK, TWITTER, INSTAGRAM, THREADS; diff --git a/src/main/java/wanted/media/post/dto/DetailResponse.java b/src/main/java/wanted/media/post/dto/DetailResponse.java new file mode 100644 index 0000000..c07630b --- /dev/null +++ b/src/main/java/wanted/media/post/dto/DetailResponse.java @@ -0,0 +1,30 @@ +package wanted.media.post.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import wanted.media.post.domain.Type; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Getter +public class DetailResponse { + private String postId; + private Type type; + private String title; + private String post; + private String hashtags; + private Long likeCount; + private Long viewCount; + private Long shareCount; + private LocalDateTime updatedAt; + private LocalDateTime createdAt; + private UUID userId; + private String account; + private String email; +} diff --git a/src/main/java/wanted/media/post/repository/PostRepository.java b/src/main/java/wanted/media/post/repository/PostRepository.java new file mode 100644 index 0000000..fb74f17 --- /dev/null +++ b/src/main/java/wanted/media/post/repository/PostRepository.java @@ -0,0 +1,7 @@ +package wanted.media.post.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import wanted.media.post.domain.Post; + +public interface PostRepository extends JpaRepository { +} diff --git a/src/main/java/wanted/media/post/service/PostService.java b/src/main/java/wanted/media/post/service/PostService.java new file mode 100644 index 0000000..3b0a331 --- /dev/null +++ b/src/main/java/wanted/media/post/service/PostService.java @@ -0,0 +1,44 @@ +package wanted.media.post.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import wanted.media.exception.ErrorCode; +import wanted.media.exception.PostNotFoundException; +import wanted.media.post.domain.Post; +import wanted.media.post.dto.DetailResponse; +import wanted.media.post.repository.PostRepository; + +@Service +@RequiredArgsConstructor +public class PostService { + + private final PostRepository postRepository; + + @Transactional + public DetailResponse getPost(String postId) { + Post post = postRepository.findById(postId) + .orElseThrow(() -> new PostNotFoundException(ErrorCode.ENTITY_NOT_FOUND)); + + post.incrementViewCount(); + postRepository.save(post); + + DetailResponse result = DetailResponse.builder() + .postId(post.getId()) + .likeCount(post.getLikeCount()) + .type(post.getType()) + .title(post.getTitle()) + .post(post.getPost()) + .hashtags(post.getHashtags()) + .viewCount(post.getViewCount()) + .shareCount(post.getShareCount()) + .updatedAt(post.getUpdatedAt()) + .createdAt(post.getCreatedAt()) + .userId(post.getUser().getUserId()) + .account(post.getUser().getAccount()) + .email(post.getUser().getEmail()) + .build(); + return result; + } + +} diff --git a/src/test/java/wanted/media/post/repository/PostRepositoryTest.java b/src/test/java/wanted/media/post/repository/PostRepositoryTest.java new file mode 100644 index 0000000..a41f6b3 --- /dev/null +++ b/src/test/java/wanted/media/post/repository/PostRepositoryTest.java @@ -0,0 +1,85 @@ +package wanted.media.post.repository; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; +import wanted.media.post.domain.Post; +import wanted.media.post.domain.Type; +import wanted.media.user.domain.Grade; +import wanted.media.user.domain.User; +import wanted.media.user.repository.UserRepository; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@ActiveProfiles("test") +class PostRepositoryTest { + @Autowired + private PostRepository postRepository; + + @Autowired + private UserRepository userRepository; + + @Test + @Transactional + void getPostTest() { + + User user = User.builder() + .account("sun") + .email("sun@gmail.com") + .password("1234") + .grade(Grade.NORMAL_USER) + .build(); + + userRepository.save(user); + + Post post = Post.builder() + .id("qwer") + .type(Type.TWITTER) + .title("제목 입력") + .user(user) + .build(); + + postRepository.save(post); + + Post result = postRepository.findById(post.getId()).orElseThrow(() -> new IllegalArgumentException("Content not found")); + + assertThat(result.getTitle()).isEqualTo("제목 입력"); + assertThat(result.getUser().getAccount()).isEqualTo("sun"); + } + + @Test + @Transactional + void addViewCountTest() { + User user = User.builder() + .account("sun") + .email("sun@gmail.com") + .password("1234") + .grade(Grade.NORMAL_USER) + .build(); + + userRepository.save(user); + + Post post = Post.builder() + .id("qwer") + .type(Type.TWITTER) + .title("제목 입력") + .user(user) + .viewCount(100L) + .build(); + + postRepository.save(post); + + Post getContent = postRepository.findById(post.getId()).orElseThrow(() -> new RuntimeException("Content not found")); + + + getContent.incrementViewCount(); + assertThat(getContent.getViewCount()).isEqualTo(101); + + + postRepository.save(getContent); + + } +} \ No newline at end of file diff --git a/src/test/java/wanted/media/post/service/PostServiceTest.java b/src/test/java/wanted/media/post/service/PostServiceTest.java new file mode 100644 index 0000000..d9913fe --- /dev/null +++ b/src/test/java/wanted/media/post/service/PostServiceTest.java @@ -0,0 +1,67 @@ +package wanted.media.post.service; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; +import wanted.media.post.domain.Post; +import wanted.media.post.domain.Type; +import wanted.media.post.dto.DetailResponse; +import wanted.media.post.repository.PostRepository; +import wanted.media.user.domain.Grade; +import wanted.media.user.domain.User; +import wanted.media.user.repository.UserRepository; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@ActiveProfiles("test") +class PostServiceTest { + + @Autowired + private PostService postService; + + @Autowired + private UserRepository userRepository; + + @Autowired + private PostRepository postRepository; + + + @Test + @Transactional + void getPostTest() { + // given + User user = User.builder() + .account("sun") + .email("sun@gmail.com") + .password("1234") + .grade(Grade.NORMAL_USER) + .build(); + + userRepository.save(user); + + Post post = Post.builder() + .id("qwer") + .type(Type.TWITTER) + .title("제목 입력") + .post("내용 입력") + .user(user) + .viewCount(100L) + .build(); + + postRepository.save(post); + + // when + DetailResponse getData = postService.getPost(post.getId()); + // then + assertThat(getData.getTitle()).isEqualTo("제목 입력"); + assertThat(getData.getPost()).isEqualTo("내용 입력"); + assertThat(getData.getViewCount()).isEqualTo(101); + assertThat(getData.getAccount()).isEqualTo("sun"); + assertThat(getData.getEmail()).isEqualTo("sun@gmail.com"); + + } + +} \ No newline at end of file From 3fc8e68128639e8eaf81578e4a5db1b64046ec57 Mon Sep 17 00:00:00 2001 From: ssunnykku <108388578+ssunnykku@users.noreply.github.com> Date: Mon, 26 Aug 2024 13:39:36 +0900 Subject: [PATCH 2/6] =?UTF-8?q?refactor:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=9A=A9=20security=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../media/user/config/SecurityConfig.java | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/wanted/media/user/config/SecurityConfig.java b/src/main/java/wanted/media/user/config/SecurityConfig.java index 0d84f89..de5abb8 100644 --- a/src/main/java/wanted/media/user/config/SecurityConfig.java +++ b/src/main/java/wanted/media/user/config/SecurityConfig.java @@ -1,7 +1,36 @@ package wanted.media.user.config; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.security.servlet.PathRequest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.web.SecurityFilterChain; + @EnableWebSecurity +@Configuration public class SecurityConfig { -} + + /** + * 테스트용 메서드 + */ + @Bean + @ConditionalOnProperty(name = "spring.h2.console.enabled", havingValue = "true") + public WebSecurityCustomizer configureH2ConsoleEnable() { + return web -> web.ignoring() + .requestMatchers(PathRequest.toH2Console()); + } + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http.authorizeHttpRequests( + request -> request.requestMatchers("/**").permitAll() + .anyRequest().authenticated()) + .csrf(csrf -> csrf.disable()); + + return http.build(); + } +} \ No newline at end of file From 6dda02c73cc1e1be29423052efc9b47723cbf5ae Mon Sep 17 00:00:00 2001 From: ssunnykku <108388578+ssunnykku@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:45:36 +0900 Subject: [PATCH 3/6] =?UTF-8?q?refactor:=20review=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 공백 제거 - dto record로 변경 - DetailResponse 반환 코드 PostService -> PostController 수정 작성 - .gitignore 수정 - PostNotFoundException -> NotFoundException --- .gitignore | 1 - ...dException.java => NotFoundException.java} | 3 +- .../handler/GlobalExceptionHandler.java | 6 ++-- .../media/post/controller/PostController.java | 28 +++++++++++++---- .../java/wanted/media/post/domain/Post.java | 1 - .../wanted/media/post/dto/DetailResponse.java | 30 ------------------- .../media/post/dto/PostDetailResponse.java | 25 ++++++++++++++++ .../media/post/service/PostService.java | 28 +++-------------- .../media/user/controller/UserController.java | 1 - .../java/wanted/media/user/domain/Code.java | 1 - .../java/wanted/media/user/domain/Token.java | 1 - .../media/user/service/UserService.java | 1 - src/main/resources/application-dev.yml | 21 +++++++++++++ .../media/post/service/PostServiceTest.java | 12 +++----- 14 files changed, 80 insertions(+), 79 deletions(-) rename src/main/java/wanted/media/exception/{PostNotFoundException.java => NotFoundException.java} (72%) delete mode 100644 src/main/java/wanted/media/post/dto/DetailResponse.java create mode 100644 src/main/java/wanted/media/post/dto/PostDetailResponse.java create mode 100644 src/main/resources/application-dev.yml diff --git a/.gitignore b/.gitignore index d15dcb2..815bf24 100644 --- a/.gitignore +++ b/.gitignore @@ -267,5 +267,4 @@ gradle-app.setting # End of https://www.toptal.com/developers/gitignore/api/macos,intellij,windows,java,gradle src/main/resources/application-secret.yml -src/main/resources/application-dev.yml src/main/resources/application-test.yml diff --git a/src/main/java/wanted/media/exception/PostNotFoundException.java b/src/main/java/wanted/media/exception/NotFoundException.java similarity index 72% rename from src/main/java/wanted/media/exception/PostNotFoundException.java rename to src/main/java/wanted/media/exception/NotFoundException.java index 7ed3177..1d1fd12 100644 --- a/src/main/java/wanted/media/exception/PostNotFoundException.java +++ b/src/main/java/wanted/media/exception/NotFoundException.java @@ -5,7 +5,6 @@ @Getter @RequiredArgsConstructor -public class PostNotFoundException extends RuntimeException { +public class NotFoundException extends RuntimeException { private final ErrorCode errorCode; - } \ No newline at end of file diff --git a/src/main/java/wanted/media/exception/handler/GlobalExceptionHandler.java b/src/main/java/wanted/media/exception/handler/GlobalExceptionHandler.java index ee159c1..f341fdd 100644 --- a/src/main/java/wanted/media/exception/handler/GlobalExceptionHandler.java +++ b/src/main/java/wanted/media/exception/handler/GlobalExceptionHandler.java @@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.RestControllerAdvice; import wanted.media.exception.ErrorCode; import wanted.media.exception.ErrorResponse; -import wanted.media.exception.PostNotFoundException; +import wanted.media.exception.NotFoundException; @RestControllerAdvice public class GlobalExceptionHandler { @@ -18,8 +18,8 @@ public ResponseEntity handleBadRequestException(BadRequestExcepti .body(new ErrorResponse(400, e.getMessage())); } - @ExceptionHandler(PostNotFoundException.class) - public ResponseEntity handlePostNotFound(PostNotFoundException e) { + @ExceptionHandler(NotFoundException.class) + public ResponseEntity handlePostNotFound(NotFoundException e) { ErrorCode errorCode = e.getErrorCode(); ErrorResponse errorResponse = new ErrorResponse( errorCode.getStatus().value(), diff --git a/src/main/java/wanted/media/post/controller/PostController.java b/src/main/java/wanted/media/post/controller/PostController.java index 509cce0..3b02153 100644 --- a/src/main/java/wanted/media/post/controller/PostController.java +++ b/src/main/java/wanted/media/post/controller/PostController.java @@ -6,7 +6,8 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import wanted.media.post.dto.DetailResponse; +import wanted.media.post.domain.Post; +import wanted.media.post.dto.PostDetailResponse; import wanted.media.post.service.PostService; @RestController @@ -14,15 +15,30 @@ @RequiredArgsConstructor public class PostController { - private final PostService contentService; + private final PostService posetService; /** * @param postId - * @return + * @return PostDetailResponse */ @GetMapping("/{postId}") - public ResponseEntity getPost(@PathVariable String postId) { - return ResponseEntity.ok(contentService.getPost(postId)); + public ResponseEntity getPost(@PathVariable String postId) { + Post post = posetService.getPost(postId); + PostDetailResponse result = PostDetailResponse.builder() + .postId(post.getId()) + .likeCount(post.getLikeCount()) + .type(post.getType()) + .title(post.getTitle()) + .post(post.getPost()) + .hashtags(post.getHashtags()) + .viewCount(post.getViewCount()) + .shareCount(post.getShareCount()) + .updatedAt(post.getUpdatedAt()) + .createdAt(post.getCreatedAt()) + .userId(post.getUser().getUserId()) + .account(post.getUser().getAccount()) + .email(post.getUser().getEmail()) + .build(); + return ResponseEntity.ok(result); } - } diff --git a/src/main/java/wanted/media/post/domain/Post.java b/src/main/java/wanted/media/post/domain/Post.java index 7906803..03ab0b0 100644 --- a/src/main/java/wanted/media/post/domain/Post.java +++ b/src/main/java/wanted/media/post/domain/Post.java @@ -61,5 +61,4 @@ public void incrementViewCount() { } this.viewCount += 1; } - } diff --git a/src/main/java/wanted/media/post/dto/DetailResponse.java b/src/main/java/wanted/media/post/dto/DetailResponse.java deleted file mode 100644 index c07630b..0000000 --- a/src/main/java/wanted/media/post/dto/DetailResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -package wanted.media.post.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import wanted.media.post.domain.Type; - -import java.time.LocalDateTime; -import java.util.UUID; - -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Getter -public class DetailResponse { - private String postId; - private Type type; - private String title; - private String post; - private String hashtags; - private Long likeCount; - private Long viewCount; - private Long shareCount; - private LocalDateTime updatedAt; - private LocalDateTime createdAt; - private UUID userId; - private String account; - private String email; -} diff --git a/src/main/java/wanted/media/post/dto/PostDetailResponse.java b/src/main/java/wanted/media/post/dto/PostDetailResponse.java new file mode 100644 index 0000000..c5514e1 --- /dev/null +++ b/src/main/java/wanted/media/post/dto/PostDetailResponse.java @@ -0,0 +1,25 @@ +package wanted.media.post.dto; + +import lombok.Builder; +import wanted.media.post.domain.Type; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Builder +public record PostDetailResponse( + String postId, + Type type, + String title, + String post, + String hashtags, + Long likeCount, + Long viewCount, + Long shareCount, + LocalDateTime updatedAt, + LocalDateTime createdAt, + UUID userId, + String account, + String email +) { +} diff --git a/src/main/java/wanted/media/post/service/PostService.java b/src/main/java/wanted/media/post/service/PostService.java index 3b0a331..aa1ecb5 100644 --- a/src/main/java/wanted/media/post/service/PostService.java +++ b/src/main/java/wanted/media/post/service/PostService.java @@ -4,41 +4,21 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import wanted.media.exception.ErrorCode; -import wanted.media.exception.PostNotFoundException; +import wanted.media.exception.NotFoundException; import wanted.media.post.domain.Post; -import wanted.media.post.dto.DetailResponse; import wanted.media.post.repository.PostRepository; @Service @RequiredArgsConstructor public class PostService { - private final PostRepository postRepository; @Transactional - public DetailResponse getPost(String postId) { + public Post getPost(String postId) { Post post = postRepository.findById(postId) - .orElseThrow(() -> new PostNotFoundException(ErrorCode.ENTITY_NOT_FOUND)); + .orElseThrow(() -> new NotFoundException(ErrorCode.ENTITY_NOT_FOUND)); post.incrementViewCount(); - postRepository.save(post); - - DetailResponse result = DetailResponse.builder() - .postId(post.getId()) - .likeCount(post.getLikeCount()) - .type(post.getType()) - .title(post.getTitle()) - .post(post.getPost()) - .hashtags(post.getHashtags()) - .viewCount(post.getViewCount()) - .shareCount(post.getShareCount()) - .updatedAt(post.getUpdatedAt()) - .createdAt(post.getCreatedAt()) - .userId(post.getUser().getUserId()) - .account(post.getUser().getAccount()) - .email(post.getUser().getEmail()) - .build(); - return result; + return post; } - } diff --git a/src/main/java/wanted/media/user/controller/UserController.java b/src/main/java/wanted/media/user/controller/UserController.java index 867ccff..ded5a42 100644 --- a/src/main/java/wanted/media/user/controller/UserController.java +++ b/src/main/java/wanted/media/user/controller/UserController.java @@ -9,6 +9,5 @@ @RequestMapping("/user") @RequiredArgsConstructor public class UserController { - private final UserService userService; } diff --git a/src/main/java/wanted/media/user/domain/Code.java b/src/main/java/wanted/media/user/domain/Code.java index 75bd557..cb08271 100644 --- a/src/main/java/wanted/media/user/domain/Code.java +++ b/src/main/java/wanted/media/user/domain/Code.java @@ -15,7 +15,6 @@ @Entity @Table(name = "codes") public class Code { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false) diff --git a/src/main/java/wanted/media/user/domain/Token.java b/src/main/java/wanted/media/user/domain/Token.java index 81fc2f5..e14e5ed 100644 --- a/src/main/java/wanted/media/user/domain/Token.java +++ b/src/main/java/wanted/media/user/domain/Token.java @@ -11,7 +11,6 @@ @Entity @Table(name = "tokens") public class Token { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false) diff --git a/src/main/java/wanted/media/user/service/UserService.java b/src/main/java/wanted/media/user/service/UserService.java index e642526..239076d 100644 --- a/src/main/java/wanted/media/user/service/UserService.java +++ b/src/main/java/wanted/media/user/service/UserService.java @@ -7,6 +7,5 @@ @Service @RequiredArgsConstructor public class UserService { - private final UserRepository userRepository; } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..9dc08f0 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,21 @@ +# application-test +spring: + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:db;MODE=MYSQL + username: sa + password: + h2: + console: + enabled: true + path: /h2-console + jpa: + show-sql: true + properties: + hibernate: + format_sql: true + hibernate: + ddl-auto: update + +jwt: + secret_key: key diff --git a/src/test/java/wanted/media/post/service/PostServiceTest.java b/src/test/java/wanted/media/post/service/PostServiceTest.java index d9913fe..018e1ce 100644 --- a/src/test/java/wanted/media/post/service/PostServiceTest.java +++ b/src/test/java/wanted/media/post/service/PostServiceTest.java @@ -7,7 +7,6 @@ import org.springframework.transaction.annotation.Transactional; import wanted.media.post.domain.Post; import wanted.media.post.domain.Type; -import wanted.media.post.dto.DetailResponse; import wanted.media.post.repository.PostRepository; import wanted.media.user.domain.Grade; import wanted.media.user.domain.User; @@ -18,7 +17,6 @@ @SpringBootTest @ActiveProfiles("test") class PostServiceTest { - @Autowired private PostService postService; @@ -28,7 +26,6 @@ class PostServiceTest { @Autowired private PostRepository postRepository; - @Test @Transactional void getPostTest() { @@ -54,14 +51,13 @@ void getPostTest() { postRepository.save(post); // when - DetailResponse getData = postService.getPost(post.getId()); + Post getData = postService.getPost(post.getId()); + // then assertThat(getData.getTitle()).isEqualTo("제목 입력"); assertThat(getData.getPost()).isEqualTo("내용 입력"); assertThat(getData.getViewCount()).isEqualTo(101); - assertThat(getData.getAccount()).isEqualTo("sun"); - assertThat(getData.getEmail()).isEqualTo("sun@gmail.com"); - + assertThat(getData.getUser().getAccount()).isEqualTo("sun"); + assertThat(getData.getUser().getEmail()).isEqualTo("sun@gmail.com"); } - } \ No newline at end of file From 9d8b0a0f03f15b16d726b4c6cb8a9c25f3ddc00a Mon Sep 17 00:00:00 2001 From: ssunnykku <108388578+ssunnykku@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:27:44 +0900 Subject: [PATCH 4/6] =?UTF-8?q?refactor:=20repository=20test=20code=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/repository/PostRepositoryTest.java | 85 ------------------- 1 file changed, 85 deletions(-) delete mode 100644 src/test/java/wanted/media/post/repository/PostRepositoryTest.java diff --git a/src/test/java/wanted/media/post/repository/PostRepositoryTest.java b/src/test/java/wanted/media/post/repository/PostRepositoryTest.java deleted file mode 100644 index a41f6b3..0000000 --- a/src/test/java/wanted/media/post/repository/PostRepositoryTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package wanted.media.post.repository; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.transaction.annotation.Transactional; -import wanted.media.post.domain.Post; -import wanted.media.post.domain.Type; -import wanted.media.user.domain.Grade; -import wanted.media.user.domain.User; -import wanted.media.user.repository.UserRepository; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest -@ActiveProfiles("test") -class PostRepositoryTest { - @Autowired - private PostRepository postRepository; - - @Autowired - private UserRepository userRepository; - - @Test - @Transactional - void getPostTest() { - - User user = User.builder() - .account("sun") - .email("sun@gmail.com") - .password("1234") - .grade(Grade.NORMAL_USER) - .build(); - - userRepository.save(user); - - Post post = Post.builder() - .id("qwer") - .type(Type.TWITTER) - .title("제목 입력") - .user(user) - .build(); - - postRepository.save(post); - - Post result = postRepository.findById(post.getId()).orElseThrow(() -> new IllegalArgumentException("Content not found")); - - assertThat(result.getTitle()).isEqualTo("제목 입력"); - assertThat(result.getUser().getAccount()).isEqualTo("sun"); - } - - @Test - @Transactional - void addViewCountTest() { - User user = User.builder() - .account("sun") - .email("sun@gmail.com") - .password("1234") - .grade(Grade.NORMAL_USER) - .build(); - - userRepository.save(user); - - Post post = Post.builder() - .id("qwer") - .type(Type.TWITTER) - .title("제목 입력") - .user(user) - .viewCount(100L) - .build(); - - postRepository.save(post); - - Post getContent = postRepository.findById(post.getId()).orElseThrow(() -> new RuntimeException("Content not found")); - - - getContent.incrementViewCount(); - assertThat(getContent.getViewCount()).isEqualTo(101); - - - postRepository.save(getContent); - - } -} \ No newline at end of file From 53480f8f62546ce3dd0b88298623fa86e2aacd70 Mon Sep 17 00:00:00 2001 From: ssunnykku <108388578+ssunnykku@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:44:33 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=20Entity,=20DTO=20Colum=20post=20?= =?UTF-8?q?->=20content=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/wanted/media/post/controller/PostController.java | 2 +- src/main/java/wanted/media/post/domain/Post.java | 2 +- src/main/java/wanted/media/post/dto/PostDetailResponse.java | 2 +- src/test/java/wanted/media/post/service/PostServiceTest.java | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/wanted/media/post/controller/PostController.java b/src/main/java/wanted/media/post/controller/PostController.java index 3b02153..66913de 100644 --- a/src/main/java/wanted/media/post/controller/PostController.java +++ b/src/main/java/wanted/media/post/controller/PostController.java @@ -29,7 +29,7 @@ public ResponseEntity getPost(@PathVariable String postId) { .likeCount(post.getLikeCount()) .type(post.getType()) .title(post.getTitle()) - .post(post.getPost()) + .content(post.getContent()) .hashtags(post.getHashtags()) .viewCount(post.getViewCount()) .shareCount(post.getShareCount()) diff --git a/src/main/java/wanted/media/post/domain/Post.java b/src/main/java/wanted/media/post/domain/Post.java index 03ab0b0..8a49ac7 100644 --- a/src/main/java/wanted/media/post/domain/Post.java +++ b/src/main/java/wanted/media/post/domain/Post.java @@ -32,7 +32,7 @@ public class Post { @Column(nullable = false) private String title; - private String post; + private String content; private String hashtags; @ColumnDefault("0") diff --git a/src/main/java/wanted/media/post/dto/PostDetailResponse.java b/src/main/java/wanted/media/post/dto/PostDetailResponse.java index c5514e1..69b9217 100644 --- a/src/main/java/wanted/media/post/dto/PostDetailResponse.java +++ b/src/main/java/wanted/media/post/dto/PostDetailResponse.java @@ -11,7 +11,7 @@ public record PostDetailResponse( String postId, Type type, String title, - String post, + String content, String hashtags, Long likeCount, Long viewCount, diff --git a/src/test/java/wanted/media/post/service/PostServiceTest.java b/src/test/java/wanted/media/post/service/PostServiceTest.java index 018e1ce..ea8295a 100644 --- a/src/test/java/wanted/media/post/service/PostServiceTest.java +++ b/src/test/java/wanted/media/post/service/PostServiceTest.java @@ -43,7 +43,7 @@ void getPostTest() { .id("qwer") .type(Type.TWITTER) .title("제목 입력") - .post("내용 입력") + .content("내용 입력") .user(user) .viewCount(100L) .build(); @@ -55,7 +55,7 @@ void getPostTest() { // then assertThat(getData.getTitle()).isEqualTo("제목 입력"); - assertThat(getData.getPost()).isEqualTo("내용 입력"); + assertThat(getData.getContent()).isEqualTo("내용 입력"); assertThat(getData.getViewCount()).isEqualTo(101); assertThat(getData.getUser().getAccount()).isEqualTo("sun"); assertThat(getData.getUser().getEmail()).isEqualTo("sun@gmail.com"); From 6fb0355ade352c5de579db110720f8ff8b481fc6 Mon Sep 17 00:00:00 2001 From: ssunnykku <108388578+ssunnykku@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:59:25 +0900 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20conflict=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/wanted/media/post/domain/Post.java | 22 ++++--------------- .../media/user/config/SecurityConfig.java | 6 ----- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/main/java/wanted/media/post/domain/Post.java b/src/main/java/wanted/media/post/domain/Post.java index 10eb3a8..617544b 100644 --- a/src/main/java/wanted/media/post/domain/Post.java +++ b/src/main/java/wanted/media/post/domain/Post.java @@ -1,30 +1,16 @@ package wanted.media.post.domain; import jakarta.persistence.*; -import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.*; -import java.time.LocalDateTime; import org.hibernate.annotations.ColumnDefault; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.EntityListeners; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.FetchType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; -import jakarta.validation.constraints.Size; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; import wanted.media.user.domain.User; +import java.time.LocalDateTime; + @Entity @Getter @Table(name = "posts") @@ -54,7 +40,7 @@ public class Post { @ColumnDefault("0") private Long viewCount; - @ColumnDefault("0" + @ColumnDefault("0") private Long shareCount; @LastModifiedDate @@ -62,7 +48,7 @@ public class Post { @CreatedDate private LocalDateTime createdAt; - + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) private User user; diff --git a/src/main/java/wanted/media/user/config/SecurityConfig.java b/src/main/java/wanted/media/user/config/SecurityConfig.java index 5eb93c1..320ed5b 100644 --- a/src/main/java/wanted/media/user/config/SecurityConfig.java +++ b/src/main/java/wanted/media/user/config/SecurityConfig.java @@ -1,19 +1,13 @@ package wanted.media.user.config; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.security.servlet.PathRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; -import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @EnableWebSecurity @Configuration public class SecurityConfig { - // 비밀번호 암호화 기능 @Bean public BCryptPasswordEncoder passwordEncoder() {