154 lines
4.5 KiB
TypeScript
154 lines
4.5 KiB
TypeScript
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
import { SmartMigration, SmartMigrationError } from '../ts/index.js';
|
|
|
|
// Pure-logic tests for the SmartMigration constructor — no database required.
|
|
|
|
tap.test('constructor: rejects empty options', async () => {
|
|
expect(() => new (SmartMigration as any)()).toThrow();
|
|
expect(() => new (SmartMigration as any)(null)).toThrow();
|
|
});
|
|
|
|
tap.test('constructor: requires targetVersion', async () => {
|
|
expect(() => new SmartMigration({} as any)).toThrow();
|
|
});
|
|
|
|
tap.test('constructor: rejects invalid targetVersion', async () => {
|
|
let caught: SmartMigrationError | undefined;
|
|
try {
|
|
// not a real semver
|
|
new SmartMigration({ targetVersion: 'not-a-version', db: {} as any });
|
|
} catch (err) {
|
|
caught = err as SmartMigrationError;
|
|
}
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
|
expect(caught!.code).toEqual('INVALID_VERSION');
|
|
});
|
|
|
|
tap.test('constructor: rejects invalid freshInstallVersion', async () => {
|
|
let caught: SmartMigrationError | undefined;
|
|
try {
|
|
new SmartMigration({
|
|
targetVersion: '1.0.0',
|
|
freshInstallVersion: 'nope',
|
|
db: {} as any,
|
|
});
|
|
} catch (err) {
|
|
caught = err as SmartMigrationError;
|
|
}
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
|
expect(caught!.code).toEqual('INVALID_VERSION');
|
|
});
|
|
|
|
tap.test('constructor: rejects when neither db nor bucket given', async () => {
|
|
let caught: SmartMigrationError | undefined;
|
|
try {
|
|
new SmartMigration({ targetVersion: '1.0.0' });
|
|
} catch (err) {
|
|
caught = err as SmartMigrationError;
|
|
}
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
|
expect(caught!.code).toEqual('NO_RESOURCES');
|
|
});
|
|
|
|
tap.test('constructor: defaults ledgerBackend to "mongo" when db is given', async () => {
|
|
const m = new SmartMigration({
|
|
targetVersion: '1.0.0',
|
|
db: {} as any,
|
|
});
|
|
expect(m.settings.ledgerBackend).toEqual('mongo');
|
|
expect(m.settings.ledgerName).toEqual('smartmigration');
|
|
expect(m.settings.lockWaitMs).toEqual(60_000);
|
|
expect(m.settings.lockTtlMs).toEqual(600_000);
|
|
expect(m.settings.dryRun).toBeFalse();
|
|
});
|
|
|
|
tap.test('constructor: defaults ledgerBackend to "s3" when only bucket is given', async () => {
|
|
const m = new SmartMigration({
|
|
targetVersion: '1.0.0',
|
|
bucket: {} as any,
|
|
});
|
|
expect(m.settings.ledgerBackend).toEqual('s3');
|
|
});
|
|
|
|
tap.test('constructor: rejects mongo backend without db', async () => {
|
|
let caught: SmartMigrationError | undefined;
|
|
try {
|
|
new SmartMigration({
|
|
targetVersion: '1.0.0',
|
|
bucket: {} as any,
|
|
ledgerBackend: 'mongo',
|
|
});
|
|
} catch (err) {
|
|
caught = err as SmartMigrationError;
|
|
}
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
|
expect(caught!.code).toEqual('LEDGER_BACKEND_MISMATCH');
|
|
});
|
|
|
|
tap.test('constructor: rejects blank ledgerName', async () => {
|
|
let caught: SmartMigrationError | undefined;
|
|
try {
|
|
new SmartMigration({
|
|
targetVersion: '1.0.0',
|
|
db: {} as any,
|
|
ledgerName: ' ',
|
|
});
|
|
} catch (err) {
|
|
caught = err as SmartMigrationError;
|
|
}
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
|
expect(caught!.code).toEqual('INVALID_LEDGER_NAME');
|
|
});
|
|
|
|
tap.test('constructor: rejects negative lockWaitMs', async () => {
|
|
let caught: SmartMigrationError | undefined;
|
|
try {
|
|
new SmartMigration({
|
|
targetVersion: '1.0.0',
|
|
db: {} as any,
|
|
lockWaitMs: -1,
|
|
});
|
|
} catch (err) {
|
|
caught = err as SmartMigrationError;
|
|
}
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
|
expect(caught!.code).toEqual('INVALID_LOCK_WAIT_MS');
|
|
});
|
|
|
|
tap.test('constructor: rejects non-positive lockTtlMs', async () => {
|
|
let caught: SmartMigrationError | undefined;
|
|
try {
|
|
new SmartMigration({
|
|
targetVersion: '1.0.0',
|
|
db: {} as any,
|
|
lockTtlMs: 0,
|
|
});
|
|
} catch (err) {
|
|
caught = err as SmartMigrationError;
|
|
}
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
|
expect(caught!.code).toEqual('INVALID_LOCK_TTL_MS');
|
|
});
|
|
|
|
tap.test('constructor: rejects s3 backend without bucket', async () => {
|
|
let caught: SmartMigrationError | undefined;
|
|
try {
|
|
new SmartMigration({
|
|
targetVersion: '1.0.0',
|
|
db: {} as any,
|
|
ledgerBackend: 's3',
|
|
});
|
|
} catch (err) {
|
|
caught = err as SmartMigrationError;
|
|
}
|
|
expect(caught).toBeInstanceOf(SmartMigrationError);
|
|
expect(caught!.code).toEqual('LEDGER_BACKEND_MISMATCH');
|
|
});
|
|
|
|
tap.test('step(): rejects empty id', async () => {
|
|
const m = new SmartMigration({ targetVersion: '1.0.0', db: {} as any });
|
|
expect(() => m.step('')).toThrow();
|
|
});
|
|
|
|
export default tap.start();
|