Skip to content

Commit

Permalink
feat: 추천 포스트 등록, 수정, 삭제 기능 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
nuyh99 committed Jul 20, 2023
1 parent b0b2c5d commit 1a8b3d8
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 0 deletions.
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.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.RecommendedRepository;
import wooteco.prolog.roadmap.exception.KeywordNotFoundException;
import wooteco.prolog.roadmap.exception.RecommendedPostNotFoundException;

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

private final RecommendedRepository recommendedRepository;
private final KeywordRepository keywordRepository;

public RecommendedService(final RecommendedRepository recommendedRepository, final KeywordRepository keywordRepository) {
this.recommendedRepository = recommendedRepository;
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());
post.addKeyword(keyword);

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

private Keyword findKeywordOrThrow(final Long keywordId) {
return keywordRepository.findById(keywordId)
.orElseThrow(KeywordNotFoundException::new);
}

@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 recommendedRepository.findById(recommendedId)
.orElseThrow(RecommendedPostNotFoundException::new);
}

@Transactional
public void delete(final Long recommendedId) {
final RecommendedPost recommendedPost = findPostOrThrow(recommendedId);
recommendedPost.remove();
recommendedRepository.delete(recommendedPost);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package wooteco.prolog.roadmap.application.dto;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class RecommendedRequest {

private String url;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package wooteco.prolog.roadmap.application.dto;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class RecommendedUpdateRequest {

private String url;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package wooteco.prolog.roadmap.domain.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import wooteco.prolog.roadmap.domain.RecommendedPost;

public interface RecommendedRepository extends JpaRepository<RecommendedPost, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package wooteco.prolog.roadmap.exception;

import wooteco.prolog.common.exception.BadRequestException;

public class RecommendedPostNotFoundException extends BadRequestException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package wooteco.prolog.roadmap.application;

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;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
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.RecommendedRepository;

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.SoftAssertions.assertSoftly;

@SpringBootTest
@Transactional
class RecommendedServiceTest {

@Autowired
private RecommendedService recommendedService;
@Autowired
private RecommendedRepository recommendedRepository;
@Autowired
private KeywordRepository keywordRepository;

private Keyword keyword;

@BeforeEach
public void init() {
final Keyword keyword = Keyword.createKeyword("이름", "설명", 1, 1, 1L, null);
this.keyword = keywordRepository.save(keyword);
}

@Test
@DisplayName("추천 포스트 생성 테스트")
void create() {
//given
final RecommendedRequest request = new RecommendedRequest("https//:example.com");

//when
Long recommendedPostId = recommendedService.create(keyword.getId(), request);

final Keyword persistedKeyword = keywordRepository.findById(keyword.getId()).get();
final RecommendedPost persistedPost = recommendedRepository.findById(recommendedPostId).get();

//then
assertSoftly(softAssertions -> {
assertThat(persistedPost.getUrl()).isEqualTo(request.getUrl());
assertThat(persistedKeyword.getRecommendedPosts()).containsExactly(persistedPost);
});
}

@Test
@DisplayName("추천 포스트 수정 테스트")
void update() {
//given
final RecommendedRequest request = new RecommendedRequest("https//:example.com");
Long recommendedPostId = recommendedService.create(keyword.getId(), request);
String newUrl = "https//:example222.com";
final RecommendedUpdateRequest updateRrequest = new RecommendedUpdateRequest(newUrl);

//when
recommendedService.update(recommendedPostId, updateRrequest);
Optional<RecommendedPost> actual = recommendedRepository.findById(recommendedPostId);

//then
assertThat(actual.get().getUrl()).isEqualTo(newUrl);
}

@Test
@DisplayName("추천 포스트 삭제 테스트")
void delete() {
//given
final RecommendedRequest request = new RecommendedRequest("https//:example.com");
Long recommendedPostId = recommendedService.create(keyword.getId(), request);

//when
recommendedService.delete(recommendedPostId);

//then
assertSoftly(softAssertions -> {
assertThat(recommendedRepository.findAll()).hasSize(0);
assertThat(keywordRepository.findById(keyword.getId()).get().getRecommendedPosts())
.isEmpty();
});
}
}

0 comments on commit 1a8b3d8

Please sign in to comment.