Files
Catalyst/tests/db.test.js
josh 6e40413385
All checks were successful
Build / test (push) Successful in 9m28s
Build / release (push) Successful in 1s
Build / build (push) Successful in 25s
claude went crazy
2026-03-28 02:35:00 -04:00

168 lines
9.2 KiB
JavaScript

import { describe, it, expect, beforeEach } from 'vitest'
import {
_resetForTest,
getInstances, getInstance, getDistinctStacks,
createInstance, updateInstance, deleteInstance,
} from '../server/db.js'
beforeEach(() => _resetForTest());
// ── getInstances ──────────────────────────────────────────────────────────────
describe('getInstances', () => {
it('returns empty array when table is empty', () => {
expect(getInstances()).toEqual([]);
});
it('returns all instances sorted by name', () => {
createInstance({ name: 'zebra', state: 'deployed', stack: 'production', vmid: 1, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
createInstance({ name: 'alpha', state: 'deployed', stack: 'production', vmid: 2, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
const result = getInstances();
expect(result[0].name).toBe('alpha');
expect(result[1].name).toBe('zebra');
});
it('filters by state', () => {
createInstance({ name: 'a', state: 'deployed', stack: 'production', vmid: 1, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
createInstance({ name: 'b', state: 'degraded', stack: 'production', vmid: 2, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
createInstance({ name: 'c', state: 'testing', stack: 'development', vmid: 3, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
expect(getInstances({ state: 'deployed' })).toHaveLength(1);
expect(getInstances({ state: 'degraded' })).toHaveLength(1);
expect(getInstances({ state: 'testing' })).toHaveLength(1);
});
it('filters by stack', () => {
createInstance({ name: 'a', state: 'deployed', stack: 'production', vmid: 1, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
createInstance({ name: 'b', state: 'testing', stack: 'development', vmid: 2, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
expect(getInstances({ stack: 'production' })).toHaveLength(1);
expect(getInstances({ stack: 'development' })).toHaveLength(1);
});
it('searches by name', () => {
createInstance({ name: 'plex', state: 'deployed', stack: 'production', vmid: 1, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
createInstance({ name: 'gitea', state: 'deployed', stack: 'production', vmid: 2, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
expect(getInstances({ search: 'ple' })).toHaveLength(1);
expect(getInstances({ search: 'ple' })[0].name).toBe('plex');
});
it('searches by vmid', () => {
createInstance({ name: 'a', state: 'deployed', stack: 'production', vmid: 137, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
createInstance({ name: 'b', state: 'deployed', stack: 'production', vmid: 200, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
expect(getInstances({ search: '137' })).toHaveLength(1);
});
it('combines filters', () => {
createInstance({ name: 'plex', state: 'deployed', stack: 'production', vmid: 1, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
createInstance({ name: 'plex2', state: 'degraded', stack: 'production', vmid: 2, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
expect(getInstances({ search: 'plex', state: 'deployed' })).toHaveLength(1);
});
});
// ── getInstance ───────────────────────────────────────────────────────────────
describe('getInstance', () => {
it('returns the instance with the given vmid', () => {
createInstance({ name: 'plex', state: 'deployed', stack: 'production', vmid: 117, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
const inst = getInstance(117);
expect(inst).not.toBeNull();
expect(inst.name).toBe('plex');
expect(inst.vmid).toBe(117);
});
it('returns null for unknown vmid', () => {
expect(getInstance(999)).toBeNull();
});
});
// ── getDistinctStacks ─────────────────────────────────────────────────────────
describe('getDistinctStacks', () => {
it('returns empty array when table is empty', () => {
expect(getDistinctStacks()).toEqual([]);
});
it('returns unique stacks sorted alphabetically', () => {
createInstance({ name: 'a', state: 'deployed', stack: 'production', vmid: 1, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
createInstance({ name: 'b', state: 'testing', stack: 'development', vmid: 2, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
createInstance({ name: 'c', state: 'deployed', stack: 'production', vmid: 3, atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 });
expect(getDistinctStacks()).toEqual(['development', 'production']);
});
});
// ── createInstance ────────────────────────────────────────────────────────────
describe('createInstance', () => {
const base = { state: 'deployed', stack: 'production', atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 };
it('inserts a new instance and sets timestamps', () => {
createInstance({ ...base, name: 'traefik', vmid: 100 });
const inst = getInstance(100);
expect(inst.name).toBe('traefik');
expect(inst.created_at).not.toBeNull();
expect(inst.updated_at).not.toBeNull();
});
it('stores service flags correctly', () => {
createInstance({ ...base, name: 'plex', vmid: 1, atlas: 1, tailscale: 1, hardware_acceleration: 1 });
const inst = getInstance(1);
expect(inst.atlas).toBe(1);
expect(inst.argus).toBe(0);
expect(inst.tailscale).toBe(1);
expect(inst.hardware_acceleration).toBe(1);
});
it('rejects duplicate vmid', () => {
createInstance({ ...base, name: 'a', vmid: 100 });
expect(() => createInstance({ ...base, name: 'b', vmid: 100 })).toThrow();
});
it('rejects invalid state', () => {
expect(() => createInstance({ ...base, name: 'a', vmid: 1, state: 'invalid' })).toThrow();
});
it('rejects invalid stack', () => {
expect(() => createInstance({ ...base, name: 'a', vmid: 1, stack: 'invalid' })).toThrow();
});
});
// ── updateInstance ────────────────────────────────────────────────────────────
describe('updateInstance', () => {
const base = { state: 'deployed', stack: 'production', atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 };
it('updates fields and refreshes updated_at', () => {
createInstance({ ...base, name: 'old', vmid: 100 });
updateInstance(100, { ...base, name: 'new', vmid: 100, state: 'degraded' });
const inst = getInstance(100);
expect(inst.name).toBe('new');
expect(inst.state).toBe('degraded');
});
it('can change vmid', () => {
createInstance({ ...base, name: 'a', vmid: 100 });
updateInstance(100, { ...base, name: 'a', vmid: 200 });
expect(getInstance(100)).toBeNull();
expect(getInstance(200)).not.toBeNull();
});
});
// ── deleteInstance ────────────────────────────────────────────────────────────
describe('deleteInstance', () => {
const base = { state: 'deployed', stack: 'production', atlas: 0, argus: 0, semaphore: 0, patchmon: 0, tailscale: 0, andromeda: 0, tailscale_ip: '', hardware_acceleration: 0 };
it('removes the instance', () => {
createInstance({ ...base, name: 'a', vmid: 1 });
deleteInstance(1);
expect(getInstance(1)).toBeNull();
});
it('only removes the targeted instance', () => {
createInstance({ ...base, name: 'a', vmid: 1 });
createInstance({ ...base, name: 'b', vmid: 2 });
deleteInstance(1);
expect(getInstance(1)).toBeNull();
expect(getInstance(2)).not.toBeNull();
});
});