Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[리팩토링] Post, Service 코드 개선 및 테스트 코드 추가 #129

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ dependencies {
// test
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.dbunit:dbunit:2.6.0'
testImplementation 'com.github.springtestdbunit:spring-test-dbunit:1.3.0'
}

test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -16,7 +14,7 @@
import java.util.Locale;

@Configuration
public class JacksonConfiguration {
public class JacksonConfig {

private final Locale locale = Locale.UK;
private final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("MMM dd, yyyy").withLocale(locale);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import javax.persistence.PersistenceContext;

@Configuration
public class QuerydslConfiguration {
public class QuerydslConfig {

@PersistenceContext
private EntityManager entityManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ public abstract class BaseTimeEntity {

@CreatedDate// Entity가 생성되어 저장될 때 시간이 자동 저장됩니다.
@Column(name ="created_at")
private LocalDateTime createdAt;
protected LocalDateTime createdAt;

@LastModifiedDate// 조회한 Entity의 값을 변경할 때 시간이 자동 저장됩니다.
@Column(name = "modified_at")
private LocalDateTime modifiedAt;
protected LocalDateTime modifiedAt;
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

public interface PostRepository extends JpaRepository<Post, Long> {

Post findByPostIdx(Long postIdx);

boolean existsByPostIdxLessThan(Long cursorId);
boolean existsByPostIdx(Long postIdx);

List<Post> findAllByUserUserIdxOrderByCreatedAtDesc(Long userIdx, Pageable pageable);

Expand Down
9 changes: 3 additions & 6 deletions src/main/java/com/yapp18/retrospect/domain/user/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@
import com.sun.istack.NotNull;
import com.yapp18.retrospect.domain.BaseTimeEntity;
import com.yapp18.retrospect.security.oauth2.AuthProvider;

import lombok.*;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Getter @Setter
@Entity
@Getter
@Table(name="user_tb")
// 기본 생성자 접근을 protected으로 변경하면 외부에서 해당 생성자를 접근 할 수 없으므로 Builder를 통해서만 객체 생성 가능하므로 안전성 보장
@Builder
Expand Down Expand Up @@ -60,10 +57,10 @@ public User updateNickname(String nickname){
return this;
}

public User updateProfile(String profile, String name, String nickname, String job, String intro){
public User updateProfile(String name, String nickname, String profile, String job, String intro){
this.name = name;
this.profile = profile;
this.nickname = nickname;
this.profile = profile;
this.job = job;
this.intro = intro;
return this;
Expand Down
34 changes: 14 additions & 20 deletions src/main/java/com/yapp18/retrospect/service/CommentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,57 @@
import com.yapp18.retrospect.domain.comment.Comment;
import com.yapp18.retrospect.domain.comment.CommentRepository;
import com.yapp18.retrospect.domain.post.Post;
import com.yapp18.retrospect.domain.post.PostRepository;
import com.yapp18.retrospect.domain.user.User;
import com.yapp18.retrospect.domain.user.UserRepository;
import com.yapp18.retrospect.mapper.CommentMapper;
import com.yapp18.retrospect.web.advice.EntityNullException;
import com.yapp18.retrospect.web.dto.ApiPagingResultResponse;
import com.yapp18.retrospect.web.dto.CommentDto;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class CommentService {
private final PostService postService;
private final CommentRepository commentRepository;
private final PostRepository postRepository;

@Transactional
public Comment inputComments(Comment comment){
//타 서비스 의존성을 제거와 코드 가독성을 위해 Entity 외의 메서드 parameter는 최소화 할 것
return commentRepository.save(comment);
Long postIdx = comment.getPost().getPostIdx();
comment.setPost(postService.findByPostIdx(postIdx));
commentRepository.save(comment);
return comment; // commentRepository.save(comment); 그대로 반환하면 테스트 코드에서 엔티티가 null로 날아옴..
}

@Transactional(readOnly = true)
public List<Comment> getCommmentsListByPostIdx(Long postIdx, Pageable page){
Post post = postRepository.findById(postIdx)
.orElseThrow(() -> new EntityNullException(ErrorInfo.POST_NULL));
public Comment getCommmentsByIdx(Long commentIdx){
return commentRepository.findById(commentIdx)
.orElseThrow(() -> new EntityNullException(ErrorInfo.COMMENT_NULL));
}

@Transactional(readOnly = true)
public List<Comment> getCommmentsListByPostIdx(Long postIdx, Pageable page){
Post post = postService.findByPostIdx(postIdx);
return commentRepository.findAllByPost(post, page);
}

@Transactional(readOnly = true)
public Long getCommmentsCountByPostIdx(Long postIdx){
Post post = postRepository.findByPostIdx(postIdx);
Post post = postService.findByPostIdx(postIdx);
return commentRepository.countCommentByPost(post);
}

@Transactional(readOnly = true)
public Comment getCommmentsByIdx(Long commentIdx){
return commentRepository.findById(commentIdx)
.orElseThrow(() -> new EntityNullException(ErrorInfo.COMMENT_NULL));
}


@Transactional
// @PreAuthorize("#oldComment.user.userIdx == #user.userIdx")
public Comment updateComments(Comment newComment){
Long commentIdx = newComment.getCommentIdx();

Comment oldComment = commentRepository.findById(commentIdx)
.orElseThrow(() -> new EntityNullException(ErrorInfo.COMMENT_NULL));
.orElseThrow(() -> new EntityNullException(ErrorInfo.COMMENT_NULL));

if(!oldComment.isWriter(newComment.getUser())){
throw new AccessDeniedException(TokenErrorInfo.ACCESS_DENIED.getMessage());
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/com/yapp18/retrospect/service/PostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@
import com.yapp18.retrospect.web.dto.ApiPagingResultResponse;
import com.yapp18.retrospect.web.dto.PostDto;
import lombok.RequiredArgsConstructor;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
//import javax.transaction.Transactional;
import java.time.LocalDateTime;

import java.util.List;
import java.util.stream.Collectors;

//import javax.transaction.Transactional;

@RequiredArgsConstructor
@Service
@Transactional
Expand Down Expand Up @@ -227,4 +227,8 @@ private List<String> compareList(List<String> newList, List<String> compareList)
return newList.stream().filter(x -> !compareList.contains(x)).collect(Collectors.toList());
}

//포스트 존재 여부
public boolean existsByPostIdx(Long postIdx){
return postRepository.existsByPostIdx(postIdx);
}
}
3 changes: 1 addition & 2 deletions src/main/java/com/yapp18/retrospect/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -67,7 +66,7 @@ public UserDto.ProfileResponse updateUserProfiles(Long userIdx, UserDto.UpdateRe
List<String> list = Arrays.asList(request.getProfile());
imageService.deleteImageList(list, userIdx, s3ProfileImagePathSuffix); // list에 없는 s3 가비지 데이터를 추출하여 삭제
}
return existingUser.updateProfile(request.getProfile(), request.getName(), request.getNickname(), request.getJob(), request.getIntro());
return existingUser.updateProfile(request.getName(), request.getNickname(), request.getProfile(), request.getJob(), request.getIntro());
})
.orElseThrow(() -> new EntityNullException(ErrorInfo.USER_NULL));
userRepository.save(user);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
package com.yapp18.retrospect.web.controller;

import com.yapp18.retrospect.annotation.CurrentUser;
import com.yapp18.retrospect.config.ErrorInfo;
import com.yapp18.retrospect.config.ResponseMessage;
import com.yapp18.retrospect.domain.comment.Comment;
import com.yapp18.retrospect.domain.comment.CommentRepository;
import com.yapp18.retrospect.domain.post.Post;
import com.yapp18.retrospect.domain.user.User;
import com.yapp18.retrospect.domain.user.UserRepository;
import com.yapp18.retrospect.mapper.CommentMapper;
import com.yapp18.retrospect.service.CommentService;
import com.yapp18.retrospect.service.PostService;
import com.yapp18.retrospect.service.TokenService;
import com.yapp18.retrospect.web.advice.EntityNullException;
import com.yapp18.retrospect.web.dto.ApiDefaultResponse;
import com.yapp18.retrospect.web.dto.CommentDto;
import com.yapp18.retrospect.web.dto.UserDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
Expand All @@ -25,7 +18,6 @@
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -53,16 +45,6 @@ public ResponseEntity<Object> inputComments(@CurrentUser User user,
);
}

@ApiOperation(value = "comment", notes = "[댓글] 댓글 상세보기")
@GetMapping("/{commentIdx}")
public ResponseEntity<Object> getCommentsById(@ApiParam(value = "상세보기 comment_idx", required = true, example = "3")
@PathVariable(value = "commentIdx") Long commentIdx) {
return ResponseEntity.status(HttpStatus.OK).body(
ApiDefaultResponse.res(200, ResponseMessage.COMMENT_DETAIL.getResponseMessage(),
commentMapper.toDto(commentService.getCommmentsByIdx(commentIdx)))
);
}

@ApiOperation(value = "comment", notes = "[댓글] 댓글 수정")
@PatchMapping("/{commentIdx}")
public ResponseEntity<Object> updateComments(@CurrentUser User user,
Expand Down Expand Up @@ -94,11 +76,11 @@ public ResponseEntity<Object> deleteComments(@CurrentUser User user,
public ResponseEntity<Object> getCommentsByPostIdx(@CurrentUser User user,
@ApiParam(value = "회고글 post_idx", required = true, example = "20")
@RequestParam(value = "postIdx") Long postIdx,
@RequestParam(value = "cursorIdx(디폴트 0, 페이징 하고 싶은 맨 마지막 postIdx 입력)", defaultValue = "0") Long cursorIdx,
@RequestParam(value = "page", defaultValue = "0") Long page,
@RequestParam(value = "pageSize") Integer pageSize){
if (pageSize == null) pageSize = DEFAULT_SIZE;

List<CommentDto.ListResponse> result = commentService.getCommmentsListByPostIdx(postIdx, PageRequest.of(page, pageSize))
List<CommentDto.ListResponse> result = commentService.getCommmentsListByPostIdx(postIdx, PageRequest.of(page.intValue(), pageSize))
.stream()
.map(comment -> commentMapper.toDto(comment, user))
.collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.yapp18.retrospect.annotation;

import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import com.yapp18.retrospect.config.DBUnitConfig;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE) // 어노테이션을 작성할 곳, @Target(ElementType.FIELD)로 지정해주면, 필드에만 어노테이션을 달 수 있습니다.
@Retention(RetentionPolicy.RUNTIME) // 어노테이션의 지속 시간을 정합니다. 이 어노테이션은 런타임시에도 .class 파일에 존재 합니다. 커스텀 어노테이션을 만들 때 주로 사용합니다. Reflection 사용 가능이 가능합니다.
@Import(DBUnitConfig.class) // https://younicode.tistory.com/entry/Spring-boot%EC%97%90%EC%84%9C-DBUnit-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
@DataJpaTest // https://webcoding-start.tistory.com/20, https://howtodoinjava.com/spring-boot2/testing/datajpatest-annotation/
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // Replace.NONE로 설정하면 @ActiveProfiles에 설정한 프로파일 환경값에 따라 데이터 소스가 적용됩니다.
// TestContextManager에 어떤 TestExecutionListener들이 등록되어야 하는지 설정할 수 있게 지원합니다.
@ContextConfiguration
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, // 스프링 테스트 환경에서 일반적으로 사용되는 의존성 주입 (DI) 리스너입니다. 테스트 인스턴스에 대한 의존성 주입 (DI) 을 제공합니다.
TransactionDbUnitTestExecutionListener.class })
@DbUnitConfiguration(databaseConnection = "dbUnitDatabaseConnection")
public @interface RetrospectDataTest {
}
4 changes: 2 additions & 2 deletions src/test/java/com/yapp18/retrospect/common/EntityCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public static User createUserEntity(){
.email("[email protected]")
.name("테스트이름")
.nickname("테스트닉네임")
.profile("profile-url")
.profile("프로필URL")
.provider(AuthProvider.kakao)
.providerId("12345")
.providerId("1")
.role(Role.MEMBER)
.job("테스트직업")
.intro("테스트자기소개")
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/com/yapp18/retrospect/config/DBUnitConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.yapp18.retrospect.config;

import com.github.springtestdbunit.bean.DatabaseConfigBean;
import com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean;
import org.dbunit.ext.h2.H2DataTypeFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class DBUnitConfig {
@Bean
public DatabaseConfigBean dbUnitDatabaseConfig() {
DatabaseConfigBean config = new DatabaseConfigBean();
config.setAllowEmptyFields(true);
config.setDatatypeFactory(new H2DataTypeFactory());
return config;
}

@Bean
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection(DataSource dataSource) {
DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection = new DatabaseDataSourceConnectionFactoryBean();
dbUnitDatabaseConnection.setDataSource(dataSource);
dbUnitDatabaseConnection.setDatabaseConfig(dbUnitDatabaseConfig());
return dbUnitDatabaseConnection;
}
}
Loading