/** * SVS MSP Calculator — Quote Engine Tests * * Run: node svsmspcalc/tests/test-quote-engine.js * * Zero dependencies. Uses a minimal test harness built-in. * Tests the pure calculateQuote(state, pricing) function against * known-good expected values using default pricing. */ // ── Minimal test harness ─────────────────────────────────────── let _passed = 0; let _failed = 0; let _group = ''; function describe(name, fn) { _group = name; console.log(`\n ${name}`); fn(); } function it(name, fn) { try { fn(); _passed++; console.log(` \x1b[32m✓\x1b[0m ${name}`); } catch (e) { _failed++; console.log(` \x1b[31m✗\x1b[0m ${name}`); console.log(` \x1b[31m${e.message}\x1b[0m`); } } function assert(condition, msg) { if (!condition) throw new Error(msg || 'Assertion failed'); } function eq(actual, expected, label) { if (actual !== expected) { throw new Error(`${label || 'Value'}: expected ${expected}, got ${actual}`); } } function near(actual, expected, tolerance, label) { if (Math.abs(actual - expected) > tolerance) { throw new Error(`${label || 'Value'}: expected ~${expected} (±${tolerance}), got ${actual}`); } } // ── Load engine (mock window as global) ──────────────────────── const _global = {}; (function loadModules() { const fs = require('fs'); const path = require('path'); const dir = path.resolve(__dirname, '..'); // Load quote-pricing.js — sets DEFAULTS on _global const pricingSrc = fs.readFileSync(path.join(dir, 'quote-pricing.js'), 'utf8') .replace(/\(window\)\s*;?\s*$/, '(_global);'); new Function('_global', pricingSrc)(_global); // Load quote-engine.js — sets calculateQuote on _global const engineSrc = fs.readFileSync(path.join(dir, 'quote-engine.js'), 'utf8') .replace(/\(window\)\s*;?\s*$/, '(_global);'); new Function('_global', engineSrc)(_global); })(); const calculateQuote = _global.calculateQuote; const DEFAULTS = _global.SVSQuotePricing.DEFAULTS; // Helper: build a state object with sensible defaults function makeState(overrides) { return Object.assign({ byol: false, users: 0, endpoints: 0, servers: 0, addExtHours: false, addPWM: false, addINKY: false, addZT: false, addUSB: false, addBMB: false, ztSeats: 0, ztRouters: 0, voipTier: 'basic', voipSeats: 0, addVoipPhone: false, addVoipFax: false, clientName: '', contractTerm: 'm2m', hstEnabled: false, oneTimeFee: 0, adminWaived: false }, overrides); } // ── Tests ────────────────────────────────────────────────────── console.log('\n\x1b[1mSVS Quote Engine — Test Suite\x1b[0m'); // ── 1. Basic pricing ────────────────────────────────────────── describe('Basic M365 quote (1 user, 1 endpoint, m2m)', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1 }), DEFAULTS); it('userBase = 140 (m2m rate)', () => eq(q.userBase, 140, 'userBase')); it('userTotal = 140', () => eq(q.userTotal, 140, 'userTotal')); it('endpointBase = 35', () => eq(q.endpointBase, 35, 'endpointBase')); it('endpointTotal = 35', () => eq(q.endpointTotal, 35, 'endpointTotal')); it('baseSubtotal = 175', () => eq(q.baseSubtotal, 175, 'baseSubtotal')); it('admin fee scales: max(150, 650-175) = 475', () => eq(q.siteAdminBase, 475, 'siteAdminBase')); it('adminFeeNet = 475', () => eq(q.adminFeeNet, 475, 'adminFeeNet')); it('MRR = 650', () => eq(q.MRR, 650, 'MRR')); it('annual = 7800', () => eq(q.annual, 7800, 'annual')); it('no discount at m2m', () => eq(q.discountAmt, 0, 'discountAmt')); it('effectiveMrr = MRR', () => eq(q.effectiveMrr, 650, 'effectiveMrr')); }); // ── 2. BYOL rate ────────────────────────────────────────────── describe('BYOL rate (1 user, 1 endpoint)', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, byol: true }), DEFAULTS); it('baseUserRate = 110 (BYOL)', () => eq(q.baseUserRate, 110, 'baseUserRate')); it('userBase = 110', () => eq(q.userBase, 110, 'userBase')); it('baseSubtotal = 145', () => eq(q.baseSubtotal, 145, 'baseSubtotal')); it('admin fee scales: max(150, 650-145) = 505', () => eq(q.siteAdminBase, 505, 'siteAdminBase')); it('MRR still = 650 (admin absorbs difference)', () => eq(q.MRR, 650, 'MRR')); }); // ── 3. Admin fee floor ──────────────────────────────────────── describe('Admin fee floor (high service volume)', () => { // 5 users + 1 endpoint: baseSubtotal = 675+35 = 710 > 650 const q = calculateQuote(makeState({ users: 5, endpoints: 1 }), DEFAULTS); it('baseSubtotal = 735', () => eq(q.baseSubtotal, 735, 'baseSubtotal')); it('admin hits floor: max(150, 650-710) = 150', () => eq(q.siteAdminBase, 150, 'siteAdminBase')); it('adminFeeNet = 150', () => eq(q.adminFeeNet, 150, 'adminFeeNet')); }); // ── 4. Admin fee ZT premium ─────────────────────────────────── describe('Admin fee with Zero Trust premium', () => { const q = calculateQuote(makeState({ users: 5, endpoints: 1, addZT: true }), DEFAULTS); it('ztActive = true', () => assert(q.ztActive, 'ztActive')); it('admin includes ZT premium: 150 + 250 = 400', () => eq(q.adminFeeNet, 400, 'adminFeeNet')); }); describe('Admin fee ZT premium via ztSeats (no addZT checkbox)', () => { const q = calculateQuote(makeState({ users: 5, endpoints: 1, ztSeats: 2 }), DEFAULTS); it('ztActive = true (from ztSeats > 0)', () => assert(q.ztActive, 'ztActive')); it('admin includes ZT premium', () => eq(q.adminFeeNet, 400, 'adminFeeNet')); }); // ── 5. Admin fee 1Password markup ───────────────────────────── describe('Admin fee with 1Password markup', () => { // 5 users, 1 endpoint, addPWM // userPWM = 5 * 9 = 45, admin1PWM = round(45 * 0.10) = 5 const q = calculateQuote(makeState({ users: 5, endpoints: 1, addPWM: true }), DEFAULTS); it('userPWM = 45', () => eq(q.userPWM, 45, 'userPWM')); it('admin1PWM = 5 (10% of 45, rounded)', () => eq(q.admin1PWM, 5, 'admin1PWM')); it('adminFeeNet = 150 + 5 = 155', () => eq(q.adminFeeNet, 155, 'adminFeeNet')); }); // ── 6. Admin waived ─────────────────────────────────────────── describe('Admin fee waived', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, adminWaived: true }), DEFAULTS); it('adminFeeNet still calculated = 475', () => eq(q.adminFeeNet, 475, 'adminFeeNet')); it('admin does not contribute to MRR', () => { eq(q.MRR, 140 + 35, 'MRR without admin'); // 175 }); }); // ── 7. User add-ons ────────────────────────────────────────── describe('All user add-ons (10 users)', () => { const q = calculateQuote(makeState({ users: 10, endpoints: 1, addExtHours: true, addPWM: true, addINKY: true, addZT: true }), DEFAULTS); it('userExt = 250', () => eq(q.userExt, 250, 'userExt')); it('userPWM = 90', () => eq(q.userPWM, 90, 'userPWM')); it('userINKY = 80', () => eq(q.userINKY, 80, 'userINKY')); it('userZT = 550', () => eq(q.userZT, 550, 'userZT')); it('addonRate = 25+9+8+55 = 97', () => { eq(q.totalUserRate - q.baseUserRate, 97, 'addonRate'); }); it('userTotal = 10 * (140+97) = 2370', () => eq(q.userTotal, 2370, 'userTotal')); }); // ── 8. Endpoint add-ons ────────────────────────────────────── describe('Endpoint add-ons (10 endpoints)', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 10, addUSB: true, addBMB: true }), DEFAULTS); it('endpointBase = 350', () => eq(q.endpointBase, 350, 'endpointBase')); it('endpointUSB = 40', () => eq(q.endpointUSB, 40, 'endpointUSB')); it('endpointBMB = 250', () => eq(q.endpointBMB, 250, 'endpointBMB')); it('endpointTotal = 640 (includes no servers)', () => eq(q.endpointTotal, 640, 'endpointTotal')); }); // ── 9. Server pricing ──────────────────────────────────────── describe('Server pricing', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, servers: 3 }), DEFAULTS); it('serverBase = 360', () => eq(q.serverBase, 360, 'serverBase')); it('servers included in endpointTotal', () => eq(q.endpointTotal, 35 + 360, 'endpointTotal')); it('servers in baseSubtotal', () => eq(q.baseSubtotal, 140 + 35 + 360, 'baseSubtotal')); }); // ── 10. Contract discounts ─────────────────────────────────── describe('Contract term discounts', () => { const base = { users: 10, endpoints: 10 }; it('m2m = 0% discount', () => { const q = calculateQuote(makeState({ ...base, contractTerm: 'm2m' }), DEFAULTS); eq(q.discountPct, 0, 'discountPct'); eq(q.discountAmt, 0, 'discountAmt'); }); it('12mo = 3% discount', () => { const q = calculateQuote(makeState({ ...base, contractTerm: '12mo' }), DEFAULTS); eq(q.discountPct, 0.03, 'discountPct'); eq(q.discountAmt, Math.round(q.MRR * 0.03), 'discountAmt'); eq(q.effectiveMrr, q.MRR - q.discountAmt, 'effectiveMrr'); }); it('24mo = 5% discount', () => { const q = calculateQuote(makeState({ ...base, contractTerm: '24mo' }), DEFAULTS); eq(q.discountPct, 0.05, 'discountPct'); eq(q.discountAmt, Math.round(q.MRR * 0.05), 'discountAmt'); }); }); // ── 10b. M365 term-aware rate ──────────────────────────────── describe('M365 rate varies by contract term', () => { it('m2m uses RATE_M365_M2M ($140)', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, contractTerm: 'm2m' }), DEFAULTS); eq(q.m365Rate, 140, 'm365Rate'); eq(q.baseUserRate, 140, 'baseUserRate'); }); it('12mo uses RATE_M365 ($130)', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, contractTerm: '12mo' }), DEFAULTS); eq(q.m365Rate, 130, 'm365Rate'); eq(q.baseUserRate, 130, 'baseUserRate'); }); it('24mo uses RATE_M365 ($130)', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, contractTerm: '24mo' }), DEFAULTS); eq(q.m365Rate, 130, 'm365Rate'); eq(q.baseUserRate, 130, 'baseUserRate'); }); it('BYOL rate unaffected by term', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, byol: true, contractTerm: '12mo' }), DEFAULTS); eq(q.baseUserRate, 110, 'baseUserRate'); }); }); // ── 11. HST calculation ────────────────────────────────────── describe('HST calculation', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, hstEnabled: true }), DEFAULTS); it('hstAmt = round(650 * 0.13) = 85', () => eq(q.hstAmt, 85, 'hstAmt')); it('mrrWithHst = 650 + 85 = 735', () => eq(q.mrrWithHst, 735, 'mrrWithHst')); }); describe('HST disabled = 0', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, hstEnabled: false }), DEFAULTS); it('hstAmt = 0', () => eq(q.hstAmt, 0, 'hstAmt')); it('mrrWithHst = effectiveMrr', () => eq(q.mrrWithHst, q.effectiveMrr, 'mrrWithHst')); }); // ── 12. VoIP tiers ─────────────────────────────────────────── describe('VoIP tiers', () => { it('basic = $28/seat', () => { const q = calculateQuote(makeState({ voipSeats: 5, voipTier: 'basic' }), DEFAULTS); eq(q.voipSeatRate, 28, 'voipSeatRate'); eq(q.voipSeatsAmt, 140, 'voipSeatsAmt'); }); it('standard = $35/seat', () => { const q = calculateQuote(makeState({ voipSeats: 5, voipTier: 'standard' }), DEFAULTS); eq(q.voipSeatRate, 35, 'voipSeatRate'); eq(q.voipSeatsAmt, 175, 'voipSeatsAmt'); }); it('premium = $45/seat', () => { const q = calculateQuote(makeState({ voipSeats: 5, voipTier: 'premium' }), DEFAULTS); eq(q.voipSeatRate, 45, 'voipSeatRate'); eq(q.voipSeatsAmt, 225, 'voipSeatsAmt'); }); }); // ── 13. VoIP add-ons ───────────────────────────────────────── describe('VoIP phone + fax add-ons', () => { const q = calculateQuote(makeState({ voipSeats: 10, voipTier: 'standard', addVoipPhone: true, addVoipFax: true }), DEFAULTS); it('voipPhoneAmt = 150', () => eq(q.voipPhoneAmt, 150, 'voipPhoneAmt')); it('voipFaxAmt = 100', () => eq(q.voipFaxAmt, 100, 'voipFaxAmt')); it('voipTotal = 350+150+100 = 600', () => eq(q.voipTotal, 600, 'voipTotal')); }); // ── 14. Zero Trust networking ──────────────────────────────── describe('Zero Trust networking', () => { const q = calculateQuote(makeState({ ztSeats: 10, ztRouters: 2 }), DEFAULTS); it('ztNetSeats = 250', () => eq(q.ztNetSeats, 250, 'ztNetSeats')); it('ztNetRouters = 200', () => eq(q.ztNetRouters, 200, 'ztNetRouters')); it('ztNetTotal = 450', () => eq(q.ztNetTotal, 450, 'ztNetTotal')); it('ztActive = true', () => assert(q.ztActive, 'ztActive')); }); // ── 15. Zero users edge case ───────────────────────────────── describe('Zero users edge case', () => { const q = calculateQuote(makeState({ users: 0, endpoints: 0 }), DEFAULTS); it('perUserAllin = 0', () => eq(q.perUserAllin, 0, 'perUserAllin')); it('perUserServices = 0', () => eq(q.perUserServices, 0, 'perUserServices')); it('userTotal = 0', () => eq(q.userTotal, 0, 'userTotal')); it('admin still applies (floor)', () => { // baseSubtotal = 0, max(150, 650-0) = 650 eq(q.siteAdminBase, 650, 'siteAdminBase'); }); }); // ── 16. Per-user breakdown ─────────────────────────────────── describe('Per-user cost breakdown', () => { const q = calculateQuote(makeState({ users: 10, endpoints: 10 }), DEFAULTS); it('perUserServices = round(userTotal / users)', () => { eq(q.perUserServices, Math.round(q.userTotal / 10), 'perUserServices'); }); it('perUserSiteOvhd = round((effectiveMrr - userTotal) / users)', () => { eq(q.perUserSiteOvhd, Math.round((q.effectiveMrr - q.userTotal) / 10), 'perUserSiteOvhd'); }); it('perUserAllin = MRR / users', () => { eq(q.perUserAllin, q.MRR / 10, 'perUserAllin'); }); }); // ── 17. HST + discount combo ───────────────────────────────── describe('HST applied AFTER contract discount', () => { const q = calculateQuote(makeState({ users: 10, endpoints: 10, contractTerm: '12mo', hstEnabled: true }), DEFAULTS); it('discount applied first', () => { eq(q.effectiveMrr, q.MRR - q.discountAmt, 'effectiveMrr'); }); it('HST on discounted amount', () => { eq(q.hstAmt, Math.round(q.effectiveMrr * 0.13), 'hstAmt'); }); it('mrrWithHst = effectiveMrr + hstAmt', () => { eq(q.mrrWithHst, q.effectiveMrr + q.hstAmt, 'mrrWithHst'); }); }); // ── 18. Realistic full quote ───────────────────────────────── describe('Realistic 22-user full quote', () => { const q = calculateQuote(makeState({ users: 22, endpoints: 22, servers: 2, addPWM: true, addINKY: true, ztSeats: 5, ztRouters: 1, voipSeats: 15, voipTier: 'standard', addVoipPhone: true, contractTerm: '12mo', hstEnabled: true }), DEFAULTS); it('userTotal = 22 * (130+9+8) = 3234', () => eq(q.userTotal, 3234, 'userTotal')); it('endpointBase = 770', () => eq(q.endpointBase, 770, 'endpointBase')); it('serverBase = 240', () => eq(q.serverBase, 240, 'serverBase')); it('ztNetTotal = 5*25 + 1*100 = 225', () => eq(q.ztNetTotal, 225, 'ztNetTotal')); it('voipTotal = 15*35 + 15*15 = 750', () => eq(q.voipTotal, 750, 'voipTotal')); it('admin: baseSubtotal = 2860+770+240 = 3870, floor applies', () => { // baseSubtotal = 22*130 + 22*35 + 2*120 = 2860+770+240 = 3870 // Wait: baseSubtotal = userBase + endpointBase + serverBase // userBase = 22*130 = 2860, endpointBase = 770, serverBase = 240 eq(q.baseSubtotal, 3870, 'baseSubtotal'); eq(q.siteAdminBase, 150, 'siteAdminBase (floor)'); }); it('admin includes ZT premium + 1PWM', () => { // ztActive because ztSeats > 0 // admin1PWM = round(22*9 * 0.10) = round(19.8) = 20 eq(q.admin1PWM, 20, 'admin1PWM'); eq(q.adminFeeNet, 150 + 250 + 20, 'adminFeeNet'); // 420 }); it('MRR components sum correctly', () => { const expected = q.userTotal + q.endpointTotal + q.adminFeeNet + q.ztNetTotal + q.voipTotal; eq(q.MRR, expected, 'MRR'); }); it('12mo discount = 3%', () => { eq(q.discountAmt, Math.round(q.MRR * 0.03), 'discountAmt'); }); it('HST on discounted total', () => { eq(q.hstAmt, Math.round(q.effectiveMrr * 0.13), 'hstAmt'); }); it('effectiveAnnual = effectiveMrr * 12', () => { eq(q.effectiveAnnual, q.effectiveMrr * 12, 'effectiveAnnual'); }); }); // ── 19. MRR components always sum ──────────────────────────── describe('MRR = sum of all components (various configs)', () => { const configs = [ { users: 1, endpoints: 1 }, { users: 50, endpoints: 50, servers: 5, addPWM: true, addZT: true }, { users: 0, endpoints: 0, voipSeats: 20, voipTier: 'premium' }, { users: 10, endpoints: 10, adminWaived: true }, { users: 3, endpoints: 3, ztSeats: 10, ztRouters: 3 } ]; configs.forEach((cfg, i) => { it(`config #${i + 1}: MRR = user + endpoint + admin + zt + voip`, () => { const q = calculateQuote(makeState(cfg), DEFAULTS); const adminEff = q.adminWaived ? 0 : q.adminFeeNet; const expected = q.userTotal + q.endpointTotal + adminEff + q.ztNetTotal + q.voipTotal; eq(q.MRR, expected, 'MRR sum'); }); }); }); // ══════════════════════════════════════════════════════════════ // ── EXPANSION: Pricing Defaults Integrity ──────────────────── // ══════════════════════════════════════════════════════════════ describe('Pricing DEFAULTS integrity', () => { const requiredKeys = [ 'RATE_M365', 'RATE_M365_M2M', 'RATE_BYOL', 'ADDON_EXT_HOURS', 'ADDON_1PASSWORD', 'ADDON_INKY', 'ADDON_ZERO_TRUST_USER', 'RATE_ENDPOINT', 'RATE_SERVER', 'ADDON_USB_BLOCKING', 'ADDON_BARE_METAL_BACKUP', 'ZT_SEAT_RATE', 'ZT_ROUTER_RATE', 'ADMIN_FEE_FLOOR', 'ADMIN_FEE_MINIMUM', 'ADMIN_FEE_ZT', 'ADMIN_1PWM_PCT', 'VOIP_RATE_BASIC', 'VOIP_RATE_STANDARD', 'VOIP_RATE_PREMIUM', 'VOIP_PHONE_RATE', 'VOIP_FAX_RATE', 'DISCOUNT_M2M', 'DISCOUNT_12MO', 'DISCOUNT_24MO', 'HST_RATE' ]; requiredKeys.forEach(key => { it(`DEFAULTS.${key} exists and is a number`, () => { assert(key in DEFAULTS, `${key} missing from DEFAULTS`); assert(typeof DEFAULTS[key] === 'number', `${key} is not a number`); }); }); it('DEFAULTS is frozen (immutable)', () => { assert(Object.isFrozen(DEFAULTS), 'DEFAULTS should be frozen'); }); it('M365 m2m rate > annual rate', () => { assert(DEFAULTS.RATE_M365_M2M > DEFAULTS.RATE_M365, 'm2m should exceed annual'); }); it('BYOL rate < M365 annual rate', () => { assert(DEFAULTS.RATE_BYOL < DEFAULTS.RATE_M365, 'BYOL should be less than M365'); }); it('VoIP tiers in ascending order', () => { assert(DEFAULTS.VOIP_RATE_BASIC < DEFAULTS.VOIP_RATE_STANDARD, 'basic < standard'); assert(DEFAULTS.VOIP_RATE_STANDARD < DEFAULTS.VOIP_RATE_PREMIUM, 'standard < premium'); }); it('Discount rates in ascending order (m2m < 12mo < 24mo)', () => { assert(DEFAULTS.DISCOUNT_M2M < DEFAULTS.DISCOUNT_12MO, 'm2m < 12mo'); assert(DEFAULTS.DISCOUNT_12MO < DEFAULTS.DISCOUNT_24MO, '12mo < 24mo'); }); it('HST_RATE is 13%', () => { eq(DEFAULTS.HST_RATE, 0.13, 'HST_RATE'); }); it('ADMIN_FEE_FLOOR < ADMIN_FEE_MINIMUM', () => { assert(DEFAULTS.ADMIN_FEE_FLOOR < DEFAULTS.ADMIN_FEE_MINIMUM, 'floor < minimum'); }); it('Known pricing values match spec', () => { eq(DEFAULTS.RATE_M365, 130, 'M365 annual'); eq(DEFAULTS.RATE_M365_M2M, 140, 'M365 m2m'); eq(DEFAULTS.RATE_BYOL, 110, 'BYOL'); eq(DEFAULTS.ADDON_EXT_HOURS, 25, 'ExtHours'); eq(DEFAULTS.ADDON_1PASSWORD, 9, '1PWM'); eq(DEFAULTS.ADDON_INKY, 8, 'INKY'); eq(DEFAULTS.ADDON_ZERO_TRUST_USER, 55, 'ZT user'); eq(DEFAULTS.RATE_ENDPOINT, 35, 'endpoint'); eq(DEFAULTS.RATE_SERVER, 120, 'server'); eq(DEFAULTS.ADMIN_FEE_FLOOR, 150, 'admin floor'); eq(DEFAULTS.ADMIN_FEE_MINIMUM, 650, 'admin minimum'); eq(DEFAULTS.ADMIN_FEE_ZT, 250, 'admin ZT'); }); }); // ══════════════════════════════════════════════════════════════ // ── EXPANSION: Engine Edge Cases & Boundaries ──────────────── // ══════════════════════════════════════════════════════════════ describe('Admin fee exact threshold (baseSubtotal = 500)', () => { // baseSubtotal = 500 → max(150, 650-500) = max(150, 150) = 150 const q = calculateQuote(makeState({ users: 3, endpoints: 1, byol: true }), DEFAULTS); // 3 * 110 = 330 + 35 = 365 … not 500. Let me use custom pricing. it('at threshold: admin = max(floor, minimum - subtotal)', () => { // 3 users BYOL + 1 endpoint: 330 + 35 = 365 eq(q.baseSubtotal, 365, 'baseSubtotal'); eq(q.siteAdminBase, Math.max(150, 650 - 365), 'siteAdminBase'); }); }); describe('Admin fee exactly at minimum (baseSubtotal = 650)', () => { // Need baseSubtotal = 650. 4 users M365 m2m = 560, + ~3 endpoints = 105 → 665 too much // 4 users m2m = 560 + 2 endpoints = 70 → 630; + 0 servers → 630 // Use: 4 users BYOL = 440 + 6 endpoints = 210 → 650 const q = calculateQuote(makeState({ users: 4, endpoints: 6, byol: true }), DEFAULTS); it('baseSubtotal = 650 exactly', () => eq(q.baseSubtotal, 650, 'baseSubtotal')); it('admin = floor (650-650=0, floor wins)', () => eq(q.siteAdminBase, 150, 'siteAdminBase')); }); describe('Admin fee when baseSubtotal just under minimum', () => { // 4 users BYOL = 440, 5 endpoints = 175 → 615 const q = calculateQuote(makeState({ users: 4, endpoints: 5, byol: true }), DEFAULTS); it('baseSubtotal = 615', () => eq(q.baseSubtotal, 615, 'baseSubtotal')); it('admin = max(150, 650-615) = max(150, 35) = 150', () => eq(q.siteAdminBase, 150, 'siteAdminBase')); }); describe('Large user count (100 users, 100 endpoints)', () => { const q = calculateQuote(makeState({ users: 100, endpoints: 100, servers: 10, addExtHours: true, addPWM: true, addINKY: true, addZT: true, addUSB: true, addBMB: true, contractTerm: '24mo', hstEnabled: true }), DEFAULTS); it('userTotal = 100 * (130+25+9+8+55) = 22700', () => eq(q.userTotal, 22700, 'userTotal')); it('endpointBase = 3500', () => eq(q.endpointBase, 3500, 'endpointBase')); it('endpointUSB = 400', () => eq(q.endpointUSB, 400, 'endpointUSB')); it('endpointBMB = 2500', () => eq(q.endpointBMB, 2500, 'endpointBMB')); it('serverBase = 1200', () => eq(q.serverBase, 1200, 'serverBase')); it('admin hits floor', () => eq(q.siteAdminBase, 150, 'siteAdminBase')); it('MRR is positive integer', () => assert(q.MRR > 0 && Number.isInteger(q.MRR), 'MRR')); it('24mo discount = 5%', () => eq(q.discountPct, 0.05, 'discountPct')); it('HST calculated on discounted MRR', () => { eq(q.hstAmt, Math.round(q.effectiveMrr * 0.13), 'hstAmt'); }); it('annual = effectiveMrr * 12', () => eq(q.effectiveAnnual, q.effectiveMrr * 12, 'effectiveAnnual')); }); describe('String coercion for numeric inputs', () => { const q = calculateQuote(makeState({ users: '5', endpoints: '3', servers: '2' }), DEFAULTS); it('users parsed from string', () => eq(q.users, 5, 'users')); it('endpoints parsed from string', () => eq(q.endpoints, 3, 'endpoints')); it('servers parsed from string', () => eq(q.servers, 2, 'servers')); it('calculations correct with string inputs', () => { eq(q.userBase, 5 * 140, 'userBase'); eq(q.endpointBase, 3 * 35, 'endpointBase'); eq(q.serverBase, 2 * 120, 'serverBase'); }); }); describe('Invalid inputs handled gracefully', () => { it('NaN endpoints → 0', () => { const q = calculateQuote(makeState({ users: 1, endpoints: NaN }), DEFAULTS); eq(q.endpoints, 0, 'endpoints'); }); it('undefined servers → 0', () => { const q = calculateQuote(makeState({ users: 1, servers: undefined }), DEFAULTS); eq(q.servers, 0, 'servers'); }); it('null users → 0', () => { const q = calculateQuote(makeState({ users: null, endpoints: 1 }), DEFAULTS); eq(q.users, 0, 'users'); }); it('empty string users → 0', () => { const q = calculateQuote(makeState({ users: '', endpoints: 1 }), DEFAULTS); eq(q.users, 0, 'users'); }); }); describe('Single endpoint, no users', () => { const q = calculateQuote(makeState({ users: 0, endpoints: 1 }), DEFAULTS); it('endpointBase = 35', () => eq(q.endpointBase, 35, 'endpointBase')); it('userTotal = 0', () => eq(q.userTotal, 0, 'userTotal')); it('admin still scales', () => { // baseSubtotal = 0 + 35 + 0 = 35, max(150, 650-35) = 615 eq(q.siteAdminBase, 615, 'siteAdminBase'); }); }); describe('Only servers, no users or endpoints', () => { const q = calculateQuote(makeState({ users: 0, endpoints: 0, servers: 5 }), DEFAULTS); it('serverBase = 600', () => eq(q.serverBase, 600, 'serverBase')); it('endpointTotal includes servers', () => eq(q.endpointTotal, 600, 'endpointTotal')); it('baseSubtotal = 600', () => eq(q.baseSubtotal, 600, 'baseSubtotal')); it('admin = max(150, 650-600) = 150', () => eq(q.siteAdminBase, 150, 'siteAdminBase')); }); describe('VoIP only quote (no users, no endpoints)', () => { const q = calculateQuote(makeState({ users: 0, endpoints: 0, voipSeats: 20, voipTier: 'premium', addVoipPhone: true, addVoipFax: true }), DEFAULTS); it('voipSeatsAmt = 900', () => eq(q.voipSeatsAmt, 900, 'voipSeatsAmt')); it('voipPhoneAmt = 300', () => eq(q.voipPhoneAmt, 300, 'voipPhoneAmt')); it('voipFaxAmt = 200', () => eq(q.voipFaxAmt, 200, 'voipFaxAmt')); it('voipTotal = 1400', () => eq(q.voipTotal, 1400, 'voipTotal')); it('admin is full (no user/endpoint base)', () => eq(q.siteAdminBase, 650, 'siteAdminBase')); }); describe('VoIP fax without phone', () => { const q = calculateQuote(makeState({ voipSeats: 5, voipTier: 'basic', addVoipFax: true, addVoipPhone: false }), DEFAULTS); it('voipFaxAmt = 50', () => eq(q.voipFaxAmt, 50, 'voipFaxAmt')); it('voipPhoneAmt = 0', () => eq(q.voipPhoneAmt, 0, 'voipPhoneAmt')); it('voipTotal = 140 + 50 = 190', () => eq(q.voipTotal, 190, 'voipTotal')); }); describe('VoIP addons with zero seats', () => { const q = calculateQuote(makeState({ voipSeats: 0, voipTier: 'standard', addVoipPhone: true, addVoipFax: true }), DEFAULTS); it('voipPhoneAmt = 0 (no seats)', () => eq(q.voipPhoneAmt, 0, 'voipPhoneAmt')); it('voipFaxAmt = 0 (no seats)', () => eq(q.voipFaxAmt, 0, 'voipFaxAmt')); it('voipTotal = 0', () => eq(q.voipTotal, 0, 'voipTotal')); }); describe('ZT networking without ZT user addon', () => { const q = calculateQuote(makeState({ users: 5, endpoints: 5, addZT: false, ztSeats: 10, ztRouters: 1 }), DEFAULTS); it('ztActive = true (from ztSeats)', () => assert(q.ztActive, 'ztActive')); it('userZT = 0 (addZT is false)', () => eq(q.userZT, 0, 'userZT')); it('ztNetTotal = 250 + 100 = 350', () => eq(q.ztNetTotal, 350, 'ztNetTotal')); it('admin includes ZT supplement', () => { assert(q.adminFeeNet >= q.siteAdminBase + 250, 'admin includes ZT'); }); }); describe('Admin waived still calculates adminFeeNet', () => { const q = calculateQuote(makeState({ users: 10, endpoints: 10, addPWM: true, addZT: true, adminWaived: true }), DEFAULTS); it('adminWaived flag is true', () => assert(q.adminWaived, 'adminWaived')); it('adminFeeNet is still calculated (non-zero)', () => assert(q.adminFeeNet > 0, 'adminFeeNet > 0')); it('MRR excludes admin', () => { const expected = q.userTotal + q.endpointTotal + q.ztNetTotal + q.voipTotal; eq(q.MRR, expected, 'MRR without admin'); }); }); describe('All addons combined with 12mo discount', () => { const q = calculateQuote(makeState({ users: 15, endpoints: 15, servers: 3, addExtHours: true, addPWM: true, addINKY: true, addZT: true, addUSB: true, addBMB: true, ztSeats: 8, ztRouters: 2, voipSeats: 10, voipTier: 'standard', addVoipPhone: true, addVoipFax: true, contractTerm: '12mo', hstEnabled: true }), DEFAULTS); it('all user addons active', () => { assert(q.userExt > 0, 'userExt'); assert(q.userPWM > 0, 'userPWM'); assert(q.userINKY > 0, 'userINKY'); assert(q.userZT > 0, 'userZT'); }); it('all endpoint addons active', () => { assert(q.endpointUSB > 0, 'endpointUSB'); assert(q.endpointBMB > 0, 'endpointBMB'); }); it('ztNetTotal > 0', () => assert(q.ztNetTotal > 0, 'ztNetTotal')); it('voipTotal > 0', () => assert(q.voipTotal > 0, 'voipTotal')); it('12mo discount applied', () => eq(q.discountPct, 0.03, 'discountPct')); it('HST on discounted total', () => { eq(q.hstAmt, Math.round(q.effectiveMrr * 0.13), 'hstAmt'); }); it('MRR components sum', () => { const expected = q.userTotal + q.endpointTotal + q.adminFeeNet + q.ztNetTotal + q.voipTotal; eq(q.MRR, expected, 'MRR sum'); }); }); describe('Per-user breakdown with admin waived', () => { const q = calculateQuote(makeState({ users: 10, endpoints: 10, adminWaived: true }), DEFAULTS); it('perUserAllin = MRR / users', () => { eq(q.perUserAllin, q.MRR / 10, 'perUserAllin'); }); it('perUserSiteOvhd reflects waived admin', () => { eq(q.perUserSiteOvhd, Math.round((q.effectiveMrr - q.userTotal) / 10), 'perUserSiteOvhd'); }); }); describe('1Password admin markup scales with users', () => { it('1 user: admin1PWM = round(9 * 0.10) = 1', () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, addPWM: true }), DEFAULTS); eq(q.admin1PWM, 1, 'admin1PWM'); }); it('50 users: admin1PWM = round(450 * 0.10) = 45', () => { const q = calculateQuote(makeState({ users: 50, endpoints: 1, addPWM: true }), DEFAULTS); eq(q.admin1PWM, 45, 'admin1PWM'); }); it('no 1PWM addon: admin1PWM = 0', () => { const q = calculateQuote(makeState({ users: 50, endpoints: 1, addPWM: false }), DEFAULTS); eq(q.admin1PWM, 0, 'admin1PWM'); }); }); describe('HST with admin waived', () => { const q = calculateQuote(makeState({ users: 10, endpoints: 10, hstEnabled: true, adminWaived: true }), DEFAULTS); it('HST computed on MRR without admin', () => { eq(q.hstAmt, Math.round(q.effectiveMrr * 0.13), 'hstAmt'); }); it('mrrWithHst = effectiveMrr + hstAmt', () => { eq(q.mrrWithHst, q.effectiveMrr + q.hstAmt, 'mrrWithHst'); }); }); describe('Contract term does not affect BYOL rate', () => { ['m2m', '12mo', '24mo'].forEach(term => { it(`${term}: BYOL rate = 110`, () => { const q = calculateQuote(makeState({ users: 1, endpoints: 1, byol: true, contractTerm: term }), DEFAULTS); eq(q.baseUserRate, 110, 'baseUserRate'); }); }); }); describe('Discount amounts are rounded integers', () => { ['12mo', '24mo'].forEach(term => { it(`${term} discount is integer`, () => { const q = calculateQuote(makeState({ users: 7, endpoints: 7, contractTerm: term }), DEFAULTS); assert(Number.isInteger(q.discountAmt), `discountAmt should be integer, got ${q.discountAmt}`); }); }); }); // ══════════════════════════════════════════════════════════════ // ── EXPANSION: Export JSON Schema Validation ───────────────── // ══════════════════════════════════════════════════════════════ describe('Export JSON payload schema (simulated)', () => { // Simulate the payload that exportQuoteJSON() builds from a quote result function buildExportPayload(q, overrides) { const o = overrides || {}; const termMap = { m2m: 'Month-to-Month', '12mo': '12-Month', '24mo': '24-Month' }; return { version: '1.1', quoteRef: o.quoteRef || 'SVS-20260315-1234', quoteDate: o.quoteDate || '2026-03-15', clientName: q.clientName || '', repName: o.repName || '', quoteNotes: o.quoteNotes || '', contractTerm: termMap[q.contractTerm] || 'Month-to-Month', licensing: q.byol ? 'BYOL' : 'M365-Included', users: q.users, endpoints: q.endpoints, servers: q.servers, addons: { extendedHours: q.addExtHours, passwordManager: q.addPWM, inkyPro: q.addINKY, zeroTrustUsers: q.addZT, baremetalBackup: q.addBMB, usbBlocking: q.addUSB }, zeroTrustNetwork: { seats: q.ztSeats, routers: q.ztRouters }, voip: { tier: q.voipSeats > 0 ? q.voipTier : null, seats: q.voipSeats, phoneHardware: q.addVoipPhone, faxLine: q.addVoipFax, currentPhoneBill: 0 }, adminWaived: q.adminWaived || false, onboardingWaived: false, onboardingManual: false, pricing: { baseMrr: q.MRR, discountPct: Math.round(q.discountPct * 100), discountAmt: q.discountAmt, effectiveMrr: q.effectiveMrr, annual: q.effectiveAnnual, oneTimeFee: q.oneTimeFee, hstIncluded: q.hstEnabled, hstAmt: q.hstAmt, mrrWithHst: q.mrrWithHst } }; } const q = calculateQuote(makeState({ users: 10, endpoints: 10, servers: 1, addPWM: true, addINKY: true, addZT: true, ztSeats: 5, ztRouters: 1, voipSeats: 8, voipTier: 'standard', addVoipPhone: true, contractTerm: '12mo', hstEnabled: true, clientName: 'Acme Corp' }), DEFAULTS); const payload = buildExportPayload(q); it('has version field = "1.1"', () => eq(payload.version, '1.1', 'version')); it('has quoteRef string', () => assert(typeof payload.quoteRef === 'string' && payload.quoteRef.length > 0, 'quoteRef')); it('has quoteDate string', () => assert(typeof payload.quoteDate === 'string', 'quoteDate')); it('clientName matches', () => eq(payload.clientName, 'Acme Corp', 'clientName')); it('contractTerm is display label', () => eq(payload.contractTerm, '12-Month', 'contractTerm')); it('licensing is M365-Included', () => eq(payload.licensing, 'M365-Included', 'licensing')); it('users/endpoints/servers are numbers', () => { assert(typeof payload.users === 'number', 'users'); assert(typeof payload.endpoints === 'number', 'endpoints'); assert(typeof payload.servers === 'number', 'servers'); }); it('addons object has all 6 boolean keys', () => { const keys = ['extendedHours', 'passwordManager', 'inkyPro', 'zeroTrustUsers', 'baremetalBackup', 'usbBlocking']; keys.forEach(k => { assert(typeof payload.addons[k] === 'boolean', `addons.${k} should be boolean`); }); }); it('zeroTrustNetwork has seats and routers', () => { assert(typeof payload.zeroTrustNetwork.seats === 'number', 'zt seats'); assert(typeof payload.zeroTrustNetwork.routers === 'number', 'zt routers'); }); it('voip object has required fields', () => { assert(typeof payload.voip.seats === 'number', 'voip seats'); assert(typeof payload.voip.phoneHardware === 'boolean', 'voip phone'); assert(typeof payload.voip.faxLine === 'boolean', 'voip fax'); assert(payload.voip.tier === 'standard', 'voip tier'); }); it('voip tier is null when no seats', () => { const q2 = calculateQuote(makeState({ users: 1, endpoints: 1, voipSeats: 0 }), DEFAULTS); const p2 = buildExportPayload(q2); eq(p2.voip.tier, null, 'voip tier null'); }); it('pricing object has all required fields', () => { const pricingKeys = ['baseMrr', 'discountPct', 'discountAmt', 'effectiveMrr', 'annual', 'oneTimeFee', 'hstIncluded', 'hstAmt', 'mrrWithHst']; pricingKeys.forEach(k => { assert(k in payload.pricing, `pricing.${k} missing`); }); }); it('pricing.discountPct is integer percentage', () => { eq(payload.pricing.discountPct, 3, 'discountPct as integer %'); }); it('pricing.baseMrr matches engine MRR', () => { eq(payload.pricing.baseMrr, q.MRR, 'baseMrr'); }); it('pricing.effectiveMrr matches engine', () => { eq(payload.pricing.effectiveMrr, q.effectiveMrr, 'effectiveMrr'); }); it('pricing.mrrWithHst matches engine', () => { eq(payload.pricing.mrrWithHst, q.mrrWithHst, 'mrrWithHst'); }); it('BYOL licensing label', () => { const q2 = calculateQuote(makeState({ users: 1, endpoints: 1, byol: true }), DEFAULTS); const p2 = buildExportPayload(q2); eq(p2.licensing, 'BYOL', 'licensing'); }); it('m2m contractTerm label', () => { const q2 = calculateQuote(makeState({ users: 1, endpoints: 1, contractTerm: 'm2m' }), DEFAULTS); const p2 = buildExportPayload(q2); eq(p2.contractTerm, 'Month-to-Month', 'contractTerm'); }); it('24mo contractTerm label', () => { const q2 = calculateQuote(makeState({ users: 1, endpoints: 1, contractTerm: '24mo' }), DEFAULTS); const p2 = buildExportPayload(q2); eq(p2.contractTerm, '24-Month', 'contractTerm'); }); it('repName is string', () => { assert(typeof payload.repName === 'string', 'repName should be string'); }); it('quoteNotes is string', () => { assert(typeof payload.quoteNotes === 'string', 'quoteNotes should be string'); }); it('repName populates from override', () => { const p2 = buildExportPayload(q, { repName: 'Jane Doe' }); eq(p2.repName, 'Jane Doe', 'repName'); }); it('quoteNotes populates from override', () => { const p2 = buildExportPayload(q, { quoteNotes: 'Special pricing approved.' }); eq(p2.quoteNotes, 'Special pricing approved.', 'quoteNotes'); }); }); // ══════════════════════════════════════════════════════════════ // ── EXPANSION: Persistence State Shape ─────────────────────── // ══════════════════════════════════════════════════════════════ describe('Persistence state shape (save round-trip)', () => { // Simulate the state shape that saveState() produces function buildPersistenceState(overrides) { return Object.assign({ clientName: '', users: 0, endpoints: 0, servers: 0, byol: false, addExtHours: false, addPWM: false, addINKY: false, addZT: false, addUSB: false, addBMB: false, ztSeats: 0, ztRouters: 0, voipTier: 'basic', voipSeats: 0, addVoipPhone: false, addVoipFax: false, phoneBill: 0, contractTerm: 'm2m', hstEnabled: false, oneTimeFee: 0, adminWaived: false, onboardingWaived: false, onboardingManual: false, repName: '', quoteNotes: '' }, overrides); } const fullState = buildPersistenceState({ clientName: 'Test Client', users: 15, endpoints: 12, servers: 2, byol: true, addExtHours: true, addPWM: true, addINKY: true, addZT: true, addUSB: true, addBMB: true, ztSeats: 5, ztRouters: 1, voipTier: 'premium', voipSeats: 10, addVoipPhone: true, addVoipFax: true, phoneBill: 250, contractTerm: '24mo', hstEnabled: true, oneTimeFee: 500, adminWaived: true, onboardingWaived: true, onboardingManual: false }); it('serializes to valid JSON', () => { const json = JSON.stringify(fullState); const parsed = JSON.parse(json); assert(typeof parsed === 'object', 'valid JSON object'); }); it('round-trip preserves all string fields', () => { const parsed = JSON.parse(JSON.stringify(fullState)); eq(parsed.clientName, 'Test Client', 'clientName'); eq(parsed.voipTier, 'premium', 'voipTier'); eq(parsed.contractTerm, '24mo', 'contractTerm'); }); it('round-trip preserves all numeric fields', () => { const parsed = JSON.parse(JSON.stringify(fullState)); eq(parsed.users, 15, 'users'); eq(parsed.endpoints, 12, 'endpoints'); eq(parsed.servers, 2, 'servers'); eq(parsed.ztSeats, 5, 'ztSeats'); eq(parsed.ztRouters, 1, 'ztRouters'); eq(parsed.voipSeats, 10, 'voipSeats'); eq(parsed.phoneBill, 250, 'phoneBill'); eq(parsed.oneTimeFee, 500, 'oneTimeFee'); }); it('round-trip preserves all boolean fields', () => { const parsed = JSON.parse(JSON.stringify(fullState)); const boolKeys = ['byol', 'addExtHours', 'addPWM', 'addINKY', 'addZT', 'addUSB', 'addBMB', 'addVoipPhone', 'addVoipFax', 'hstEnabled', 'adminWaived', 'onboardingWaived', 'onboardingManual']; boolKeys.forEach(k => { assert(typeof parsed[k] === 'boolean', `${k} should be boolean after round-trip`); }); }); it('persistence state feeds engine correctly', () => { const q = calculateQuote(fullState, DEFAULTS); eq(q.users, 15, 'users'); eq(q.byol, true, 'byol'); eq(q.contractTerm, '24mo', 'contractTerm'); assert(q.MRR > 0, 'MRR > 0'); }); it('default state produces valid zero quote', () => { const q = calculateQuote(buildPersistenceState(), DEFAULTS); eq(q.users, 0, 'users'); eq(q.userTotal, 0, 'userTotal'); eq(q.endpointTotal, 0, 'endpointTotal'); eq(q.voipTotal, 0, 'voipTotal'); }); }); // ══════════════════════════════════════════════════════════════ // ── EXPANSION: Import Payload Mapping ──────────────────────── // ══════════════════════════════════════════════════════════════ describe('Import payload reverse-maps contract term correctly', () => { const termReverseMap = { 'Month-to-Month': 'm2m', '12-Month': '12mo', '24-Month': '24mo' }; it('Month-to-Month → m2m', () => eq(termReverseMap['Month-to-Month'], 'm2m', 'term')); it('12-Month → 12mo', () => eq(termReverseMap['12-Month'], '12mo', 'term')); it('24-Month → 24mo', () => eq(termReverseMap['24-Month'], '24mo', 'term')); it('unknown defaults to m2m', () => eq(termReverseMap['bogus'] || 'm2m', 'm2m', 'fallback')); }); describe('Import → engine round-trip (full payload)', () => { // Build an export payload, then feed it back through the engine const original = calculateQuote(makeState({ users: 20, endpoints: 18, servers: 2, byol: true, addPWM: true, addINKY: true, ztSeats: 3, ztRouters: 1, voipSeats: 12, voipTier: 'premium', addVoipPhone: true, contractTerm: '12mo', hstEnabled: true, clientName: 'Round Trip Inc' }), DEFAULTS); // Simulate import: map export payload fields back to engine state const imported = makeState({ users: original.users, endpoints: original.endpoints, servers: original.servers, byol: original.byol, addPWM: original.addPWM, addINKY: original.addINKY, addExtHours: original.addExtHours, addZT: original.addZT, addUSB: original.addUSB, addBMB: original.addBMB, ztSeats: original.ztSeats, ztRouters: original.ztRouters, voipTier: original.voipTier, voipSeats: original.voipSeats, addVoipPhone: original.addVoipPhone, addVoipFax: original.addVoipFax, contractTerm: original.contractTerm, hstEnabled: original.hstEnabled, clientName: original.clientName, adminWaived: original.adminWaived }); const reimported = calculateQuote(imported, DEFAULTS); it('MRR matches after round-trip', () => eq(reimported.MRR, original.MRR, 'MRR')); it('effectiveMrr matches', () => eq(reimported.effectiveMrr, original.effectiveMrr, 'effectiveMrr')); it('mrrWithHst matches', () => eq(reimported.mrrWithHst, original.mrrWithHst, 'mrrWithHst')); it('userTotal matches', () => eq(reimported.userTotal, original.userTotal, 'userTotal')); it('endpointTotal matches', () => eq(reimported.endpointTotal, original.endpointTotal, 'endpointTotal')); it('voipTotal matches', () => eq(reimported.voipTotal, original.voipTotal, 'voipTotal')); it('adminFeeNet matches', () => eq(reimported.adminFeeNet, original.adminFeeNet, 'adminFeeNet')); it('effectiveAnnual matches', () => eq(reimported.effectiveAnnual, original.effectiveAnnual, 'effectiveAnnual')); }); // ══════════════════════════════════════════════════════════════ // ── EXPANSION: Quote Output Invariants ─────────────────────── // ══════════════════════════════════════════════════════════════ describe('Quote output invariants across random configs', () => { const configs = [ { users: 1, endpoints: 1 }, { users: 25, endpoints: 25, servers: 5, addPWM: true }, { users: 0, endpoints: 0, voipSeats: 30, voipTier: 'premium' }, { users: 50, endpoints: 50, addZT: true, ztSeats: 20, ztRouters: 5, contractTerm: '24mo', hstEnabled: true }, { users: 10, endpoints: 10, adminWaived: true, contractTerm: '12mo' }, { users: 3, endpoints: 3, byol: true, addExtHours: true, addINKY: true } ]; configs.forEach((cfg, i) => { const q = calculateQuote(makeState(cfg), DEFAULTS); it(`config #${i + 1}: effectiveMrr = MRR - discountAmt`, () => { eq(q.effectiveMrr, q.MRR - q.discountAmt, 'effectiveMrr'); }); it(`config #${i + 1}: effectiveAnnual = effectiveMrr * 12`, () => { eq(q.effectiveAnnual, q.effectiveMrr * 12, 'effectiveAnnual'); }); it(`config #${i + 1}: mrrWithHst = effectiveMrr + hstAmt`, () => { eq(q.mrrWithHst, q.effectiveMrr + q.hstAmt, 'mrrWithHst'); }); it(`config #${i + 1}: all monetary values ≥ 0`, () => { assert(q.MRR >= 0, 'MRR >= 0'); assert(q.effectiveMrr >= 0, 'effectiveMrr >= 0'); assert(q.hstAmt >= 0, 'hstAmt >= 0'); assert(q.mrrWithHst >= 0, 'mrrWithHst >= 0'); }); }); }); // ── Results ────────────────────────────────────────────────── console.log(`\n${'─'.repeat(50)}`); if (_failed === 0) { console.log(`\x1b[32m All ${_passed} tests passed.\x1b[0m\n`); process.exit(0); } else { console.log(`\x1b[31m ${_failed} of ${_passed + _failed} tests failed.\x1b[0m\n`); process.exit(1); }