import { expect, test } from "bun:test"; import { scoreSupplierProduct } from "./supplier-scoring.ts"; import type { KeepaData, ProductRecord, SpApiData } from "../types.ts"; function record(overrides: Partial = {}): ProductRecord { return { asin: "B000000001", name: "Test Product", unitCost: 10, ...overrides, }; } function keepa(overrides: Partial = {}): KeepaData { return { currentPrice: 30, avgPrice90: 29, minPrice90: 25, maxPrice90: 35, salesRank: 8_000, salesRankAvg90: 10_000, salesRankDrops30: 80, salesRankDrops90: 220, sellerCount: 4, amazonIsSeller: false, amazonBuyboxSharePct90d: 0, buyBoxSeller: "SELLER", buyBoxPrice: 30, buyBoxAvg90: 29, monthlySold: 350, categoryTree: ["Grocery"], ...overrides, }; } function spApi(overrides: Partial = {}): SpApiData { return { fbaFee: 5, fbmFee: 3, referralFeePercent: 15, estimatedSalePrice: 30, canSell: true, sellabilityStatus: "available", sellabilityReason: "ok", ...overrides, }; } test("profitable high-demand product ranks above competitive product", () => { const strong = scoreSupplierProduct(record(), keepa(), spApi()); const competitive = scoreSupplierProduct( record(), keepa({ sellerCount: 35, amazonIsSeller: true, amazonBuyboxSharePct90d: 90, }), spApi(), ); expect(strong.verdict).toBe("BUY"); expect(strong.score).toBeGreaterThan(competitive.score); }); test("missing cost skips", () => { const score = scoreSupplierProduct(record({ unitCost: 0 }), keepa(), spApi()); expect(score.verdict).toBe("SKIP"); expect(score.reason).toContain("unit cost"); }); test("restricted ASIN skips", () => { const score = scoreSupplierProduct( record(), keepa(), spApi({ canSell: false, sellabilityStatus: "restricted" }), ); expect(score.verdict).toBe("SKIP"); expect(score.reason).toContain("restricted"); }); test("missing price skips", () => { const score = scoreSupplierProduct( record(), keepa({ currentPrice: null, avgPrice90: null, buyBoxPrice: null, buyBoxAvg90: null, }), spApi({ estimatedSalePrice: 0 }), ); expect(score.verdict).toBe("SKIP"); expect(score.reason).toContain("price"); });