cat / goq
clone

turns a linux box into a private steam streaming appliance: plug in, tap your key, play from another computer

fix/website-download-wiring
goq / decky / tests / model.test.mjs
model.test.mjs 4.1K
1import assert from "node:assert/strict";2import test from "node:test";34import {5 buildConfigRequest,6 formatUptime,7 isValidHostFingerprint,8 normalizeConfig,9 normalizeSnapshot,10 transactionId,11 unwrapRpc,12} from "../src/model.mjs";1314const revision = `sha256:${"a".repeat(64)}`;1516test("unwrapRpc accepts only a successful envelope", () => {17 assert.deepEqual(unwrapRpc({ ok: true, value: { ready: true } }), { ready: true });18 assert.throws(() => unwrapRpc({ ok: false, error: "service timeout" }), /service timeout/);19 assert.throws(() => unwrapRpc({ ok: true }), /request failed/);20});2122test("normalizes the backend snapshot without exposing endpoint identity", () => {23 const snapshot = normalizeSnapshot({24 schema_version: 1,25 installed: true,26 compatible: true,27 service: { installed: true, active: true, active_state: "active", sub_state: "running" },28 capabilities: { stream_diagnostics: false, factory_reset: false },29 appliance: {30 sigil_version: "0.4.0",31 overall: "active",32 identity: { host_fingerprint: "12345678…90abcdef" },33 enrollment: {34 peer_fingerprint: "abcdef12…34567890",35 grants: ["view", "pointer_keyboard", "gamepad"],36 epoch: 7,37 },38 config: { pending_transaction: { transaction: "tx-1" } },39 runtime: { uptime_ms: 3_720_000, session: "active", last_error: null },40 },41 });4243 assert.equal(snapshot.summary, "Streaming");44 assert.equal(snapshot.serviceLabel, "active (running)");45 assert.equal(snapshot.uptime, "1h 2m");46 assert.equal(snapshot.peerFingerprint, "abcdef12…34567890");47 assert.deepEqual(snapshot.grants, ["View", "Pointer + keyboard", "Gamepad"]);48 assert.equal(snapshot.streamDiagnosticsAvailable, false);49 assert.equal(snapshot.factoryResetAvailable, false);50 assert.equal(transactionId(snapshot.pendingTransaction), "tx-1");51});5253test("normalizes native CBR configuration and builds its strict request", () => {54 const config = normalizeConfig({55 schema_version: 1,56 revision,57 settings: {58 resolution: { mode: "native" },59 framerate: 60,60 rate_control: { mode: "cbr", bitrate_kbps: 12000 },61 },62 pending_transaction: null,63 });6465 assert.equal(config.draft.resolutionMode, "native");66 assert.equal(config.draft.rateMode, "cbr");67 assert.deepEqual(buildConfigRequest(config.revision, config.draft), {68 schema_version: 1,69 expected_revision: revision,70 settings: {71 resolution: { mode: "native" },72 framerate: 60,73 rate_control: { mode: "cbr", bitrate_kbps: 12000 },74 },75 });76});7778test("builds fixed CQP configuration without pinning a product resolution", () => {79 const request = buildConfigRequest(revision, {80 resolutionMode: "fixed",81 width: "2560",82 height: "1600",83 framerate: "144",84 rateMode: "cqp",85 bitrateKbps: "12000",86 quantizer: "24",87 });88 assert.deepEqual(request.settings.resolution, { mode: "fixed", width: 2560, height: 1600 });89 assert.deepEqual(request.settings.rate_control, { mode: "cqp", quantizer: 24 });90});9192test("rejects unsafe or invalid local edits before backend validation", () => {93 const base = {94 resolutionMode: "fixed",95 width: "1281",96 height: "800",97 framerate: "60",98 rateMode: "cbr",99 bitrateKbps: "12000",100 quantizer: "24",101 };102 assert.throws(() => buildConfigRequest(revision, base), /Width must be even/);103 assert.throws(() => buildConfigRequest("not-a-revision", { ...base, width: "1280" }), /Reload/);104 assert.throws(105 () => buildConfigRequest(revision, { ...base, width: "1280", framerate: "241" }),106 /Frame rate must be between 1 and 240/,107 );108});109110test("formats short and absent uptime safely", () => {111 assert.equal(formatUptime(59_999), "0m");112 assert.equal(formatUptime(undefined), "Unavailable");113});114115test("accepts only the redacted lowercase host fingerprint interlock", () => {116 assert.equal(isValidHostFingerprint("12345678…90abcdef"), true);117 assert.equal(isValidHostFingerprint("12345678...90abcdef"), false);118 assert.equal(isValidHostFingerprint("12345678…90abcdeF"), false);119 assert.equal(isValidHostFingerprint("Unavailable"), false);120 assert.equal(isValidHostFingerprint(undefined), false);121});