internal product index
This commit is contained in:
@@ -146,6 +146,45 @@ func TestProjectionCache_BusRaceSafe(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestApply_MixedUpsertDelete verifies the realistic per-batch sequence a
|
||||
// publisher emits: a single Apply call interleaves upserts and deletes, and
|
||||
// the per-batch counters report the right split. Without this the cache could
|
||||
// drift on count semantics across batched events.
|
||||
func TestApply_MixedUpsertDelete(t *testing.T) {
|
||||
c := newCatalogProjectionCache()
|
||||
// Order matters: prior in-cache state for A is upserted twice (latest wins),
|
||||
// B is tombstoned, C cold-upserted, D cold-tombstoned.
|
||||
updates := []catalog.ProjectionUpdate{
|
||||
{Projection: catalog.Projection{SKU: "A", PriceIncVat: money.Cents(50_00)}},
|
||||
{Projection: catalog.Projection{SKU: "B"}, Deleted: true},
|
||||
{Projection: catalog.Projection{SKU: "C", PriceIncVat: money.Cents(75_00)}},
|
||||
{Projection: catalog.Projection{SKU: "A", PriceIncVat: money.Cents(60_00)}}, // later wins
|
||||
{Projection: catalog.Projection{SKU: "D"}, Deleted: true},
|
||||
}
|
||||
upserts, deletes := c.Apply(updates)
|
||||
if upserts != 3 || deletes != 2 {
|
||||
t.Fatalf("counts: upserts=%d deletes=%d, want 3/2 (A,C live-upserts; B,D tombstones)", upserts, deletes)
|
||||
}
|
||||
if got, ok := c.Get("A"); !ok || got.PriceIncVat != money.Cents(60_00) {
|
||||
t.Fatalf("A latest-wins: got %+v ok=%v, want 6000", got, ok)
|
||||
}
|
||||
if _, ok := c.Get("B"); ok {
|
||||
t.Fatalf("B: tombstoned but Get returned a value")
|
||||
}
|
||||
if !c.IsDeleted("B") {
|
||||
t.Fatalf("B: IsDeleted not true")
|
||||
}
|
||||
if got, ok := c.Get("C"); !ok || got.PriceIncVat != money.Cents(75_00) {
|
||||
t.Fatalf("C cold-upsert: got %+v ok=%v, want 7500", got, ok)
|
||||
}
|
||||
if !c.IsDeleted("D") {
|
||||
t.Fatalf("D: IsDeleted not true")
|
||||
}
|
||||
if c.Len() != 4 {
|
||||
t.Fatalf("Len() after mixed batch: %d, want 4 (A live + B tombstone + C live + D tombstone)", c.Len())
|
||||
}
|
||||
}
|
||||
|
||||
// TestTaxResolveBp covers the static TaxClass→bp mapping used by
|
||||
// ApplyProjectionOverlay. Adds a regression net for the common Nordic rates.
|
||||
func TestTaxResolveBp(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user