← back to Fix Live Board

config/test/showroom-vendor.test.cjs

106 lines

/**
 * showroom-vendor.test.cjs — regression suite for the showroom-only predicate. (TK-11307)
 *
 * WHY THIS EXISTS. The exact-match tag comparison in showroom-vendor.cjs IS the entire
 * safety design of the showroom-only rollout, and it has already broken TWICE:
 *
 *   1. A theme backstop split tags on WHITESPACE (`split(/[,\s]+/)`) and tested for
 *      'showroom'. The pre-existing, unrelated tag 'Showroom Line' tokenizes to
 *      ['showroom','line'] and MATCHED — which would have hidden 18,518+ ACTIVE
 *      SELLABLE products (Kravet, Scalamandre, Phillip Jeffries, Osborne & Little,
 *      sellable Phillipe Romano ...) from every browse and search grid.
 *   2. A Liquid consumer enumerated only three casings instead of comparing lowercased,
 *      so 'SHOWROOMONLY' / 'ShowroomONLY' silently failed to match.
 *
 * Both were caught by hand. This file makes the guarantee durable: the fixture strings
 * below are REAL tag values observed live on the DW store, and the suite asserts the
 * predicate is TRUE for the showroom cohort and FALSE for every sellable collision.
 *
 * Per the standing rule, a check must go RED on an injected fault. Run with --mutate to
 * prove it: `node showroom-vendor.test.cjs --mutate` swaps in the historical broken
 * whitespace-split predicate and the suite MUST fail. If it passes under --mutate, this
 * test is not actually guarding anything.
 *
 * Read-only, zero dependencies, $0. Run: node config/test/showroom-vendor.test.cjs
 */
'use strict';
const assert = require('node:assert');
const { hasShowroomTag, isShowroomProduct, isShowroomVendor } = require('../showroom-vendor.cjs');

const MUTATE = process.argv.includes('--mutate');

// The historical BROKEN predicate, kept verbatim as the injected fault.
function brokenHasShowroomTag(tags) {
  if (tags == null) return false;
  const s = Array.isArray(tags) ? tags.join(',') : String(tags);
  return s.toLowerCase().split(/[,\s]+/).indexOf('showroom') > -1;
}
const hasTag = MUTATE ? brokenHasShowroomTag : hasShowroomTag;

let pass = 0, fail = 0;
function check(name, fn) {
  try { fn(); pass++; }
  catch (e) { fail++; console.log(`  FAIL  ${name}\n        ${e.message}`); }
}

// ---- MUST MATCH: the MDC showroom cohort, in every casing/format seen live ----
const SHOULD_MATCH = [
  ['exact tag, array', ['ShowroomOnly']],
  ['exact tag among siblings', ['Type II', 'ShowroomOnly', 'Quote Only']],
  ['comma string', 'Type II,ShowroomOnly,Quote Only'],
  ['comma string with spaces', 'Type II, ShowroomOnly, Quote Only'],
  ['all upper', ['SHOWROOMONLY']],
  ['mixed case', ['ShowroomONLY']],
  ['all lower', ['showroomonly']],
  ['padded whitespace', ['  ShowroomOnly  ']],
];

// ---- MUST NOT MATCH: real sellable tags that must never be hidden ----
const SHOULD_NOT_MATCH = [
  ['the 18,518-product collision tag', ['Showroom Line']],
  ['collision tag among siblings', ['Kravet', 'Showroom Line', 'Wallcovering']],
  ['collision tag as comma string', 'Kravet,Showroom Line,Wallcovering'],
  ['bare legacy Showroom', ['Showroom']],
  ['showroom as a word in a phrase', ['As Seen In Showroom']],
  ['hyphenated near-miss', ['showroom-only']],
  ['substring superset', ['ShowroomOnlyExtra']],
  ['substring subset', ['Showroom On']],
  ['empty array', []],
  ['null', null],
  ['empty string', ''],
];

console.log(`showroom tag predicate — ${MUTATE ? 'MUTATED (expect FAIL)' : 'canonical'}`);
for (const [name, tags] of SHOULD_MATCH) {
  check(`MATCH: ${name}`, () => assert.strictEqual(hasTag(tags), true));
}
for (const [name, tags] of SHOULD_NOT_MATCH) {
  check(`NO-MATCH: ${name}`, () => assert.strictEqual(hasTag(tags), false));
}

// ---- vendor path must not regress (Phillip Jeffries stays suppressed) ----
if (!MUTATE) {
  check('vendor: Phillip Jeffries is showroom', () => assert.strictEqual(isShowroomVendor('Phillip Jeffries'), true));
  check('vendor: case/space insensitive', () => assert.strictEqual(isShowroomVendor('  phillip jeffries '), true));
  check('vendor: Kravet is not showroom', () => assert.strictEqual(isShowroomVendor('Kravet'), false));
  check('vendor: unknown vendor is not showroom', () => assert.strictEqual(isShowroomVendor('Nope'), false));

  // ---- product path: the whole point — a SHARED vendor split by tag ----
  check('product: MDC (shared vendor + tag) is showroom', () =>
    assert.strictEqual(isShowroomProduct({ vendor: 'Phillipe Romano', tags: ['Type II', 'ShowroomOnly'] }), true));
  check('product: SELLABLE sibling on the SAME shared vendor is NOT showroom', () =>
    assert.strictEqual(isShowroomProduct({ vendor: 'Phillipe Romano', tags: ['Spazzolato', 'Showroom Line'] }), false));
  check('product: showroom VENDOR is showroom even with no tag', () =>
    assert.strictEqual(isShowroomProduct({ vendor: 'Phillip Jeffries', tags: [] }), true));
  check('product: sellable vendor with collision tag is NOT showroom', () =>
    assert.strictEqual(isShowroomProduct({ vendor: 'Kravet', tags: ['Showroom Line'] }), false));
  check('product: null product', () => assert.strictEqual(isShowroomProduct(null), false));
}

console.log(`\n  ${pass} passed, ${fail} failed`);
if (MUTATE) {
  if (fail > 0) { console.log('  MUTATION DETECTED — suite correctly goes RED on the broken predicate. OK'); process.exit(0); }
  console.log('  MUTATION NOT DETECTED — this suite does not guard the predicate. BAD'); process.exit(1);
}
process.exit(fail ? 1 : 0);