项目文件夹

文件
wehub-resource-sync 070959e133
landing-page-staging / Deploy landing page to staging (push) Has been skipped
landing-page-ci / Validate landing page (push) Failing after 4s
visual-baseline / Capture visual baselines (push) Has been cancelled
bake-plugin-previews / Bake plugin previews (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:00:47 +08:00

59 行
2.4 KiB
TypeScript

// @vitest-environment jsdom
import { beforeEach, describe, expect, it } from 'vitest';
import {
claimProjectTurnIndex,
claimRunTurnIndex,
} from '../../src/analytics/identity';
// `claimRunTurnIndex` is the session-wide run counter (sessionStorage, spans
// all projects, resets each browser session). `claimProjectTurnIndex` is the
// per-project counter (localStorage, project-lifetime per device). These tests
// pin the semantic difference between the two.
describe('run turn index: session-wide vs per-project', () => {
beforeEach(() => {
window.localStorage.clear();
window.sessionStorage.clear();
});
it('per-project index starts at 0 and increments within a project', () => {
expect(claimProjectTurnIndex('proj-a')).toEqual({ projectTurnIndex: 0 });
expect(claimProjectTurnIndex('proj-a')).toEqual({ projectTurnIndex: 1 });
expect(claimProjectTurnIndex('proj-a')).toEqual({ projectTurnIndex: 2 });
});
it('keeps an independent counter per project id', () => {
claimProjectTurnIndex('proj-a'); // 0
claimProjectTurnIndex('proj-a'); // 1
expect(claimProjectTurnIndex('proj-b')).toEqual({ projectTurnIndex: 0 });
expect(claimProjectTurnIndex('proj-a')).toEqual({ projectTurnIndex: 2 });
});
it('persists across browser sessions (survives a sessionStorage reset)', () => {
claimProjectTurnIndex('proj-a'); // 0
claimProjectTurnIndex('proj-a'); // 1
// A new browser session clears sessionStorage but NOT localStorage.
window.sessionStorage.clear();
expect(claimProjectTurnIndex('proj-a')).toEqual({ projectTurnIndex: 2 });
});
it('returns null for an empty project id', () => {
expect(claimProjectTurnIndex('')).toBeNull();
});
it('session counter resets on new session while project counters persist', () => {
expect(claimRunTurnIndex()).toEqual({ turnIndex: 0, isFirstRun: true });
claimRunTurnIndex(); // turnIndex 1
claimProjectTurnIndex('proj-a'); // 0
claimProjectTurnIndex('proj-b'); // 0
window.sessionStorage.clear(); // simulate a new browser session
// Session-wide counter starts over…
expect(claimRunTurnIndex()).toEqual({ turnIndex: 0, isFirstRun: true });
// …but each project keeps its own place.
expect(claimProjectTurnIndex('proj-a')).toEqual({ projectTurnIndex: 1 });
expect(claimProjectTurnIndex('proj-b')).toEqual({ projectTurnIndex: 1 });
});
});