using Data.SeaHavenIndustries; using FluentAssertions; using Microsoft.EntityFrameworkCore; using SeaHaven.DataServices.Implementation; using Xunit; namespace Api.SeaHavenIndustries.Tests; public class LocationDataServiceTests { private static ApplicationDbContext NewContext() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; return new ApplicationDbContext(options); } private static async Task SeedAsync(ApplicationDbContext ctx) { ctx.Locations.AddRange( new Locations { Id = 1, Name = "Alpha Site", City = "Austin", State = "TX" }, new Locations { Id = 2, Name = "Beta Site", City = "Dallas", State = "TX" }, new Locations { Id = 3, Name = "Gamma Yard", City = "Kansas City", State = "MO" }, new Locations { Id = 4, Name = "Delta Hub", City = "Indianapolis", State = "indiana" }, new Locations { Id = 5, Name = "Epsilon Depot", City = "Houston", State = "TX" }, new Locations { Id = 6, Name = "Zeta Lot", City = "Nowhere", State = null }); await ctx.SaveChangesAsync(); } [Fact] public async Task GetListPagedAsync_WithoutStates_ReturnsAllRows() { await using var ctx = NewContext(); await SeedAsync(ctx); var (items, totalCount) = await new LocationDataService(ctx) .GetListPagedAsync(1, 10, null, null, CancellationToken.None); totalCount.Should().Be(6); items.Should().HaveCount(6); } [Fact] public async Task GetListPagedAsync_AppliesStatesFilterBeforeCountAndPaging() { await using var ctx = NewContext(); await SeedAsync(ctx); var (page1, totalCount) = await new LocationDataService(ctx) .GetListPagedAsync(1, 2, null, new[] { "TX" }, CancellationToken.None); totalCount.Should().Be(3, "count must reflect the state filter, not the whole table"); page1.Should().HaveCount(2); page1.Select(l => l.Name).Should().ContainInOrder("Alpha Site", "Beta Site"); var (page2, totalCountAgain) = await new LocationDataService(ctx) .GetListPagedAsync(2, 2, null, new[] { "TX" }, CancellationToken.None); totalCountAgain.Should().Be(3); page2.Select(l => l.Name).Should().ContainSingle("Epsilon Depot"); } [Fact] public async Task GetListPagedAsync_MultipleStates_KeepSearchFilter() { await using var ctx = NewContext(); await SeedAsync(ctx); var (items, totalCount) = await new LocationDataService(ctx) .GetListPagedAsync(1, 10, "Dallas", new[] { "TX", "MO" }, CancellationToken.None); totalCount.Should().Be(1); items.Should().ContainSingle().Which.Name.Should().Be("Beta Site"); } [Fact] public async Task GetListPagedAsync_StatesFilter_ExcludesNullAndNonMatchingStates() { await using var ctx = NewContext(); await SeedAsync(ctx); var (items, totalCount) = await new LocationDataService(ctx) .GetListPagedAsync(1, 10, null, new[] { "IN", "INDIANA", "MO", "MISSOURI" }, CancellationToken.None); totalCount.Should().Be(2); items.Select(l => l.State).Should().BeEquivalentTo("indiana", "MO"); } }