fix(leads): disable sign-in submit until exhibit loads; add licensed-user auth tests
Prevents silent no-op when user clicks submit before lq__exhibit_obj is ready (exhibit not yet written to Dexie). Button now shows 'Loading...' spinner while the exhibit record is resolving, eliminating the two-tap workaround needed on first page load. Also adds 7 Playwright tests for licensed user sign-in (leads_licensed_signin.test.ts) covering success path, wrong credentials, email/identity tagging on captured leads, identity isolation between staff members, and returning-session bypass. Helpers: attach_leads_routes/setup_leads_test_page now accept exhibit_overrides (e.g. license_li_json) to inject licensed users into mocked API responses. seed_leads_loc import added to leads_auth.test.ts multi-exhibit test. Total leads test coverage: 29 tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -350,6 +350,7 @@ export async function attach_leads_routes(
|
||||
opts: {
|
||||
staff_passcode?: string;
|
||||
exhibit_name?: string;
|
||||
exhibit_overrides?: Record<string, unknown>;
|
||||
tracking_li?: any[];
|
||||
badge_li?: any[];
|
||||
event_data_overrides?: Record<string, any>;
|
||||
@@ -358,6 +359,7 @@ export async function attach_leads_routes(
|
||||
const {
|
||||
staff_passcode = exhibit_staff_passcode,
|
||||
exhibit_name = 'Test Booth — ACME Corp',
|
||||
exhibit_overrides = {} as Record<string, unknown>,
|
||||
tracking_li = [],
|
||||
badge_li = [minimal_badge()],
|
||||
event_data_overrides = {},
|
||||
@@ -387,7 +389,7 @@ export async function attach_leads_routes(
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(
|
||||
minimal_exhibit(exhibit_id, { staff_passcode, name: exhibit_name })
|
||||
minimal_exhibit(exhibit_id, { staff_passcode, name: exhibit_name, ...exhibit_overrides })
|
||||
),
|
||||
});
|
||||
}
|
||||
@@ -492,6 +494,7 @@ export async function setup_leads_test_page(
|
||||
leads_overrides?: Record<string, any>;
|
||||
staff_passcode?: string;
|
||||
exhibit_name?: string;
|
||||
exhibit_overrides?: Record<string, unknown>;
|
||||
tracking_li?: any[];
|
||||
badge_li?: any[];
|
||||
event_data_overrides?: Record<string, any>;
|
||||
@@ -499,10 +502,18 @@ export async function setup_leads_test_page(
|
||||
): Promise<void> {
|
||||
const { access = {}, auth_kv = {}, leads_overrides = {}, ...route_opts } = opts;
|
||||
|
||||
// Build auth_exhibit_kv with timestamps for ae_leads_loc (the current store).
|
||||
// seed_events_loc also seeds the old ae_events_loc for backwards compatibility,
|
||||
// but is_signed_in now reads from leads_loc (ae_leads_loc) exclusively.
|
||||
const auth_exhibit_kv_with_ts: Record<string, { key: string; type: string; updated_on: string }> = {};
|
||||
for (const [eid, entry] of Object.entries(auth_kv)) {
|
||||
auth_exhibit_kv_with_ts[eid] = { ...entry, updated_on: new Date().toISOString() };
|
||||
}
|
||||
|
||||
page.on('pageerror', (err) => console.error(`BROWSER ERROR: ${err.message}`));
|
||||
await attach_leads_routes(page, event_id, exhibit_id, route_opts);
|
||||
await seed_ae_loc(page, access);
|
||||
await seed_leads_loc(page, leads_overrides);
|
||||
await seed_leads_loc(page, { ...leads_overrides, auth_exhibit_kv: auth_exhibit_kv_with_ts });
|
||||
await seed_events_loc(page, auth_kv, leads_overrides);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user