57 lines
2.1 KiB
TypeScript
57 lines
2.1 KiB
TypeScript
/**
|
|
* The three facts a first-run walkthrough has to keep apart.
|
|
*
|
|
* Conflating them is what makes onboarding annoying: an offer that reappears
|
|
* every morning, a walkthrough that drops out on refresh, or a "skip" that
|
|
* quietly counts as done.
|
|
*/
|
|
import assert from 'node:assert/strict';
|
|
import { test, beforeEach } from 'node:test';
|
|
import { shouldOfferTour, type TourState } from './tourState';
|
|
|
|
const state = (over: Partial<TourState> = {}): TourState => ({
|
|
prompted: false,
|
|
active: false,
|
|
skipped: [],
|
|
...over,
|
|
});
|
|
|
|
beforeEach(() => {
|
|
delete (globalThis as { localStorage?: unknown }).localStorage;
|
|
});
|
|
|
|
test('a new account with work to do is offered the walkthrough', () => {
|
|
assert.equal(shouldOfferTour(state(), true), true);
|
|
});
|
|
|
|
// Asked once. An offer that returns on every sign-in stops being an offer and
|
|
// becomes something to dismiss without reading.
|
|
test('somebody who already said no is not asked again', () => {
|
|
assert.equal(shouldOfferTour(state({ prompted: true }), true), false);
|
|
});
|
|
|
|
test('somebody already in the walkthrough is not offered it again', () => {
|
|
assert.equal(shouldOfferTour(state({ active: true, prompted: true }), true), false);
|
|
});
|
|
|
|
/*
|
|
The check that matters most. A shop already selling is not a first-run case
|
|
however new the account is — three of the four live merchants on 31 Aug were
|
|
trading and still missing a licence number, and offering them a setup tour would
|
|
read as the console not knowing what it is looking at.
|
|
*/
|
|
test('a shop with nothing left to do is never offered a walkthrough', () => {
|
|
assert.equal(shouldOfferTour(state(), false), false);
|
|
assert.equal(shouldOfferTour(state({ prompted: false }), false), false);
|
|
});
|
|
|
|
// Storage the browser refuses must not throw, and must fail towards offering
|
|
// the guidance rather than silently swallowing it.
|
|
test('unavailable storage reads as nothing recorded', async () => {
|
|
const { readTour } = await import('./tourState');
|
|
const read = readTour(1475, 1141);
|
|
assert.equal(read.prompted, false);
|
|
assert.equal(read.active, false);
|
|
assert.deepEqual(read.skipped, []);
|
|
});
|