From d83a3de020f67296f6a6d32367dde0ae67ea93fc Mon Sep 17 00:00:00 2001 From: thisisnabi Date: Mon, 3 Jun 2024 13:23:35 +0330 Subject: [PATCH] Add GetTagsQueryHandlerTests tests --- .../Articles/GetTags/GetTagsQuery.cs | 2 +- .../Articles/GetTags/GetTagsQueryHandler.cs | 8 +-- .../ArticleAggregate/IArticleRepository.cs | 2 +- .../ArticleAggregate/Models/TagModel.cs | 2 + .../Repositories/ArticleRepository.cs | 11 ++- .../Articles/GetTagsQueryHandlerTests.cs | 69 +++++++++++++++++++ 6 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 src/Blogger.Domain/ArticleAggregate/Models/TagModel.cs create mode 100644 tests/Blogger.IntegrationTests/Articles/GetTagsQueryHandlerTests.cs diff --git a/src/Blogger.Application/Articles/GetTags/GetTagsQuery.cs b/src/Blogger.Application/Articles/GetTags/GetTagsQuery.cs index bdabdd8..ffc4c5e 100644 --- a/src/Blogger.Application/Articles/GetTags/GetTagsQuery.cs +++ b/src/Blogger.Application/Articles/GetTags/GetTagsQuery.cs @@ -1,3 +1,3 @@ namespace Blogger.Application.Articles.GetTags; public record GetTagsQuery() - : IRequest>; \ No newline at end of file + : IRequest>; \ No newline at end of file diff --git a/src/Blogger.Application/Articles/GetTags/GetTagsQueryHandler.cs b/src/Blogger.Application/Articles/GetTags/GetTagsQueryHandler.cs index 16565b2..da19b5c 100644 --- a/src/Blogger.Application/Articles/GetTags/GetTagsQueryHandler.cs +++ b/src/Blogger.Application/Articles/GetTags/GetTagsQueryHandler.cs @@ -1,16 +1,14 @@ namespace Blogger.Application.Articles.GetTags; public class GetTagsQueryHandler(IArticleRepository articleRepository) - : IRequestHandler> + : IRequestHandler> { private readonly IArticleRepository _articleRepository = articleRepository; - public async Task> Handle(GetTagsQuery request, CancellationToken cancellationToken) + public async Task> Handle(GetTagsQuery request, CancellationToken cancellationToken) { var tags = await _articleRepository.GetTagsAsync(cancellationToken); - return tags.GroupBy(x => x) - .Select(x => new GetTagsQueryResponse(x.Key, x.Count())) - .ToImmutableList(); + return [.. tags.Select(x => new GetTagsQueryResponse(x.Tag, x.Count))]; } } diff --git a/src/Blogger.Domain/ArticleAggregate/IArticleRepository.cs b/src/Blogger.Domain/ArticleAggregate/IArticleRepository.cs index 1be15d9..7589bcd 100644 --- a/src/Blogger.Domain/ArticleAggregate/IArticleRepository.cs +++ b/src/Blogger.Domain/ArticleAggregate/IArticleRepository.cs @@ -20,8 +20,8 @@ public interface IArticleRepository Task> GetLatestArticlesAsync(Tag tag, CancellationToken cancellationToken); + Task> GetTagsAsync(CancellationToken cancellationToken); - Task> GetTagsAsync(CancellationToken cancellationToken); Task SaveChangesAsync(CancellationToken cancellationToken); void Delete(Article draft); Task GetDraftByIdAsync(ArticleId draftId, CancellationToken cancellationToken); diff --git a/src/Blogger.Domain/ArticleAggregate/Models/TagModel.cs b/src/Blogger.Domain/ArticleAggregate/Models/TagModel.cs new file mode 100644 index 0000000..41035c4 --- /dev/null +++ b/src/Blogger.Domain/ArticleAggregate/Models/TagModel.cs @@ -0,0 +1,2 @@ +namespace Blogger.Domain.ArticleAggregate.Models; +public sealed record TagModel(Tag Tag, int Count); \ No newline at end of file diff --git a/src/Blogger.Infrastructure/Persistence/Repositories/ArticleRepository.cs b/src/Blogger.Infrastructure/Persistence/Repositories/ArticleRepository.cs index 6c7fe65..5c0f81a 100644 --- a/src/Blogger.Infrastructure/Persistence/Repositories/ArticleRepository.cs +++ b/src/Blogger.Infrastructure/Persistence/Repositories/ArticleRepository.cs @@ -83,19 +83,18 @@ public async Task> GetLatestArticlesAsync(Tag tag, return [.. articles]; } - - - - - public async Task> GetTagsAsync(CancellationToken cancellationToken) + + public async Task> GetTagsAsync(CancellationToken cancellationToken) { var tags = await bloggerDbContext.Articles .AsNoTracking() .Where(x => x.Status == ArticleStatus.Published) .SelectMany(x => x.Tags) + .GroupBy(x => x.Value) + .Select(x => new TagModel(Tag.Create(x.Key), x.Count())) .ToListAsync(cancellationToken); - return tags.ToImmutableList(); + return[.. tags]; } diff --git a/tests/Blogger.IntegrationTests/Articles/GetTagsQueryHandlerTests.cs b/tests/Blogger.IntegrationTests/Articles/GetTagsQueryHandlerTests.cs new file mode 100644 index 0000000..b90ce8c --- /dev/null +++ b/tests/Blogger.IntegrationTests/Articles/GetTagsQueryHandlerTests.cs @@ -0,0 +1,69 @@ +using System.Collections.Immutable; +using Blogger.Application.Articles.GetTags; +using Blogger.Domain.ArticleAggregate; +using Blogger.Infrastructure.Persistence.Repositories; +using Blogger.IntegrationTests.Fixtures; + +using FluentAssertions; + +namespace Blogger.IntegrationTests.Articles; +public class GetTagsQueryHandlerTests : IClassFixture +{ + private readonly BloggerDbContextFixture _fixture; + + public GetTagsQueryHandlerTests(BloggerDbContextFixture fixture) + { + _fixture = fixture; + } + + [Fact] + public async Task Handle_ShouldReturnTags_WhenTagsExist() + { + // Arrange + var articleRepository = new ArticleRepository(_fixture.BuildDbContext(Guid.NewGuid().ToString())); + var sut = new GetTagsQueryHandler(articleRepository); + + var article_1 = Article.CreateArticle("Title 1", "Test Body", "Test Summary", [Tag.Create("tag1"), Tag.Create("tag3")]); + var article_2 = Article.CreateArticle("Title 2", "Test Body", "Test Summary", [Tag.Create("tag1"), Tag.Create("tag4")]); + + articleRepository.Add(article_1); + articleRepository.Add(article_2); + + await articleRepository.SaveChangesAsync(CancellationToken.None); + + var request = new GetTagsQuery(); + + // Act + var response = (await sut.Handle(request, CancellationToken.None)).ToImmutableList(); + + // Assert + response.Should().NotBeNull(); + response.Should().HaveCount(3); + + response[0].Tag.Value.Should().Be("tag1"); + response[0].Count.Should().Be(2); + + response[1].Tag.Value.Should().Be("tag3"); + response[1].Count.Should().Be(1); + + response[2].Tag.Value.Should().Be("tag4"); + response[2].Count.Should().Be(1); + } + + [Fact] + public async Task Handle_ShouldReturnEmpty_WhenNoTagsExist() + { + // Arrange + var articleRepository = new ArticleRepository(_fixture.BuildDbContext(Guid.NewGuid().ToString())); + var sut = new GetTagsQueryHandler(articleRepository); + + var request = new GetTagsQuery(); + + // Act + var response = await sut.Handle(request, CancellationToken.None); + + // Assert + response.Should().NotBeNull(); + response.Should().BeEmpty(); + } +}