From 3608bfe9c9fc225a9ea44fb911786dc80ac29743 Mon Sep 17 00:00:00 2001 From: luckhee Date: Fri, 19 Sep 2025 11:25:33 +0900 Subject: [PATCH 1/5] =?UTF-8?q?=20=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +++ .../controller/InformationPostController.java | 29 +++++++++++++++++++ .../back/domain/Post/dto/PostAllResponse.java | 26 +++++++++++++++++ .../com/back/domain/Post/entity/Post.java | 25 ++++++++++++++++ .../Post/repository/PostRepository.java | 11 +++++++ .../com/back/domain/Post/rq/ApiResponse.java | 12 ++++++++ .../back/domain/Post/service/PostService.java | 27 +++++++++++++++++ .../java/com/back/global/jpa/BaseEntity.java | 2 +- 8 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 back/src/main/java/com/back/domain/Post/controller/InformationPostController.java create mode 100644 back/src/main/java/com/back/domain/Post/dto/PostAllResponse.java create mode 100644 back/src/main/java/com/back/domain/Post/entity/Post.java create mode 100644 back/src/main/java/com/back/domain/Post/repository/PostRepository.java create mode 100644 back/src/main/java/com/back/domain/Post/rq/ApiResponse.java create mode 100644 back/src/main/java/com/back/domain/Post/service/PostService.java diff --git a/.gitignore b/.gitignore index d1be1544..9251e929 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,8 @@ CLAUDE.md db_dev.mv.db db_dev.trace.db + cookies.txt + +.DS_Store + diff --git a/back/src/main/java/com/back/domain/Post/controller/InformationPostController.java b/back/src/main/java/com/back/domain/Post/controller/InformationPostController.java new file mode 100644 index 00000000..74f8980b --- /dev/null +++ b/back/src/main/java/com/back/domain/Post/controller/InformationPostController.java @@ -0,0 +1,29 @@ +package com.back.domain.Post.controller; + +import com.back.domain.Post.dto.PostAllResponse; +import com.back.domain.Post.rq.ApiResponse; +import com.back.domain.Post.service.PostService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("post/infor") +@RequiredArgsConstructor +public class InformationPostController { + private final PostService postService; + + + + @GetMapping + public ResponseEntity>> getAllPost() { + List posts = postService.getAllPosts(); + ApiResponse> response = new ApiResponse<>("게시글 조회 성공", posts); + return ResponseEntity.ok(response); + } + +} diff --git a/back/src/main/java/com/back/domain/Post/dto/PostAllResponse.java b/back/src/main/java/com/back/domain/Post/dto/PostAllResponse.java new file mode 100644 index 00000000..f2e64121 --- /dev/null +++ b/back/src/main/java/com/back/domain/Post/dto/PostAllResponse.java @@ -0,0 +1,26 @@ +package com.back.domain.Post.dto; + +import com.back.domain.Post.entity.Post; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class PostAllResponse { + private Long id; + private String title; + private String authorName; + private LocalDateTime createdAt; + private int viewCount; + private int like; + + public PostAllResponse(Post post) { + this.id = post.getId(); + this.title = post.getTitle(); + this.authorName = post.getAuthorName(); + this.createdAt = post.getCreateDate(); + this.viewCount = post.getViewCount(); + this.like = post.getLiked(); + } + +} diff --git a/back/src/main/java/com/back/domain/Post/entity/Post.java b/back/src/main/java/com/back/domain/Post/entity/Post.java new file mode 100644 index 00000000..94f823d3 --- /dev/null +++ b/back/src/main/java/com/back/domain/Post/entity/Post.java @@ -0,0 +1,25 @@ +package com.back.domain.Post.entity; + +import com.back.global.jpa.BaseEntity; +import jakarta.persistence.Entity; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@NoArgsConstructor +@Getter +@Setter +public class Post extends BaseEntity { + private String title; + private String content; + private String authorName; + + private enum postType { + informationPost, practicePost, questionPost + } + + private int viewCount; + + private int liked; +} diff --git a/back/src/main/java/com/back/domain/Post/repository/PostRepository.java b/back/src/main/java/com/back/domain/Post/repository/PostRepository.java new file mode 100644 index 00000000..80cf5c09 --- /dev/null +++ b/back/src/main/java/com/back/domain/Post/repository/PostRepository.java @@ -0,0 +1,11 @@ +package com.back.domain.Post.repository; + +import com.back.domain.Post.entity.Post; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface PostRepository extends JpaRepository { + + void getAllPosts(); +} diff --git a/back/src/main/java/com/back/domain/Post/rq/ApiResponse.java b/back/src/main/java/com/back/domain/Post/rq/ApiResponse.java new file mode 100644 index 00000000..e1f62087 --- /dev/null +++ b/back/src/main/java/com/back/domain/Post/rq/ApiResponse.java @@ -0,0 +1,12 @@ +package com.back.domain.Post.rq; + +public class ApiResponse { + private String message; + private T data; + + + public ApiResponse(String message, T data) { + this.message= message; + this.data = data; + } +} diff --git a/back/src/main/java/com/back/domain/Post/service/PostService.java b/back/src/main/java/com/back/domain/Post/service/PostService.java new file mode 100644 index 00000000..3f58f69c --- /dev/null +++ b/back/src/main/java/com/back/domain/Post/service/PostService.java @@ -0,0 +1,27 @@ +package com.back.domain.Post.service; + +import com.back.domain.Post.dto.PostAllResponse; +import com.back.domain.Post.entity.Post; +import com.back.domain.Post.repository.PostRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class PostService { + + private final PostRepository postRepository; + + public List getAllPosts() { + List posts = postRepository.findAll(); + + return posts.stream() + .map(PostAllResponse::new) + .collect(Collectors.toList()); + } + + +} diff --git a/back/src/main/java/com/back/global/jpa/BaseEntity.java b/back/src/main/java/com/back/global/jpa/BaseEntity.java index eb21883d..f7b35e6e 100644 --- a/back/src/main/java/com/back/global/jpa/BaseEntity.java +++ b/back/src/main/java/com/back/global/jpa/BaseEntity.java @@ -43,4 +43,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(id); } -} \ No newline at end of file +} From 847d70ab26901141d1af52d7ba9de293cc453536 Mon Sep 17 00:00:00 2001 From: luckhee Date: Fri, 19 Sep 2025 16:03:33 +0900 Subject: [PATCH 2/5] =?UTF-8?q?=20@Currentuser=20=EC=BB=A4=EC=8A=A4?= =?UTF-8?q?=ED=85=80=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/InformationPostController.java | 29 --------- .../back/domain/Post/service/PostService.java | 27 -------- .../member/repository/MemberRepository.java | 2 +- .../controller/InformationPostController.java | 45 +++++++++++++ .../{Post => post}/dto/PostAllResponse.java | 4 +- .../domain/post/dto/PostCreateRequest.java | 12 ++++ .../domain/post/dto/PostCreateResponse.java | 17 +++++ .../domain/{Post => post}/entity/Post.java | 14 ++++- .../back/domain/post/entity/PracticePost.java | 11 ++++ .../back/domain/post/entity/QuestionPost.java | 8 +++ .../repository/PostRepository.java | 6 +- .../domain/{Post => post}/rq/ApiResponse.java | 5 +- .../back/domain/post/service/PostService.java | 60 ++++++++++++++++++ .../com/back/global/auth/CurrentUser.java | 11 ++++ .../auth/CurrentUserArgumentResolver.java | 61 ++++++++++++++++++ .../com/back/global/config/WebConfig.java | 21 +++++++ back/src/main/java/com/back/global/rq/Rq.java | 2 +- .../security/CustomAuthenticationFilter.java | 2 +- .../back/global/security/SecurityConfig.java | 3 +- .../back/global/security/SecurityUser.java | 2 +- .../InformationPostControllerTest.java | 63 +++++++++++++++++++ 21 files changed, 334 insertions(+), 71 deletions(-) delete mode 100644 back/src/main/java/com/back/domain/Post/controller/InformationPostController.java delete mode 100644 back/src/main/java/com/back/domain/Post/service/PostService.java create mode 100644 back/src/main/java/com/back/domain/post/controller/InformationPostController.java rename back/src/main/java/com/back/domain/{Post => post}/dto/PostAllResponse.java (88%) create mode 100644 back/src/main/java/com/back/domain/post/dto/PostCreateRequest.java create mode 100644 back/src/main/java/com/back/domain/post/dto/PostCreateResponse.java rename back/src/main/java/com/back/domain/{Post => post}/entity/Post.java (57%) create mode 100644 back/src/main/java/com/back/domain/post/entity/PracticePost.java create mode 100644 back/src/main/java/com/back/domain/post/entity/QuestionPost.java rename back/src/main/java/com/back/domain/{Post => post}/repository/PostRepository.java (64%) rename back/src/main/java/com/back/domain/{Post => post}/rq/ApiResponse.java (75%) create mode 100644 back/src/main/java/com/back/domain/post/service/PostService.java create mode 100644 back/src/main/java/com/back/global/auth/CurrentUser.java create mode 100644 back/src/main/java/com/back/global/auth/CurrentUserArgumentResolver.java create mode 100644 back/src/main/java/com/back/global/config/WebConfig.java create mode 100644 back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java diff --git a/back/src/main/java/com/back/domain/Post/controller/InformationPostController.java b/back/src/main/java/com/back/domain/Post/controller/InformationPostController.java deleted file mode 100644 index 74f8980b..00000000 --- a/back/src/main/java/com/back/domain/Post/controller/InformationPostController.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.back.domain.Post.controller; - -import com.back.domain.Post.dto.PostAllResponse; -import com.back.domain.Post.rq.ApiResponse; -import com.back.domain.Post.service.PostService; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; - -@RestController -@RequestMapping("post/infor") -@RequiredArgsConstructor -public class InformationPostController { - private final PostService postService; - - - - @GetMapping - public ResponseEntity>> getAllPost() { - List posts = postService.getAllPosts(); - ApiResponse> response = new ApiResponse<>("게시글 조회 성공", posts); - return ResponseEntity.ok(response); - } - -} diff --git a/back/src/main/java/com/back/domain/Post/service/PostService.java b/back/src/main/java/com/back/domain/Post/service/PostService.java deleted file mode 100644 index 3f58f69c..00000000 --- a/back/src/main/java/com/back/domain/Post/service/PostService.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.back.domain.Post.service; - -import com.back.domain.Post.dto.PostAllResponse; -import com.back.domain.Post.entity.Post; -import com.back.domain.Post.repository.PostRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -import java.util.List; -import java.util.stream.Collectors; - -@Service -@RequiredArgsConstructor -public class PostService { - - private final PostRepository postRepository; - - public List getAllPosts() { - List posts = postRepository.findAll(); - - return posts.stream() - .map(PostAllResponse::new) - .collect(Collectors.toList()); - } - - -} diff --git a/back/src/main/java/com/back/domain/member/member/repository/MemberRepository.java b/back/src/main/java/com/back/domain/member/member/repository/MemberRepository.java index ece6c652..dc00e93f 100644 --- a/back/src/main/java/com/back/domain/member/member/repository/MemberRepository.java +++ b/back/src/main/java/com/back/domain/member/member/repository/MemberRepository.java @@ -5,7 +5,7 @@ import java.util.Optional; -public interface MemberRepository extends JpaRepository { +public interface MemberRepository extends JpaRepository { Optional findByEmail(String email); } diff --git a/back/src/main/java/com/back/domain/post/controller/InformationPostController.java b/back/src/main/java/com/back/domain/post/controller/InformationPostController.java new file mode 100644 index 00000000..0de7fac9 --- /dev/null +++ b/back/src/main/java/com/back/domain/post/controller/InformationPostController.java @@ -0,0 +1,45 @@ +package com.back.domain.post.controller; + +import com.back.domain.member.member.entity.Member; +import com.back.domain.post.dto.PostAllResponse; +import com.back.domain.post.dto.PostCreateRequest; +import com.back.domain.post.dto.PostCreateResponse; +import com.back.domain.post.entity.Post; +import com.back.domain.post.rq.ApiResponse; +import com.back.domain.post.service.PostService; +import com.back.global.auth.CurrentUser; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("post/infor") +@RequiredArgsConstructor +public class InformationPostController { + private final PostService postService; + + + @Operation(summary = "게시글 생성") + @PostMapping + public ResponseEntity> createPost( + @RequestBody PostCreateRequest postCreateRequest, + @CurrentUser Member member + ) { + String authorName = member.getName(); + Post post = postService.createPost(postCreateRequest, authorName); + PostCreateResponse postCreateResponse = PostCreateResponse.from(post); + ApiResponse response = new ApiResponse<>("게시글이 성공적으로 생성되었습니다. " , postCreateResponse); + return ResponseEntity.ok(response); + } + + @Operation(summary = "게시글 다건 조회") + @GetMapping + public ResponseEntity>> getAllPost() { + List posts = postService.getAllPosts(); + ApiResponse> response = new ApiResponse<>("게시글 조회 성공", posts); + return ResponseEntity.ok(response); + } +} diff --git a/back/src/main/java/com/back/domain/Post/dto/PostAllResponse.java b/back/src/main/java/com/back/domain/post/dto/PostAllResponse.java similarity index 88% rename from back/src/main/java/com/back/domain/Post/dto/PostAllResponse.java rename to back/src/main/java/com/back/domain/post/dto/PostAllResponse.java index f2e64121..7760b45e 100644 --- a/back/src/main/java/com/back/domain/Post/dto/PostAllResponse.java +++ b/back/src/main/java/com/back/domain/post/dto/PostAllResponse.java @@ -1,6 +1,6 @@ -package com.back.domain.Post.dto; +package com.back.domain.post.dto; -import com.back.domain.Post.entity.Post; +import com.back.domain.post.entity.Post; import lombok.Data; import java.time.LocalDateTime; diff --git a/back/src/main/java/com/back/domain/post/dto/PostCreateRequest.java b/back/src/main/java/com/back/domain/post/dto/PostCreateRequest.java new file mode 100644 index 00000000..84684fd6 --- /dev/null +++ b/back/src/main/java/com/back/domain/post/dto/PostCreateRequest.java @@ -0,0 +1,12 @@ +package com.back.domain.post.dto; + +import lombok.Data; + +@Data +public class PostCreateRequest { + private Long memberId; + private String postType; + private String title; + private String content; + +} diff --git a/back/src/main/java/com/back/domain/post/dto/PostCreateResponse.java b/back/src/main/java/com/back/domain/post/dto/PostCreateResponse.java new file mode 100644 index 00000000..c3b5505b --- /dev/null +++ b/back/src/main/java/com/back/domain/post/dto/PostCreateResponse.java @@ -0,0 +1,17 @@ +package com.back.domain.post.dto; + +import com.back.domain.post.entity.Post; +import lombok.Data; + +@Data +public class PostCreateResponse { + private Long postId; + private String title; + + public static PostCreateResponse from(Post post) { + PostCreateResponse response = new PostCreateResponse(); + response.setPostId(post.getId()); + response.setTitle(post.getTitle()); + return response; + } +} diff --git a/back/src/main/java/com/back/domain/Post/entity/Post.java b/back/src/main/java/com/back/domain/post/entity/Post.java similarity index 57% rename from back/src/main/java/com/back/domain/Post/entity/Post.java rename to back/src/main/java/com/back/domain/post/entity/Post.java index 94f823d3..ff6f1367 100644 --- a/back/src/main/java/com/back/domain/Post/entity/Post.java +++ b/back/src/main/java/com/back/domain/post/entity/Post.java @@ -1,7 +1,9 @@ -package com.back.domain.Post.entity; +package com.back.domain.post.entity; import com.back.global.jpa.BaseEntity; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -15,11 +17,17 @@ public class Post extends BaseEntity { private String content; private String authorName; - private enum postType { - informationPost, practicePost, questionPost + @Enumerated(EnumType.STRING) + private PostType postType; + + public enum PostType { + INFORMATION_POST, + PRACTICE_POST, + QUESTION_POST } private int viewCount; private int liked; + } diff --git a/back/src/main/java/com/back/domain/post/entity/PracticePost.java b/back/src/main/java/com/back/domain/post/entity/PracticePost.java new file mode 100644 index 00000000..6c9940a6 --- /dev/null +++ b/back/src/main/java/com/back/domain/post/entity/PracticePost.java @@ -0,0 +1,11 @@ +package com.back.domain.post.entity; + +import jakarta.persistence.Entity; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor +public class PracticePost extends Post{ + private Boolean isMento; + private String carrer; +} diff --git a/back/src/main/java/com/back/domain/post/entity/QuestionPost.java b/back/src/main/java/com/back/domain/post/entity/QuestionPost.java new file mode 100644 index 00000000..5a9c49f8 --- /dev/null +++ b/back/src/main/java/com/back/domain/post/entity/QuestionPost.java @@ -0,0 +1,8 @@ +package com.back.domain.post.entity; + +import jakarta.persistence.Entity; + +@Entity +public class QuestionPost extends Post{ + private Boolean isResolve; +} diff --git a/back/src/main/java/com/back/domain/Post/repository/PostRepository.java b/back/src/main/java/com/back/domain/post/repository/PostRepository.java similarity index 64% rename from back/src/main/java/com/back/domain/Post/repository/PostRepository.java rename to back/src/main/java/com/back/domain/post/repository/PostRepository.java index 80cf5c09..628d0fa8 100644 --- a/back/src/main/java/com/back/domain/Post/repository/PostRepository.java +++ b/back/src/main/java/com/back/domain/post/repository/PostRepository.java @@ -1,11 +1,9 @@ -package com.back.domain.Post.repository; +package com.back.domain.post.repository; -import com.back.domain.Post.entity.Post; +import com.back.domain.post.entity.Post; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface PostRepository extends JpaRepository { - - void getAllPosts(); } diff --git a/back/src/main/java/com/back/domain/Post/rq/ApiResponse.java b/back/src/main/java/com/back/domain/post/rq/ApiResponse.java similarity index 75% rename from back/src/main/java/com/back/domain/Post/rq/ApiResponse.java rename to back/src/main/java/com/back/domain/post/rq/ApiResponse.java index e1f62087..d999348b 100644 --- a/back/src/main/java/com/back/domain/Post/rq/ApiResponse.java +++ b/back/src/main/java/com/back/domain/post/rq/ApiResponse.java @@ -1,5 +1,8 @@ -package com.back.domain.Post.rq; +package com.back.domain.post.rq; +import lombok.Getter; + +@Getter public class ApiResponse { private String message; private T data; diff --git a/back/src/main/java/com/back/domain/post/service/PostService.java b/back/src/main/java/com/back/domain/post/service/PostService.java new file mode 100644 index 00000000..cfc34518 --- /dev/null +++ b/back/src/main/java/com/back/domain/post/service/PostService.java @@ -0,0 +1,60 @@ +package com.back.domain.post.service; + +import com.back.domain.post.dto.PostAllResponse; +import com.back.domain.post.dto.PostCreateRequest; +import com.back.domain.post.entity.Post; +import com.back.domain.post.repository.PostRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class PostService { + + private final PostRepository postRepository; + + public List getAllPosts() { + List posts = postRepository.findAll(); + + return posts.stream() + .map(PostAllResponse::new) + .collect(Collectors.toList()); + } + + + public Post createPost(PostCreateRequest postCreateRequest, String authorName) { + Post post = new Post(); + post.setTitle(postCreateRequest.getTitle()); + post.setContent(postCreateRequest.getContent()); + post.setAuthorName(authorName); + String postTypeStr = postCreateRequest.getPostType(); + Post.PostType postType; + + switch(postTypeStr) { + case "informationPost": + postType = Post.PostType.INFORMATION_POST; + break; + case "practicePost": + postType = Post.PostType.PRACTICE_POST; + break; + case "questionPost": + postType = Post.PostType.QUESTION_POST; + break; + default: + throw new IllegalArgumentException("Invalid post type: " + postTypeStr); + } + + post.setPostType(postType); + + postRepository.save(post); + + return post; + } + + public Post findByid(Long id) { + return postRepository.findById(id).get(); + } +} diff --git a/back/src/main/java/com/back/global/auth/CurrentUser.java b/back/src/main/java/com/back/global/auth/CurrentUser.java new file mode 100644 index 00000000..70888101 --- /dev/null +++ b/back/src/main/java/com/back/global/auth/CurrentUser.java @@ -0,0 +1,11 @@ +package com.back.global.auth; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface CurrentUser { +} diff --git a/back/src/main/java/com/back/global/auth/CurrentUserArgumentResolver.java b/back/src/main/java/com/back/global/auth/CurrentUserArgumentResolver.java new file mode 100644 index 00000000..d6d20700 --- /dev/null +++ b/back/src/main/java/com/back/global/auth/CurrentUserArgumentResolver.java @@ -0,0 +1,61 @@ +package com.back.global.auth; + +import com.back.domain.member.member.entity.Member; +import com.back.domain.member.member.repository.MemberRepository; +import com.back.global.security.SecurityUser; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.MethodParameter; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@Component +@RequiredArgsConstructor +@Slf4j +public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver { + private final MemberRepository memberRepository; + @Override + public boolean supportsParameter(MethodParameter parameter) { + // 여기에 구현 + return parameter.hasParameterAnnotation(CurrentUser.class) && parameter.getParameterType().equals(Member.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, + ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, + WebDataBinderFactory binderFactory) { + // 여기에 구현 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + log.info("Authentication: {}", authentication != null ? "존재" : "null"); + + if (authentication == null || !authentication.isAuthenticated()) { + // 인증되지 않은 사용자라면 예외 처리 + log.warn("인증 정보 없음"); + return null; + } + + log.info("Principal 타입: {}", authentication.getPrincipal().getClass().getSimpleName()); + + + SecurityUser securityUser = (SecurityUser) authentication.getPrincipal(); + + + Long memberId = securityUser.getId(); + log.info("Member ID: {}", memberId); + + + + Member member = memberRepository.findById(memberId).orElse(null); + + log.info("Member 조회 결과: {}", member != null ? "성공" : "실패"); + + + return member; + } +} diff --git a/back/src/main/java/com/back/global/config/WebConfig.java b/back/src/main/java/com/back/global/config/WebConfig.java new file mode 100644 index 00000000..a5eeab15 --- /dev/null +++ b/back/src/main/java/com/back/global/config/WebConfig.java @@ -0,0 +1,21 @@ +package com.back.global.config; + +import com.back.global.auth.CurrentUserArgumentResolver; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +@Configuration +@RequiredArgsConstructor +public class WebConfig implements WebMvcConfigurer { + + private final CurrentUserArgumentResolver currentUserArgumentResolver; + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(currentUserArgumentResolver); + } +} diff --git a/back/src/main/java/com/back/global/rq/Rq.java b/back/src/main/java/com/back/global/rq/Rq.java index 684745fb..a590c7ef 100644 --- a/back/src/main/java/com/back/global/rq/Rq.java +++ b/back/src/main/java/com/back/global/rq/Rq.java @@ -115,4 +115,4 @@ public void setHeader(String name, String value) { resp.setHeader(name, value); } } -} \ No newline at end of file +} diff --git a/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java b/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java index d56a8002..30a99319 100644 --- a/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java +++ b/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java @@ -122,4 +122,4 @@ private void work(HttpServletRequest request, HttpServletResponse response, Filt filterChain.doFilter(request, response); } -} \ No newline at end of file +} diff --git a/back/src/main/java/com/back/global/security/SecurityConfig.java b/back/src/main/java/com/back/global/security/SecurityConfig.java index 321ff8dd..be843799 100644 --- a/back/src/main/java/com/back/global/security/SecurityConfig.java +++ b/back/src/main/java/com/back/global/security/SecurityConfig.java @@ -28,6 +28,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers("/auth/**").permitAll() .requestMatchers("/actuator/**").permitAll() .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**").permitAll() + .requestMatchers("/post/infor").permitAll() .anyRequest().authenticated() ) .headers(headers -> headers @@ -59,4 +60,4 @@ public UrlBasedCorsConfigurationSource corsConfigurationSource() { return source; } -} \ No newline at end of file +} diff --git a/back/src/main/java/com/back/global/security/SecurityUser.java b/back/src/main/java/com/back/global/security/SecurityUser.java index 326860c8..5eeb8fd4 100644 --- a/back/src/main/java/com/back/global/security/SecurityUser.java +++ b/back/src/main/java/com/back/global/security/SecurityUser.java @@ -25,4 +25,4 @@ public SecurityUser( this.id = id; this.name = name; } -} \ No newline at end of file +} diff --git a/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java b/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java new file mode 100644 index 00000000..a6a7e178 --- /dev/null +++ b/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java @@ -0,0 +1,63 @@ +package com.back.domain.post.controller; + +import com.back.domain.post.entity.Post; +import com.back.domain.post.service.PostService; +import jakarta.transaction.Transactional; +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.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +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.*; + + +@ActiveProfiles("test") +@SpringBootTest +@AutoConfigureMockMvc +@Transactional +public class InformationPostControllerTest { + + @Autowired + private PostService postService; + + @Autowired + private MockMvc mvc; + + @Test + @DisplayName("게시글 생성") + void createPost() throws Exception { + ResultActions resultActions = mvc + .perform( + post("/post/infor") + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "memberId": 123, + "postType": "informationPost", + "title": "테스트 제목", + "content": "테스트 내용" + } + """.stripIndent()) + ) + .andDo(print()); + + // 실제 생성된 게시글 조회 (실제 DB에서) + Post createdPost = postService.findByid(1L); + + resultActions + .andExpect(handler().handlerType(InformationPostController.class)) + .andExpect(handler().methodName("createPost")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.message").value("게시글이 성공적으로 생성되었습니다. ")) + .andExpect(jsonPath("$.data").exists()) + .andExpect(jsonPath("$.data.postId").value(createdPost.getId())) + .andExpect(jsonPath("$.data.title").value(createdPost.getTitle())); + } +} From ee0383abf9b822b526fe41c82f8a471d399125a7 Mon Sep 17 00:00:00 2001 From: luckhee Date: Fri, 19 Sep 2025 23:47:35 +0900 Subject: [PATCH 3/5] =?UTF-8?q?log=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/.env.default | 2 +- .../java/com/back/domain/post/entity/Post.java | 6 +++--- .../back/domain/post/service/PostService.java | 12 ++++++------ .../auth/CurrentUserArgumentResolver.java | 7 ++----- .../security/CustomAuthenticationFilter.java | 7 ++++--- .../InformationPostControllerTest.java | 17 +++++++++++++++-- 6 files changed, 31 insertions(+), 20 deletions(-) diff --git a/back/.env.default b/back/.env.default index 47d2f175..da8cf60b 100644 --- a/back/.env.default +++ b/back/.env.default @@ -1 +1 @@ -CUSTOM__JWT__SECRET_KEY=NEED_TO_SET \ No newline at end of file +CUSTOM__JWT__SECRET_KEY=abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789 diff --git a/back/src/main/java/com/back/domain/post/entity/Post.java b/back/src/main/java/com/back/domain/post/entity/Post.java index ff6f1367..fa12a4c8 100644 --- a/back/src/main/java/com/back/domain/post/entity/Post.java +++ b/back/src/main/java/com/back/domain/post/entity/Post.java @@ -21,9 +21,9 @@ public class Post extends BaseEntity { private PostType postType; public enum PostType { - INFORMATION_POST, - PRACTICE_POST, - QUESTION_POST + INFORMATIONPOST, + PRACTICEPOST, + QUESTIONPOST } private int viewCount; diff --git a/back/src/main/java/com/back/domain/post/service/PostService.java b/back/src/main/java/com/back/domain/post/service/PostService.java index cfc34518..74c1d50a 100644 --- a/back/src/main/java/com/back/domain/post/service/PostService.java +++ b/back/src/main/java/com/back/domain/post/service/PostService.java @@ -34,14 +34,14 @@ public Post createPost(PostCreateRequest postCreateRequest, String authorName) { Post.PostType postType; switch(postTypeStr) { - case "informationPost": - postType = Post.PostType.INFORMATION_POST; + case "INFORMATIONPOST": + postType = Post.PostType.INFORMATIONPOST; break; - case "practicePost": - postType = Post.PostType.PRACTICE_POST; + case "PRACTICEPOST": + postType = Post.PostType.PRACTICEPOST; break; - case "questionPost": - postType = Post.PostType.QUESTION_POST; + case "QUESTIONPOST": + postType = Post.PostType.QUESTIONPOST; break; default: throw new IllegalArgumentException("Invalid post type: " + postTypeStr); diff --git a/back/src/main/java/com/back/global/auth/CurrentUserArgumentResolver.java b/back/src/main/java/com/back/global/auth/CurrentUserArgumentResolver.java index d6d20700..0c42b611 100644 --- a/back/src/main/java/com/back/global/auth/CurrentUserArgumentResolver.java +++ b/back/src/main/java/com/back/global/auth/CurrentUserArgumentResolver.java @@ -39,20 +39,17 @@ public Object resolveArgument(MethodParameter parameter, log.warn("인증 정보 없음"); return null; } - + Object principal = authentication.getPrincipal(); log.info("Principal 타입: {}", authentication.getPrincipal().getClass().getSimpleName()); - + log.info("Principal 값: {}", principal); SecurityUser securityUser = (SecurityUser) authentication.getPrincipal(); - - Long memberId = securityUser.getId(); log.info("Member ID: {}", memberId); Member member = memberRepository.findById(memberId).orElse(null); - log.info("Member 조회 결과: {}", member != null ? "성공" : "실패"); diff --git a/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java b/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java index 30a99319..a0a373bc 100644 --- a/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java +++ b/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java @@ -11,6 +11,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -22,7 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; - +@Slf4j @Component @RequiredArgsConstructor public class CustomAuthenticationFilter extends OncePerRequestFilter { @@ -36,6 +37,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse try { work(request, response, filterChain); } catch (Exception e) { + log.error("CustomAuthenticationFilter에서 예외 발생: ", e); RsData rsData = new RsData<>("401-1", "인증 오류가 발생했습니다."); response.setContentType("application/json;charset=UTF-8"); response.setStatus(rsData.statusCode()); @@ -47,7 +49,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse private void work(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 인증이 필요없는 API 요청이라면 패스 - if (List.of("/auth/login", "/auth/signup", "auth/refresh", "/h2-console").contains(request.getRequestURI()) || + if (List.of("/auth/login", "/auth/signup", "/auth/refresh", "/h2-console").contains(request.getRequestURI()) || request.getRequestURI().startsWith("/h2-console/") || request.getRequestURI().startsWith("/swagger-ui/") || request.getRequestURI().startsWith("/v3/api-docs/") || @@ -56,7 +58,6 @@ private void work(HttpServletRequest request, HttpServletResponse response, Filt return; } - // 쿠키에서 토큰 추출 String accessToken = rq.getCookieValue("accessToken", ""); if (accessToken.isBlank()) { diff --git a/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java b/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java index a6a7e178..80f84fe5 100644 --- a/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java +++ b/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java @@ -1,8 +1,11 @@ package com.back.domain.post.controller; +import com.back.domain.member.member.entity.Member; +import com.back.domain.member.member.service.MemberService; import com.back.domain.post.entity.Post; import com.back.domain.post.service.PostService; import jakarta.transaction.Transactional; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -27,9 +30,17 @@ public class InformationPostControllerTest { @Autowired private PostService postService; + @Autowired + private MemberService memberService; + @Autowired private MockMvc mvc; + @BeforeEach + void setUp() { + memberService.join("user1", "사용자1", "password123", Member.Role.MENTEE); + } + @Test @DisplayName("게시글 생성") void createPost() throws Exception { @@ -39,8 +50,8 @@ void createPost() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(""" { - "memberId": 123, - "postType": "informationPost", + "memberId": 1, + "postType": "INFORMATIONPOST", "title": "테스트 제목", "content": "테스트 내용" } @@ -48,6 +59,8 @@ void createPost() throws Exception { ) .andDo(print()); + Member member = new Member(); + // 실제 생성된 게시글 조회 (실제 DB에서) Post createdPost = postService.findByid(1L); From c8a703c36851f1885b848b594b89c691c8f8170d Mon Sep 17 00:00:00 2001 From: luckhee Date: Mon, 22 Sep 2025 09:52:34 +0900 Subject: [PATCH 4/5] =?UTF-8?q?postType=20=EC=97=90=EB=9F=AC=20TC=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../back/domain/post/service/PostService.java | 3 +- .../security/CustomAuthenticationFilter.java | 1 - .../back/global/security/SecurityConfig.java | 1 - .../InformationPostControllerTest.java | 56 +++++++++++++++++-- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/back/src/main/java/com/back/domain/post/service/PostService.java b/back/src/main/java/com/back/domain/post/service/PostService.java index 74c1d50a..c2071c5b 100644 --- a/back/src/main/java/com/back/domain/post/service/PostService.java +++ b/back/src/main/java/com/back/domain/post/service/PostService.java @@ -4,6 +4,7 @@ import com.back.domain.post.dto.PostCreateRequest; import com.back.domain.post.entity.Post; import com.back.domain.post.repository.PostRepository; +import com.back.global.exception.ServiceException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -44,7 +45,7 @@ public Post createPost(PostCreateRequest postCreateRequest, String authorName) { postType = Post.PostType.QUESTIONPOST; break; default: - throw new IllegalArgumentException("Invalid post type: " + postTypeStr); + throw new ServiceException("400-2", "유효하지 않은 PostType입니다."); } post.setPostType(postType); diff --git a/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java b/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java index a0a373bc..df065fb6 100644 --- a/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java +++ b/back/src/main/java/com/back/global/security/CustomAuthenticationFilter.java @@ -37,7 +37,6 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse try { work(request, response, filterChain); } catch (Exception e) { - log.error("CustomAuthenticationFilter에서 예외 발생: ", e); RsData rsData = new RsData<>("401-1", "인증 오류가 발생했습니다."); response.setContentType("application/json;charset=UTF-8"); response.setStatus(rsData.statusCode()); diff --git a/back/src/main/java/com/back/global/security/SecurityConfig.java b/back/src/main/java/com/back/global/security/SecurityConfig.java index be843799..d79a3444 100644 --- a/back/src/main/java/com/back/global/security/SecurityConfig.java +++ b/back/src/main/java/com/back/global/security/SecurityConfig.java @@ -28,7 +28,6 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers("/auth/**").permitAll() .requestMatchers("/actuator/**").permitAll() .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**").permitAll() - .requestMatchers("/post/infor").permitAll() .anyRequest().authenticated() ) .headers(headers -> headers diff --git a/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java b/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java index 80f84fe5..ce81ef11 100644 --- a/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java +++ b/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java @@ -4,6 +4,7 @@ import com.back.domain.member.member.service.MemberService; import com.back.domain.post.entity.Post; import com.back.domain.post.service.PostService; +import com.back.global.security.SecurityUser; import jakarta.transaction.Transactional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -12,10 +13,16 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import java.util.List; + 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.*; @@ -38,12 +45,29 @@ public class InformationPostControllerTest { @BeforeEach void setUp() { - memberService.join("user1", "사용자1", "password123", Member.Role.MENTEE); + Member member = memberService.join("user1", "사용자1", "password123", Member.Role.MENTEE); + + // SecurityContext에 인증 정보 설정 + SecurityUser securityUser = new SecurityUser( + member.getId(), + member.getEmail(), + member.getPassword(), + member.getName(), + List.of(new SimpleGrantedAuthority("ROLE_" + member.getRole().name())) + ); + + Authentication auth = new UsernamePasswordAuthenticationToken( + securityUser, + null, + securityUser.getAuthorities() + ); + + SecurityContextHolder.getContext().setAuthentication(auth); } @Test @DisplayName("게시글 생성") - void createPost() throws Exception { + void t1() throws Exception { ResultActions resultActions = mvc .perform( post("/post/infor") @@ -59,8 +83,6 @@ void createPost() throws Exception { ) .andDo(print()); - Member member = new Member(); - // 실제 생성된 게시글 조회 (실제 DB에서) Post createdPost = postService.findByid(1L); @@ -73,4 +95,30 @@ void createPost() throws Exception { .andExpect(jsonPath("$.data.postId").value(createdPost.getId())) .andExpect(jsonPath("$.data.title").value(createdPost.getTitle())); } + + @Test + @DisplayName("일치하지 않는 postType") + void t2() throws Exception { + ResultActions resultActions = mvc + .perform( + post("/post/infor") + .contentType(MediaType.APPLICATION_JSON) + .content(""" + { + "memberId": 3, + "postType": "INFORMATIONPOST12", + "title": "테스트 제목", + "content": "테스트 내용" + } + """.stripIndent()) + ) + .andDo(print()); + + resultActions + .andExpect(handler().handlerType(InformationPostController.class)) + .andExpect(handler().methodName("createPost")) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.resultCode").value("400-2")) + .andExpect(jsonPath("$.msg").value("유효하지 않은 PostType입니다.")); + } } From 416b68b4bc92c67564ef0f1e17b37aec566d1d01 Mon Sep 17 00:00:00 2001 From: luckhee Date: Mon, 22 Sep 2025 11:46:53 +0900 Subject: [PATCH 5/5] =?UTF-8?q?PostSingleResponseDto=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/InformationPostController.java | 18 +++++- .../domain/post/dto/PostSingleResponse.java | 25 ++++++++ .../back/domain/post/service/PostService.java | 17 +++--- .../InformationPostControllerTest.java | 57 ++++++++++++++++++- 4 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 back/src/main/java/com/back/domain/post/dto/PostSingleResponse.java diff --git a/back/src/main/java/com/back/domain/post/controller/InformationPostController.java b/back/src/main/java/com/back/domain/post/controller/InformationPostController.java index 0de7fac9..9616272e 100644 --- a/back/src/main/java/com/back/domain/post/controller/InformationPostController.java +++ b/back/src/main/java/com/back/domain/post/controller/InformationPostController.java @@ -4,6 +4,7 @@ import com.back.domain.post.dto.PostAllResponse; import com.back.domain.post.dto.PostCreateRequest; import com.back.domain.post.dto.PostCreateResponse; +import com.back.domain.post.dto.PostSingleResponse; import com.back.domain.post.entity.Post; import com.back.domain.post.rq.ApiResponse; import com.back.domain.post.service.PostService; @@ -38,8 +39,21 @@ public ResponseEntity> createPost( @Operation(summary = "게시글 다건 조회") @GetMapping public ResponseEntity>> getAllPost() { - List posts = postService.getAllPosts(); - ApiResponse> response = new ApiResponse<>("게시글 조회 성공", posts); + List postAllResponse = postService.getAllPostResponse(); + + + ApiResponse> response = new ApiResponse<>("게시글 다건 조회 성공", postAllResponse); + return ResponseEntity.ok(response); + } + + @Operation(summary = "게시글 단건 조회") + @GetMapping("/{post_id}") + public ResponseEntity> getSinglePost(@PathVariable long post_id) { + Post post = postService.findById(post_id); + + PostSingleResponse postSingleResponse = new PostSingleResponse(post); + + ApiResponse response = new ApiResponse<>("게시글 단건 조회 성공", postSingleResponse); return ResponseEntity.ok(response); } } diff --git a/back/src/main/java/com/back/domain/post/dto/PostSingleResponse.java b/back/src/main/java/com/back/domain/post/dto/PostSingleResponse.java new file mode 100644 index 00000000..4e40ce19 --- /dev/null +++ b/back/src/main/java/com/back/domain/post/dto/PostSingleResponse.java @@ -0,0 +1,25 @@ +package com.back.domain.post.dto; + +import com.back.domain.post.entity.Post; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class PostSingleResponse { + private Long id; + private String title; + private String authorName; + private LocalDateTime createdAt; + private int viewCount; + private int like; + + public PostSingleResponse(Post post) { + this.id = post.getId(); + this.title = post.getTitle(); + this.authorName = post.getAuthorName(); + this.createdAt = post.getCreateDate(); + this.viewCount = post.getViewCount(); + this.like = post.getLiked(); + } +} diff --git a/back/src/main/java/com/back/domain/post/service/PostService.java b/back/src/main/java/com/back/domain/post/service/PostService.java index c2071c5b..0f69cf8c 100644 --- a/back/src/main/java/com/back/domain/post/service/PostService.java +++ b/back/src/main/java/com/back/domain/post/service/PostService.java @@ -9,7 +9,6 @@ import org.springframework.stereotype.Service; import java.util.List; -import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -17,12 +16,10 @@ public class PostService { private final PostRepository postRepository; - public List getAllPosts() { + public List getAllPosts() { List posts = postRepository.findAll(); - return posts.stream() - .map(PostAllResponse::new) - .collect(Collectors.toList()); + return posts; } @@ -55,7 +52,13 @@ public Post createPost(PostCreateRequest postCreateRequest, String authorName) { return post; } - public Post findByid(Long id) { - return postRepository.findById(id).get(); + public Post findById(Long id) { + return postRepository.findById(id).orElseThrow(() -> new ServiceException("400", "해당 Id의 게시글이 없습니다.")); + } + + public List getAllPostResponse() { + return postRepository.findAll().stream() + .map(PostAllResponse::new) + .toList(); } } diff --git a/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java b/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java index ce81ef11..ee751913 100644 --- a/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java +++ b/back/src/test/java/com/back/domain/post/controller/InformationPostControllerTest.java @@ -23,6 +23,7 @@ import java.util.List; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -37,6 +38,9 @@ public class InformationPostControllerTest { @Autowired private PostService postService; +// @MockBean +// private PostService postMockService; + @Autowired private MemberService memberService; @@ -84,7 +88,7 @@ void t1() throws Exception { .andDo(print()); // 실제 생성된 게시글 조회 (실제 DB에서) - Post createdPost = postService.findByid(1L); + Post createdPost = postService.findById(1L); resultActions .andExpect(handler().handlerType(InformationPostController.class)) @@ -121,4 +125,55 @@ void t2() throws Exception { .andExpect(jsonPath("$.resultCode").value("400-2")) .andExpect(jsonPath("$.msg").value("유효하지 않은 PostType입니다.")); } + + @Test + @DisplayName("게시글 다건조회") + void t3() throws Exception { + ResultActions resultActions = mvc + .perform( + get("/post/infor") + ) + .andDo(print()); + + + resultActions + .andExpect(handler().handlerType(InformationPostController.class)) + .andExpect(handler().methodName("getAllPost")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data").isArray()) + .andExpect(jsonPath("$.message").value("게시글 다건 조회 성공")) + .andExpect(jsonPath("$.data").exists()); + } + +// @Test +// @DisplayName("게시글 단건조회") +// void t4() throws Exception { +// Post mockPost = new Post(); +// +// // 리플렉션으로 ID 설정 +// Field idField = BaseEntity.class.getDeclaredField("id"); +// idField.setAccessible(true); +// idField.set(mockPost, 1L); +// +// mockPost.setTitle("테스트 제목"); +// mockPost.setContent("테스트 내용"); +// mockPost.setAuthorName("테스트유저"); +// mockPost.setPostType(Post.PostType.INFORMATIONPOST); +// +// when(postService.findById(1L)).thenReturn(mockPost); +// +// ResultActions resultActions = mvc +// .perform( +// get("/post/infor/{post_id}", 1L) +// ) +// .andDo(print()); +// +// +// resultActions +// .andExpect(handler().handlerType(InformationPostController.class)) +// .andExpect(handler().methodName("getSinglePost")) +// .andExpect(status().isOk()) +// .andExpect(jsonPath("$.message").value("게시글 단건 조회 성공")) +// .andExpect(jsonPath("$.data").exists()); +// } }