- useOnboarding.ts: prefer the backend over localStorage when checking onboarding completion. The old order (localStorage first) meant any browser that had ever onboarded a node would treat every new fresh node as already-onboarded and skip the wizard, dumping the user straight at the inline set-password form. Backend is now authoritative; localStorage stays as the offline fallback. - OnboardingWrapper.vue: skip the intro video on `/login` once `neode_onboarding_complete` is set. Returning logged-out users now get the static lock-screen background + glitch overlay instead of replaying the full intro on every logout. - RootRedirect.vue: when the health check fails, only show the full BootScreen if the node was never onboarded. For already-onboarded nodes (i.e. an OTA-update blip), keep the spinner and poll the health endpoint every 2s for up to 60s before falling back to the boot screen. Fixes the "fake boot loader" / "server starting up" screens flashing on every successful update. - loginTransition store: new `justCompletedOnboarding` flag distinct from `justLoggedIn`. Set true only by the inline setup-password flow (handleSetup). Dashboard.vue branches on it: full glitch+zoom reveal for the post-onboarding entry, quick zoom + welcome typing on every other login (no triple glitch flashes, ~1.2s vs 8s). - vite.config.ts: bump assets cache from `assets-cache-v2` to `assets-cache-v3` so service workers running the previous bundle invalidate their cache and pick up the new UI cleanly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
import { describe, it, expect, beforeEach } from 'vitest'
|
|
import { setActivePinia, createPinia } from 'pinia'
|
|
import { useLoginTransitionStore } from '../loginTransition'
|
|
|
|
describe('useLoginTransitionStore', () => {
|
|
beforeEach(() => {
|
|
setActivePinia(createPinia())
|
|
})
|
|
|
|
it('starts with all flags false', () => {
|
|
const store = useLoginTransitionStore()
|
|
expect(store.justLoggedIn).toBe(false)
|
|
expect(store.justCompletedOnboarding).toBe(false)
|
|
expect(store.pendingWelcomeTyping).toBe(false)
|
|
expect(store.startWelcomeTyping).toBe(false)
|
|
})
|
|
|
|
it('setJustCompletedOnboarding updates justCompletedOnboarding', () => {
|
|
const store = useLoginTransitionStore()
|
|
store.setJustCompletedOnboarding(true)
|
|
expect(store.justCompletedOnboarding).toBe(true)
|
|
store.setJustCompletedOnboarding(false)
|
|
expect(store.justCompletedOnboarding).toBe(false)
|
|
})
|
|
|
|
it('setJustLoggedIn updates justLoggedIn', () => {
|
|
const store = useLoginTransitionStore()
|
|
store.setJustLoggedIn(true)
|
|
expect(store.justLoggedIn).toBe(true)
|
|
store.setJustLoggedIn(false)
|
|
expect(store.justLoggedIn).toBe(false)
|
|
})
|
|
|
|
it('setPendingWelcomeTyping updates pendingWelcomeTyping', () => {
|
|
const store = useLoginTransitionStore()
|
|
store.setPendingWelcomeTyping(true)
|
|
expect(store.pendingWelcomeTyping).toBe(true)
|
|
store.setPendingWelcomeTyping(false)
|
|
expect(store.pendingWelcomeTyping).toBe(false)
|
|
})
|
|
|
|
it('setStartWelcomeTyping updates startWelcomeTyping', () => {
|
|
const store = useLoginTransitionStore()
|
|
store.setStartWelcomeTyping(true)
|
|
expect(store.startWelcomeTyping).toBe(true)
|
|
store.setStartWelcomeTyping(false)
|
|
expect(store.startWelcomeTyping).toBe(false)
|
|
})
|
|
|
|
it('flags are independent of each other', () => {
|
|
const store = useLoginTransitionStore()
|
|
store.setJustLoggedIn(true)
|
|
store.setPendingWelcomeTyping(true)
|
|
expect(store.startWelcomeTyping).toBe(false)
|
|
|
|
store.setStartWelcomeTyping(true)
|
|
store.setJustLoggedIn(false)
|
|
expect(store.pendingWelcomeTyping).toBe(true)
|
|
expect(store.startWelcomeTyping).toBe(true)
|
|
})
|
|
})
|