// The remembered-banks list behind the boot reopen: a successful open records
// its token, a reload redials every recorded token, and nothing else touches
// the list. The bug this pins: store/remember-bank! existed — docstring,
// dedup, the works — with ZERO call sites, so no connection was ever recorded
// and every reload showed every bank as never-connected. Verified live, in a
// v8 browser, by the key simply not being there. Recording is now tied to the
// open's own settled value (lib/banks), where this suite can hold it.
import test from "node:test";
import assert from "node:assert/strict";
import * as L from "../test-dist/testlib.js";
const KEY = "bursa-test:banks";
/** The storage seam lib/banks takes — what js/localStorage is to the store. */
function fakeStorage() {
const m = new Map();
return {
getItem: (k) => (m.has(k) ? m.get(k) : null),
setItem: (k, v) => { m.set(k, String(v)); },
};
}
test("a successful open records the token — exactly once", async () => {
const s = fakeStorage();
const out = await L.recordBankOnOpen(s, KEY, "tok", Promise.resolve(null));
assert.equal(out, null, "the settled value passes through");
assert.deepEqual([...L.recordedBanks(s, KEY)], ["tok"]);
// the boot reopen redials through the same recording path — by design
await L.recordBankOnOpen(s, KEY, "tok", Promise.resolve(null));
assert.deepEqual([...L.recordedBanks(s, KEY)], ["tok"], "double-open stays deduped");
});
test("a refused open records nothing — the catalog key stays the caller's", async () => {
const s = fakeStorage();
const out = await L.recordBankOnOpen(s, KEY, "tok", Promise.resolve("err.bank.open"));
assert.equal(out, "err.bank.open");
assert.deepEqual([...L.recordedBanks(s, KEY)], []);
});
test("a rejecting open records nothing and the rejection passes through", async () => {
const s = fakeStorage();
await assert.rejects(
L.recordBankOnOpen(s, KEY, "tok", Promise.reject(new Error("boom"))),
);
assert.deepEqual([...L.recordedBanks(s, KEY)], []);
});
test("reopen dials exactly what was recorded, and one dead bank stops nothing", async () => {
const s = fakeStorage();
await L.recordBankOnOpen(s, KEY, "b1", Promise.resolve(null));
await L.recordBankOnOpen(s, KEY, "b2", Promise.resolve(null));
const dialed = [];
L.reopenBanks(s, KEY, (token) => {
dialed.push(token);
// the first remembered bank will not open today — the second still must
return token === "b1" ? Promise.reject(new Error("down")) : Promise.resolve(null);
});
assert.deepEqual(dialed, ["b1", "b2"]);
});
test("a device that cannot read its history boots as a fresh one", async () => {
const s = fakeStorage();
s.setItem(KEY, "not json");
assert.deepEqual([...L.recordedBanks(s, KEY)], []);
const throwing = {
getItem: () => { throw new Error("denied"); },
setItem: () => { throw new Error("denied"); },
};
assert.deepEqual([...L.recordedBanks(throwing, KEY)], []);
// storage refusing to WRITE is non-fatal too: the open's verdict still lands
const out = await L.recordBankOnOpen(throwing, KEY, "tok", Promise.resolve(null));
assert.equal(out, null);
});