Skip to content

Commit

Permalink
Add GetPopularArticlesHandlerTests test
Browse files Browse the repository at this point in the history
  • Loading branch information
thisisnabi committed Jun 3, 2024
1 parent 5201fbd commit 2e9418a
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
namespace Blogger.Application.Articles.GetPopularArticles;

public class GetPopularArticlesHandler(IArticleRepository articleRepository)
: IRequestHandler<GetPopularArticlesQuery, IReadOnlyList<GetPopularArticlesQueryResponse>>
: IRequestHandler<GetPopularArticlesQuery, IReadOnlyCollection<GetPopularArticlesQueryResponse>>
{
private readonly IArticleRepository _articleRepository = articleRepository;

public async Task<IReadOnlyList<GetPopularArticlesQueryResponse>> Handle(GetPopularArticlesQuery request, CancellationToken cancellationToken)
public async Task<IReadOnlyCollection<GetPopularArticlesQueryResponse>> Handle(GetPopularArticlesQuery request, CancellationToken cancellationToken)
{
var articles = await _articleRepository.GetPopularArticlesAsync(request.Size, cancellationToken);

return articles.Select(x => new GetPopularArticlesQueryResponse(x.Id, x.Title))
.ToImmutableList();
return [.. articles.Select(x => new GetPopularArticlesQueryResponse(x.Id, x.Title))];
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
namespace Blogger.Application.Articles.GetPopularArticles;
public record GetPopularArticlesQuery(int Size)
: IRequest<IReadOnlyList<GetPopularArticlesQueryResponse>>;
: IRequest<IReadOnlyCollection<GetPopularArticlesQueryResponse>>;
11 changes: 11 additions & 0 deletions src/Blogger.Domain/ArticleAggregate/Article.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ private Article(ArticleId slug) : base(slug)
{
_tags = [];
_commentIds = [];
_likes = [];
}

private Article() : this(null!) { }
Expand Down Expand Up @@ -107,5 +108,15 @@ public void Remove()
{
Status = ArticleStatus.Deleted;
}

public void Like(Like like)
{
var item = _likes.FirstOrDefault(x => x == like);

if (item is null)
{
_likes.Add(like);
}
}
}

8 changes: 7 additions & 1 deletion src/Blogger.Domain/ArticleAggregate/IArticleRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@ namespace Blogger.Domain.ArticleAggregate;
public interface IArticleRepository
{
Task<bool> HasIdAsync(ArticleId articleId, CancellationToken cancellationToken);

void Add(Article article);

Task<IReadOnlyCollection<ArchiveModel>> GetArchivesAsync(CancellationToken cancellationToken);

Task<Article?> GetArticleByIdAsync(ArticleId articleId, CancellationToken cancellationToken);

Task<IReadOnlyCollection<Article>> GetLatestArticlesAsync(int pageNumber, int pageSize, CancellationToken cancellationToken);

Task<IReadOnlyCollection<Article>> GetPopularArticlesAsync(int size, CancellationToken cancellationToken);

Task<IReadOnlyList<Tag>> GetPopularTagsAsync(int size,CancellationToken cancellationToken);
Task<IReadOnlyList<Tag>> GetTagsAsync(CancellationToken cancellationToken);
Task SaveChangesAsync(CancellationToken cancellationToken);
void Delete(Article draft);
Task<Article?> GetDraftByIdAsync(ArticleId draftId, CancellationToken cancellationToken);

Task<IReadOnlyList<Article>> GetLatestArticlesAsync(Tag tag, CancellationToken cancellationToken);
Task<IReadOnlyList<Article>> GetPopularArticlesAsync(int size, CancellationToken cancellationToken);

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,19 @@ public async Task<IReadOnlyCollection<Article>> GetLatestArticlesAsync(int pageN

return [.. articles];
}


public async Task<IReadOnlyCollection<Article>> GetPopularArticlesAsync(int size, CancellationToken cancellationToken)
{
var articles = await bloggerDbContext.Articles.Where(x => x.Status == ArticleStatus.Published)
.OrderByDescending(x => (x.Likes.Count() + x.CommentIds.Count()))
.Take(size)
.ToListAsync(cancellationToken);

return [.. articles];
}



public async Task<IReadOnlyList<Tag>> GetPopularTagsAsync(int size, CancellationToken cancellationToken)
{
var topSizeTags = bloggerDbContext.Articles
Expand Down Expand Up @@ -87,15 +99,7 @@ public async Task<IReadOnlyList<Tag>> GetTagsAsync(CancellationToken cancellatio
}


public async Task<IReadOnlyList<Article>> GetPopularArticlesAsync(int size, CancellationToken cancellationToken)
{
var que = await bloggerDbContext.Articles.Where(x => x.Status == ArticleStatus.Published)
.OrderByDescending(x => x.CommentIds.Count)
.Take(size)
.ToListAsync(cancellationToken);

return que.ToImmutableList();
}

public async Task<IReadOnlyList<Article>> GetLatestArticlesAsync(Tag tag, CancellationToken cancellationToken)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using Blogger.Application.Articles.GetPopularArticles;
using Blogger.Domain.ArticleAggregate;
using Blogger.Infrastructure.Persistence.Repositories;
using Blogger.IntegrationTests.Fixtures;

using FluentAssertions;

namespace Blogger.IntegrationTests.Articles;
public class GetPopularArticlesHandlerTests : IClassFixture<BloggerDbContextFixture>
{
private readonly BloggerDbContextFixture _fixture;

public GetPopularArticlesHandlerTests(BloggerDbContextFixture fixture)
{
_fixture = fixture;
}

[Fact]
public async Task Handle_ShouldReturnPopularArticles_WhenArticlesExist()
{
// Arrange
var articleRepository = new ArticleRepository(_fixture.BuildDbContext(Guid.NewGuid().ToString()));
var _sut = new GetPopularArticlesHandler(articleRepository);

var article_1 = Article.CreateArticle("Title 1", "Test Body", "Test Summary", [Tag.Create("tag1"), Tag.Create("tag2")]);
var article_2 = Article.CreateArticle("Title 2", "Test Body", "Test Summary", [Tag.Create("tag1"), Tag.Create("tag2")]);
var article_3 = Article.CreateArticle("Title 3", "Test Body", "Test Summary", [Tag.Create("tag1"), Tag.Create("tag2")]);

var like_1 = Like.Create("127.0.0.1", DateTime.UtcNow);
var like_2 = Like.Create("127.0.0.2", DateTime.UtcNow);
var like_3 = Like.Create("127.0.0.3", DateTime.UtcNow);
var like_4 = Like.Create("127.0.0.4", DateTime.UtcNow);
var like_5 = Like.Create("127.0.0.1", DateTime.UtcNow);
var like_6 = Like.Create("127.0.0.2", DateTime.UtcNow);
var like_7 = Like.Create("127.0.0.3", DateTime.UtcNow);
var like_8 = Like.Create("127.0.0.4", DateTime.UtcNow);
var like_9 = Like.Create("127.0.0.1", DateTime.UtcNow);

article_1.Like(like_1);
article_1.Like(like_2);
articleRepository.Add(article_1);

article_2.Like(like_3);
article_2.Like(like_4);
article_2.Like(like_5);
articleRepository.Add(article_2);

article_3.Like(like_6);
article_3.Like(like_7);
article_3.Like(like_8);
article_3.Like(like_9);
articleRepository.Add(article_3);
await articleRepository.SaveChangesAsync(CancellationToken.None);

var request = new GetPopularArticlesQuery(2);

// Act
var response = await _sut.Handle(request, CancellationToken.None);

// Assert
response.Should().NotBeNull();
response.Should().HaveCount(2);

var firstArticleResponse = response.First();
firstArticleResponse.ArticleId.Should().Be(article_3.Id);

var secondArticleResponse = response.Last();
secondArticleResponse.ArticleId.Should().Be(article_2.Id);
}


[Fact]
public async Task Handle_ShouldReturnEmpty_WhenNoArticlesExist()
{
// Arrange
var articleRepository = new ArticleRepository(_fixture.BuildDbContext(Guid.NewGuid().ToString()));
var _sut = new GetPopularArticlesHandler(articleRepository);

var request = new GetPopularArticlesQuery(2);

// Act
var response = await _sut.Handle(request, CancellationToken.None);

// Assert
response.Should().NotBeNull();
response.Should().BeEmpty();
}


}

0 comments on commit 2e9418a

Please sign in to comment.