using JobTrackerApi.Controllers; using JobTrackerApi.Data; using JobTrackerApi.Models; using JobTrackerApi.Services; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Moq; using Xunit; namespace JobTrackerApi.Tests; public sealed class CareerEvidenceControllerTests { [Fact] public async Task Evidence_is_user_approved_tenant_scoped_and_deletable() { var current = new Mock(); current.SetupGet(x => x.UserId).Returns("owner-1"); await using var db = new JobTrackerContext(new DbContextOptionsBuilder().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options, current.Object); var controller = new CareerEvidenceController(db, Users("owner-1").Object); var request = new CareerEvidenceController.EvidenceRequest("achievement", "Reduced incidents", "Introduced tested deployment rollback.", ["deployment", "reliability"], "manual", "production retrospective", true); var created = Assert.IsType(Assert.IsType((await controller.Create(request, default)).Result).Value); Assert.True(created.IsVerified); Assert.Equal(["deployment", "reliability"], created.Tags); db.CareerEvidence.Add(new CareerEvidence { OwnerUserId = "owner-2", Title = "Private", Statement = "Other tenant" }); await db.SaveChangesAsync(); var listed = Assert.IsAssignableFrom>(Assert.IsType((await controller.List(default)).Result).Value).ToList(); Assert.Single(listed); Assert.Equal("Reduced incidents", listed[0].Title); Assert.IsType(await controller.Delete(created.Id, default)); Assert.Empty(await db.CareerEvidence.Where(x => x.OwnerUserId == "owner-1").ToListAsync()); } [Fact] public async Task List_orders_owned_evidence_by_actual_timestamp_with_sqlite() { await using var connection = new SqliteConnection("Data Source=:memory:"); await connection.OpenAsync(); var current = new Mock(); current.SetupGet(x => x.UserId).Returns("owner-1"); await using var db = new JobTrackerContext(new DbContextOptionsBuilder().UseSqlite(connection).Options, current.Object); await db.Database.EnsureCreatedAsync(); db.CareerEvidence.AddRange( new CareerEvidence { OwnerUserId = "owner-1", Title = "Older local clock", Statement = "Owned earlier fact", UpdatedAtUtc = DateTimeOffset.Parse("2026-10-11T22:00:00+02:00") }, new CareerEvidence { OwnerUserId = "owner-1", Title = "Newer instant", Statement = "Owned later fact", UpdatedAtUtc = DateTimeOffset.Parse("2026-10-11T20:30:00+00:00") }, new CareerEvidence { OwnerUserId = "owner-2", Title = "Private future fact", Statement = "Other tenant", UpdatedAtUtc = DateTimeOffset.Parse("2026-10-12T12:00:00+00:00") }); await db.SaveChangesAsync(); var controller = new CareerEvidenceController(db, Users("owner-1").Object); var listed = Assert.IsAssignableFrom>(Assert.IsType((await controller.List(default)).Result).Value).ToList(); Assert.Equal(["Newer instant", "Older local clock"], listed.Select(x => x.Title)); Assert.Equal(3, await db.CareerEvidence.IgnoreQueryFilters().CountAsync()); } private static Mock> Users(string id) { var store = new Mock>(); var manager = new Mock>(store.Object, null!, null!, null!, null!, null!, null!, null!, null!); manager.Setup(x => x.GetUserAsync(It.IsAny())).ReturnsAsync(new ApplicationUser { Id = id }); return manager; } }