using System.Net.Http.Json;
using FluentAssertions;
namespace FamilyNido.Tests.Integration;
///
/// Coverage for /api/school: profile upsert, holidays, weekly day-schedule
/// patterns and per-date exceptions, plus the overview resolver that merges
/// them into resolved per-day rows.
///
public sealed class SchoolTests : IntegrationTestBase
{
public SchoolTests(IntegrationFixture fixture) : base(fixture) { }
[Fact]
public async Task Holiday_added_then_listed_in_overview()
{
var handle = await WithDbAsync(db => TestSeed.SeedFamilyAsync(db, Fixture.Factory.Services));
await TestSeed.LoginAsync(Client, "dan@example.com");
var today = DateOnly.FromDateTime(DateTime.UtcNow);
var add = await Client.PostAsJsonAsync("/api/school/holidays", new
{
startDate = today.ToString("yyyy-MM-dd"),
endDate = today.AddDays(2).ToString("yyyy-MM-dd"),
label = "Festivo de prueba",
});
add.IsSuccessStatusCode.Should().BeTrue();
var resp = await Client.GetAsync(
$"/api/school/overview?from={today:yyyy-MM-dd}&to={today.AddDays(2):yyyy-MM-dd}");
var overview = await ReadAsync(resp);
overview!.Holidays.Should().Contain(h => h.Label == "Festivo de prueba");
}
[Fact]
public async Task Day_schedule_pattern_persists_for_a_kid()
{
var handle = await WithDbAsync(db => TestSeed.SeedFamilyAsync(db, Fixture.Factory.Services));
await TestSeed.LoginAsync(Client, "dan@example.com");
// A child member to schedule.
var bob = await WithDbAsync(db => TestSeed.SeedMemberAsync(db, handle.Family.Id, "Bob"));
var resp = await Client.PutAsJsonAsync(
$"/api/school/members/{bob.Id}/day-schedule",
new
{
slots = new[]
{
new
{
dayOfWeek = "Monday",
dropoffMemberId = (Guid?)handle.Member.Id,
pickupMemberId = (Guid?)null,
},
},
});
resp.IsSuccessStatusCode.Should().BeTrue();
var today = DateOnly.FromDateTime(DateTime.UtcNow);
var monday = today;
for (var i = 0; i < 14; i++)
{
if (today.AddDays(i).DayOfWeek == DayOfWeek.Monday)
{
monday = today.AddDays(i);
break;
}
}
var ovResp = await Client.GetAsync(
$"/api/school/overview?from={monday:yyyy-MM-dd}&to={monday:yyyy-MM-dd}");
var ov = await ReadAsync(ovResp);
ov!.ResolvedDays.Should().Contain(d => d.MemberId == bob.Id && d.DropoffMemberId == handle.Member.Id);
}
private sealed record OverviewDto(
List Holidays,
List ResolvedDays);
private sealed record HolidayDto(Guid Id, string StartDate, string EndDate, string Label);
private sealed record ResolvedDayDto(
Guid MemberId,
string Date,
Guid? DropoffMemberId,
Guid? PickupMemberId);
}