mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-10-05 10:42:08 +00:00
Merge pull request #133 from Sea-Haven-Industries/feat/ab/sh-348-dashboard-region
Some checks are pending
Validate and deploy / Validate deployable source bundle (push) Waiting to run
Validate and deploy / Deploy shoc-backend-dev through Terraform (push) Blocked by required conditions
Validate and deploy / Deploy shoc-backend-staging to Elastic Beanstalk (push) Blocked by required conditions
Some checks are pending
Validate and deploy / Validate deployable source bundle (push) Waiting to run
Validate and deploy / Deploy shoc-backend-dev through Terraform (push) Blocked by required conditions
Validate and deploy / Deploy shoc-backend-staging to Elastic Beanstalk (push) Blocked by required conditions
SH-348: Add dashboard region metrics
This commit is contained in:
commit
782165a4cf
3 changed files with 53 additions and 4 deletions
|
|
@ -358,11 +358,17 @@ public class DashboardServiceTests
|
||||||
ctx.Locations.AddRange(
|
ctx.Locations.AddRange(
|
||||||
new Locations { Id = 1, State = "NY" },
|
new Locations { Id = 1, State = "NY" },
|
||||||
new Locations { Id = 2, State = "ca" },
|
new Locations { Id = 2, State = "ca" },
|
||||||
new Locations { Id = 3, State = "XX" });
|
new Locations { Id = 3, State = "XX" },
|
||||||
|
new Locations { Id = 4, State = "indiana" },
|
||||||
|
new Locations { Id = 5, State = "NEW YORK" },
|
||||||
|
new Locations { Id = 6, State = "California" });
|
||||||
ctx.workOrders.AddRange(
|
ctx.workOrders.AddRange(
|
||||||
new WorkOrder { AccountId = 1, LocationId = 1 },
|
new WorkOrder { AccountId = 1, LocationId = 1 },
|
||||||
new WorkOrder { AccountId = 1, LocationId = 2 },
|
new WorkOrder { AccountId = 1, LocationId = 2 },
|
||||||
new WorkOrder { AccountId = 1, LocationId = 3 },
|
new WorkOrder { AccountId = 1, LocationId = 3 },
|
||||||
|
new WorkOrder { AccountId = 1, LocationId = 4 },
|
||||||
|
new WorkOrder { AccountId = 1, LocationId = 5 },
|
||||||
|
new WorkOrder { AccountId = 1, LocationId = 6 },
|
||||||
new WorkOrder { AccountId = 1, LocationId = null });
|
new WorkOrder { AccountId = 1, LocationId = null });
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
|
||||||
|
|
@ -371,7 +377,28 @@ public class DashboardServiceTests
|
||||||
|
|
||||||
result.Items.Select(row => row.Region).Should().Equal(
|
result.Items.Select(row => row.Region).Should().Equal(
|
||||||
"East", "Central", "West", "California", "Unmapped/Other");
|
"East", "Central", "West", "California", "Unmapped/Other");
|
||||||
result.Items.Select(row => row.WorkOrderCount).Should().Equal(1, 0, 0, 1, 2);
|
// NY + "NEW YORK" -> East; "indiana" -> Central; "ca" + "California" -> California;
|
||||||
|
// "XX" + unassigned location -> Unmapped/Other. Full-name storage forms must not
|
||||||
|
// fall through to Unmapped/Other (SH-348 review).
|
||||||
|
result.Items.Select(row => row.WorkOrderCount).Should().Equal(2, 1, 0, 2, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Resolve_MapsEveryUsStateAndItsFullNameToACanonicalBucket()
|
||||||
|
{
|
||||||
|
foreach (var code in UsStateCodes.All)
|
||||||
|
{
|
||||||
|
var byCode = DashboardRegions.Resolve(code);
|
||||||
|
byCode.Should().NotBe(
|
||||||
|
"Unmapped/Other",
|
||||||
|
$"state code {code} must belong to a canonical region");
|
||||||
|
|
||||||
|
var fullName = UsStateCodes.ExpandStorageValues(new[] { code })
|
||||||
|
.First(value => value != code);
|
||||||
|
DashboardRegions.Resolve(fullName).Should().Be(
|
||||||
|
byCode,
|
||||||
|
$"the full-name storage form of {code} must resolve to the same region as the code");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,11 @@ public static class DashboardRegions
|
||||||
|
|
||||||
public static string Resolve(string? state)
|
public static string Resolve(string? state)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(state))
|
var code = UsStateCodes.ToCode(state);
|
||||||
|
if (code is null)
|
||||||
return "Unmapped/Other";
|
return "Unmapped/Other";
|
||||||
|
|
||||||
return StateToRegion.TryGetValue(state.Trim().ToUpperInvariant(), out var region)
|
return StateToRegion.TryGetValue(code, out var region)
|
||||||
? region
|
? region
|
||||||
: "Unmapped/Other";
|
: "Unmapped/Other";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,29 @@ namespace SeaHaven.Services.Helpers
|
||||||
["WY"] = "WYOMING"
|
["WY"] = "WYOMING"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static readonly IReadOnlyDictionary<string, string> CodesByName =
|
||||||
|
Names.ToDictionary(pair => pair.Value, pair => pair.Key, StringComparer.Ordinal);
|
||||||
|
|
||||||
public static IReadOnlySet<string> All { get; } = new HashSet<string>(Names.Keys, StringComparer.Ordinal);
|
public static IReadOnlySet<string> All { get; } = new HashSet<string>(Names.Keys, StringComparer.Ordinal);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Normalises a stored state value to its two-letter postal code. Accepts either a
|
||||||
|
/// postal code ("IN") or a full state name ("Indiana"), case-insensitively, matching
|
||||||
|
/// the storage forms produced by <see cref="ExpandStorageValues"/>. Returns null when
|
||||||
|
/// the value is blank or is not a recognised US state.
|
||||||
|
/// </summary>
|
||||||
|
public static string? ToCode(string? value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var normalized = value.Trim().ToUpperInvariant();
|
||||||
|
if (All.Contains(normalized))
|
||||||
|
return normalized;
|
||||||
|
|
||||||
|
return CodesByName.TryGetValue(normalized, out var code) ? code : null;
|
||||||
|
}
|
||||||
|
|
||||||
public static IReadOnlyCollection<string> ExpandStorageValues(IEnumerable<string> codes)
|
public static IReadOnlyCollection<string> ExpandStorageValues(IEnumerable<string> codes)
|
||||||
{
|
{
|
||||||
return codes
|
return codes
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue