familynido/tests/FamilyNido.Tests/Integration/DigestTests.cs
Pablo Fernández a308041d59 Initial commit
FamilyNido — a self-hosted PWA for a single household: shared calendar,
chores, meals, school agenda, health records and a family wall. One
instance per family, deployable with `docker compose` on any home
server.

Stack: .NET 10 (ASP.NET Core Minimal APIs) + EF Core 10 + PostgreSQL 16
on the backend, Angular 21 (standalone, signals, zoneless) + Tailwind
CSS v4 on the frontend, SignalR for realtime, optional OIDC alongside
local credentials, integration via a versioned `/api/v1/**` public API.

See README.md for the module overview and how to deploy.
2026-05-13 00:23:14 +02:00

94 lines
3.3 KiB
C#

using System.Net.Http.Json;
using FamilyNido.Domain.HouseholdTasks;
using FluentAssertions;
namespace FamilyNido.Tests.Integration;
/// <summary>
/// Coverage for the manual digest preview endpoint
/// (<c>POST /api/notifications/digest/me</c>) — focused on the rule that
/// completed-today tasks must NOT appear in the email, while pending-today
/// tasks must.
/// </summary>
public sealed class DigestTests : IntegrationTestBase
{
public DigestTests(IntegrationFixture fixture) : base(fixture) { }
[Fact]
public async Task Digest_excludes_tasks_that_are_already_completed_for_today()
{
var handle = await WithDbAsync(db => TestSeed.SeedFamilyAsync(db, Fixture.Factory.Services));
await TestSeed.LoginAsync(Client, "dan@example.com");
var today = DateOnly.FromDateTime(DateTime.UtcNow);
await WithDbAsync(async db =>
{
var task = new HouseholdTask
{
FamilyId = handle.Family.Id,
Title = "Recoger el lavavajillas",
Category = "Hogar",
Recurrence = RecurrenceMode.None,
StartDate = today,
DueDate = today,
IsFloating = false,
Points = 3,
CreatedByMemberId = handle.Member.Id,
};
db.HouseholdTasks.Add(task);
await db.SaveChangesAsync();
db.TaskCompletions.Add(new TaskCompletion
{
TaskId = task.Id,
CompletedByMemberId = handle.Member.Id,
OccurrenceDate = today,
CompletedAt = DateTimeOffset.UtcNow,
});
await db.SaveChangesAsync();
});
// The only thing seeded for today is a task that is already done.
// The digest must therefore have nothing to report.
var resp = await Client.PostAsync("/api/notifications/digest/me", content: null);
resp.IsSuccessStatusCode.Should().BeTrue();
var body = await ReadAsync<DigestResponse>(resp);
body!.IsEmpty.Should().BeTrue("a task already completed today should not appear in the digest");
}
[Fact]
public async Task Digest_includes_tasks_that_are_pending_for_today()
{
var handle = await WithDbAsync(db => TestSeed.SeedFamilyAsync(db, Fixture.Factory.Services));
await TestSeed.LoginAsync(Client, "dan@example.com");
var today = DateOnly.FromDateTime(DateTime.UtcNow);
await WithDbAsync(async db =>
{
db.HouseholdTasks.Add(new HouseholdTask
{
FamilyId = handle.Family.Id,
Title = "Recoger la lavadora",
Category = "Hogar",
Recurrence = RecurrenceMode.None,
StartDate = today,
DueDate = today,
IsFloating = false,
Points = 3,
CreatedByMemberId = handle.Member.Id,
});
await db.SaveChangesAsync();
});
var resp = await Client.PostAsync("/api/notifications/digest/me", content: null);
resp.IsSuccessStatusCode.Should().BeTrue();
var body = await ReadAsync<DigestResponse>(resp);
body!.IsEmpty.Should().BeFalse("a pending task for today should be reported");
}
private sealed record DigestResponse(string Email, bool IsEmpty);
}