Skip to content

Commit

Permalink
fix: merge conflict 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
amaran-th committed Aug 16, 2023
2 parents 9745eef + e3ff353 commit 20b8821
Show file tree
Hide file tree
Showing 36 changed files with 1,196 additions and 108 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package wooteco.prolog.steps;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.springframework.http.HttpStatus;
import wooteco.prolog.AcceptanceSteps;
import wooteco.prolog.roadmap.application.dto.RecommendedRequest;

import static org.assertj.core.api.Assertions.assertThat;
import static wooteco.prolog.fixtures.KeywordAcceptanceFixture.KEYWORD_REQUEST;

public class KeywordRecommendedPostStepDefinitions extends AcceptanceSteps {

@Given("{int}번 키워드에 대해 추천 포스트 {string}를 작성하고")
@When("{int}번 키워드에 대해 추천 포스트 {string}를 작성하면")
public void 추천_포스트를_하면(int keywordId, String url) {
context.invokeHttpPost(
"/keywords/"+keywordId+"/recommended-posts",
new RecommendedRequest(url)
);
}

@When("{int}번 키워드에 대한 {int}번 추천 포스트를 {string}로 수정하면")
public void 추천_포스트를_수정하면(int keywordId, int recommendedId, String url) {
context.invokeHttpPut(
"/keywords/"+keywordId+"/recommended-posts/"+recommendedId,
new RecommendedRequest(url));
}

@When("{int}번 키워드에 대한 {int}번 추천 포스트를 삭제하면")
public void 추천_포스트를_삭제하면(int keywordId, int recommendedId) {
context.invokeHttpDelete(
"/keywords/" + keywordId + "/recommended-posts/" + recommendedId
);
}

@Then("추천 포스트가 생성된다")
public void 추천_포스트가_생성된다() {
int statusCode = context.response.statusCode();

assertThat(statusCode).isEqualTo(HttpStatus.CREATED.value());
}

@Then("추천 포스트가 수정된다")
public void 추천_포스트가_수정된다() {
int statusCode = context.response.statusCode();

assertThat(statusCode).isEqualTo(HttpStatus.OK.value());
}

@Then("추천 포스트가 삭제된다")
public void 추천_포스트가_삭제된다() {
int statusCode = context.response.statusCode();

assertThat(statusCode).isEqualTo(HttpStatus.NO_CONTENT.value());
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package wooteco.prolog.steps;

import static org.assertj.core.api.Assertions.assertThat;
import static wooteco.prolog.fixtures.KeywordAcceptanceFixture.KEYWORD_REQUEST;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.springframework.http.HttpStatus;
import wooteco.prolog.AcceptanceSteps;
import wooteco.prolog.session.application.dto.SessionRequest;

import static org.assertj.core.api.Assertions.assertThat;
import static wooteco.prolog.fixtures.KeywordAcceptanceFixture.KEYWORD_REQUEST;

public class KeywordStepDefinitions extends AcceptanceSteps {

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@api
Feature: 로드맵 키워드 추천 포스트 관련 기능

Background: 사전 작업
Given "2022 백엔드 레벨1" 세션을 생성하고 - 1번 세션
And 1번 세션에 "자바"라는 키워드를 순서 1, 중요도 2로 작성하고

Scenario: 키워드 추천 포스트 생성하기
When 1번 키워드에 대해 추천 포스트 "https://javajavajava"를 작성하면
Then 추천 포스트가 생성된다

Scenario: 키워드 추천 포스트 수정하기
Given 1번 키워드에 대해 추천 포스트 "https://javajavajava"를 작성하고
When 1번 키워드에 대한 1번 추천 포스트를 "https://java2java2"로 수정하면
Then 추천 포스트가 수정된다

Scenario: 키워드 추천 포스트 삭제하기
Given 1번 키워드에 대해 추천 포스트 "https://javajavajava"를 작성하고
When 1번 키워드에 대한 1번 추천 포스트를 삭제하면
Then 추천 포스트가 삭제된다
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
package wooteco.prolog.docu;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doNothing;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;

import java.util.Arrays;
import java.util.HashSet;
import org.elasticsearch.common.collect.List;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
Expand All @@ -21,6 +14,14 @@
import wooteco.prolog.roadmap.application.dto.KeywordsResponse;
import wooteco.prolog.roadmap.ui.KeywordController;

import java.util.Arrays;
import java.util.HashSet;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doNothing;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;

@WebMvcTest(controllers = KeywordController.class)
public class KeywordDocumentation extends NewDocumentation {

Expand Down Expand Up @@ -108,6 +109,7 @@ public class KeywordDocumentation extends NewDocumentation {
1,
1,
null,
null,
null
);

Expand All @@ -133,6 +135,7 @@ public class KeywordDocumentation extends NewDocumentation {
1,
1,
null,
null,
new HashSet<>(
Arrays.asList(
new KeywordResponse(
Expand All @@ -142,6 +145,7 @@ public class KeywordDocumentation extends NewDocumentation {
1,
1,
1L,
null,
null
),
new KeywordResponse(
Expand All @@ -151,6 +155,7 @@ public class KeywordDocumentation extends NewDocumentation {
2,
1,
1L,
null,
null
))
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.AllArgsConstructor;
import lombok.Getter;
import wooteco.prolog.roadmap.domain.RecommendedPost;
import wooteco.prolog.session.domain.Mission;
import wooteco.prolog.session.domain.Session;
import wooteco.prolog.studylog.domain.TagName;
Expand Down Expand Up @@ -70,12 +71,15 @@ public enum BadRequestCode {
NOT_EMPTY_ESSAY_ANSWER_EXCEPTION(8013, "답변은 공백일 수 없습니다."),
ESSAY_ANSWER_NOT_VALID_USER(8014, "본인이 작성한 답변만 수정할 수 있습니다."),

ROADMAP_RECOMMENDED_POST_NOT_FOUND(8101, "해당 추천 포스트가 존재하지 않습니다."),
ROADMAP_RECOMMENDED_POST_INVALID_URL_LENGTH(8102, String.format(
"해당 추천 포스트의 URL 길이는 1 ~ %d여야 합니다.", RecommendedPost.URL_LENGTH_UPPER_BOUND)),

FILE_NAME_EMPTY_EXCEPTION(9001, "파일 이름이 존재하지 않습니다."),
UNSUPPORTED_FILE_EXTENSION_EXCEPTION(9002, "지원하지 않는 파일 확장자입니다."),
FILE_UPLOAD_FAIL_EXCEPTION(9003, "파일 업로드에 실패했습니다."),

DUPLICATE_SESSION_EXCEPTION(10001, "중복되는 세션입니다."),
SESSION_NOT_FOUND_EXCEPTION(10002, "세션을 찾을 수 없습니다."),
TOO_LONG_LEVEL_NAME_EXCEPTION(10003, String.format("세션 이름이 %d자 초과입니다.", Session.MAX_LENGTH)),

SEARCH_ARGUMENT_PARSE_EXCEPTION(11001, "parsing 할 수 없는 argument입니다."),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
package wooteco.prolog.roadmap.application;

import static wooteco.prolog.common.exception.BadRequestCode.CURRICULUM_NOT_FOUND_EXCEPTION;
import static wooteco.prolog.common.exception.BadRequestCode.ESSAY_ANSWER_NOT_FOUND_EXCEPTION;
import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_QUIZ_NOT_FOUND_EXCEPTION;
import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_SESSION_NOT_FOUND_EXCEPTION;

import java.util.List;
import java.util.stream.Collectors;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import wooteco.prolog.common.exception.BadRequestException;
import wooteco.prolog.member.application.MemberService;
import wooteco.prolog.member.domain.Member;
import wooteco.prolog.roadmap.application.dto.EssayAnswerRequest;
import wooteco.prolog.roadmap.application.dto.EssayAnswerSearchRequest;
import wooteco.prolog.roadmap.application.dto.EssayAnswerUpdateRequest;
import wooteco.prolog.roadmap.domain.Curriculum;
import wooteco.prolog.roadmap.domain.EssayAnswer;
import wooteco.prolog.roadmap.domain.Quiz;
import wooteco.prolog.roadmap.domain.repository.CurriculumRepository;
import wooteco.prolog.roadmap.domain.repository.EssayAnswerRepository;
import wooteco.prolog.roadmap.domain.repository.EssayAnswerSpecification;
import wooteco.prolog.roadmap.domain.repository.QuizRepository;

import java.util.List;
import wooteco.prolog.session.domain.Session;
import wooteco.prolog.session.domain.repository.SessionRepository;
import wooteco.prolog.studylog.application.dto.EssayAnswersResponse;

@Transactional
@Service
Expand All @@ -26,14 +37,20 @@ public class EssayAnswerService {
private final EssayAnswerRepository essayAnswerRepository;
private final QuizRepository quizRepository;
private final MemberService memberService;

@Autowired
public EssayAnswerService(EssayAnswerRepository essayAnswerRepository,
QuizRepository quizRepository,
MemberService memberService) {
private final CurriculumRepository curriculumRepository;
private final SessionRepository sessionRepository;

public EssayAnswerService(
EssayAnswerRepository essayAnswerRepository,
QuizRepository quizRepository,
MemberService memberService,
CurriculumRepository curriculumRepository,
SessionRepository sessionRepository) {
this.essayAnswerRepository = essayAnswerRepository;
this.quizRepository = quizRepository;
this.memberService = memberService;
this.curriculumRepository = curriculumRepository;
this.sessionRepository = sessionRepository;
}

@Transactional
Expand Down Expand Up @@ -85,4 +102,35 @@ public List<EssayAnswer> findByQuizId(Long quizId) {

return essayAnswers;
}

public EssayAnswersResponse searchEssayAnswers(
final EssayAnswerSearchRequest request,
final Pageable pageable
) {

final Long curriculumId = request.getCurriculumId();

final Curriculum curriculum = curriculumRepository.findById(curriculumId)
.orElseThrow(() -> new BadRequestException(CURRICULUM_NOT_FOUND_EXCEPTION));

final List<Long> sessionIds = sessionRepository.findAllByCurriculumId(curriculum.getId())
.stream()
.map(Session::getId)
.collect(Collectors.toList());

if (sessionIds.isEmpty()) {
throw new BadRequestException(ROADMAP_SESSION_NOT_FOUND_EXCEPTION);
}

final Specification<EssayAnswer> essayAnswerSpecification = EssayAnswerSpecification.equalsSessionIdsIn(
sessionIds)
.and(EssayAnswerSpecification.equalsKeywordId(request.getKeywordId()))
.and(EssayAnswerSpecification.inQuizIds(request.getQuizIds()))
.and(EssayAnswerSpecification.inMemberIds(request.getMemberIds()))
.and(EssayAnswerSpecification.orderByIdDesc());

final Page<EssayAnswer> essayAnswers = essayAnswerRepository.findAll(essayAnswerSpecification,
pageable);
return EssayAnswersResponse.of(essayAnswers);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package wooteco.prolog.roadmap.application;

import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_KEYWORD_NOT_FOUND_EXCEPTION;
import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_SESSION_NOT_FOUND_EXCEPTION;

import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import wooteco.prolog.common.exception.BadRequestException;
Expand All @@ -15,6 +11,11 @@
import wooteco.prolog.roadmap.domain.repository.KeywordRepository;
import wooteco.prolog.session.domain.repository.SessionRepository;

import java.util.List;

import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_KEYWORD_NOT_FOUND_EXCEPTION;
import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_SESSION_NOT_FOUND_EXCEPTION;

@Transactional
@Service
public class KeywordService {
Expand Down Expand Up @@ -55,7 +56,7 @@ public KeywordResponse findKeywordWithAllChild(final Long sessionId, final Long
existSession(sessionId);
existKeyword(keywordId);

Keyword keyword = keywordRepository.findFetchById(keywordId);
Keyword keyword = keywordRepository.findFetchByIdOrderBySeq(keywordId);

return KeywordResponse.createWithAllChildResponse(keyword);
}
Expand All @@ -82,7 +83,7 @@ public void updateKeyword(final Long sessionId, final Long keywordId,

public void deleteKeyword(final Long sessionId, final Long keywordId) {
existSession(sessionId);
Keyword keyword = keywordRepository.findFetchById(keywordId);
Keyword keyword = keywordRepository.findFetchByIdOrderBySeq(keywordId);

keywordRepository.delete(keyword);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package wooteco.prolog.roadmap.application;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import wooteco.prolog.common.exception.BadRequestException;
import wooteco.prolog.roadmap.application.dto.RecommendedRequest;
import wooteco.prolog.roadmap.application.dto.RecommendedUpdateRequest;
import wooteco.prolog.roadmap.domain.Keyword;
import wooteco.prolog.roadmap.domain.RecommendedPost;
import wooteco.prolog.roadmap.domain.repository.KeywordRepository;
import wooteco.prolog.roadmap.domain.repository.RecommendedPostRepository;

import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_KEYWORD_NOT_FOUND_EXCEPTION;
import static wooteco.prolog.common.exception.BadRequestCode.ROADMAP_RECOMMENDED_POST_NOT_FOUND;

@Transactional(readOnly = true)
@Service
public class RecommendedPostService {

private final RecommendedPostRepository recommendedPostRepository;
private final KeywordRepository keywordRepository;

public RecommendedPostService(final RecommendedPostRepository recommendedPostRepository,
final KeywordRepository keywordRepository) {
this.recommendedPostRepository = recommendedPostRepository;
this.keywordRepository = keywordRepository;
}

@Transactional
public Long create(final Long keywordId, final RecommendedRequest request) {
final Keyword keyword = findKeywordOrThrow(keywordId);
final RecommendedPost post = new RecommendedPost(request.getUrl(), keyword);

return recommendedPostRepository.save(post).getId();
}

private Keyword findKeywordOrThrow(final Long keywordId) {
return keywordRepository.findById(keywordId)
.orElseThrow(() -> new BadRequestException(ROADMAP_KEYWORD_NOT_FOUND_EXCEPTION));
}

@Transactional
public void update(final Long recommendedId, final RecommendedUpdateRequest request) {
final RecommendedPost post = findPostOrThrow(recommendedId);

post.updateUrl(request.getUrl());
}

private RecommendedPost findPostOrThrow(final Long recommendedId) {
return recommendedPostRepository.findById(recommendedId)
.orElseThrow(() -> new BadRequestException(ROADMAP_RECOMMENDED_POST_NOT_FOUND));
}

@Transactional
public void delete(final Long recommendedId) {
final RecommendedPost recommendedPost = findPostOrThrow(recommendedId);
recommendedPost.remove();
}
}
Loading

0 comments on commit 20b8821

Please sign in to comment.