Skip to content

Commit

Permalink
Merge pull request #105 from Seasoning-Today/refactor/reorganize-arti…
Browse files Browse the repository at this point in the history
…cle-like-services

기록장 좋아요 서비스 로직 분리 및 기록장 좋아요 취소 통합 테스트 작성
  • Loading branch information
csct3434 authored Mar 29, 2024
2 parents 76253b3 + ac3f478 commit d3d7fdd
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@
import today.seasoning.seasoning.article.dto.FindMyArticlesByYearResponse;
import today.seasoning.seasoning.article.dto.RegisterArticleRequest;
import today.seasoning.seasoning.article.dto.UpdateArticleRequest;
import today.seasoning.seasoning.article.service.ArticleLikeService;
import today.seasoning.seasoning.article.service.CancelArticleLikeService;
import today.seasoning.seasoning.article.service.DeleteArticleService;
import today.seasoning.seasoning.article.service.FindArticleService;
import today.seasoning.seasoning.article.service.FindCollageService;
import today.seasoning.seasoning.article.service.FindFriendArticlesService;
import today.seasoning.seasoning.article.service.FindMyArticlesByTermService;
import today.seasoning.seasoning.article.service.FindMyArticlesByYearService;
import today.seasoning.seasoning.article.service.RegisterArticleLikeService;
import today.seasoning.seasoning.article.service.RegisterArticleService;
import today.seasoning.seasoning.article.service.UpdateArticleService;
import today.seasoning.seasoning.common.UserPrincipal;
Expand All @@ -47,7 +48,8 @@ public class ArticleController {
private final DeleteArticleService deleteArticleService;
private final FindMyArticlesByYearService findMyArticlesByYearService;
private final FindMyArticlesByTermService findMyArticlesByTermService;
private final ArticleLikeService articleLikeService;
private final RegisterArticleLikeService registerArticleLikeService;
private final CancelArticleLikeService cancelArticleLikeService;
private final FindCollageService findCollageService;
private final FindFriendArticlesService findFriendArticlesService;

Expand Down Expand Up @@ -115,7 +117,7 @@ public ResponseEntity<Void> likeArticle(
@AuthenticationPrincipal UserPrincipal principal,
@PathVariable String articleId
) {
articleLikeService.doLike(principal.getId(), TsidUtil.toLong(articleId));
registerArticleLikeService.doService(principal.getId(), TsidUtil.toLong(articleId));
return ResponseEntity.ok().build();
}

Expand All @@ -124,7 +126,7 @@ public ResponseEntity<Void> cancelLikeArticle(
@AuthenticationPrincipal UserPrincipal principal,
@PathVariable String articleId
) {
articleLikeService.cancelLike(principal.getId(), TsidUtil.toLong(articleId));
cancelArticleLikeService.doService(principal.getId(), TsidUtil.toLong(articleId));
return ResponseEntity.ok().build();
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package today.seasoning.seasoning.article.service;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import today.seasoning.seasoning.article.domain.ArticleLikeRepository;
import today.seasoning.seasoning.common.exception.CustomException;

@Service
@RequiredArgsConstructor
public class CancelArticleLikeService {

private final ArticleLikeRepository articleLikeRepository;
private final ValidateArticleLikePolicy validateArticleLikePolicy;

@Transactional
public void doService(Long userId, Long articleId) {
if (!validateArticleLikePolicy.validate(userId, articleId)) {
throw new CustomException(HttpStatus.FORBIDDEN, "권한 없음");
}
articleLikeRepository.findByArticleAndUser(articleId, userId).ifPresent(articleLikeRepository::delete);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package today.seasoning.seasoning.article.service;

import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import today.seasoning.seasoning.article.domain.Article;
import today.seasoning.seasoning.article.domain.ArticleLike;
import today.seasoning.seasoning.article.domain.ArticleLikeRepository;
import today.seasoning.seasoning.article.domain.ArticleRepository;
import today.seasoning.seasoning.article.event.ArticleLikedEvent;
import today.seasoning.seasoning.common.exception.CustomException;
import today.seasoning.seasoning.user.domain.User;
import today.seasoning.seasoning.user.domain.UserRepository;

@Service
@RequiredArgsConstructor
public class RegisterArticleLikeService {

private final UserRepository userRepository;
private final ArticleRepository articleRepository;
private final ArticleLikeRepository articleLikeRepository;
private final ValidateArticleLikePolicy validateArticleLikePolicy;
private final ApplicationEventPublisher applicationEventPublisher;

@Transactional
public void doService(Long userId, Long articleId) {
Article article = articleRepository.findByIdOrElseThrow(articleId);
User user = userRepository.findByIdOrElseThrow(userId);
User author = article.getUser();

// 사용자 권한 검증
if (!validateArticleLikePolicy.validate(userId, articleId)) {
throw new CustomException(HttpStatus.FORBIDDEN, "권한 없음");
}

// 중복 요청의 경우 무시
if (articleLikeRepository.findByArticleAndUser(articleId, userId).isPresent()) {
return;
}

articleLikeRepository.save(new ArticleLike(article, user));

// 타인의 글에 좋아요를 누른 경우, 상대방에게 관련 알림 전송
if (user != author) {
ArticleLikedEvent articleLikedEvent = new ArticleLikedEvent(user.getId(), author.getId(), articleId);
applicationEventPublisher.publishEvent(articleLikedEvent);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package today.seasoning.seasoning.article.service;

public interface ValidateArticleLikePolicy {

boolean validate(Long userId, Long articleId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package today.seasoning.seasoning.article.service;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import today.seasoning.seasoning.article.domain.Article;
import today.seasoning.seasoning.article.domain.ArticleRepository;
import today.seasoning.seasoning.friendship.domain.FriendshipRepository;

@Component
@RequiredArgsConstructor
public class ValidateArticleLikePolicyImpl implements ValidateArticleLikePolicy {

private final ArticleRepository articleRepository;
private final FriendshipRepository friendshipRepository;

@Override
public boolean validate(Long userId, Long articleId) {
Article article = articleRepository.findByIdOrElseThrow(articleId);
Long authorId = article.getUser().getId();

// 자신의 글
if (authorId.equals(userId)) {
return true;
}
// 공개된 친구의 글
if (article.isPublished() && friendshipRepository.existsByUserIdAndFriendId(userId, authorId)) {
return true;
}

return false;
}
}
Loading

0 comments on commit d3d7fdd

Please sign in to comment.