mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-24 07:53:09 +00:00
77dddd5e8a
Release branch for 4.0.0.
98 lines
4.2 KiB
TypeScript
98 lines
4.2 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import semver from 'semver';
|
|
import { SYSTEM_NOTICES } from '../../../src/systemNotices/registry.js';
|
|
import { isNoticeVersionActive } from '../../../src/systemNotices/service.js';
|
|
|
|
/** Collect all actionIds registered via registerNoticeAction() in client source files. */
|
|
function collectRegisteredActionIds(): Set<string> {
|
|
const clientSrc = path.resolve(__dirname, '../../../../client/src');
|
|
const ids = new Set<string>();
|
|
const queue = [clientSrc];
|
|
while (queue.length) {
|
|
const dir = queue.pop()!;
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
const full = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) { queue.push(full); continue; }
|
|
if (!entry.name.endsWith('noticeActions.ts') && !entry.name.endsWith('noticeActions.js')) continue;
|
|
const src = fs.readFileSync(full, 'utf8');
|
|
for (const m of src.matchAll(/registerNoticeAction\(\s*['"]([^'"]+)['"]/g)) {
|
|
ids.add(m[1]);
|
|
}
|
|
}
|
|
}
|
|
return ids;
|
|
}
|
|
|
|
describe('registry integrity', () => {
|
|
it('has no duplicate ids', () => {
|
|
const ids = SYSTEM_NOTICES.map(n => n.id);
|
|
expect(new Set(ids).size).toBe(ids.length);
|
|
});
|
|
|
|
it('all action CTAs reference a registered actionId', () => {
|
|
const registeredActionIds = collectRegisteredActionIds();
|
|
const actionCtaIds = SYSTEM_NOTICES
|
|
.filter(n => n.cta?.kind === 'action')
|
|
.map(n => (n.cta as { actionId: string }).actionId);
|
|
|
|
for (const id of actionCtaIds) {
|
|
expect(registeredActionIds, `actionId "${id}" not found in any client noticeActions.ts`).toContain(id);
|
|
}
|
|
});
|
|
|
|
it('all publishedAt are valid ISO dates', () => {
|
|
for (const n of SYSTEM_NOTICES) {
|
|
expect(() => new Date(n.publishedAt).toISOString()).not.toThrow();
|
|
}
|
|
});
|
|
|
|
it('minVersion and maxVersion are valid semver when set, and minVersion <= maxVersion when both set', () => {
|
|
for (const n of SYSTEM_NOTICES) {
|
|
if (n.minVersion !== undefined) {
|
|
expect(semver.valid(n.minVersion), `notice "${n.id}" has invalid minVersion "${n.minVersion}"`).not.toBeNull();
|
|
}
|
|
if (n.maxVersion !== undefined) {
|
|
expect(semver.valid(n.maxVersion), `notice "${n.id}" has invalid maxVersion "${n.maxVersion}"`).not.toBeNull();
|
|
}
|
|
if (n.minVersion && n.maxVersion) {
|
|
expect(
|
|
semver.lte(n.minVersion, n.maxVersion),
|
|
`notice "${n.id}": minVersion ${n.minVersion} > maxVersion ${n.maxVersion}`
|
|
).toBe(true);
|
|
}
|
|
}
|
|
});
|
|
|
|
it('the 4.0.0 release notice is confined to the 4.0.x line', () => {
|
|
const release = SYSTEM_NOTICES.find(n => n.id === 'release-4-0-0');
|
|
expect(release).toBeDefined();
|
|
// Its copy is about this release, so it must not greet somebody who skipped
|
|
// straight past it, and it must not run alongside the next release's notice.
|
|
expect(isNoticeVersionActive(release!, '3.4.1')).toBe(false);
|
|
expect(isNoticeVersionActive(release!, '4.0.0')).toBe(true);
|
|
expect(isNoticeVersionActive(release!, '4.0.7')).toBe(true);
|
|
// The upper bound is exclusive, so every 4.0.x patch still gets it.
|
|
expect(isNoticeVersionActive(release!, '4.0.9')).toBe(true);
|
|
expect(isNoticeVersionActive(release!, '4.0.12')).toBe(true);
|
|
expect(isNoticeVersionActive(release!, '4.1.0')).toBe(false);
|
|
expect(isNoticeVersionActive(release!, '4.2.0')).toBe(false);
|
|
});
|
|
|
|
it('the thank-you notice hands over to the release modal at 4.0.0', () => {
|
|
const thankYou = SYSTEM_NOTICES.find(n => n.id === 'thank-you-support');
|
|
expect(thankYou).toBeDefined();
|
|
// Both carry the same thank-you and the same two support links, so exactly
|
|
// one of them may be active at any version.
|
|
expect(isNoticeVersionActive(thankYou!, '3.4.1')).toBe(true);
|
|
expect(isNoticeVersionActive(thankYou!, '4.0.0')).toBe(false);
|
|
|
|
const release = SYSTEM_NOTICES.find(n => n.id === 'release-4-0-0')!;
|
|
for (const version of ['3.4.1', '4.0.0', '4.0.7', '4.1.0', '5.0.0']) {
|
|
const active = [thankYou!, release].filter(n => isNoticeVersionActive(n, version));
|
|
expect(active.length, `both thank-you notices active at ${version}`).toBeLessThanOrEqual(1);
|
|
}
|
|
});
|
|
});
|