Files
kestrelos/test/unit/queries.spec.js
Madison Grubb b0e8dd7ad9
Some checks failed
ci/woodpecker/pr/pr Pipeline failed
make kestrel a tak server, so that it can send and receive pois as cots data
2026-02-17 10:42:53 -05:00

348 lines
9.6 KiB
JavaScript

import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { getDb, setDbPathForTest } from '../../server/utils/db.js'
import {
getDeviceById,
getAllDevices,
createDevice,
updateDevice,
getUserById,
getUserByIdentifier,
createUser,
updateUser,
getPoiById,
getAllPois,
createPoi,
updatePoi,
getSessionById,
createDbSession,
deleteSession,
} from '../../server/utils/queries.js'
describe('queries', () => {
let db
beforeEach(async () => {
setDbPathForTest(':memory:')
db = await getDb()
})
afterEach(() => {
setDbPathForTest(null)
})
describe('device queries', () => {
it('getDeviceById returns null for non-existent device', async () => {
const device = await getDeviceById(db, 'non-existent')
expect(device).toBeNull()
})
it('createDevice and getDeviceById work together', async () => {
const deviceData = {
name: 'Test Device',
device_type: 'traffic',
vendor: 'Test Vendor',
lat: 40.7128,
lng: -74.0060,
stream_url: 'https://example.com/stream',
source_type: 'mjpeg',
config: null,
}
const created = await createDevice(db, deviceData)
expect(created).toBeDefined()
expect(created.name).toBe('Test Device')
const retrieved = await getDeviceById(db, created.id)
expect(retrieved).toBeDefined()
expect(retrieved.name).toBe('Test Device')
})
it('createDevice handles vendor null', async () => {
const deviceData = {
name: 'Test',
device_type: 'feed',
vendor: null,
lat: 40.7128,
lng: -74.0060,
stream_url: '',
source_type: 'mjpeg',
config: null,
}
const created = await createDevice(db, deviceData)
expect(created.vendor).toBeNull()
})
it('createDevice handles all optional fields', async () => {
const deviceData = {
name: 'Full Device',
device_type: 'traffic',
vendor: 'Vendor Name',
lat: 40.7128,
lng: -74.0060,
stream_url: 'https://example.com/stream',
source_type: 'hls',
config: '{"key":"value"}',
}
const created = await createDevice(db, deviceData)
expect(created.name).toBe('Full Device')
expect(created.vendor).toBe('Vendor Name')
expect(created.stream_url).toBe('https://example.com/stream')
expect(created.source_type).toBe('hls')
expect(created.config).toBe('{"key":"value"}')
})
it('getAllDevices returns all devices', async () => {
await createDevice(db, {
name: 'Device 1',
device_type: 'feed',
lat: 40.7128,
lng: -74.0060,
stream_url: '',
source_type: 'mjpeg',
config: null,
})
await createDevice(db, {
name: 'Device 2',
device_type: 'traffic',
lat: 41.7128,
lng: -75.0060,
stream_url: '',
source_type: 'hls',
config: null,
})
const devices = await getAllDevices(db)
expect(devices).toHaveLength(2)
})
it('updateDevice updates device fields', async () => {
const created = await createDevice(db, {
name: 'Original',
device_type: 'feed',
lat: 40.7128,
lng: -74.0060,
stream_url: '',
source_type: 'mjpeg',
config: null,
})
const updated = await updateDevice(db, created.id, {
name: 'Updated',
lat: 41.7128,
})
expect(updated.name).toBe('Updated')
expect(updated.lat).toBe(41.7128)
})
it('updateDevice returns existing device when no updates', async () => {
const created = await createDevice(db, {
name: 'Test',
device_type: 'feed',
lat: 40.7128,
lng: -74.0060,
stream_url: '',
source_type: 'mjpeg',
config: null,
})
const result = await updateDevice(db, created.id, {})
expect(result.id).toBe(created.id)
})
})
describe('user queries', () => {
it('getUserById returns null for non-existent user', async () => {
const user = await getUserById(db, 'non-existent')
expect(user).toBeNull()
})
it('createUser and getUserById work together', async () => {
const userData = {
identifier: 'testuser',
password_hash: 'hash123',
role: 'admin',
created_at: new Date().toISOString(),
auth_provider: 'local',
}
const created = await createUser(db, userData)
expect(created).toBeDefined()
expect(created.identifier).toBe('testuser')
const retrieved = await getUserById(db, created.id)
expect(retrieved).toBeDefined()
expect(retrieved.identifier).toBe('testuser')
})
it('createUser defaults auth_provider to local', async () => {
const userData = {
identifier: 'testuser2',
password_hash: 'hash',
role: 'member',
created_at: new Date().toISOString(),
}
const created = await createUser(db, userData)
expect(created.auth_provider).toBe('local')
})
it('createUser handles oidc fields', async () => {
const userData = {
identifier: 'oidcuser',
password_hash: null,
role: 'member',
created_at: new Date().toISOString(),
auth_provider: 'oidc',
oidc_issuer: 'https://example.com',
oidc_sub: 'sub123',
}
const created = await createUser(db, userData)
expect(created.auth_provider).toBe('oidc')
})
it('getUserByIdentifier finds user by identifier', async () => {
await createUser(db, {
identifier: 'findme',
password_hash: 'hash',
role: 'member',
created_at: new Date().toISOString(),
auth_provider: 'local',
})
const user = await getUserByIdentifier(db, 'findme')
expect(user).toBeDefined()
expect(user.identifier).toBe('findme')
})
it('updateUser updates user fields', async () => {
const created = await createUser(db, {
identifier: 'original',
password_hash: 'hash',
role: 'member',
created_at: new Date().toISOString(),
auth_provider: 'local',
})
const updated = await updateUser(db, created.id, {
role: 'admin',
})
expect(updated.role).toBe('admin')
})
it('updateUser returns existing user when no updates', async () => {
const created = await createUser(db, {
identifier: 'test',
password_hash: 'hash',
role: 'member',
created_at: new Date().toISOString(),
auth_provider: 'local',
})
const result = await updateUser(db, created.id, {})
expect(result.id).toBe(created.id)
})
})
describe('POI queries', () => {
it('getPoiById returns null for non-existent POI', async () => {
const poi = await getPoiById(db, 'non-existent')
expect(poi).toBeNull()
})
it('createPoi and getPoiById work together', async () => {
const poiData = {
lat: 40.7128,
lng: -74.0060,
label: 'Test POI',
icon_type: 'flag',
}
const created = await createPoi(db, poiData)
expect(created).toBeDefined()
expect(created.label).toBe('Test POI')
const retrieved = await getPoiById(db, created.id)
expect(retrieved).toBeDefined()
expect(retrieved.label).toBe('Test POI')
})
it('createPoi defaults label and icon_type', async () => {
const poiData = {
lat: 40.7128,
lng: -74.0060,
}
const created = await createPoi(db, poiData)
expect(created.label).toBe('')
expect(created.icon_type).toBe('pin')
})
it('getAllPois returns all POIs', async () => {
await createPoi(db, { lat: 40.7128, lng: -74.0060, label: 'POI 1' })
await createPoi(db, { lat: 41.7128, lng: -75.0060, label: 'POI 2' })
const pois = await getAllPois(db)
expect(pois).toHaveLength(2)
})
it('updatePoi updates POI fields', async () => {
const created = await createPoi(db, {
lat: 40.7128,
lng: -74.0060,
label: 'Original',
})
const updated = await updatePoi(db, created.id, {
label: 'Updated',
lat: 41.7128,
})
expect(updated.label).toBe('Updated')
expect(updated.lat).toBe(41.7128)
})
it('updatePoi returns existing POI when no updates', async () => {
const created = await createPoi(db, {
lat: 40.7128,
lng: -74.0060,
label: 'Test',
})
const result = await updatePoi(db, created.id, {})
expect(result.id).toBe(created.id)
})
})
describe('session queries', () => {
it('getSessionById returns null for non-existent session', async () => {
const session = await getSessionById(db, 'non-existent')
expect(session).toBeNull()
})
it('createDbSession and getSessionById work together', async () => {
const sessionData = {
id: 'session-1',
user_id: 'user-1',
created_at: new Date().toISOString(),
expires_at: new Date(Date.now() + 86400000).toISOString(),
}
await createDbSession(db, sessionData)
const retrieved = await getSessionById(db, 'session-1')
expect(retrieved).toBeDefined()
expect(retrieved.user_id).toBe('user-1')
})
it('deleteSession removes session', async () => {
await createDbSession(db, {
id: 'session-1',
user_id: 'user-1',
created_at: new Date().toISOString(),
expires_at: new Date(Date.now() + 86400000).toISOString(),
})
await deleteSession(db, 'session-1')
const retrieved = await getSessionById(db, 'session-1')
expect(retrieved).toBeNull()
})
})
})