Remove all Dexie/IndexedDB code and dependencies, including document and preview caches, local config, onboarding, and migration logic. Replace with server-backed React Query hooks for documents, folders, preferences, onboarding, and progress. Add browser Cache Storage for blob caching of documents, previews, and audio. Update API routes, database schema, and tests to support folder management, onboarding state, and server-side persistence of all user data. Refactor UI and hooks to use server state exclusively, ensuring all user state is synced and portable across devices. BREAKING CHANGE: All user data, preferences, onboarding, and document state are now stored and synced on the server; browser IndexedDB is no longer used. Existing local-only data will not be available after this update.
89 lines
2.2 KiB
TypeScript
89 lines
2.2 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,
|
|
changelogPending: true,
|
|
});
|
|
|
|
expect(step).toBe('privacy');
|
|
});
|
|
|
|
test('resolves claim after privacy is accepted', () => {
|
|
const step = resolveNextOnboardingStep({
|
|
privacyRequired: true,
|
|
privacyAccepted: true,
|
|
claimEligible: true,
|
|
claimHasData: true,
|
|
changelogPending: true,
|
|
});
|
|
|
|
expect(step).toBe('claim');
|
|
});
|
|
|
|
test('resolves changelog when prior steps are clear', () => {
|
|
const step = resolveNextOnboardingStep({
|
|
privacyRequired: true,
|
|
privacyAccepted: true,
|
|
claimEligible: true,
|
|
claimHasData: 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,
|
|
changelogPending: false,
|
|
});
|
|
const minimalStep = resolveNextOnboardingStep({
|
|
privacyRequired: false,
|
|
privacyAccepted: false,
|
|
claimEligible: false,
|
|
claimHasData: 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);
|
|
});
|
|
});
|