← back to Costa Rica

test/plaid.test.js

47 lines

'use strict';
// Offline tests (node:test) for lib/plaid.js sandbox-default safety. Plaid is a
// LIVE-MONEY (bank ACH) integration; the critical invariant is that WITHOUT creds
// it never makes a live API call — liveMode is false and every entrypoint returns
// deterministic sandbox values. Run: node --test
const { test, before, after } = require('node:test');
const assert = require('node:assert');

let plaid;
const realFetch = global.fetch;
before(() => {
  // Guarantee no live creds leak in from the ambient env for this assertion.
  delete process.env.PLAID_CLIENT_ID;
  delete process.env.PLAID_SECRET;
  // Booby-trap fetch: if any sandbox entrypoint ever reaches _post(), the test
  // fails LOUDLY instead of silently making a (would-be live) network call.
  global.fetch = () => { throw new Error('LIVE PLAID CALL ATTEMPTED — sandbox guard failed'); };
  delete require.cache[require.resolve('../lib/plaid')];
  plaid = require('../lib/plaid');
});
after(() => { global.fetch = realFetch; });

test('SAFETY: liveMode is false and ENV defaults to sandbox when no creds', () => {
  assert.equal(plaid.liveMode, false);
  assert.equal(plaid.ENV, 'sandbox');
});

test('createLinkToken returns a deterministic sandbox link token (no live call)', async () => {
  const r = await plaid.createLinkToken('user-123');
  assert.equal(r.sandbox, true);
  assert.match(r.link_token, /^link-sandbox-/);
});

test('exchangePublicToken returns a sandbox access token + item id (no live call)', async () => {
  const r = await plaid.exchangePublicToken('public-sandbox-abc');
  assert.equal(r.sandbox, true);
  assert.match(r.access_token, /^access-sandbox-/);
  assert.match(r.item_id, /^item-/);
});

test('getAuth returns a sandbox account (no live call)', async () => {
  const r = await plaid.getAuth('access-sandbox-abc');
  assert.equal(r.sandbox, true);
  assert.ok(Array.isArray(r.accounts) && r.accounts.length >= 1);
  assert.ok(r.accounts[0].mask);
});