348 lines
9.6 KiB
JavaScript
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()
|
|
})
|
|
})
|
|
})
|