[object Object]

← back to Costa Rica

costa-rica: money-math coverage — processor-fee host-payout deduction + conservation, currency validation, fmt, reversed-nights clamp (24→29 tests) — TK-10346 yoloforever C2

9a92040b93dd1e4574d732ab448f2fb4647f9fee · 2026-08-07 11:41:55 -0700 · Steve

Files touched

Diff

commit 9a92040b93dd1e4574d732ab448f2fb4647f9fee
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Aug 7 11:41:55 2026 -0700

    costa-rica: money-math coverage — processor-fee host-payout deduction + conservation, currency validation, fmt, reversed-nights clamp (24→29 tests) — TK-10346 yoloforever C2
---
 test/money.test.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/test/money.test.js b/test/money.test.js
new file mode 100644
index 0000000..4b9ac2c
--- /dev/null
+++ b/test/money.test.js
@@ -0,0 +1,47 @@
+'use strict';
+// Pure money-math coverage for the branches marketplace.test.js doesn't hit:
+// a nonzero processor fee (which reduces host payout), currency validation,
+// formatting, and reversed/zero night ranges. Integer minor units throughout.
+const { test } = require('node:test');
+const assert = require('node:assert');
+const { computeSplit, nights, fmt, assertCurrency } = require('../lib/money');
+
+test('computeSplit: a processor fee comes out of the host payout, total unchanged', () => {
+  // 3 nights @ $120 + $40 cleaning = $400.00 total; 10% platform + 3% processor.
+  const s = computeSplit({ subtotal: 36000, cleaningFee: 4000, currency: 'USD',
+    platformFeeBps: 1000, processorFeeBps: 300 });
+  assert.equal(s.total, 40000);            // traveler still charged the full total
+  assert.equal(s.platformFee, 4000);       // 10% of 400.00
+  assert.equal(s.processorFee, 1200);      // 3% of 400.00
+  assert.equal(s.hostPayout, 34800);       // total - platform - processor
+  // Conservation: nothing vanishes, nothing is minted.
+  assert.equal(s.hostPayout + s.platformFee + s.processorFee, s.total);
+});
+
+test('computeSplit: conservation holds across processor-fee combos (no rounding leak)', () => {
+  for (const [sub, clean, pbps, prbps] of [
+    [3333, 777, 1000, 250], [9999, 0, 1250, 300], [10001, 501, 999, 175], [1, 0, 1, 1]]) {
+    const s = computeSplit({ subtotal: sub, cleaningFee: clean, currency: 'CRC',
+      platformFeeBps: pbps, processorFeeBps: prbps });
+    assert.equal(s.hostPayout + s.platformFee + s.processorFee, s.total);
+    assert.ok(s.hostPayout >= 0, 'host payout never goes negative');
+  }
+});
+
+test('assertCurrency rejects an unsupported currency and computeSplit refuses it', () => {
+  assert.throws(() => assertCurrency('EUR'), /unsupported currency/);
+  assert.throws(() => computeSplit({ subtotal: 100, currency: 'BTC' }), /unsupported currency/);
+  assert.doesNotThrow(() => assertCurrency('USD'));
+  assert.doesNotThrow(() => assertCurrency('CRC'));
+});
+
+test('fmt renders minor units as major with 2 decimals', () => {
+  assert.equal(fmt(40000, 'USD'), 'USD 400.00');
+  assert.equal(fmt(5, 'CRC'), 'CRC 0.05');
+  assert.equal(fmt(0, 'USD'), 'USD 0.00');
+});
+
+test('nights clamps reversed ranges to 0 (never negative)', () => {
+  assert.equal(nights('2026-09-13', '2026-09-10'), 0); // check-out before check-in
+  assert.equal(nights('2026-09-10', '2026-09-11'), 1);
+});

← 3eaa493 costa-rica: sort+density controls on search + vertical grids  ·  back to Costa Rica  ·  costa-rica: BEST WAY TO CONTACT — contact-card endpoint (wha c05bcd2 →