fixing tests

This commit is contained in:
orangecoding
2025-12-17 16:35:24 +01:00
parent 6e8a35a836
commit 05f1bc61c9
2 changed files with 23 additions and 9 deletions

View File

@@ -19,8 +19,13 @@ import { runMigrations, listMigrationFiles } from './migrations/migrate.js';
let _AdmZipSingleton = null; let _AdmZipSingleton = null;
async function getAdmZip() { async function getAdmZip() {
if (_AdmZipSingleton) return _AdmZipSingleton; if (_AdmZipSingleton) return _AdmZipSingleton;
// Allow tests to provide a mock constructor without ESM loader intricacies
if (globalThis && globalThis.__TEST_ADM_ZIP__) {
_AdmZipSingleton = globalThis.__TEST_ADM_ZIP__;
return _AdmZipSingleton;
}
const mod = await import('adm-zip'); const mod = await import('adm-zip');
_AdmZipSingleton = mod.default || mod; _AdmZipSingleton = (mod && mod.default) || mod;
return _AdmZipSingleton; return _AdmZipSingleton;
} }

View File

@@ -8,17 +8,21 @@ import esmock from 'esmock';
describe('services/storage/backupRestoreService.js - precheck & filename', () => { describe('services/storage/backupRestoreService.js - precheck & filename', () => {
let svc; let svc;
let admZipMock; let setZipState;
let calls; let calls;
beforeEach(async () => { beforeEach(async () => {
calls = { logger: { info: [], warn: [], error: [] } }; calls = { logger: { info: [], warn: [], error: [] } };
// Mock AdmZip with configurable state // Mock AdmZip with configurable state via globalThis (avoid esmock export name pitfalls)
let state = { hasDb: false, meta: null }; globalThis.__ADM_ZIP_STATE__ = { hasDb: false, meta: null };
setZipState = (s) => {
globalThis.__ADM_ZIP_STATE__ = { ...globalThis.__ADM_ZIP_STATE__, ...s };
};
class MockAdmZip { class MockAdmZip {
constructor() {} constructor() {}
getEntry(name) { getEntry(name) {
const state = globalThis.__ADM_ZIP_STATE__ || {};
if (name === 'listings.db') { if (name === 'listings.db') {
if (state.hasDb) return { getData: () => Buffer.from('db') }; if (state.hasDb) return { getData: () => Buffer.from('db') };
return null; return null;
@@ -30,12 +34,15 @@ describe('services/storage/backupRestoreService.js - precheck & filename', () =>
return null; return null;
} }
getEntries() { getEntries() {
const state = globalThis.__ADM_ZIP_STATE__ || {};
const arr = []; const arr = [];
if (state.hasDb) arr.push({ entryName: 'listings.db', getData: () => Buffer.from('db') }); if (state.hasDb) arr.push({ entryName: 'listings.db', getData: () => Buffer.from('db') });
return arr; return arr;
} }
} }
admZipMock = { default: MockAdmZip, __set: (s) => (state = { ...state, ...s }) }; const admZipMock = { default: MockAdmZip };
// Also expose for service via globalThis escape hatch
globalThis.__TEST_ADM_ZIP__ = MockAdmZip;
const path = await import('node:path'); const path = await import('node:path');
const ROOT = path.resolve('.'); const ROOT = path.resolve('.');
@@ -70,11 +77,13 @@ describe('services/storage/backupRestoreService.js - precheck & filename', () =>
const utilsMock = { getPackageVersion: async () => '16.2.0' }; const utilsMock = { getPackageVersion: async () => '16.2.0' };
const admZipPath = path.join(ROOT, 'node_modules', 'adm-zip', 'adm-zip.js');
const mod = await esmock( const mod = await esmock(
path.join(ROOT, 'lib', 'services', 'storage', 'backupRestoreService.js'), path.join(ROOT, 'lib', 'services', 'storage', 'backupRestoreService.js'),
{}, {},
{ {
'adm-zip': admZipMock, 'adm-zip': admZipMock,
[admZipPath]: admZipMock,
[migratePath]: migrateMock, [migratePath]: migrateMock,
[sqlitePath]: sqliteMock, [sqlitePath]: sqliteMock,
[loggerPath]: loggerMock, [loggerPath]: loggerMock,
@@ -94,7 +103,7 @@ describe('services/storage/backupRestoreService.js - precheck & filename', () =>
}); });
it('precheck: missing listings.db yields danger', async () => { it('precheck: missing listings.db yields danger', async () => {
admZipMock.__set({ hasDb: false, meta: { dbMigration: 9 } }); setZipState({ hasDb: false, meta: { dbMigration: 9 } });
const res = await svc.precheckRestore(Buffer.from('dummy')); const res = await svc.precheckRestore(Buffer.from('dummy'));
expect(res.compatible).to.equal(false); expect(res.compatible).to.equal(false);
expect(res.severity).to.equal('danger'); expect(res.severity).to.equal('danger');
@@ -102,7 +111,7 @@ describe('services/storage/backupRestoreService.js - precheck & filename', () =>
}); });
it('precheck: older backup is compatible with warning', async () => { it('precheck: older backup is compatible with warning', async () => {
admZipMock.__set({ hasDb: true, meta: { dbMigration: 5, fredyVersion: '16.0.0' } }); setZipState({ hasDb: true, meta: { dbMigration: 5, fredyVersion: '16.0.0' } });
const res = await svc.precheckRestore(Buffer.from('zip')); const res = await svc.precheckRestore(Buffer.from('zip'));
expect(res.compatible).to.equal(true); expect(res.compatible).to.equal(true);
expect(res.severity).to.equal('warning'); expect(res.severity).to.equal('warning');
@@ -112,14 +121,14 @@ describe('services/storage/backupRestoreService.js - precheck & filename', () =>
}); });
it('precheck: equal backup is compatible with info', async () => { it('precheck: equal backup is compatible with info', async () => {
admZipMock.__set({ hasDb: true, meta: { dbMigration: 10 } }); setZipState({ hasDb: true, meta: { dbMigration: 10 } });
const res = await svc.precheckRestore(Buffer.from('zip')); const res = await svc.precheckRestore(Buffer.from('zip'));
expect(res.compatible).to.equal(true); expect(res.compatible).to.equal(true);
expect(res.severity).to.equal('info'); expect(res.severity).to.equal('info');
}); });
it('precheck: newer backup yields danger', async () => { it('precheck: newer backup yields danger', async () => {
admZipMock.__set({ hasDb: true, meta: { dbMigration: 11 } }); setZipState({ hasDb: true, meta: { dbMigration: 11 } });
const res = await svc.precheckRestore(Buffer.from('zip')); const res = await svc.precheckRestore(Buffer.from('zip'));
expect(res.compatible).to.equal(false); expect(res.compatible).to.equal(false);
expect(res.severity).to.equal('danger'); expect(res.severity).to.equal('danger');