← back to Dw Rotation Activator
test/weight-gate.test.js
84 lines
// weight-gate.test.js — TK-11471 NEGATIVE TEST for the weight gate on the highest-blast-radius
// activation path in the fleet (hourly, catalog-wide DRAFT->ACTIVE, 500/day cap).
// A positive-only test on a gate proves nothing (CLAUDE.md TK-11431 amendment 3).
// Offline: zero network, zero DB, zero Shopify.
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const { weightGuard, currentWeightLb, TYPE_DEFAULT_LB, SAMPLE_WEIGHT_LB } = require('../lib/weight-gate.js');
let pass = 0, fail = 0;
const t = (n, fn) => { try { fn(); console.log('PASS ' + n); pass++; } catch (e) { console.log('FAIL ' + n + ' — ' + e.message); fail++; } };
const V = (sku, lb, unit = 'POUNDS') => ({ sku, title: sku, price: '10.00',
inventoryItem: { id: 'gid://shopify/InventoryItem/1', measurement: { weight: lb == null ? null : { value: lb, unit } } } });
const NOFIELD = (sku) => ({ sku, title: sku, price: '10.00', inventoryItem: { id: 'x', measurement: {} } });
const P = (variants, productType = 'Wallcovering') => ({ productType, variants: { nodes: variants } });
// ── STRUCTURAL: the gate cannot be vacuous ────────────────────────────────────────────────────
const SRC = fs.readFileSync(path.join(__dirname, '..', 'rotate-activate.js'), 'utf8');
t('S1 STATUS_Q actually SELECTS weight (else the gate measures nothing and passes 100%)', () => {
const q = SRC.slice(SRC.indexOf('const STATUS_Q'), SRC.indexOf('const mfVal'));
assert.ok(/inventoryItem\s*\{\s*id\s+measurement\s*\{\s*weight\s*\{\s*value\s+unit/.test(q),
'STATUS_Q does not select inventoryItem measurement weight value+unit');
});
t('S2 weight gate is ANDed into `passes` (not computed and ignored)', () => {
assert.ok(/const passes = .*weight\.ok/.test(SRC), 'weight.ok is not part of the passes expression');
});
t('S3 gate is evaluated BEFORE the ACTIVATE mutation call site', () => {
assert.ok(SRC.indexOf('weightGuard(n)') < SRC.indexOf('gqlRetry(ACTIVATE'),
'weightGuard does not precede the ACTIVATE call');
});
t('S4 constants have not drifted from the canonical weight-guard.mjs', () => {
const mjs = path.join(process.env.HOME, 'Projects/designerwallcoverings/scripts/lib/weight-guard.mjs');
if (!fs.existsSync(mjs)) { console.log(' (canonical .mjs not present — skipping drift check)'); return; }
const src = fs.readFileSync(mjs, 'utf8');
assert.ok(src.includes('SAMPLE_WEIGHT_LB = 0.25'), 'canonical sample weight changed');
for (const [k, v] of Object.entries(TYPE_DEFAULT_LB)) {
const re = new RegExp(`'${k.replace(/[/\\^$*+?.()|[\]{}]/g, '\\$&')}':\\s*${v}`);
assert.ok(re.test(src), `TYPE_DEFAULT_LB drift: '${k}' not ${v} in the canonical .mjs`);
}
assert.strictEqual(SAMPLE_WEIGHT_LB, 0.25);
});
// ── INJECTED FAULTS: each MUST block ──────────────────────────────────────────────────────────
t('zero-weight SELLABLE blocks activation', () => {
assert.strictEqual(weightGuard(P([V('DW-1', 0), V('DW-1-Sample', 0.25)])).ok, false);
});
t('zero-weight SAMPLE blocks activation (samples count — the canary FAILs on them)', () => {
assert.strictEqual(weightGuard(P([V('DW-1', 3), V('DW-1-Sample', 0)])).ok, false);
});
t('NULL weight blocks', () => { assert.strictEqual(weightGuard(P([V('DW-1', null)])).ok, false); });
t('negative weight blocks', () => { assert.strictEqual(weightGuard(P([V('DW-1', -5)])).ok, false); });
t('NaN weight blocks', () => { assert.strictEqual(weightGuard(P([V('DW-1', 'abc')])).ok, false); });
t('MISSING weight FIELD blocks (query regression must not silently re-open the hole)', () => {
const r = weightGuard(P([NOFIELD('DW-1')]));
assert.strictEqual(r.ok, false);
assert.ok(/WITHOUT the weight field/.test(r.reasons[0]), 'did not name the unmeasured cause');
});
t('NO variants blocks (cannot assert weight>0 on nothing)', () => {
assert.strictEqual(weightGuard(P([])).ok, false);
});
t('reason names the offending SKUs', () => {
const r = weightGuard(P([V('DW-1', 0), V('DW-1-Sample', 0)]));
assert.ok(r.reasons[0].includes('DW-1') && r.reasons[0].includes('DW-1-Sample'));
});
// ── NOT trigger-happy: a noisy gate dies the same death as a false green ──────────────────────
t('properly weighted product PASSES', () => {
assert.strictEqual(weightGuard(P([V('DW-1', 3), V('DW-1-Sample', 0.25)])).ok, true);
});
t('GRAMS converts and does NOT falsely block', () => {
assert.strictEqual(weightGuard(P([V('DW-1', 1360, 'GRAMS')])).ok, true);
assert.ok(Math.abs(currentWeightLb(V('DW-1', 1360, 'GRAMS')) - 2.9982) < 0.01);
});
t('KILOGRAMS converts and does NOT falsely block', () => {
assert.strictEqual(weightGuard(P([V('DW-1', 1.36, 'KILOGRAMS')])).ok, true);
});
t('OUNCES converts and does NOT falsely block', () => {
assert.strictEqual(weightGuard(P([V('DW-1', 4, 'OUNCES')])).ok, true);
});
console.log(`\n${fail ? 'TESTS FAILED' : 'ALL TESTS PASS'} — ${pass} passed, ${fail} failed`);
process.exit(fail ? 1 : 0);