refactor lot matching into shared module
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.mchus.pro/mchus/quoteforge/internal/lotmatch"
|
||||
"git.mchus.pro/mchus/quoteforge/internal/models"
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
@@ -99,39 +100,42 @@ func TestParseXLSXRows(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLotResolverPrecedenceAndConflicts(t *testing.T) {
|
||||
r := &lotResolver{
|
||||
partnumberToLots: map[string][]string{
|
||||
"pn-1": {"LOT_MAPPED"},
|
||||
"pn-conflict": {"LOT_A", "LOT_B"},
|
||||
resolver := lotmatch.NewLotResolver(
|
||||
[]models.LotPartnumber{
|
||||
{Partnumber: "pn-1", LotName: "LOT_MAPPED"},
|
||||
{Partnumber: "pn-conflict", LotName: "LOT_A"},
|
||||
{Partnumber: "pn-conflict", LotName: "LOT_B"},
|
||||
},
|
||||
exactLots: map[string]string{
|
||||
"cpu_a": "CPU_A",
|
||||
[]models.Lot{
|
||||
{LotName: "CPU_A_LONG"},
|
||||
{LotName: "CPU_A"},
|
||||
{LotName: "ABC "},
|
||||
{LotName: "ABC\t"},
|
||||
},
|
||||
allLots: []string{"CPU_A_LONG", "CPU_A", "ABC ", "ABC\t"},
|
||||
}
|
||||
)
|
||||
|
||||
lot, typ, err := r.resolve("pn-1")
|
||||
lot, typ, err := resolver.Resolve("pn-1")
|
||||
if err != nil || lot != "LOT_MAPPED" || typ != "mapping_table" {
|
||||
t.Fatalf("mapping_table mismatch: lot=%s typ=%s err=%v", lot, typ, err)
|
||||
}
|
||||
|
||||
lot, typ, err = r.resolve("cpu_a")
|
||||
lot, typ, err = resolver.Resolve("cpu_a")
|
||||
if err != nil || lot != "CPU_A" || typ != "article_exact" {
|
||||
t.Fatalf("article_exact mismatch: lot=%s typ=%s err=%v", lot, typ, err)
|
||||
}
|
||||
|
||||
lot, typ, err = r.resolve("cpu_a_long_suffix")
|
||||
lot, typ, err = resolver.Resolve("cpu_a_long_suffix")
|
||||
if err != nil || lot != "CPU_A_LONG" || typ != "prefix" {
|
||||
t.Fatalf("prefix mismatch: lot=%s typ=%s err=%v", lot, typ, err)
|
||||
}
|
||||
|
||||
_, _, err = r.resolve("abx")
|
||||
if err == nil {
|
||||
t.Fatalf("expected not found error")
|
||||
_, _, err = resolver.Resolve("abx")
|
||||
if err == nil || err != lotmatch.ErrResolveNotFound {
|
||||
t.Fatalf("expected not found error, got %v", err)
|
||||
}
|
||||
|
||||
_, _, err = r.resolve("pn-conflict")
|
||||
if err == nil || err != errResolveConflict {
|
||||
_, _, err = resolver.Resolve("pn-conflict")
|
||||
if err == nil || err != lotmatch.ErrResolveConflict {
|
||||
t.Fatalf("expected conflict, got %v", err)
|
||||
}
|
||||
}
|
||||
@@ -267,6 +271,42 @@ func TestBuildWarehousePricelistItems_UsesPrefixResolver(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPartnumberMappings_WildcardMatch(t *testing.T) {
|
||||
db := openTestDB(t)
|
||||
if err := db.AutoMigrate(&models.LotPartnumber{}, &models.Lot{}); err != nil {
|
||||
t.Fatalf("automigrate: %v", err)
|
||||
}
|
||||
|
||||
mappings := []models.LotPartnumber{
|
||||
{Partnumber: "R750*", LotName: "SERVER_R750"},
|
||||
{Partnumber: "HDD-01", LotName: "HDD_01"},
|
||||
}
|
||||
if err := db.Create(&mappings).Error; err != nil {
|
||||
t.Fatalf("seed mappings: %v", err)
|
||||
}
|
||||
if err := db.Create(&models.Lot{LotName: "MEM_DDR5_16G_4800"}).Error; err != nil {
|
||||
t.Fatalf("seed lot: %v", err)
|
||||
}
|
||||
|
||||
resolver, err := lotmatch.NewMappingMatcherFromDB(db)
|
||||
if err != nil {
|
||||
t.Fatalf("NewMappingMatcherFromDB: %v", err)
|
||||
}
|
||||
|
||||
if got := resolver.MatchLots("R750XD"); len(got) != 1 || got[0] != "SERVER_R750" {
|
||||
t.Fatalf("expected wildcard match SERVER_R750, got %#v", got)
|
||||
}
|
||||
if got := resolver.MatchLots("HDD-01"); len(got) != 1 || got[0] != "HDD_01" {
|
||||
t.Fatalf("expected exact match HDD_01, got %#v", got)
|
||||
}
|
||||
if got := resolver.MatchLots("UNKNOWN"); len(got) != 0 {
|
||||
t.Fatalf("expected no matches, got %#v", got)
|
||||
}
|
||||
if got := resolver.MatchLots("MEM_DDR5_16G_4800"); len(got) != 1 || got[0] != "MEM_DDR5_16G_4800" {
|
||||
t.Fatalf("expected exact lot fallback, got %#v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func openTestDB(t *testing.T) *gorm.DB {
|
||||
t.Helper()
|
||||
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
||||
|
||||
Reference in New Issue
Block a user