Files
PowderCoatingLogix/tests/PowderCoating.UnitTests/InventoryDuplicateMatcherTests.cs
T
spouliot 517e452c64 Add inventory duplicate detection on add and label scan
Introduce a shared InventoryDuplicateMatcher (SKU, manufacturer part number,
manufacturer color) used by both manual inventory creation and powder-label
scanning, so the two paths flag duplicates consistently. Surfaces a duplicate
warning in the Create/Edit forms via inventory-duplicate-check.js and the
catalog-lookup / label-scan flows. Callers pass tenant-restricted inventory;
the matcher re-checks CompanyId as defense in depth.

Adds InventoryDuplicateMatcherTests covering the match precedence.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 19:39:24 -04:00

168 lines
4.6 KiB
C#

using PowderCoating.Application.Services;
using PowderCoating.Core.Entities;
namespace PowderCoating.UnitTests;
public class InventoryDuplicateMatcherTests
{
[Fact]
public void Find_SkuMatch_IsRestrictedToRequestedCompany()
{
var otherTenantItem = Item(
id: 1,
companyId: 22,
sku: "POW-001",
manufacturer: "Prismatic Powders",
colorName: "Illusion Malbec");
var result = InventoryDuplicateMatcher.Find(
new[] { otherTenantItem },
companyId: 11,
sku: "POW-001",
manufacturer: null,
manufacturerPartNumber: null,
colorName: null,
isCoating: false);
Assert.Null(result);
}
[Fact]
public void Find_SkuMatch_IsCaseAndWhitespaceInsensitive()
{
var item = Item(1, 11, "POW-001", null, null);
var result = InventoryDuplicateMatcher.Find(
new[] { item },
companyId: 11,
sku: " pow-001 ",
manufacturer: null,
manufacturerPartNumber: null,
colorName: null,
isCoating: false);
Assert.NotNull(result);
Assert.Equal(InventoryDuplicateMatchType.Sku, result!.MatchType);
Assert.Same(item, result.Item);
}
[Fact]
public void Find_PowderManufacturerAndColor_NormalizesSpacingAndCase()
{
var item = Item(
id: 1,
companyId: 11,
sku: "POW-001",
manufacturer: "Prismatic Powders",
colorName: "Illusion Malbec");
var result = InventoryDuplicateMatcher.Find(
new[] { item },
companyId: 11,
sku: null,
manufacturer: " prismatic powders ",
manufacturerPartNumber: null,
colorName: "illusion malbec",
isCoating: true);
Assert.NotNull(result);
Assert.Equal(InventoryDuplicateMatchType.ManufacturerColor, result!.MatchType);
}
[Fact]
public void Find_SameColorFromDifferentManufacturer_IsNotDuplicate()
{
var item = Item(
id: 1,
companyId: 11,
sku: "POW-001",
manufacturer: "Prismatic Powders",
colorName: "Gloss Black");
var result = InventoryDuplicateMatcher.Find(
new[] { item },
companyId: 11,
sku: null,
manufacturer: "Columbia Coatings",
manufacturerPartNumber: null,
colorName: "Gloss Black",
isCoating: true);
Assert.Null(result);
}
[Fact]
public void Find_ManufacturerPartNumber_UsesSharedPowderRule()
{
var item = Item(
id: 1,
companyId: 11,
sku: "POW-001",
manufacturer: "Columbia Coatings",
colorName: "Smokey Blue",
manufacturerPartNumber: "S5704126");
var result = InventoryDuplicateMatcher.Find(
new[] { item },
companyId: 11,
sku: null,
manufacturer: "columbia coatings",
manufacturerPartNumber: " s5704126 ",
colorName: null,
isCoating: true);
Assert.NotNull(result);
Assert.Equal(InventoryDuplicateMatchType.ManufacturerPartNumber, result!.MatchType);
}
[Fact]
public void Find_NonCoating_DoesNotUsePowderIdentityRules()
{
var item = Item(
id: 1,
companyId: 11,
sku: "SUP-001",
manufacturer: "Acme",
colorName: "Blue");
var result = InventoryDuplicateMatcher.Find(
new[] { item },
companyId: 11,
sku: null,
manufacturer: "Acme",
manufacturerPartNumber: null,
colorName: "Blue",
isCoating: false);
Assert.Null(result);
}
private static InventoryItem Item(
int id,
int companyId,
string sku,
string? manufacturer,
string? colorName,
string? manufacturerPartNumber = null)
{
return new InventoryItem
{
Id = id,
CompanyId = companyId,
SKU = sku,
Name = colorName ?? sku,
Manufacturer = manufacturer,
ManufacturerPartNumber = manufacturerPartNumber,
ColorName = colorName,
InventoryCategory = new InventoryCategoryLookup
{
Id = id,
CompanyId = companyId,
DisplayName = "Powder",
CategoryCode = "POWDER",
IsCoating = true
}
};
}
}