Skip to content

Commit

Permalink
feat: GET article(s) returned with favorites
Browse files Browse the repository at this point in the history
  • Loading branch information
zoooo-hs committed May 18, 2022
1 parent 60c194f commit 102a1a0
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

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

@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name = "articles")
Expand All @@ -36,6 +38,9 @@ public class ArticleEntity extends BaseEntity {
@OneToMany(mappedBy = "article", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<ArticleTagRelationEntity> tagList;

@OneToMany(mappedBy = "article", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<FavoriteEntity> favoriteList;

@Builder
public ArticleEntity(Long id, String slug, String title, String description, String body, UserEntity author) {
this.id = id;
Expand All @@ -46,29 +51,4 @@ public ArticleEntity(Long id, String slug, String title, String description, Str
this.author = author;
this.tagList = new ArrayList<>();
}

public void setSlug(String slug) {
this.slug = slug;
}

public void setTitle(String title) {
this.title = title;
}

public void setDescription(String description) {
this.description = description;
}

public void setBody(String body) {
this.body = body;
}

public void setTagList(List<ArticleTagRelationEntity> tagList) {
this.tagList = tagList;
}

// TODO: need another relation model
// private Boolean favorited;
// private Long favoritesCount;

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
Expand All @@ -12,8 +14,10 @@
@Repository
public interface ArticleRepository extends JpaRepository<ArticleEntity, Long> {
@EntityGraph("fetch-author-tagList")
Optional<ArticleEntity> findBySlug(String slug);
@Query("SELECT a FROM ArticleEntity a LEFT JOIN FavoriteEntity f ON f.article.id = a.id WHERE a.slug = :slug")
Optional<ArticleEntity> findBySlug(@Param("slug") String slug);

@EntityGraph("fetch-author-tagList")
List<ArticleEntity> findByAuthorIdInOrderByCreatedAtDesc(List<Long> feedAuthorIds, Pageable pageable);
@Query("SELECT a FROM ArticleEntity a LEFT JOIN FavoriteEntity f ON f.article.id = a.id WHERE a.author.id IN :ids ORDER BY a.createdAt DESC")
List<ArticleEntity> findByAuthorIdInOrderByCreatedAtDesc(@Param("ids") List<Long> ids, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface FavoriteRepository extends JpaRepository<FavoriteEntity, Long> {
Optional<FavoriteEntity> findByArticleIdAndUserId(Long articleId, Long userId);

List<FavoriteEntity> findByArticleId(Long articleId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ public ArticleDto createArticle(ArticleDto article, UserDto.Auth authUser) {
public ArticleDto getArticle(String slug, UserDto.Auth authUser) {
ArticleEntity found = articleRepository.findBySlug(slug).orElseThrow(() -> new AppException(Error.ARTICLE_NOT_FOUND));
Boolean following = profileService.getProfile(found.getAuthor().getName(), authUser).getFollowing();
return convertEntityToDto(found, false, 0L, following);
List<FavoriteEntity> favorites = found.getFavoriteList();
Boolean favorited = favorites.stream().anyMatch(favoriteEntity -> favoriteEntity.getUser().getId().equals(authUser.getId()));
int favoriteCount = favorites.size();
return convertEntityToDto(found, favorited, (long) favoriteCount, following);
}

private ArticleDto convertEntityToDto(ArticleEntity entity, Boolean favorited, Long favoritesCount, Boolean following) {
Expand Down Expand Up @@ -109,8 +112,7 @@ public ArticleDto updateArticle(String slug, ArticleDto.Update article, UserDto.

articleRepository.save(found);

Boolean following = profileService.getProfile(found.getAuthor().getName(), authUser).getFollowing();
return convertEntityToDto(found, false, 0L, following);
return getArticle(slug, authUser);
}

@Transactional
Expand All @@ -123,9 +125,15 @@ public void deleteArticle(String slug, UserDto.Auth authUser) {
@Override
public List<ArticleDto> feedArticles(UserDto.Auth authUser, FeedParams feedParams) {
List<Long> feedAuthorIds = followRepository.findByFollowerId(authUser.getId()).stream().map(FollowEntity::getFollowee).map(BaseEntity::getId).collect(Collectors.toList());
return articleRepository.findByAuthorIdInOrderByCreatedAtDesc(feedAuthorIds, PageRequest.of(feedParams.getOffset(), feedParams.getLimit())).stream().map(entity -> convertEntityToDto(entity, false, 0L, true)).collect(Collectors.toList());
return articleRepository.findByAuthorIdInOrderByCreatedAtDesc(feedAuthorIds, PageRequest.of(feedParams.getOffset(), feedParams.getLimit())).stream().map(entity -> {
List<FavoriteEntity> favorites = entity.getFavoriteList();
Boolean favorited = favorites.stream().anyMatch(favoriteEntity -> favoriteEntity.getUser().getId().equals(authUser.getId()));
int favoriteCount = favorites.size();
return convertEntityToDto(entity, favorited, (long) favoriteCount, true);
}).collect(Collectors.toList());
}

@Transactional
@Override
public ArticleDto favoriteArticle(String slug, UserDto.Auth authUser) {
ArticleEntity found = articleRepository.findBySlug(slug).orElseThrow(() -> new AppException(Error.ARTICLE_NOT_FOUND));
Expand All @@ -139,11 +147,6 @@ public ArticleDto favoriteArticle(String slug, UserDto.Auth authUser) {
.build();
favoriteRepository.save(favorite);

// TODO: do in get single article
boolean favorited = true;
int favoriteCount = favoriteRepository.findByArticleId(found.getId()).size();
Boolean following = profileService.getProfile(found.getAuthor().getName(), authUser).getFollowing();

return convertEntityToDto(found, favorited, (long) favoriteCount, following);
return getArticle(slug, authUser);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.stubbing.Answer;

import java.time.LocalDateTime;
import java.util.List;
Expand Down Expand Up @@ -91,6 +93,7 @@ void setUp() {
.build();

expectedArticle.setTagList(List.of(ArticleTagRelationEntity.builder().article(expectedArticle).tag("tag1").build(),ArticleTagRelationEntity.builder().article(expectedArticle).tag("tag2").build()));
expectedArticle.setFavoriteList(List.of());

beforeWrite = LocalDateTime.now();

Expand Down Expand Up @@ -167,8 +170,20 @@ void whenValidUserFeed_thenReturnMultipleArticle() {
@Test
void whenFavoriteArticle_thenReturnArticleWithUpdatedFavorite() {
Long favoritesCount = article.getFavoritesCount();
when(articleRepository.findBySlug(eq(expectedArticle.getSlug()))).thenReturn(Optional.ofNullable(expectedArticle));
when(favoriteRepository.findByArticleId(any())).thenReturn(List.of(FavoriteEntity.builder().build()));
when(articleRepository.findBySlug(eq(expectedArticle.getSlug())))
.thenAnswer(new Answer<>() {
int count = 0;
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
if (count == 0) {
count += 1;
return Optional.ofNullable(expectedArticle);
} else {
expectedArticle.setFavoriteList(List.of(FavoriteEntity.builder().article(expectedArticle).user(UserEntity.builder().id(authUser.getId()).build()).build()));
return Optional.ofNullable(expectedArticle);
}
}
});
when(profileService.getProfile(eq(author.getName()), any(UserDto.Auth.class))).thenReturn(ProfileDto.builder().following(false).build());


Expand Down

0 comments on commit 102a1a0

Please sign in to comment.