Spaces:
Sleeping
Sleeping
| import test from "node:test"; | |
| import assert from "node:assert/strict"; | |
| import { analyzeCheckoutContext } from "../src/lib/checkout-analysis"; | |
| import { buildScanArtifacts } from "../src/lib/scan-pipeline"; | |
| import { buildTrustRatingMutation, computeTrustScoreDelta, computeTrustTier } from "../src/lib/trust-rating"; | |
| import { buildAgenticMission } from "../src/lib/agentic-mission"; | |
| import { analyzeDealIntelligence } from "../src/lib/deal-intelligence"; | |
| import { checkoutFixtures } from "./fixtures/checkout-fixtures"; | |
| test("checkout analysis rejects known non-commerce domains", () => { | |
| const result = analyzeCheckoutContext({ | |
| domain: "github.com", | |
| url: "https://github.com/openai/openai-python", | |
| pageText: "Repository home with issues, pull requests, and actions.", | |
| buttonLabels: ["Code", "Issues", "Pull requests"], | |
| priceStrings: [], | |
| }); | |
| assert.equal(result.isShoppingPage, false); | |
| assert.equal(result.pageType, "non_commerce"); | |
| assert.equal(result.trustScore, 95); | |
| assert.match(result.nonCommerceReason ?? "", /non-commerce/i); | |
| }); | |
| test("checkout analysis detects commerce signals and baseline patterns", () => { | |
| const result = analyzeCheckoutContext({ | |
| domain: "makemytrip.com", | |
| url: "https://www.makemytrip.com/hotels/checkout", | |
| pageText: | |
| "Flash sale ends in 04:59. Only 1 room left. Convenience fee applies at payment. Travel insurance is pre-checked.", | |
| buttonLabels: ["Continue to payment", "Book now"], | |
| priceStrings: ["Rs 4,999", "Rs 349"], | |
| timerElements: ["Deal ends in 04:59"], | |
| stockAlerts: ["Only 1 room left at this price"], | |
| }); | |
| assert.equal(result.isShoppingPage, true); | |
| assert.equal(result.pageType, "checkout"); | |
| assert.equal(result.falseUrgency.detected, true); | |
| assert.equal(result.falseScarcity.detected, true); | |
| assert.equal(result.hiddenFees.detected, true); | |
| assert.equal(result.preCheckedAddOns.detected, true); | |
| assert.ok(result.totalPatternsDetected >= 4); | |
| }); | |
| test("checkout analysis treats product listing grids as shopping pages when product candidates are present", () => { | |
| const result = analyzeCheckoutContext({ | |
| domain: "amazon.in", | |
| url: "https://www.amazon.in/s?k=multivitamin", | |
| pageText: "Results for multivitamin. Customer review filters and product cards.", | |
| buttonLabels: ["Customer Service", "Today's Deals"], | |
| priceStrings: [], | |
| productCandidates: [ | |
| { title: "Centrum Women Multivitamin", listedPrice: 445, dealSignals: ["limited time deal"] }, | |
| { title: "Tata 1mg Salmon Omega 3", listedPrice: 529, dealSignals: [] }, | |
| ], | |
| }); | |
| assert.equal(result.isShoppingPage, true); | |
| assert.equal(result.pageType, "product"); | |
| }); | |
| test("checkout analysis treats single product detail pages as shopping pages", () => { | |
| const result = analyzeCheckoutContext({ | |
| domain: "amazon.in", | |
| url: "https://www.amazon.in/dp/B0D1234567", | |
| pageText: "Samsung Galaxy M36 5G. Limited time deal. Price 18,499. Add to Cart.", | |
| buttonLabels: ["Add to Cart", "Buy Now"], | |
| priceStrings: ["Rs 18,499"], | |
| productCandidates: [{ title: "Samsung Galaxy M36 5G", listedPrice: 18499, dealSignals: ["limited time deal"] }], | |
| }); | |
| assert.equal(result.isShoppingPage, true); | |
| assert.ok(["product", "cart"].includes(result.pageType)); | |
| }); | |
| test("scan artifacts merge deterministic and AI signals consistently", () => { | |
| const baseAnalysis = analyzeCheckoutContext({ | |
| domain: "booking.com", | |
| url: "https://booking.com/checkout", | |
| pageText: "Only 1 room left. Resort fee applies later.", | |
| buttonLabels: ["Reserve now"], | |
| priceStrings: ["$165.00", "$24.99"], | |
| }); | |
| const merged = buildScanArtifacts({ | |
| domain: "booking.com", | |
| url: "https://booking.com/checkout", | |
| pageText: "Only 1 room left. Resort fee applies later.", | |
| baseAnalysis, | |
| aiReport: { | |
| confirmShaming: { | |
| detected: true, | |
| shamingText: "No thanks, I prefer to miss the best deal", | |
| rewrittenText: "No thanks", | |
| }, | |
| summary: "AI and rules both flagged manipulation.", | |
| }, | |
| trustRating: { score: 33, tier: "suspicious" }, | |
| }); | |
| assert.equal(merged.darkPatternReport.confirmShaming.detected, true); | |
| assert.match(merged.darkPatternReport.summary, /AI and rules/i); | |
| assert.ok(merged.totalPatternsDetected >= baseAnalysis.totalPatternsDetected); | |
| assert.equal(typeof merged.aiCopilot.headline, "string"); | |
| }); | |
| test("trust mutation helper creates and updates trust records consistently", () => { | |
| const scoreDelta = computeTrustScoreDelta(3); | |
| const created = buildTrustRatingMutation({ | |
| domain: "booking.com", | |
| scoreDelta, | |
| patternsFound: 3, | |
| hiddenFeesFound: 1, | |
| }); | |
| assert.equal(created.tier, computeTrustTier(created.score)); | |
| assert.equal(created.totalScans, 1); | |
| assert.equal(created.patternsDetectedCount, 3); | |
| assert.equal(created.hiddenFeesCount, 1); | |
| const updated = buildTrustRatingMutation({ | |
| domain: "booking.com", | |
| scoreDelta: 5, | |
| patternsFound: 0, | |
| hiddenFeesFound: 0, | |
| existing: { | |
| score: 40, | |
| totalScans: 7, | |
| patternsDetectedCount: 15, | |
| hiddenFeesCount: 4, | |
| }, | |
| }); | |
| assert.equal(updated.score, 45); | |
| assert.equal(updated.tier, "neutral"); | |
| assert.equal(updated.totalScans, 8); | |
| assert.equal(updated.patternsDetectedCount, 15); | |
| }); | |
| test("agentic mission gates non-commerce pages", () => { | |
| const mission = buildAgenticMission({ | |
| domain: "github.com", | |
| url: "https://github.com/openai/openai-python", | |
| purchaseGoal: "Check if this repo is safe to buy from", | |
| pageText: "Repository page with issues and pull requests.", | |
| buttonLabels: ["Code", "Issues"], | |
| priceStrings: [], | |
| }); | |
| assert.equal(mission.commerceIntent.isShoppingPage, false); | |
| assert.equal(mission.trust.score, 95); | |
| assert.equal(mission.estimatedTrueTotal, null); | |
| assert.equal(mission.alternatives.length, 0); | |
| assert.match(mission.summary, /not a commerce page/i); | |
| }); | |
| for (const fixture of checkoutFixtures) { | |
| test(`fixture corpus: ${fixture.id}`, () => { | |
| const result = analyzeCheckoutContext({ | |
| domain: fixture.domain, | |
| url: fixture.url, | |
| pageText: fixture.pageText, | |
| buttonLabels: fixture.buttonLabels, | |
| priceStrings: fixture.priceStrings, | |
| timerElements: fixture.timerElements, | |
| stockAlerts: fixture.stockAlerts, | |
| }); | |
| assert.equal(result.isShoppingPage, fixture.expected.isShoppingPage); | |
| assert.equal(result.pageType, fixture.expected.pageType); | |
| if (typeof fixture.expected.minPatterns === "number") { | |
| assert.ok( | |
| result.totalPatternsDetected >= fixture.expected.minPatterns, | |
| `expected at least ${fixture.expected.minPatterns} patterns, got ${result.totalPatternsDetected}`, | |
| ); | |
| } | |
| if (typeof fixture.expected.trustScoreAtMost === "number") { | |
| assert.ok( | |
| result.trustScore <= fixture.expected.trustScoreAtMost, | |
| `expected trust <= ${fixture.expected.trustScoreAtMost}, got ${result.trustScore}`, | |
| ); | |
| } | |
| if (typeof fixture.expected.trustScoreAtLeast === "number") { | |
| assert.ok( | |
| result.trustScore >= fixture.expected.trustScoreAtLeast, | |
| `expected trust >= ${fixture.expected.trustScoreAtLeast}, got ${result.trustScore}`, | |
| ); | |
| } | |
| if (typeof fixture.expected.hiddenFees === "boolean") { | |
| assert.equal(result.hiddenFees.detected, fixture.expected.hiddenFees); | |
| } | |
| if (typeof fixture.expected.urgency === "boolean") { | |
| assert.equal(result.falseUrgency.detected, fixture.expected.urgency); | |
| } | |
| if (typeof fixture.expected.scarcity === "boolean") { | |
| assert.equal(result.falseScarcity.detected, fixture.expected.scarcity); | |
| } | |
| if (typeof fixture.expected.preCheckedAddOns === "boolean") { | |
| assert.equal(result.preCheckedAddOns.detected, fixture.expected.preCheckedAddOns); | |
| } | |
| }); | |
| } | |
| test("fixture corpus mission uses safer alternatives on manipulative travel flows", () => { | |
| const hotelFixture = checkoutFixtures.find((fixture) => fixture.id === "hotel-manipulative-booking"); | |
| assert.ok(hotelFixture, "missing hotel fixture"); | |
| const mission = buildAgenticMission({ | |
| domain: hotelFixture.domain, | |
| url: hotelFixture.url, | |
| purchaseGoal: "Find the safest hotel checkout path", | |
| budget: 200, | |
| listedPrice: 165, | |
| pageText: hotelFixture.pageText, | |
| buttonLabels: hotelFixture.buttonLabels, | |
| priceStrings: hotelFixture.priceStrings, | |
| compareAcrossSites: true, | |
| allowAutoDeclineUpsells: true, | |
| }); | |
| assert.equal(mission.commerceIntent.isShoppingPage, true); | |
| assert.ok(mission.alternatives.length > 0); | |
| assert.ok(["switch", "proceed_with_caution"].includes(mission.recommendation)); | |
| assert.equal(mission.ghostCheckout.mode, "simulated_supervised"); | |
| assert.ok((mission.ghostCheckout.hiddenCostLanes?.length ?? 0) > 0); | |
| assert.equal(mission.ghostCheckout.saferPathMode.available, true); | |
| assert.ok(Array.isArray(mission.dealIntelligence?.items)); | |
| }); | |
| test("deal intelligence marks generic countdown-based claims as likely misleading", () => { | |
| const result = analyzeDealIntelligence({ | |
| domain: "amazon.com", | |
| url: "https://www.amazon.com/s?k=headphones", | |
| pageText: "Limited time deal ends in 01:59. 400+ bought in the last month.", | |
| timerElements: ["Deal ends in 01:59"], | |
| stockAlerts: ["Only 2 left in stock", "21 people viewing this item right now"], | |
| productCandidates: [ | |
| { | |
| title: "Wireless Headphones X200", | |
| listedPrice: 49.99, | |
| currency: "USD", | |
| dealSignals: ["limited time deal", "only 2 left in stock"], | |
| }, | |
| ], | |
| }); | |
| assert.equal(result.items.length, 1); | |
| assert.equal(result.items[0]?.status, "likely_misleading"); | |
| assert.ok(result.items[0]?.evidence?.length > 0); | |
| assert.ok(result.items[0]?.trustVerification); | |
| assert.ok(["REAL", "FAKE", "UNCERTAIN"].includes(result.items[0]!.trustVerification.reality)); | |
| assert.ok(["GOOD", "AVERAGE", "BAD"].includes(result.items[0]!.trustVerification.deal_quality)); | |
| assert.ok(["ACT_FAST", "COMPARE_OPTIONS", "RELAX_IGNORE"].includes(result.items[0]!.trustVerification.final_advice)); | |
| assert.equal(typeof result.items[0]!.trustVerification.confidence_score, "number"); | |
| assert.ok(result.items[0]!.trustVerification.confidence_score >= 0 && result.items[0]!.trustVerification.confidence_score <= 1); | |
| assert.ok(result.items[0]!.trustVerification.checks?.pattern_check); | |
| assert.equal(typeof result.items[0]!.trustVerification.signal_tally?.strong_fake, "number"); | |
| }); | |
| test("deal intelligence downgrades repeated limited-deal pressure across multiple products", () => { | |
| const result = analyzeDealIntelligence({ | |
| domain: "amazon.in", | |
| url: "https://www.amazon.in/gp/goldbox", | |
| pageText: "Limited time deal offers across product grid.", | |
| timerElements: ["Ends in 11:07:48"], | |
| stockAlerts: ["Selling fast"], | |
| productCandidates: [ | |
| { title: "OnePlus Pad Go 2", listedPrice: 33499, currency: "INR", dealSignals: ["limited time deal"] }, | |
| { title: "OnePlus Pad Lite", listedPrice: 17999, currency: "INR", dealSignals: ["limited time deal"] }, | |
| { title: "iQOO 15R", listedPrice: 47998, currency: "INR", dealSignals: ["limited time deal"] }, | |
| ], | |
| }); | |
| const misleading = result.items.filter((item) => item.status === "likely_misleading"); | |
| assert.ok(misleading.length >= 2); | |
| }); | |
| test("deal intelligence uses historical scarcity repetition as evidence of likely FOMO manipulation", () => { | |
| const result = analyzeDealIntelligence({ | |
| domain: "myntra.com", | |
| url: "https://www.myntra.com/men-tshirts", | |
| pageText: "Only few left! Limited time deal.", | |
| productCandidates: [ | |
| { | |
| title: "Highlander Men T-shirt", | |
| listedPrice: 174, | |
| currency: "INR", | |
| dealSignals: ["only few left", "limited time deal"], | |
| historySnapshot: { | |
| observations: 6, | |
| scarcityClaimRate: 0.92, | |
| uniquePricePoints: 4, | |
| }, | |
| }, | |
| ], | |
| }); | |
| assert.equal(result.items.length, 1); | |
| assert.equal(result.items[0]?.status, "likely_misleading"); | |
| assert.ok(result.items[0]?.evidence.some((item: string) => /history/i.test(item))); | |
| }); | |
| test("mission recommendation de-risks when deal authenticity is likely misleading", () => { | |
| const mission = buildAgenticMission({ | |
| domain: "amazon.com", | |
| url: "https://www.amazon.com/s?k=headphones", | |
| purchaseGoal: "Find the safest and most genuine deal", | |
| listedPrice: 49.99, | |
| pageText: "Limited time deal ends in 01:59. 20 people viewing this right now.", | |
| timerElements: ["Deal ends in 01:59"], | |
| stockAlerts: ["Only 1 left at this price", "20 people viewing this now"], | |
| productCandidates: [ | |
| { | |
| title: "Wireless Headphones X200", | |
| listedPrice: 49.99, | |
| currency: "USD", | |
| dealSignals: ["limited time deal", "only 1 left"], | |
| }, | |
| ], | |
| }); | |
| assert.ok(mission.dealIntelligence.items.some((item: any) => item.status === "likely_misleading")); | |
| assert.ok(["switch", "proceed_with_caution"].includes(mission.recommendation)); | |
| }); | |