make kestrel a tak server, so that it can send and receive pois as cots data
Some checks failed
ci/woodpecker/pr/pr Pipeline failed
Some checks failed
ci/woodpecker/pr/pr Pipeline failed
This commit is contained in:
347
test/unit/queries.spec.js
Normal file
347
test/unit/queries.spec.js
Normal file
@@ -0,0 +1,347 @@
|
||||
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()
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user