Files
basket_utils/src/sessionActivity.test.js
T

26 lines
3.0 KiB
JavaScript

import { describe, expect, it, vi } from 'vitest';
import { createSessionActivityTracker } from './sessionActivity.js';
function harness() {
const target = new EventTarget(); const calls = []; let authenticated = true;
const tracker = createSessionActivityTracker({ target, throttleMs: 1000, isAuthenticated: () => authenticated, onActivity: () => { calls.push('request'); return Promise.resolve(); } });
return { target, calls, tracker, setAuthenticated: (value) => { authenticated = value; } };
}
describe('session activity tracker', () => {
it('sends one immediate request and one trailing request for a burst', async () => {
vi.useFakeTimers(); const { target, calls, tracker } = harness(); tracker.start(); target.dispatchEvent(new Event('pointerdown')); await vi.runOnlyPendingTimersAsync(); expect(calls).toHaveLength(1);
target.dispatchEvent(new Event('pointermove')); target.dispatchEvent(new Event('keydown')); await vi.advanceTimersByTimeAsync(999); expect(calls).toHaveLength(1); await vi.advanceTimersByTimeAsync(1); expect(calls).toHaveLength(2); await vi.advanceTimersByTimeAsync(60_000); expect(calls).toHaveLength(2); tracker.stop(); vi.useRealTimers();
});
it('stays idle, avoids overlap, then stops on the current generation 401', async () => {
vi.useFakeTimers(); const target = new EventTarget(); let resolveFirst; let rejectSecond; let authenticated = true; const calls = []; const onActivity = vi.fn(() => new Promise((resolve, reject) => { calls.push({ resolve, reject }); if (calls.length === 1) resolveFirst = resolve; else rejectSecond = reject; })); const tracker = createSessionActivityTracker({ target, throttleMs: 1000, isAuthenticated: () => authenticated, onActivity });
tracker.start(); await vi.advanceTimersByTimeAsync(3_600_000); expect(onActivity).not.toHaveBeenCalled();
target.dispatchEvent(new Event('click')); target.dispatchEvent(new Event('pointermove')); await vi.runOnlyPendingTimersAsync(); expect(onActivity).toHaveBeenCalledTimes(1); target.dispatchEvent(new Event('keydown')); await vi.advanceTimersByTimeAsync(1000); expect(onActivity).toHaveBeenCalledTimes(1); resolveFirst(); await Promise.resolve(); await vi.runOnlyPendingTimersAsync(); expect(onActivity).toHaveBeenCalledTimes(2); rejectSecond({ status: 401 }); await Promise.resolve(); await vi.runOnlyPendingTimersAsync(); expect(tracker.isActive()).toBe(false); target.dispatchEvent(new Event('click')); await vi.advanceTimersByTimeAsync(10_000); expect(onActivity).toHaveBeenCalledTimes(2); vi.useRealTimers();
});
it('removes listeners and makes no calls while unauthenticated', async () => {
vi.useFakeTimers(); const { target, calls, tracker, setAuthenticated } = harness(); setAuthenticated(false); tracker.start(); target.dispatchEvent(new Event('wheel')); await vi.runOnlyPendingTimersAsync(); expect(calls).toHaveLength(0); tracker.stop(); setAuthenticated(true); target.dispatchEvent(new Event('wheel')); await vi.runOnlyPendingTimersAsync(); expect(calls).toHaveLength(0); vi.useRealTimers();
});
});