openreader/tests/unit/onboarding-flow.vitest.spec.ts
Richard R 936aa50f9a refactor(api): remove all legacy unclaimed user scope logic and enforce strict userId scoping
Eliminate all code, tests, and utilities related to the legacy 'unclaimed' user
scope. All API endpoints, document and audiobook storage, and access logic now
require a valid authenticated userId and only operate on resources owned by that
user. Remove related helper functions, test cases, and conditional flows for
anonymous/unclaimed data. Update types, client APIs, and UI logic to reflect
that only 'user' scope is supported. This simplifies ownership checks and
removes ambiguity around document and audiobook access.
2026-05-31 13:01:55 -06:00

107 lines
2.7 KiB
TypeScript

import { describe, expect, test } from 'vitest';
import { createCoalescedAsyncRunner, resolveNextOnboardingStep } from '../../src/lib/client/onboarding-flow';
describe('onboarding flow resolver', () => {
test('resolves deterministic order with privacy first', () => {
const step = resolveNextOnboardingStep({
privacyRequired: true,
privacyAccepted: false,
claimEligible: true,
claimHasData: true,
migrationRequired: true,
changelogPending: true,
});
expect(step).toBe('privacy');
});
test('resolves claim after privacy is accepted', () => {
const step = resolveNextOnboardingStep({
privacyRequired: true,
privacyAccepted: true,
claimEligible: true,
claimHasData: true,
migrationRequired: true,
changelogPending: true,
});
expect(step).toBe('claim');
});
test('resolves migration when no claim is needed', () => {
const step = resolveNextOnboardingStep({
privacyRequired: true,
privacyAccepted: true,
claimEligible: true,
claimHasData: false,
migrationRequired: true,
changelogPending: true,
});
expect(step).toBe('migration');
});
test('resolves changelog when prior steps are clear', () => {
const step = resolveNextOnboardingStep({
privacyRequired: true,
privacyAccepted: true,
claimEligible: true,
claimHasData: false,
migrationRequired: false,
changelogPending: true,
});
expect(step).toBe('changelog');
});
test('resolves done when no steps are pending', () => {
const authStep = resolveNextOnboardingStep({
privacyRequired: true,
privacyAccepted: true,
claimEligible: true,
claimHasData: false,
migrationRequired: false,
changelogPending: false,
});
const minimalStep = resolveNextOnboardingStep({
privacyRequired: false,
privacyAccepted: false,
claimEligible: false,
claimHasData: false,
migrationRequired: false,
changelogPending: false,
});
expect(authStep).toBe('done');
expect(minimalStep).toBe('done');
});
});
describe('coalesced onboarding runner', () => {
test('coalesces concurrent triggers into one extra rerun', async () => {
let runs = 0;
let nestedRequested = false;
const run = createCoalescedAsyncRunner(async () => {
runs += 1;
if (!nestedRequested) {
nestedRequested = true;
await run();
}
});
await run();
expect(runs).toBe(2);
});
test('does not rerun when no trigger arrives during execution', async () => {
let runs = 0;
const run = createCoalescedAsyncRunner(async () => {
runs += 1;
});
await run();
expect(runs).toBe(1);
});
});