26 lines
3.0 KiB
JavaScript
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();
|
|
});
|
|
});
|