Co-authored-by: Madison Grubb <madison@elastiflow.com> Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -1,119 +0,0 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { isValidFeed, getValidFeeds, sanitizeStreamUrl, sanitizeFeedForResponse } from '../../server/utils/feedUtils.js'
|
||||
|
||||
describe('feedUtils', () => {
|
||||
describe('isValidFeed', () => {
|
||||
it('returns true for valid feed', () => {
|
||||
expect(isValidFeed({
|
||||
id: '1',
|
||||
name: 'Cam',
|
||||
lat: 37.7,
|
||||
lng: -122.4,
|
||||
})).toBe(true)
|
||||
})
|
||||
|
||||
it('returns false for null', () => {
|
||||
expect(isValidFeed(null)).toBe(false)
|
||||
})
|
||||
|
||||
it('returns false for missing id', () => {
|
||||
expect(isValidFeed({ name: 'x', lat: 0, lng: 0 })).toBe(false)
|
||||
})
|
||||
|
||||
it('returns false for wrong lat type', () => {
|
||||
expect(isValidFeed({ id: '1', name: 'x', lat: '37', lng: -122 })).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getValidFeeds', () => {
|
||||
it('returns only valid feeds', () => {
|
||||
const list = [
|
||||
{ id: 'a', name: 'A', lat: 1, lng: 2 },
|
||||
null,
|
||||
{ id: 'b', name: 'B', lat: 3, lng: 4 },
|
||||
]
|
||||
expect(getValidFeeds(list)).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('returns empty array for non-array', () => {
|
||||
expect(getValidFeeds(null)).toEqual([])
|
||||
expect(getValidFeeds({})).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
describe('sanitizeStreamUrl', () => {
|
||||
it('allows http and https', () => {
|
||||
expect(sanitizeStreamUrl('https://example.com/stream')).toBe('https://example.com/stream')
|
||||
expect(sanitizeStreamUrl('http://example.com/stream')).toBe('http://example.com/stream')
|
||||
})
|
||||
|
||||
it('returns empty for javascript:, data:, and other schemes', () => {
|
||||
expect(sanitizeStreamUrl('javascript:alert(1)')).toBe('')
|
||||
expect(sanitizeStreamUrl('data:text/html,<script>')).toBe('')
|
||||
expect(sanitizeStreamUrl('file:///etc/passwd')).toBe('')
|
||||
})
|
||||
|
||||
it('returns empty for non-strings or empty', () => {
|
||||
expect(sanitizeStreamUrl('')).toBe('')
|
||||
expect(sanitizeStreamUrl(' ')).toBe('')
|
||||
expect(sanitizeStreamUrl(null)).toBe('')
|
||||
expect(sanitizeStreamUrl(123)).toBe('')
|
||||
})
|
||||
})
|
||||
|
||||
describe('sanitizeFeedForResponse', () => {
|
||||
it('returns safe shape with sanitized streamUrl and sourceType', () => {
|
||||
const feed = {
|
||||
id: 'f1',
|
||||
name: 'Cam',
|
||||
lat: 37,
|
||||
lng: -122,
|
||||
streamUrl: 'https://safe.com/s',
|
||||
sourceType: 'mjpeg',
|
||||
}
|
||||
const out = sanitizeFeedForResponse(feed)
|
||||
expect(out).toEqual({
|
||||
id: 'f1',
|
||||
name: 'Cam',
|
||||
lat: 37,
|
||||
lng: -122,
|
||||
streamUrl: 'https://safe.com/s',
|
||||
sourceType: 'mjpeg',
|
||||
})
|
||||
})
|
||||
|
||||
it('strips dangerous streamUrl and normalizes sourceType', () => {
|
||||
const feed = {
|
||||
id: 'f2',
|
||||
name: 'Bad',
|
||||
lat: 0,
|
||||
lng: 0,
|
||||
streamUrl: 'javascript:alert(1)',
|
||||
sourceType: 'hls',
|
||||
}
|
||||
const out = sanitizeFeedForResponse(feed)
|
||||
expect(out.streamUrl).toBe('')
|
||||
expect(out.sourceType).toBe('hls')
|
||||
})
|
||||
|
||||
it('includes description only when string', () => {
|
||||
const withDesc = sanitizeFeedForResponse({
|
||||
id: 'a',
|
||||
name: 'n',
|
||||
lat: 0,
|
||||
lng: 0,
|
||||
description: 'A camera',
|
||||
})
|
||||
expect(withDesc.description).toBe('A camera')
|
||||
|
||||
const noDesc = sanitizeFeedForResponse({
|
||||
id: 'b',
|
||||
name: 'n',
|
||||
lat: 0,
|
||||
lng: 0,
|
||||
description: 123,
|
||||
})
|
||||
expect(noDesc).not.toHaveProperty('description')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -25,7 +25,7 @@ describe('Mediasoup', () => {
|
||||
|
||||
it('should create a transport', async () => {
|
||||
const router = await getRouter(sessionId)
|
||||
const { transport, params } = await createTransport(router, true)
|
||||
const { transport, params } = await createTransport(router)
|
||||
expect(transport).toBeDefined()
|
||||
expect(params.id).toBe(transport.id)
|
||||
expect(params.iceParameters).toBeDefined()
|
||||
@@ -35,7 +35,7 @@ describe('Mediasoup', () => {
|
||||
|
||||
it('should create a transport with requestHost IPv4 and return valid params', async () => {
|
||||
const router = await getRouter(sessionId)
|
||||
const { transport, params } = await createTransport(router, true, '192.168.2.100')
|
||||
const { transport, params } = await createTransport(router, '192.168.2.100')
|
||||
expect(transport).toBeDefined()
|
||||
expect(params.id).toBe(transport.id)
|
||||
expect(params.iceParameters).toBeDefined()
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
||||
import { getDb, setDbPathForTest } from '../../server/utils/db.js'
|
||||
import { migrateFeedsToDevices } from '../../server/utils/migrateFeedsToDevices.js'
|
||||
|
||||
describe('migrateFeedsToDevices', () => {
|
||||
beforeEach(() => {
|
||||
setDbPathForTest(':memory:')
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
setDbPathForTest(null)
|
||||
})
|
||||
|
||||
it('runs without error when devices table is empty', async () => {
|
||||
const db = await getDb()
|
||||
await expect(migrateFeedsToDevices()).resolves.toBeUndefined()
|
||||
const rows = await db.all('SELECT id FROM devices')
|
||||
expect(rows.length).toBeGreaterThanOrEqual(0)
|
||||
})
|
||||
|
||||
it('is no-op when devices already has rows', async () => {
|
||||
const db = await getDb()
|
||||
await db.run(
|
||||
'INSERT INTO devices (id, name, device_type, vendor, lat, lng, stream_url, source_type, config) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
['existing', 'Existing', 'feed', null, 0, 0, '', 'mjpeg', null],
|
||||
)
|
||||
await migrateFeedsToDevices()
|
||||
const rows = await db.all('SELECT id FROM devices')
|
||||
expect(rows).toHaveLength(1)
|
||||
expect(rows[0].id).toBe('existing')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user