diff --git a/src/main/java/com/example/demo/PersistenceDateConverter.java b/src/main/java/com/example/demo/PersistenceDateConverter.java index 123d596..fac6233 100644 --- a/src/main/java/com/example/demo/PersistenceDateConverter.java +++ b/src/main/java/com/example/demo/PersistenceDateConverter.java @@ -1,2 +1,22 @@ -package com.example.demo;public class PersistenceDateConverter { +package com.example.demo; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +import java.sql.Date; +import java.time.*; + + +//@Converter(autoApply = true) +public class PersistenceDateConverter implements AttributeConverter { + + @Override + public Date convertToDatabaseColumn(LocalDateTime attribute) { + return Date.valueOf(attribute.toLocalDate()); + } + + @Override + public LocalDateTime convertToEntityAttribute(Date dbData) { + return dbData.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); + } } diff --git a/src/main/java/com/example/demo/controller/PostController.java b/src/main/java/com/example/demo/controller/PostController.java index fc82b87..bb35ac1 100644 --- a/src/main/java/com/example/demo/controller/PostController.java +++ b/src/main/java/com/example/demo/controller/PostController.java @@ -1,5 +1,7 @@ package com.example.demo.controller; +import com.example.demo.domain.Post; +import com.example.demo.dto.AllPostResponseDto; import com.example.demo.dto.PostModifyRequestDto; import com.example.demo.dto.PostSaveRequestDto; import com.example.demo.dto.PostResponseDto; @@ -9,30 +11,55 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.List; +import java.util.stream.Collectors; + @RestController @RequestMapping("/post") @RequiredArgsConstructor public class PostController { private final PostService postService; - @GetMapping() + @GetMapping public PostResponseDto getPostById(@RequestParam Long postId) { return postService.getPostById(postId); } - @PostMapping() + @GetMapping("/all") + public AllPostResponseDto getAllPosts() { + List postList = postService.getAllPosts(); + List responseDtos = postList.stream().map(PostResponseDto::new) + .collect(Collectors.toList()); + return new AllPostResponseDto(responseDtos); + } + + @PostMapping ResponseEntity savePost(@RequestBody PostSaveRequestDto postSaveRequestDto) { - Long id = postService.savePost(postSaveRequestDto.getWriter(), postSaveRequestDto.getInfo()); + Long id = postService.savePost(postSaveRequestDto.getWriter(), postSaveRequestDto.getInfo() + ,postSaveRequestDto.getTag()); return new ResponseEntity(id, HttpStatus.OK); } - @PatchMapping() + @PatchMapping ResponseEntity modifyPost(@RequestBody PostModifyRequestDto postRequestDto) { - Long id = postService.modifyPost(postRequestDto.getPostId(), postRequestDto.getInfo()); + Long id = postService.modifyPost(postRequestDto.getPostId(), postRequestDto.getInfo() + ,postRequestDto.getTag()); return new ResponseEntity(id, HttpStatus.OK); } - @DeleteMapping() + @PatchMapping("/like") + ResponseEntity likePost(@RequestParam Long postId) { + Long id = postService.likePost(postId); + return new ResponseEntity<>(id, HttpStatus.OK); + } + + @PatchMapping("/unlike") + ResponseEntity unlikePost(@RequestParam Long postId) { + Long id = postService.unlikePost(postId); + return new ResponseEntity<>(id, HttpStatus.OK); + } + + @DeleteMapping ResponseEntity deletePost(@RequestParam Long postId) { Long id = postService.deletePost(postId); return new ResponseEntity(id, HttpStatus.OK); diff --git a/src/main/java/com/example/demo/domain/Post.java b/src/main/java/com/example/demo/domain/Post.java index a638ea8..be7e39a 100644 --- a/src/main/java/com/example/demo/domain/Post.java +++ b/src/main/java/com/example/demo/domain/Post.java @@ -2,25 +2,62 @@ import com.example.demo.util.BaseTimeEntity; import jakarta.persistence.*; +import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -@Entity -@NoArgsConstructor @Getter +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Post extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private String info; private String writer; + private Long likeCnt; + private Long viewCnt; + private String tag; - public Post(String info, String writer) { + private Post(String info, String writer) { this.info = info; this.writer = writer; + this.tag = ""; + this.likeCnt = Long.valueOf(0); + this.viewCnt = Long.valueOf(0); + } + + private Post(String info, String writer, String tag) { + this.info = info; + this.writer = writer; + this.tag = tag; + this.likeCnt = Long.valueOf(0); + this.viewCnt = Long.valueOf(0); + } + + public static Post createPostWithoutTag(String info, String writer) { + return new Post(info, writer); + } + + public static Post createPost(String info, String writer, String tag) { + return new Post(info, writer, tag); + } + + public void addLike() { + this.likeCnt++; + } + + public void cancelLike() { + if (this.likeCnt > 0) + this.likeCnt--; + } + + public void addViewCount() { + this.viewCnt++; } - public void modifyPost(String info) { + public void modifyPost(String info, String tag) { this.info = info; + if (tag != null) + this.tag = tag; } } diff --git a/src/main/java/com/example/demo/dto/AllPostResponseDto.java b/src/main/java/com/example/demo/dto/AllPostResponseDto.java new file mode 100644 index 0000000..ddb869d --- /dev/null +++ b/src/main/java/com/example/demo/dto/AllPostResponseDto.java @@ -0,0 +1,18 @@ +package com.example.demo.dto; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@NoArgsConstructor +@Getter +public class AllPostResponseDto { + private List dataList; + private Long postCnt; + + public AllPostResponseDto (List dataList) { + this.dataList = dataList; + this.postCnt = Long.valueOf(dataList.size()); + } +} diff --git a/src/main/java/com/example/demo/dto/PostModifyRequestDto.java b/src/main/java/com/example/demo/dto/PostModifyRequestDto.java index ab76d5b..eca810b 100644 --- a/src/main/java/com/example/demo/dto/PostModifyRequestDto.java +++ b/src/main/java/com/example/demo/dto/PostModifyRequestDto.java @@ -11,4 +11,5 @@ public class PostModifyRequestDto { private Long postId; private String info; + private String tag; } diff --git a/src/main/java/com/example/demo/dto/PostResponseDto.java b/src/main/java/com/example/demo/dto/PostResponseDto.java index 81e9274..4cafedc 100644 --- a/src/main/java/com/example/demo/dto/PostResponseDto.java +++ b/src/main/java/com/example/demo/dto/PostResponseDto.java @@ -16,12 +16,18 @@ public class PostResponseDto { private String info; private LocalDateTime createdDate; private LocalDateTime modifiedDate; + private Long likeCnt; + private Long viewCnt; + private String tag; public PostResponseDto(Post post) { this.writer = post.getWriter(); this.info = post.getInfo(); this.createdDate = post.getCreatedDate(); this.modifiedDate = post.getModifiedDate(); + this.likeCnt = post.getLikeCnt(); + this.viewCnt = post.getViewCnt(); + this.tag = post.getTag(); } @Override diff --git a/src/main/java/com/example/demo/dto/PostSaveRequestDto.java b/src/main/java/com/example/demo/dto/PostSaveRequestDto.java index 7f696f0..e332d4a 100644 --- a/src/main/java/com/example/demo/dto/PostSaveRequestDto.java +++ b/src/main/java/com/example/demo/dto/PostSaveRequestDto.java @@ -1,5 +1,6 @@ package com.example.demo.dto; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -7,7 +8,9 @@ @NoArgsConstructor @Setter @Getter +@AllArgsConstructor public class PostSaveRequestDto { private String writer; private String info; + private String tag; } diff --git a/src/main/java/com/example/demo/service/PostService.java b/src/main/java/com/example/demo/service/PostService.java index f2ccd53..e32efea 100644 --- a/src/main/java/com/example/demo/service/PostService.java +++ b/src/main/java/com/example/demo/service/PostService.java @@ -3,10 +3,12 @@ import com.example.demo.domain.Post; import com.example.demo.dto.PostResponseDto; import com.example.demo.repository.PostRepository; +import jakarta.persistence.EntityManager; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.Optional; @Service @@ -14,23 +16,28 @@ @Transactional public class PostService { private final PostRepository postRepository; - @Transactional(readOnly = true) + public PostResponseDto getPostById(Long postId) { Optional opPost = postRepository.findById(postId); Post findedPost = opPost.orElseThrow(RuntimeException::new); + findedPost.addViewCount(); //get 메서드에서 조회수 증가시키는 로직 안좋은 것 같음..,, return new PostResponseDto(findedPost); } - public Long savePost(String writer, String info) { - Post post = new Post(info, writer); - postRepository.save(new Post(info, writer)); + public Long savePost(String writer, String info, String tag) { + Post post; + if (tag == null) + post = Post.createPostWithoutTag(writer, info); + else + post = Post.createPost(writer, info, tag); + postRepository.save(post); return post.getId(); } - public Long modifyPost(Long postId, String info) { + public Long modifyPost(Long postId, String info, String tag) { Optional opPost = postRepository.findById(postId); Post findedPost = opPost.orElseThrow(RuntimeException::new); - findedPost.modifyPost(info); + findedPost.modifyPost(info, tag); return findedPost.getId(); } @@ -38,4 +45,22 @@ public Long deletePost(Long postId) { postRepository.deleteById(postId); return postId; } + + public List getAllPosts() { + return postRepository.findAll(); + } + + public Long likePost(Long postId) { + Post post = postRepository.findById(postId) + .orElseThrow(RuntimeException::new); + post.addLike(); + return post.getId(); + } + + public Long unlikePost(Long postId) { + Post post = postRepository.findById(postId) + .orElseThrow(RuntimeException::new); + post.cancelLike(); + return post.getId(); + } } diff --git a/src/test/java/com/example/demo/api/PostControllerTest.java b/src/test/java/com/example/demo/api/PostControllerTest.java new file mode 100644 index 0000000..4c27fb0 --- /dev/null +++ b/src/test/java/com/example/demo/api/PostControllerTest.java @@ -0,0 +1,56 @@ +package com.example.demo.api; + +import com.example.demo.domain.Post; +import com.example.demo.dto.PostResponseDto; +import com.example.demo.dto.PostSaveRequestDto; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.PersistenceUnit; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; + +import static org.assertj.core.api.Assertions.*; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@Transactional +public class PostControllerTest { + + @LocalServerPort + private int port; + @Autowired + private TestRestTemplate restTemplate; + @PersistenceUnit + EntityManagerFactory emf; + EntityManager em; + + @Test + public void savePostTest() { + PostSaveRequestDto postRequest = new PostSaveRequestDto("hyunkyu", "info", "tag"); + + String url = "http://localhost:" + port + "/post"; + ResponseEntity responseEntity = restTemplate.postForEntity(url, postRequest, Long.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + @Transactional + public void getPostTest(){ + em = emf.createEntityManager(); + EntityTransaction entityTransaction = em.getTransaction(); + Post post = Post.createPost("content", "hyunkyu", "tag"); + em.persist(post); + + String url = "http://localhost:" + port + "/post?postId=" + post.getId(); + ResponseEntity responseEntity = restTemplate.getForEntity(url, PostResponseDto.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(responseEntity.getBody().getInfo()).isEqualTo("content"); + } +}