mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 06:03:12 +00:00
fix: omit unmapped sites from work order options
This commit is contained in:
parent
5a70d5004e
commit
2d4b51f9f1
7 changed files with 69 additions and 15 deletions
|
|
@ -46,10 +46,10 @@ public class LocationControllerSitesTests
|
|||
private static async Task SeedSitesAsync(ApplicationDbContext ctx)
|
||||
{
|
||||
ctx.Locations.AddRange(
|
||||
new Locations { Id = 1, Name = "STL8", City = "St. Louis", State = "MO" },
|
||||
new Locations { Id = 2, Name = "BK5", City = "Dallas", State = "TX" },
|
||||
new Locations { Id = 3, Name = "IND9", City = "Indianapolis", State = "IN" },
|
||||
new Locations { Id = 4, Name = "DFW8", City = "Dallas", State = "TX" });
|
||||
new Locations { Id = 1, Name = "STL8", City = "St. Louis", State = "MO", AccountId = 100 },
|
||||
new Locations { Id = 2, Name = "BK5", City = "Dallas", State = "TX", AccountId = 100 },
|
||||
new Locations { Id = 3, Name = "IND9", City = "Indianapolis", State = "IN", AccountId = 100 },
|
||||
new Locations { Id = 4, Name = "DFW8", City = "Dallas", State = "TX", AccountId = 100 });
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
|
@ -107,4 +107,44 @@ public class LocationControllerSitesTests
|
|||
data.Should().HaveCount(2);
|
||||
data.Select(s => s.Code).Should().BeEquivalentTo("BK5", "DFW8");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSites_OmitsLocationsWithoutAccountMapping()
|
||||
{
|
||||
await using var ctx = NewContext();
|
||||
ctx.Locations.AddRange(
|
||||
new Locations { Id = 1, Name = "STL8", City = "St. Louis", State = "MO", AccountId = 100 },
|
||||
new Locations { Id = 2, Name = "UNMAPPED1", City = "Nowhere", State = "ZZ" });
|
||||
await ctx.SaveChangesAsync();
|
||||
var controller = NewController(ctx);
|
||||
|
||||
var result = await controller.GetSites();
|
||||
|
||||
var ok = result.Should().BeOfType<OkObjectResult>().Subject;
|
||||
var data = ok.Value.Should().BeAssignableTo<IReadOnlyList<SiteOptionDTO>>().Subject;
|
||||
|
||||
data.Should().ContainSingle();
|
||||
data[0].Code.Should().Be("STL8");
|
||||
|
||||
var searchResult = await controller.GetSites("unmapped1");
|
||||
|
||||
var searchOk = searchResult.Should().BeOfType<OkObjectResult>().Subject;
|
||||
var searchData = searchOk.Value.Should().BeAssignableTo<IReadOnlyList<SiteOptionDTO>>().Subject;
|
||||
|
||||
searchData.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSites_ForwardsCancellationToken()
|
||||
{
|
||||
await using var ctx = NewContext();
|
||||
await SeedSitesAsync(ctx);
|
||||
var controller = NewController(ctx);
|
||||
using var cancellation = new CancellationTokenSource();
|
||||
await cancellation.CancelAsync();
|
||||
|
||||
var act = () => controller.GetSites(cancellationToken: cancellation.Token);
|
||||
|
||||
await act.Should().ThrowAsync<OperationCanceledException>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,9 +26,11 @@ namespace Api.SeaHavenIndustries.Controllers
|
|||
}
|
||||
|
||||
[HttpGet("sites")]
|
||||
public async Task<IActionResult> GetSites(string? search = null)
|
||||
public async Task<IActionResult> GetSites(
|
||||
string? search = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var data = await _locationService.GetSiteOptionsAsync(search);
|
||||
var data = await _locationService.GetSiteOptionsAsync(search, cancellationToken);
|
||||
return Ok(data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,9 +74,13 @@ namespace SeaHaven.DataServices.Implementation
|
|||
return (items, totalCount);
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<SiteOptionRow>> GetSiteOptionsAsync(string? search = null)
|
||||
public async Task<IReadOnlyList<SiteOptionRow>> GetSiteOptionsAsync(
|
||||
string? search = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var query = _context.Locations.AsNoTracking();
|
||||
var query = _context.Locations
|
||||
.AsNoTracking()
|
||||
.Where(l => l.AccountId != null);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(search))
|
||||
{
|
||||
|
|
@ -89,7 +93,7 @@ namespace SeaHaven.DataServices.Implementation
|
|||
return await query
|
||||
.OrderBy(l => l.Name)
|
||||
.Select(l => new SiteOptionRow(l.Id, l.Name, l.City, l.State))
|
||||
.ToListAsync();
|
||||
.ToListAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<Locations> AddAsync(Locations location)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ namespace SeaHaven.DataServices.Interfaces
|
|||
// For addressbook endpoint - returns simplified DTO
|
||||
Task<(IEnumerable<object> Items, int TotalCount)> GetAddressbookPagedAsync(int page, int pageSize, string? search = null);
|
||||
|
||||
Task<IReadOnlyList<SiteOptionRow>> GetSiteOptionsAsync(string? search = null);
|
||||
Task<IReadOnlyList<SiteOptionRow>> GetSiteOptionsAsync(
|
||||
string? search = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Exists is false when the row is missing. AccountId is null when the site has no account.
|
||||
|
|
|
|||
|
|
@ -64,9 +64,11 @@ namespace SeaHaven.Services.Implementation
|
|||
};
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<SiteOptionDTO>> GetSiteOptionsAsync(string? search = null)
|
||||
public async Task<IReadOnlyList<SiteOptionDTO>> GetSiteOptionsAsync(
|
||||
string? search = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var rows = await _locationDataService.GetSiteOptionsAsync(search);
|
||||
var rows = await _locationDataService.GetSiteOptionsAsync(search, cancellationToken);
|
||||
return rows
|
||||
.Select(r => new SiteOptionDTO
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ namespace SeaHaven.Services.Interfaces
|
|||
Task<IEnumerable<LocationDTO>> GetAllLocationsAsync();
|
||||
Task<IEnumerable<LocationDTO>> GetLocationsByAccountIdAsync(int accountId);
|
||||
Task<PagedResult<LocationDTO>> GetLocationsPagedAsync(int page, int pageSize, string? search = null);
|
||||
Task<IReadOnlyList<SiteOptionDTO>> GetSiteOptionsAsync(string? search = null);
|
||||
Task<IReadOnlyList<SiteOptionDTO>> GetSiteOptionsAsync(
|
||||
string? search = null,
|
||||
CancellationToken cancellationToken = default);
|
||||
Task<LocationDTO> CreateLocationAsync(CreateLocationDTO dto, string userId);
|
||||
Task<LocationDTO> UpdateLocationAsync(int id, UpdateLocationDTO dto, string userId);
|
||||
Task DeleteLocationAsync(int id, string userId);
|
||||
|
|
|
|||
|
|
@ -816,8 +816,10 @@ public class WorkOrderAccountScopeTests
|
|||
=> _inner.GetPagedAsync(page, pageSize, search);
|
||||
public Task<(IEnumerable<object> Items, int TotalCount)> GetAddressbookPagedAsync(int page, int pageSize, string? search = null)
|
||||
=> _inner.GetAddressbookPagedAsync(page, pageSize, search);
|
||||
public Task<IReadOnlyList<SiteOptionRow>> GetSiteOptionsAsync(string? search = null)
|
||||
=> _inner.GetSiteOptionsAsync(search);
|
||||
public Task<IReadOnlyList<SiteOptionRow>> GetSiteOptionsAsync(
|
||||
string? search = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> _inner.GetSiteOptionsAsync(search, cancellationToken);
|
||||
|
||||
public Task<(bool Exists, int? AccountId)> GetAccountScopeAsync(
|
||||
int locationId,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue