mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
@
test(server): unpin three fixtures from the 3.x version window The 4.0.0 bump turned three suites red on dev, all for the same reason: they described a world where the host was still 3.x. The plugin install fixtures declared trek ">=3.2.0 <4.0.0" and ">=3.0.0 <4.0.0", so every default artifact became incompatible with its own host and 23 tests failed on the version gate instead of on what they were testing. The upper bound bought nothing — the cases that exercise the gate pass their own range — so it is gone rather than moved to 5.0.0. The system-notice suite named thank-you-support twice. It is capped at 4.0.0 and handed over to release-4-0-0 there, so the established-user case saw a notice it had never been told about, and the per-version recurrence case rode on a notice that no longer applies at all. The first now reads the always-on set out of the registry instead of naming it, and the second drives the mechanism through a notice it pushes itself. Neither ages out at the next release. @
This commit is contained in:
@@ -47,7 +47,7 @@ function writeSource(id: string, opts: { index?: string; native?: boolean; noBui
|
||||
fs.mkdirSync(path.join(dir, 'server'), { recursive: true });
|
||||
// dev-link requires a `trek` range like any other install front door; `opts.trek`
|
||||
// overrides it to exercise the gate.
|
||||
fs.writeFileSync(path.join(dir, 'trek-plugin.json'), JSON.stringify({ id, name: id, version: '1.0.0', type: 'integration', permissions: [], trek: opts.trek ?? '>=3.0.0 <4.0.0' }));
|
||||
fs.writeFileSync(path.join(dir, 'trek-plugin.json'), JSON.stringify({ id, name: id, version: '1.0.0', type: 'integration', permissions: [], trek: opts.trek ?? '>=3.0.0' }));
|
||||
if (!opts.noBuild) fs.writeFileSync(path.join(dir, 'server', 'index.js'), opts.index ?? 'module.exports = {};');
|
||||
if (opts.native) fs.writeFileSync(path.join(dir, 'server', 'addon.node'), '\0');
|
||||
return dir;
|
||||
|
||||
@@ -49,7 +49,7 @@ function tarHeader(name: string, size: number, typeflag = '0'): Buffer {
|
||||
// without it would be testing the version gate rather than whatever the test is about.
|
||||
// Pass an explicit `trek` (or null, spread last) to exercise the gate itself.
|
||||
function makeArtifact(manifest: object): Buffer {
|
||||
const withTrek = { trek: '>=3.2.0 <4.0.0', ...manifest };
|
||||
const withTrek = { trek: '>=3.2.0', ...manifest };
|
||||
const files = [
|
||||
{ name: 'plug-abc/', type: '5' as const, data: '' },
|
||||
{ name: 'plug-abc/trek-plugin.json', type: '0' as const, data: JSON.stringify(withTrek) },
|
||||
|
||||
@@ -95,14 +95,21 @@ describe('GET /api/system-notices/active', () => {
|
||||
it('returns no login/version-gated notices for an established user', async () => {
|
||||
const { user } = createUser(testDb);
|
||||
// login_count > 1 means firstLogin does not match; first_seen_version >= 3.0.0 means
|
||||
// existingUserBeforeVersion('3.0.0') does not match either. The always-on thank-you
|
||||
// notice (no conditions) may still apply, so only filter it out.
|
||||
// existingUserBeforeVersion('3.0.0') does not match either. Notices that gate on
|
||||
// nothing but the install being self-hosted still apply, and which ones those are
|
||||
// changes every release — the thank-you modal handed over to release-4-0-0 at 4.0.0.
|
||||
// Read the set out of the registry rather than naming them, or this ages out again.
|
||||
testDb.prepare('UPDATE users SET login_count = 5, first_seen_version = ? WHERE id = ?').run('3.0.0', user.id);
|
||||
const alwaysOn = new Set(
|
||||
SYSTEM_NOTICES
|
||||
.filter(n => (n.conditions ?? []).every(c => c.kind === 'managed'))
|
||||
.map(n => n.id),
|
||||
);
|
||||
const res = await request(app)
|
||||
.get('/api/system-notices/active')
|
||||
.set('Cookie', authCookie(user.id));
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body.filter((n: { id: string }) => n.id !== 'thank-you-support')).toEqual([]);
|
||||
expect(res.body.filter((n: { id: string }) => !alwaysOn.has(n.id))).toEqual([]);
|
||||
});
|
||||
|
||||
it('returns firstLogin notice for user with login_count <= 1', async () => {
|
||||
@@ -171,33 +178,53 @@ describe('GET /api/system-notices/active', () => {
|
||||
}
|
||||
});
|
||||
|
||||
// Drives the recurrence mechanism through a notice this test owns. It used to
|
||||
// ride on thank-you-support, which stopped applying the moment that notice was
|
||||
// capped at 4.0.0 — the mechanism was fine, the fixture had retired.
|
||||
it('re-surfaces a per-version notice after an upgrade but hides it within the same version', async () => {
|
||||
const TY = 'thank-you-support';
|
||||
const { user } = createUser(testDb);
|
||||
testDb.prepare('UPDATE users SET login_count = 5, first_seen_version = ? WHERE id = ?').run('3.0.0', user.id);
|
||||
|
||||
const shows = async () => {
|
||||
const res = await request(app)
|
||||
.get('/api/system-notices/active')
|
||||
.set('Cookie', authCookie(user.id));
|
||||
expect(res.status).toBe(200);
|
||||
return res.body.some((n: { id: string }) => n.id === TY);
|
||||
const RECURRING: SystemNotice = {
|
||||
id: 'test-per-version-notice',
|
||||
display: 'modal',
|
||||
severity: 'info',
|
||||
titleKey: 'system_notice.test_per_version_notice.title',
|
||||
bodyKey: 'system_notice.test_per_version_notice.body',
|
||||
dismissible: true,
|
||||
conditions: [],
|
||||
recurring: 'per-version',
|
||||
publishedAt: '2026-01-01T00:00:00Z',
|
||||
priority: 0,
|
||||
};
|
||||
SYSTEM_NOTICES.push(RECURRING);
|
||||
try {
|
||||
const { user } = createUser(testDb);
|
||||
testDb.prepare('UPDATE users SET login_count = 5, first_seen_version = ? WHERE id = ?').run('3.0.0', user.id);
|
||||
|
||||
// Fresh user with no dismissal: the recurring thank-you shows.
|
||||
expect(await shows()).toBe(true);
|
||||
const shows = async () => {
|
||||
const res = await request(app)
|
||||
.get('/api/system-notices/active')
|
||||
.set('Cookie', authCookie(user.id));
|
||||
expect(res.status).toBe(200);
|
||||
return res.body.some((n: { id: string }) => n.id === RECURRING.id);
|
||||
};
|
||||
|
||||
// Dismissed at an old version → it returns once the running version is newer.
|
||||
testDb.prepare(
|
||||
'INSERT INTO user_notice_dismissals (user_id, notice_id, dismissed_at, dismissed_app_version) VALUES (?, ?, ?, ?)'
|
||||
).run(user.id, TY, Date.now(), '0.0.1');
|
||||
expect(await shows()).toBe(true);
|
||||
// Fresh user with no dismissal: the recurring notice shows.
|
||||
expect(await shows()).toBe(true);
|
||||
|
||||
// Dismissed at a version >= the running one → stays hidden until the next upgrade.
|
||||
testDb.prepare(
|
||||
'UPDATE user_notice_dismissals SET dismissed_app_version = ? WHERE user_id = ? AND notice_id = ?'
|
||||
).run('99.0.0', user.id, TY);
|
||||
expect(await shows()).toBe(false);
|
||||
// Dismissed at an old version → it returns once the running version is newer.
|
||||
testDb.prepare(
|
||||
'INSERT INTO user_notice_dismissals (user_id, notice_id, dismissed_at, dismissed_app_version) VALUES (?, ?, ?, ?)'
|
||||
).run(user.id, RECURRING.id, Date.now(), '0.0.1');
|
||||
expect(await shows()).toBe(true);
|
||||
|
||||
// Dismissed at a version >= the running one → stays hidden until the next upgrade.
|
||||
testDb.prepare(
|
||||
'UPDATE user_notice_dismissals SET dismissed_app_version = ? WHERE user_id = ? AND notice_id = ?'
|
||||
).run('99.0.0', user.id, RECURRING.id);
|
||||
expect(await shows()).toBe(false);
|
||||
} finally {
|
||||
const idx = SYSTEM_NOTICES.indexOf(RECURRING);
|
||||
if (idx !== -1) SYSTEM_NOTICES.splice(idx, 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user