diff --git a/src/backend/src/FoodDiary.API/Mapping/PagesMapper.cs b/src/backend/src/FoodDiary.API/Mapping/PagesMapper.cs new file mode 100644 index 000000000..623cdea2b --- /dev/null +++ b/src/backend/src/FoodDiary.API/Mapping/PagesMapper.cs @@ -0,0 +1,16 @@ +using FoodDiary.API.Dtos; +using FoodDiary.Domain.Entities; +using FoodDiary.Domain.Utils; + +namespace FoodDiary.API.Mapping; + +public static class PagesMapper +{ + public static PageItemDto ToPageItemDto(this Page page, ICaloriesCalculator caloriesCalculator) => new() + { + Id = page.Id, + Date = page.Date.ToString("yyyy-MM-dd"), + CountNotes = page.Notes.Count, + CountCalories = caloriesCalculator.Calculate(page.Notes) + }; +} \ No newline at end of file diff --git a/src/backend/tests/FoodDiary.ComponentTests/Dsl/Create.cs b/src/backend/tests/FoodDiary.ComponentTests/Dsl/Create.cs index fa76527d9..3881d9d84 100644 --- a/src/backend/tests/FoodDiary.ComponentTests/Dsl/Create.cs +++ b/src/backend/tests/FoodDiary.ComponentTests/Dsl/Create.cs @@ -4,6 +4,7 @@ public static class Create { public static CategoryBuilder Category(string? name = null) => new(name); public static PageBuilder Page(string date) => new(date); + public static PagesListBuilder PagesList(int count) => new(count); public static ProductBuilder Product(string name) => new(name); public static NoteBuilder Note() => new(); diff --git a/src/backend/tests/FoodDiary.ComponentTests/Dsl/PageBuilder.cs b/src/backend/tests/FoodDiary.ComponentTests/Dsl/PageBuilder.cs index 2b09bad36..d4d59f6d0 100644 --- a/src/backend/tests/FoodDiary.ComponentTests/Dsl/PageBuilder.cs +++ b/src/backend/tests/FoodDiary.ComponentTests/Dsl/PageBuilder.cs @@ -6,7 +6,8 @@ public class PageBuilder { private readonly Page _page = new() { - Id = Random.Shared.Next() + Id = Random.Shared.Next(), + Notes = new List() }; public PageBuilder(string date) diff --git a/src/backend/tests/FoodDiary.ComponentTests/Dsl/PagesListBuilder.cs b/src/backend/tests/FoodDiary.ComponentTests/Dsl/PagesListBuilder.cs new file mode 100644 index 000000000..903076fc4 --- /dev/null +++ b/src/backend/tests/FoodDiary.ComponentTests/Dsl/PagesListBuilder.cs @@ -0,0 +1,42 @@ +using FoodDiary.Domain.Entities; + +namespace FoodDiary.ComponentTests.Dsl; + +public class PagesListBuilder +{ + private readonly int _count; + private DateOnly _startDate = DateOnly.FromDateTime(DateTime.UtcNow); + private int _intervalInDays = 1; + + public PagesListBuilder(int count) + { + _count = count; + } + + public Page[] Please() + { + var pages = new List(_count); + var currentDate = _startDate; + + for (var i = 0; i < _count; i++) + { + var page = Create.Page(currentDate.ToString("O")).Please(); + pages.Add(page); + currentDate = currentDate.AddDays(_intervalInDays); + } + + return pages.ToArray(); + } + + public PagesListBuilder StartingFrom(string date) + { + _startDate = DateOnly.Parse(date); + return this; + } + + public PagesListBuilder WithOneDayInterval() + { + _intervalInDays = 1; + return this; + } +} \ No newline at end of file diff --git a/src/backend/tests/FoodDiary.ComponentTests/Scenarios/Pages/PagesApiContext.cs b/src/backend/tests/FoodDiary.ComponentTests/Scenarios/Pages/PagesApiContext.cs new file mode 100644 index 000000000..55af8ac34 --- /dev/null +++ b/src/backend/tests/FoodDiary.ComponentTests/Scenarios/Pages/PagesApiContext.cs @@ -0,0 +1,43 @@ +using System.Net.Http.Json; +using FoodDiary.API.Dtos; +using FoodDiary.API.Mapping; +using FoodDiary.ComponentTests.Infrastructure; +using FoodDiary.Domain.Entities; +using FoodDiary.Domain.Utils; +using Microsoft.Extensions.DependencyInjection; + +namespace FoodDiary.ComponentTests.Scenarios.Pages; + +public class PagesApiContext : BaseContext +{ + private PagesSearchResultDto? _pagesSearchResult; + + public PagesApiContext(FoodDiaryWebApplicationFactory factory) : base(factory) + { + } + + public Task Given_pages(params Page[] pages) + { + return Factory.SeedDataAsync(pages); + } + + public async Task When_user_retieves_pages_list_from_to(string from, string to) + { + _pagesSearchResult = await ApiClient.GetFromJsonAsync( + $"/api/v1/pages?startDate={from}&endDate={to}"); + } + + public Task Then_pages_list_contains_total_items_count(int count) + { + _pagesSearchResult?.TotalPagesCount.Should().Be(count); + return Task.CompletedTask; + } + + public Task Then_pages_list_contains_items(params Page[] items) + { + var caloriesCalculator = Factory.Services.GetRequiredService(); + var expectedPageItems = items.Select(p => p.ToPageItemDto(caloriesCalculator)); + _pagesSearchResult?.PageItems.Should().BeEquivalentTo(expectedPageItems); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/src/backend/tests/FoodDiary.ComponentTests/Scenarios/Pages/PagesApiTests.cs b/src/backend/tests/FoodDiary.ComponentTests/Scenarios/Pages/PagesApiTests.cs new file mode 100644 index 000000000..be172c43c --- /dev/null +++ b/src/backend/tests/FoodDiary.ComponentTests/Scenarios/Pages/PagesApiTests.cs @@ -0,0 +1,29 @@ +using FoodDiary.ComponentTests.Dsl; +using FoodDiary.ComponentTests.Infrastructure; + +namespace FoodDiary.ComponentTests.Scenarios.Pages; + +public class PagesApiTests : ScenarioBase +{ + public PagesApiTests(FoodDiaryWebApplicationFactory factory) : base(factory, () => new PagesApiContext(factory)) + { + } + + [Scenario] + public Task I_can_retrieve_pages_list() + { + var pages = Create.PagesList(5) + .StartingFrom("2024-01-01") + .WithOneDayInterval() + .Please(); + + var expectedPages = pages[1..4]; + + return Run( + c => c.Given_authenticated_user(), + c => c.Given_pages(pages), + c => c.When_user_retieves_pages_list_from_to("2024-01-02", "2024-01-04"), + c => c.Then_pages_list_contains_total_items_count(3), + c => c.Then_pages_list_contains_items(expectedPages)); + } +} \ No newline at end of file