import { assert } from "chai"; import { describe, it, beforeEach, afterEach } from "node:test"; import * as m from "../index"; import * as config from "./config"; import mockModule from "./mock"; describe("AudioStream", function() { let models: m.BackendModels, mongoose: m.MongooseModule; let authRecord: m.AudioStreamAuthentication; beforeEach(async function() { const c = await m.connect(config.url); models = c.models; mongoose = c.mongoose; const mock = mockModule({ mongoose }); await mock.beforeEach(); // TODO: Move to mock (?) // Create an AudioStreamAuthentication record to reference const authItem = new models.AudioStreamAuthentication({ name: "test-auth-record", secret: { iv: "test-iv", encryptedData: "test-encrypted-data" }, rotateInterval: 3600, }); authRecord = await authItem.save(); }); afterEach(async function() { await mongoose.disconnect(); }); it("saves Department with AudioStream authentication", async function() { const department = new models.Department({ department: "Test Fire Department", apikey: "test-api-key-123", audioConfiguration: [ { group: "Fire Dispatch", order: 1, streams: [ { description: "Main Dispatch Channel", channel: "CH1", url: "https://example.com/stream1", order: 1, authentication: { authId: authRecord._id, path: "test/stream/path/", } } ] } ] }); const saved = await department.save(); assert.isNotNull(saved._id); assert.isArray(saved.audioConfiguration); assert.equal(saved.audioConfiguration.length, 1); const group = saved.audioConfiguration[0]; if (!group) { assert.fail("Group should be defined"); return; } assert.equal(group.group, "Fire Dispatch"); assert.equal(group.order, 1); assert.equal(group.streams.length, 1); const stream = group.streams[0]; if (!stream) { assert.fail("Stream should be defined"); return; } assert.equal(stream.description, "Main Dispatch Channel"); assert.equal(stream.channel, "CH1"); assert.equal(stream.url, "https://example.com/stream1"); assert.equal(stream.order, 1); // Verify authentication assert.isObject(stream.authentication); if (!stream.authentication) { assert.fail("Authentication should be defined"); return; } assert.equal(stream.authentication.authId.toString(), authRecord._id.toString()); assert.equal(stream.authentication.path, "test/stream/path/"); }); it("saves Department with AudioStream without authentication", async function() { const department = new models.Department({ department: "Test Fire Department 2", apikey: "test-api-key-456", audioConfiguration: [ { group: "Police Dispatch", order: 1, streams: [ { description: "Public Channel", channel: "CH2", url: "https://example.com/stream2", order: 1, } ] } ] }); const saved = await department.save(); assert.isNotNull(saved._id); assert.isArray(saved.audioConfiguration); assert.equal(saved.audioConfiguration.length, 1); const group = saved.audioConfiguration[0]; if (!group) { assert.fail("Group should be defined"); return; } const stream = group.streams[0]; if (!stream) { assert.fail("Stream should be defined"); return; } assert.equal(stream.description, "Public Channel"); assert.isUndefined(stream.authentication); }); it("saves Department with mixed AudioStreams (with and without auth)", async function() { const department = new models.Department({ department: "Test Mixed Department", apikey: "test-api-key-789", audioConfiguration: [ { group: "Dispatch Channels", order: 1, streams: [ { description: "Secure Channel", channel: "CH1", url: "https://example.com/secure", order: 1, authentication: { authId: authRecord._id, path: "secure/stream/path/", } }, { description: "Public Channel", channel: "CH2", url: "https://example.com/public", order: 2, } ] } ] }); const saved = await department.save(); const group = saved.audioConfiguration[0]; if (!group) { assert.fail("Group should be defined"); return; } assert.equal(group.streams.length, 2); const secureStream = group.streams[0]; if (!secureStream) { assert.fail("Secure stream should be defined"); return; } assert.isObject(secureStream.authentication); if (!secureStream.authentication) { assert.fail("Authentication should be defined"); return; } assert.equal(secureStream.authentication.path, "secure/stream/path/"); const publicStream = group.streams[1]; if (!publicStream) { assert.fail("Public stream should be defined"); return; } assert.isUndefined(publicStream.authentication); }); it("validates required authentication fields when present", async function() { const department = new models.Department({ department: "Test Invalid Department", apikey: "test-api-key-invalid", audioConfiguration: [ { group: "Test Group", order: 1, streams: [ { description: "Invalid Stream", channel: "CH1", url: "https://example.com/invalid", order: 1, authentication: { authId: authRecord._id, // Missing path - should fail validation } as unknown as { authId: m.AudioStreamAuthentication["_id"]; path: string; } } ] } ] }); try { await department.save(); assert.fail("Should have thrown validation error"); } catch (error) { assert.include(String((error as Error).message), "path"); } }); });