0189278aa5
qa/harness-server.js boots the real server with chain reads stubbed (COLD=1 reproduces the cached-index state that left #787 without a profile). qa/join-flow-e2e.mjs drives the real /join-now page with a fake wallet producing genuine secp256k1 signatures. Three scenarios pass: signs on a cold index (9) - the gate appears on their own dashboard; refuses to sign (10) - REGRESSION, the join still completes and redirects with the page usable; signs on a warm index (9). Full set green: profiles-unit 28, signin-fallback 7, gate-e2e 47, join-flow 9/10/9, plus the live shared-link check. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
43 lines
2.2 KiB
JavaScript
43 lines
2.2 KiB
JavaScript
// QA harness: boots the real server with the chain reads stubbed, so the join flow
|
|
// can be driven end to end without spending POL or waiting on the indexer.
|
|
//
|
|
// TEST_ADDR=0x.. TEST_ID=9001 COLD=1 PORT=3399 DATA_DIR=... node qa/harness-server.js
|
|
//
|
|
// COLD=1 reproduces the state that broke #787: the cached index does NOT know the
|
|
// brand-new position, so only a live contract read can resolve it.
|
|
const path = require('path');
|
|
process.chdir(path.join(__dirname, '..'));
|
|
const chain = require('../chain.js');
|
|
|
|
const ADDR = String(process.env.TEST_ADDR || '').toLowerCase();
|
|
const ID = Number(process.env.TEST_ID || 9001);
|
|
const COLD = process.env.COLD !== '0';
|
|
let seeded = !COLD; // warm index = already knows the member
|
|
|
|
chain.startIndexer = function () { /* no RPC polling in the harness */ };
|
|
chain.memberIdByAccount = function (a) {
|
|
return (seeded && String(a || '').toLowerCase() === ADDR) ? ID : null;
|
|
};
|
|
chain.verifyMember = async function (id) {
|
|
if (Number(id) !== ID) return { registered: false };
|
|
seeded = true; // a live read seeds the index, as the real one does
|
|
return { registered: true, id: ID, account: ADDR, referrerId: 21, uplineId: 21, tier: 2, level: 1,
|
|
directCount: 0, joinedAt: Math.floor(Date.now() / 1000), tierName: 'Premium', levelName: 'Scintilla' };
|
|
};
|
|
chain.memberPublic = async function (id) { return Number(id) === ID ? { registered: true, id: ID, level: 1, tier: 2, directCount: 0 } : { registered: false, id }; };
|
|
chain.memberLookup = async function (id) { return chain.memberPublic(id); };
|
|
chain.isInTeam = function () { return true; };
|
|
chain.getPayoutsPublic = function () { return []; };
|
|
chain.getIncome = async function () { return []; };
|
|
chain.getMatrixTree = async function () { return null; };
|
|
chain.getCoachingScan = async function () { return { rows: [] }; };
|
|
chain.liveDirects = async function () { return []; };
|
|
chain.balanceOf = async function () { return '0'; };
|
|
chain.getOwnerUpgradeNeeds = async function () { return null; };
|
|
chain.getOrgRouting = async function () { return null; };
|
|
chain.getOrgShare = async function () { return null; };
|
|
chain.nextOpenPosition = function () { return 21; };
|
|
|
|
console.log('harness: addr=' + ADDR + ' id=' + ID + ' coldIndex=' + COLD);
|
|
require('../server.js');
|