using System.Security.Claims; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Moq; using ROLAC.API.Data; using ROLAC.API.Data.Interceptors; using ROLAC.API.Services; using Xunit; namespace ROLAC.API.Tests.Services; public class MealAttendanceServiceTests { // MealAttendance is auditable, so the InMemory provider requires CreatedBy/UpdatedBy // to be set before insert. Wire in the AuditSaveChangesInterceptor (as the other // service tests do) so those columns are stamped automatically on SaveChanges. private static AppDbContext BuildDb() { var claims = new[] { new Claim(ClaimTypes.NameIdentifier, "test-user") }; var ctx = new DefaultHttpContext { User = new(new ClaimsIdentity(claims)) }; var mock = new Mock(); mock.Setup(x => x.HttpContext).Returns(ctx); return new AppDbContext(new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .AddInterceptors(new AuditSaveChangesInterceptor( new ROLAC.API.Services.Logging.CurrentUserAccessor(mock.Object))).Options); } [Fact] public async Task SetCountsAsync_CreatesRowWhenMissing_AndReturnsTotals() { using var db = BuildDb(); var svc = new MealAttendanceService(db); var date = new DateOnly(2026, 5, 31); var result = await svc.SetCountsAsync(date, adult: 40, youth: 12, kid: 8); Assert.Equal("2026-05-31", result.Date); Assert.Equal(40, result.Adult); Assert.Equal(12, result.Youth); Assert.Equal(8, result.Kid); Assert.Single(db.MealAttendances.Where(a => a.AttendanceDate == date)); } [Fact] public async Task SetCountsAsync_OverwritesExistingRow_AndClampsNegativesToZero() { using var db = BuildDb(); var svc = new MealAttendanceService(db); var date = new DateOnly(2026, 5, 31); await svc.SetCountsAsync(date, 40, 12, 8); var result = await svc.SetCountsAsync(date, adult: 50, youth: -3, kid: 0); Assert.Equal(50, result.Adult); Assert.Equal(0, result.Youth); // negative clamped to zero Assert.Equal(0, result.Kid); Assert.Single(db.MealAttendances.Where(a => a.AttendanceDate == date)); // still one row } }