Files
bitvid/tests/profile-switch-coordinator-delegators.test.mjs
T
thePR0M3TH3ANandClaude Opus 4.8 a2c9f44307 [auth] Fix "prepareStoredNsecSwitch is not a function" when switching to a saved nsec account
Switching (from NIP-07) to an added nsec account threw
"this.prepareStoredNsecSwitch is not a function".

Root cause: bindCoordinator binds every coordinator method to the Application
instance, so inside handleProfileSwitchRequest `this` === app. Its call to the
sibling `this.prepareStoredNsecSwitch(pubkey)` therefore resolves against the
Application and needs an app-level delegator (like handleProfileSwitchRequest,
handleModerationSettingsChange, and waitForIdentityRefresh all have). The #48 work
added prepareStoredNsecSwitch as a coordinator sibling but not its delegator, and
its tests only exercised authService.switchProfile — not the full app wiring — so
it slipped through.

Fix: add the app.prepareStoredNsecSwitch delegator (-> this._auth.prepareStoredNsecSwitch).

Tests: tests/profile-switch-coordinator-delegators.test.mjs (4) — asserts every
sibling handleProfileSwitchRequest calls via this.X exists as an app method.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-01 15:34:20 -04:00

51 lines
2.2 KiB
JavaScript

// Switching to a saved nsec account threw "this.prepareStoredNsecSwitch is not a
// function". Root cause: bindCoordinator binds every coordinator method to the
// Application (`this` === app), so when a coordinator method calls a SIBLING via
// `this.sibling(...)` it resolves against the Application — which therefore needs
// an app-level delegator for that sibling. handleProfileSwitchRequest calls
// this.prepareStoredNsecSwitch / this.handleModerationSettingsChange /
// this.waitForIdentityRefresh; the nsec one was missing its delegator.
//
// test_integrity_note:
// change_type: ["new_tests"]
// scenarios:
// - id: SCN-profile-switch-coordinator-delegators
// given: "the Application class"
// when: "handleProfileSwitchRequest runs (bound to app) and calls siblings"
// then: "every sibling it calls exists as an app-level method/delegator"
// observable_outcomes:
// - "Application.prototype.prepareStoredNsecSwitch is a function"
// - "the other siblings it invokes are also app methods"
// determinism_controls:
// - "static prototype inspection; no network/clock/DOM"
// anti_cheat_rationale:
// prevents: ["hard-coded return value"]
// relaxation:
// did_relax_any_assertion: false
import "./test-helpers/setup-localstorage.mjs";
import test from "node:test";
import { strict as assert } from "node:assert";
import { Application } from "../js/app.js";
// Every coordinator sibling that handleProfileSwitchRequest calls via `this.X`
// must exist as an app-level method, because bindCoordinator binds the coordinator
// methods to the Application instance.
const REQUIRED_APP_METHODS = [
"handleProfileSwitchRequest",
"prepareStoredNsecSwitch", // was missing -> the reported bug
"handleModerationSettingsChange",
"waitForIdentityRefresh",
];
for (const name of REQUIRED_APP_METHODS) {
test(`Application exposes ${name}() so the bound profile-switch flow can call it`, () => {
assert.equal(
typeof Application.prototype[name],
"function",
`Application.prototype.${name} must be a function (coordinator siblings are ` +
`bound to app; handleProfileSwitchRequest calls it via this.${name}())`,
);
});
}