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

[feat #21] : 답변 등록/조회 API #22

Merged
merged 29 commits into from
Aug 7, 2024
Merged
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e19997d
[feat] : Answer 엔티티 질문자여부 필드 추가, questionPost 연관관계 매핑 아이디로 대체
hyun2371 Aug 6, 2024
3960fdc
[feat] : 상세답변 응답 DTO 추가
hyun2371 Aug 6, 2024
5db6245
[feat] : 답변등록 요청 DTO 추가
hyun2371 Aug 6, 2024
9f29aa8
[feat] : 답변 DTO<-> 엔티티 Mapper 추가
hyun2371 Aug 6, 2024
50db282
[feat] : answer repository 추가
hyun2371 Aug 6, 2024
fc9f7fe
[feat] : 답변 등록 비즈니스 로직 작성
hyun2371 Aug 6, 2024
b402979
[feat] : 답변 등록 controller 함수 추가
hyun2371 Aug 6, 2024
897508d
[refactor] : static import 제거
hyun2371 Aug 6, 2024
e4fb45e
[feat] : answer fixture 추가
hyun2371 Aug 6, 2024
aded720
[refactor] : 불필요한 모킹 제거
hyun2371 Aug 6, 2024
5a33762
[test] : 단위 테스트용 member fixture 생성
hyun2371 Aug 6, 2024
b216952
[test] : 답변 등록 단위 테스트 작성
hyun2371 Aug 6, 2024
53f50e1
[feat] : 답변 등록 검증 로직 추가
hyun2371 Aug 6, 2024
c40a8a0
[refactor] : 불필요한 출력문 제거
hyun2371 Aug 6, 2024
0785f41
[style] : fixture 파라미터 명시적으로 수정
hyun2371 Aug 6, 2024
0521376
[test] : memberFixture 새로운 유저 객체 추가
hyun2371 Aug 6, 2024
036717f
[test] : 답변 등록 통합 테스트 작성
hyun2371 Aug 6, 2024
3b44b3b
[feat] 페이징 응답 dto 및 변환 함수 추가
hyun2371 Aug 6, 2024
9e2ac38
[feat] : 질문글 아이디로 답변 조회 함수 추가
hyun2371 Aug 6, 2024
eca6a17
[test] : answer fixture 파라미터 추가
hyun2371 Aug 6, 2024
15ad368
[feat] : 질문글의 답변 모두 조회 비즈니스 로직 작성
hyun2371 Aug 6, 2024
635c5f6
[test] : 질문글의 답변 모두 조회 로직 테스트
hyun2371 Aug 6, 2024
0a3f34e
[feat] : 질문글 아이디로 답변 조회 API 작성
hyun2371 Aug 6, 2024
2a1f925
[test] : AnswerFixture 객체 추가
hyun2371 Aug 6, 2024
89ea108
[feat] : 답변 등록 request validation 추가
hyun2371 Aug 6, 2024
15fe1e9
[test] : 질문글의 답변 모두 조회 api 테스트
hyun2371 Aug 7, 2024
6e1a083
[style] : 코드 리포멧팅
hyun2371 Aug 7, 2024
39f6c4d
[feat] : 질문글 등록 리워드 검증 로직 추가
hyun2371 Aug 7, 2024
6ed1a9b
[test] : 질문글 등록 리워드 검증 로직 테스트
hyun2371 Aug 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[style] : 코드 리포멧팅
hyun2371 committed Aug 7, 2024
commit 6e1a0831b6ea2dc6722f422602cd08c4e6506428
4 changes: 1 addition & 3 deletions src/main/java/com/dnd/gongmuin/answer/domain/Answer.java
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@

import com.dnd.gongmuin.common.entity.TimeBaseEntity;
import com.dnd.gongmuin.member.domain.Member;
import com.dnd.gongmuin.question_post.domain.QuestionPost;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
@@ -16,7 +15,6 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@@ -55,7 +53,7 @@ private Answer(String content, Boolean isQuestioner, Long questionPostId, Member
this.member = member;
}

public static Answer of(String content, boolean isQuestioner, Long questionPostId, Member member){
public static Answer of(String content, boolean isQuestioner, Long questionPostId, Member member) {
return new Answer(content, isQuestioner, questionPostId, member);
}

Original file line number Diff line number Diff line change
@@ -9,6 +9,6 @@ public record AnswerDetailResponse(
boolean isQuestioner,
MemberInfo memberInfo,
String createdAt
){
) {

}
4 changes: 2 additions & 2 deletions src/main/java/com/dnd/gongmuin/answer/dto/AnswerMapper.java
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ public static Answer toAnswer(
boolean isQuestioner,
RegisterAnswerRequest request,
Member member
){
) {
return Answer.of(
request.content(),
isQuestioner,
@@ -24,7 +24,7 @@ public static Answer toAnswer(
);
}

public static AnswerDetailResponse toAnswerDetailResponse(Answer answer){
public static AnswerDetailResponse toAnswerDetailResponse(Answer answer) {
Member member = answer.getMember();
return new AnswerDetailResponse(
answer.getId(),
Original file line number Diff line number Diff line change
@@ -2,14 +2,14 @@

import jakarta.validation.constraints.NotBlank;

public record RegisterAnswerRequest (
public record RegisterAnswerRequest(

@NotBlank(message = "답변을 입력해주세요.")
String content
){
) {
public static RegisterAnswerRequest from(
String content
){
) {
return new RegisterAnswerRequest(content);
}
}
Original file line number Diff line number Diff line change
@@ -33,15 +33,15 @@ public AnswerDetailResponse registerAnswer(
Member member
) {
QuestionPost questionPost = questionPostRepository.findById(questionPostId)
.orElseThrow(()-> new NotFoundException(QuestionPostErrorCode.NOT_FOUND_QUESTION_POST));
.orElseThrow(() -> new NotFoundException(QuestionPostErrorCode.NOT_FOUND_QUESTION_POST));
boolean isQuestioner
= questionPost.getMember().getId().equals(member.getId());
Answer answer = AnswerMapper.toAnswer(questionPostId, isQuestioner, request, member);
return AnswerMapper.toAnswerDetailResponse(answerRepository.save(answer));
}

@Transactional(readOnly = true)
public PageResponse<AnswerDetailResponse> getAnswersByQuestionPostId(Long questionPostId){
public PageResponse<AnswerDetailResponse> getAnswersByQuestionPostId(Long questionPostId) {
validateIfQuestionPostExists(questionPostId);
Slice<AnswerDetailResponse> answerResponsePage = answerRepository
.findByQuestionPostId(questionPostId)
@@ -51,7 +51,7 @@ public PageResponse<AnswerDetailResponse> getAnswersByQuestionPostId(Long questi

private void validateIfQuestionPostExists(Long questionPostId) {
boolean isExists = questionPostRepository.existsById(questionPostId);
if (!isExists){
if (!isExists) {
throw new NotFoundException(QuestionPostErrorCode.NOT_FOUND_QUESTION_POST);
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/dnd/gongmuin/common/dto/PageResponse.java
Original file line number Diff line number Diff line change
@@ -2,9 +2,9 @@

import java.util.List;

public record PageResponse<T> (
public record PageResponse<T>(
List<T> content,
long size,
boolean hasNext
){
) {
}
Original file line number Diff line number Diff line change
@@ -31,6 +31,8 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class QuestionPost extends TimeBaseEntity {

@OneToMany(mappedBy = "questionPost", cascade = CascadeType.ALL)
private final List<QuestionPostImage> images = new ArrayList<>();
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "question_post_id", nullable = false)
@@ -46,9 +48,6 @@ public class QuestionPost extends TimeBaseEntity {
private JobGroup jobGroup;
@Column(name = "is_chosen", nullable = false)
private Boolean isChosen;

@OneToMany(mappedBy = "questionPost", cascade = CascadeType.ALL)
private final List<QuestionPostImage> images = new ArrayList<>();
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "member_id",
nullable = false,
Original file line number Diff line number Diff line change
@@ -21,8 +21,8 @@
@Component
public class TokenAuthenticationFilter extends OncePerRequestFilter {

private final TokenProvider tokenProvider;
private static final String TOKEN_PREFIX = "Bearer ";
private final TokenProvider tokenProvider;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
Original file line number Diff line number Diff line change
@@ -35,14 +35,14 @@
@RequiredArgsConstructor
public class TokenProvider {

@Value("${spring.jwt.key}")
private String key;
private SecretKey secretKey;
private static final String ROLE_KEY = "ROLE";
private static final long ACCESS_TOKEN_EXPIRE_TIME = 1000 * 60 * 30L;
private static final long REFRESH_TOKEN_EXPIRE_TIME = 1000 * 60 * 60 * 24L;
private final TokenService tokenService;
private final MemberService memberService;
@Value("${spring.jwt.key}")
private String key;
private SecretKey secretKey;

@PostConstruct
private void initSecretKey() {
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ void registerAnswer() {

@DisplayName("[질문글 아이디로 답변을 모두 조회할 수 있다.]")
@Test
void getAnswerByQuestionPostId(){
void getAnswerByQuestionPostId() {
//given
Long questionPostId = 1L;
QuestionPost questionPost = QuestionPostFixture.questionPost(questionPostId);
@@ -76,7 +76,7 @@ void getAnswerByQuestionPostId(){
given(questionPostRepository.existsById(questionPost.getId()))
.willReturn(true);
given(answerRepository.findByQuestionPostId(questionPostId))
.willReturn(new SliceImpl<>(List.of(answer1, answer2), pageRequest,false));
.willReturn(new SliceImpl<>(List.of(answer1, answer2), pageRequest, false));

//when
PageResponse<AnswerDetailResponse> response = answerService.getAnswersByQuestionPostId(
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class AnswerFixture {

public static Answer answer(Long questionPostId, Member member){
public static Answer answer(Long questionPostId, Member member) {
return Answer.of(
"답변 내용",
false,
@@ -23,7 +23,7 @@ public static Answer answer(Long questionPostId, Member member){
}

// 단위 테스트용
public static Answer answer(Long answerId, Long questionPostId){
public static Answer answer(Long answerId, Long questionPostId) {
Answer answer = Answer.of(
"답변 내용",
false,
Original file line number Diff line number Diff line change
@@ -18,7 +18,6 @@
import com.dnd.gongmuin.common.fixture.MemberFixture;
import com.dnd.gongmuin.common.fixture.QuestionPostFixture;
import com.dnd.gongmuin.member.domain.Member;
import com.dnd.gongmuin.member.repository.MemberRepository;
import com.dnd.gongmuin.question_post.domain.QuestionPost;
import com.dnd.gongmuin.question_post.dto.QuestionPostDetailResponse;
import com.dnd.gongmuin.question_post.dto.RegisterQuestionPostRequest;