openreader/tests/unit/changelog-check.spec.ts
Richard R 0787d2e88a refactor(settings): extract changelog check logic to reusable utility
Move changelog version check effect from SettingsModal to a new
scheduleChangelogCheck utility for improved modularity and testability.
Add unit tests for changelog check scheduling behavior.
2026-05-14 10:58:32 -06:00

81 lines
2.1 KiB
TypeScript

import { expect, test } from '@playwright/test';
import { scheduleChangelogCheck } from '../../src/lib/client/changelog-check';
function wait(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
test.describe('changelog check scheduling', () => {
test('cancels throwaway mount and runs exactly once on remount', async () => {
const completedRef = { current: null as string | null };
const inFlightRef = { current: null as string | null };
let apiCalls = 0;
let openCalls = 0;
const args = {
authEnabled: true,
isSessionPending: false,
sessionUserId: 'u1',
appVersion: '3.3.0',
completedRef,
inFlightRef,
postCheck: async () => {
apiCalls += 1;
return {
shouldOpen: true,
currentVersion: '3.3.0',
lastSeenVersion: null,
};
},
onShouldOpen: () => {
openCalls += 1;
},
delayMs: 40,
retryDelayMs: 1,
} as const;
const cleanupThrowaway = scheduleChangelogCheck(args);
cleanupThrowaway();
const cleanupReal = scheduleChangelogCheck(args);
await wait(120);
cleanupReal();
expect(apiCalls).toBe(1);
expect(openCalls).toBe(1);
expect(completedRef.current).toBe('u1:3.3.0');
expect(inFlightRef.current).toBeNull();
});
test('does not run when auth is enabled and session is pending', async () => {
const completedRef = { current: null as string | null };
const inFlightRef = { current: null as string | null };
let apiCalls = 0;
const cleanup = scheduleChangelogCheck({
authEnabled: true,
isSessionPending: true,
sessionUserId: null,
appVersion: '3.3.0',
completedRef,
inFlightRef,
postCheck: async () => {
apiCalls += 1;
return {
shouldOpen: true,
currentVersion: '3.3.0',
lastSeenVersion: null,
};
},
onShouldOpen: () => undefined,
delayMs: 20,
});
await wait(80);
cleanup();
expect(apiCalls).toBe(0);
expect(completedRef.current).toBeNull();
expect(inFlightRef.current).toBeNull();
});
});