release: prepare v0.9.7

This commit is contained in:
BigBodyCobain
2026-05-01 22:56:50 -06:00
parent ea457f27da
commit 28b3bd5ebf
670 changed files with 187059 additions and 14005 deletions
@@ -0,0 +1,49 @@
/**
* Tests for getBackendEndpoint() — the runtime-resolved API endpoint
* displayed in "Connect" modals for external tool configuration.
*
* Verifies:
* - Returns window.location.origin when window is available
* - Returns fallback when window is undefined (SSR)
* - Does NOT hardcode :8000
*/
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
describe('getBackendEndpoint', () => {
const originalWindow = globalThis.window;
afterEach(() => {
vi.resetModules();
// Restore window if we deleted it
if (!globalThis.window && originalWindow) {
globalThis.window = originalWindow;
}
});
it('returns window.location.origin in browser context', async () => {
// Default test environment (jsdom) has window defined
const { getBackendEndpoint } = await import('@/lib/backendEndpoint');
const result = getBackendEndpoint();
expect(result).toBe(window.location.origin);
expect(result).not.toContain(':8000');
});
it('does not hardcode port 8000', async () => {
const { getBackendEndpoint } = await import('@/lib/backendEndpoint');
const result = getBackendEndpoint();
// The result should be derived from window.location, not a hardcoded backend port
expect(result).not.toMatch(/:8000$/);
});
it('returns http://localhost:8000 fallback when window is undefined (SSR)', async () => {
// Temporarily remove window to simulate SSR
// @ts-expect-error — intentionally removing window for SSR simulation
delete globalThis.window;
const { getBackendEndpoint } = await import('@/lib/backendEndpoint');
const result = getBackendEndpoint();
expect(result).toBe('http://localhost:8000');
// Restore
globalThis.window = originalWindow;
});
});
@@ -0,0 +1,75 @@
/**
* Tests for companion section failure visibility in SettingsPanel.
*
* Verifies the contract from P6E:
* - When fetchCompanionStatus rejects, the companion section still renders
* (with an unavailable/error state) rather than silently disappearing
* - When fetchCompanionStatus succeeds, normal controls are shown
*
* These are logic-level tests for the state transitions — they do NOT
* render SettingsPanel (which has deep dependency chains). They verify
* the decision logic: companionLoadFailed drives visibility.
*/
import { describe, expect, it } from 'vitest';
describe('companion section visibility contract', () => {
it('companionAvailable && companionLoadFailed shows the section (failure path)', () => {
// Simulates the render guard: {companionAvailable && (companion || companionLoadFailed) && (...)}
const companionAvailable = true;
const companion = null; // fetch failed, no status loaded
const companionLoadFailed = true;
const shouldRender = companionAvailable && (companion || companionLoadFailed);
expect(shouldRender).toBeTruthy();
});
it('companionAvailable && companion shows the section (success path)', () => {
const companionAvailable = true;
const companion = { enabled: false, url: null, warning: 'Reduced trust.' };
const companionLoadFailed = false;
const shouldRender = companionAvailable && (companion || companionLoadFailed);
expect(shouldRender).toBeTruthy();
});
it('section is hidden when not on desktop (companionAvailable=false)', () => {
const companionAvailable = false;
const companion = null;
const companionLoadFailed = true;
const shouldRender = companionAvailable && (companion || companionLoadFailed);
expect(shouldRender).toBeFalsy();
});
it('section is hidden before first load attempt (no status, no failure)', () => {
const companionAvailable = true;
const companion = null;
const companionLoadFailed = false;
const shouldRender = companionAvailable && (companion || companionLoadFailed);
expect(shouldRender).toBeFalsy();
});
it('controls are hidden when companion is null (failure mode shows only error)', () => {
// In the rendered UI: {companion && (<buttons>)} — buttons hidden when companion is null
const companion = null;
const companionLoadFailed = true;
const showControls = !!companion;
expect(showControls).toBe(false);
// But the section itself should still render
expect(companionLoadFailed).toBe(true);
});
it('warning box only renders when companion has a warning string', () => {
// {companion?.warning && (<warning>)}
const companionNull = null;
const companionWithWarning = { enabled: true, url: 'http://127.0.0.1:9876', warning: 'Reduced trust.' };
const companionNoWarning = { enabled: false, url: null, warning: '' };
expect(companionNull?.warning).toBeFalsy();
expect(companionWithWarning?.warning).toBeTruthy();
expect(companionNoWarning?.warning).toBeFalsy();
});
});
@@ -0,0 +1,387 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { ShadowbrokerDesktopRuntime } from '@/lib/desktopBridge';
describe('desktopBridgeBootstrapPreference', () => {
beforeEach(() => {
vi.resetModules();
// Clean window globals before each test
delete (window as Record<string, unknown>).__SHADOWBROKER_DESKTOP__;
delete (window as Record<string, unknown>).__SHADOWBROKER_LOCAL_CONTROL__;
});
it('prefers a pre-installed native runtime over the HTTP shim', async () => {
const nativeInvoke = vi.fn().mockResolvedValue({ ok: true });
const nativeRuntime: ShadowbrokerDesktopRuntime = {
invokeLocalControl: nativeInvoke,
getNativeControlAuditReport: () => ({
totalEvents: 0,
totalRecorded: 0,
recent: [],
byOutcome: {},
}),
clearNativeControlAuditReport: vi.fn(),
};
// Simulate Tauri injection: set __SHADOWBROKER_DESKTOP__ before bootstrap
window.__SHADOWBROKER_DESKTOP__ = nativeRuntime;
const { bootstrapDesktopControlBridge } = await import('@/lib/desktopBridge');
const installed = bootstrapDesktopControlBridge();
expect(installed).toBe(true);
// The bridge should have been derived from the native runtime
expect(window.__SHADOWBROKER_LOCAL_CONTROL__).toBeDefined();
expect(window.__SHADOWBROKER_LOCAL_CONTROL__!.invoke).toBeDefined();
// Invoke through the bridge — should delegate to the native runtime
await window.__SHADOWBROKER_LOCAL_CONTROL__!.invoke!({
command: 'wormhole.status',
payload: undefined,
});
expect(nativeInvoke).toHaveBeenCalledTimes(1);
expect(nativeInvoke.mock.calls[0][0]).toBe('wormhole.status');
});
it('does not install bridge when no native runtime and shim env is off', async () => {
// No __SHADOWBROKER_DESKTOP__ and NEXT_PUBLIC_ENABLE_DESKTOP_BRIDGE_SHIM != '1'
const originalEnv = process.env.NEXT_PUBLIC_ENABLE_DESKTOP_BRIDGE_SHIM;
process.env.NEXT_PUBLIC_ENABLE_DESKTOP_BRIDGE_SHIM = '0';
const { bootstrapDesktopControlBridge } = await import('@/lib/desktopBridge');
const installed = bootstrapDesktopControlBridge();
expect(installed).toBe(false);
expect(window.__SHADOWBROKER_LOCAL_CONTROL__).toBeUndefined();
process.env.NEXT_PUBLIC_ENABLE_DESKTOP_BRIDGE_SHIM = originalEnv;
});
it('falls back to HTTP shim when no native runtime and shim env is on', async () => {
const originalEnv = process.env.NEXT_PUBLIC_ENABLE_DESKTOP_BRIDGE_SHIM;
process.env.NEXT_PUBLIC_ENABLE_DESKTOP_BRIDGE_SHIM = '1';
const { bootstrapDesktopControlBridge } = await import('@/lib/desktopBridge');
const installed = bootstrapDesktopControlBridge();
expect(installed).toBe(true);
// Bridge installed via shim
expect(window.__SHADOWBROKER_LOCAL_CONTROL__).toBeDefined();
// __SHADOWBROKER_DESKTOP__ is the HTTP-backed shim
expect(window.__SHADOWBROKER_DESKTOP__).toBeDefined();
expect(window.__SHADOWBROKER_DESKTOP__!.invokeLocalControl).toBeDefined();
expect(window.__SHADOWBROKER_DESKTOP__!.getNativeControlAuditReport).toBeDefined();
expect(window.__SHADOWBROKER_DESKTOP__!.clearNativeControlAuditReport).toBeDefined();
process.env.NEXT_PUBLIC_ENABLE_DESKTOP_BRIDGE_SHIM = originalEnv;
});
it('native runtime audit report is accessible through getDesktopNativeControlAuditReport', async () => {
const auditReport = {
totalEvents: 5,
totalRecorded: 5,
recent: [],
byOutcome: { allowed: 5 },
};
const nativeRuntime: ShadowbrokerDesktopRuntime = {
invokeLocalControl: vi.fn().mockResolvedValue({}),
getNativeControlAuditReport: () => auditReport,
clearNativeControlAuditReport: vi.fn(),
};
window.__SHADOWBROKER_DESKTOP__ = nativeRuntime;
const { bootstrapDesktopControlBridge, getDesktopNativeControlAuditReport } =
await import('@/lib/desktopBridge');
bootstrapDesktopControlBridge();
const report = getDesktopNativeControlAuditReport();
expect(report).toEqual(auditReport);
});
it('localControlFetch routes through native bridge when available', async () => {
const nativeInvoke = vi
.fn()
.mockResolvedValue({ ok: true, status: 'connected' });
const nativeRuntime: ShadowbrokerDesktopRuntime = {
invokeLocalControl: nativeInvoke,
};
window.__SHADOWBROKER_DESKTOP__ = nativeRuntime;
const { installDesktopControlBridge } = await import('@/lib/desktopBridge');
installDesktopControlBridge(nativeRuntime);
const { localControlFetch } = await import('@/lib/localControlTransport');
const response = await localControlFetch('/api/wormhole/status');
const data = await response.json();
expect(nativeInvoke).toHaveBeenCalledTimes(1);
expect(nativeInvoke.mock.calls[0][0]).toBe('wormhole.status');
expect(data).toEqual({ ok: true, status: 'connected' });
});
it('localControlFetch falls back to fetch when no bridge is present', async () => {
// No bridge installed — localControlFetch should use regular fetch
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockResolvedValue(
new Response(JSON.stringify({ ok: true }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
}),
);
const { localControlFetch } = await import('@/lib/localControlTransport');
await localControlFetch('/api/wormhole/status');
expect(fetchSpy).toHaveBeenCalledTimes(1);
const callUrl = fetchSpy.mock.calls[0][0] as string;
expect(callUrl).toContain('/api/wormhole/status');
fetchSpy.mockRestore();
});
it('Rust handler coverage matches the full contract command set', async () => {
const { DESKTOP_CONTROL_COMMANDS } = await import(
'@/lib/desktopControlContract'
);
// This test documents the expected contract size.
// If the contract grows, the Rust handlers.rs must be updated to match.
expect(DESKTOP_CONTROL_COMMANDS.length).toBe(27);
// Verify every command has a corresponding HTTP route
const { commandToHttpRequest } = await import(
'@/lib/desktopControlRouting'
);
for (const command of DESKTOP_CONTROL_COMMANDS) {
// Gate commands need a payload with gate_id
const payload = command.includes('gate')
? { gate_id: 'test-gate', plaintext: 'x', reason: 'test', label: 'l', persona_id: 'p', epoch: 0, ciphertext: '', nonce: '', sender_ref: '', messages: [] }
: undefined;
expect(() => commandToHttpRequest(command, payload)).not.toThrow();
}
});
it('native runtime forwards meta to invokeLocalControl', async () => {
const nativeInvoke = vi.fn().mockResolvedValue({ ok: true });
const nativeRuntime: ShadowbrokerDesktopRuntime = {
invokeLocalControl: nativeInvoke,
};
window.__SHADOWBROKER_DESKTOP__ = nativeRuntime;
const { installDesktopControlBridge } = await import('@/lib/desktopBridge');
installDesktopControlBridge(nativeRuntime);
await window.__SHADOWBROKER_LOCAL_CONTROL__!.invoke!({
command: 'wormhole.gate.key.rotate',
payload: { gate_id: 'infonet', reason: 'operator_reset' },
meta: {
capability: 'wormhole_gate_key',
sessionProfileHint: 'gate_operator',
enforceProfileHint: true,
},
});
expect(nativeInvoke).toHaveBeenCalledTimes(1);
expect(nativeInvoke.mock.calls[0][0]).toBe('wormhole.gate.key.rotate');
expect(nativeInvoke.mock.calls[0][1]).toEqual({ gate_id: 'infonet', reason: 'operator_reset' });
// meta must not be dropped
const receivedMeta = nativeInvoke.mock.calls[0][2];
expect(receivedMeta).toBeDefined();
expect(receivedMeta).toEqual(expect.objectContaining({
capability: 'wormhole_gate_key',
sessionProfileHint: 'gate_operator',
enforceProfileHint: true,
}));
});
it('native runtime rejects on capability mismatch and records audit', async () => {
const { controlCommandCapability } = await import('@/lib/desktopControlContract');
const nativeInvoke = vi.fn().mockResolvedValue({ ok: true });
const auditEntries: unknown[] = [];
// Simulate a Tauri-like runtime that checks capability mismatch
const nativeRuntime: ShadowbrokerDesktopRuntime = {
invokeLocalControl: async (command, payload, meta) => {
const expectedCap = controlCommandCapability(command!);
if (meta?.capability && meta.capability !== expectedCap) {
auditEntries.push({
command,
expectedCapability: expectedCap,
declaredCapability: meta.capability,
outcome: 'capability_mismatch',
});
throw new Error(
`native_control_capability_mismatch:${meta.capability}:${expectedCap}`,
);
}
return nativeInvoke(command, payload, meta);
},
getNativeControlAuditReport: () => ({
totalEvents: auditEntries.length,
totalRecorded: auditEntries.length,
recent: [],
byOutcome: { capability_mismatch: auditEntries.length },
}),
clearNativeControlAuditReport: vi.fn(),
};
window.__SHADOWBROKER_DESKTOP__ = nativeRuntime;
const { installDesktopControlBridge } = await import('@/lib/desktopBridge');
installDesktopControlBridge(nativeRuntime);
// Declare wrong capability: 'settings' for a wormhole_gate_key command
await expect(
window.__SHADOWBROKER_LOCAL_CONTROL__!.invoke!({
command: 'wormhole.gate.key.rotate',
payload: { gate_id: 'infonet', reason: 'test' },
meta: { capability: 'settings' },
}),
).rejects.toThrow('native_control_capability_mismatch');
expect(nativeInvoke).not.toHaveBeenCalled();
expect(auditEntries).toHaveLength(1);
expect(auditEntries[0]).toEqual(
expect.objectContaining({
command: 'wormhole.gate.key.rotate',
declaredCapability: 'settings',
expectedCapability: 'wormhole_gate_key',
outcome: 'capability_mismatch',
}),
);
});
it('native runtime denies on profile enforcement and records audit', async () => {
const { controlCommandCapability, sessionProfileCapabilities } = await import(
'@/lib/desktopControlContract'
);
const nativeInvoke = vi.fn().mockResolvedValue({ ok: true });
const auditEntries: unknown[] = [];
// Simulate a Tauri-like runtime that enforces session profiles
const nativeRuntime: ShadowbrokerDesktopRuntime = {
invokeLocalControl: async (command, payload, meta) => {
const expectedCap = controlCommandCapability(command!);
const profile = meta?.sessionProfileHint;
const profileCaps = profile ? sessionProfileCapabilities(profile) : [];
const profileAllows =
!profile || profileCaps.length === 0 || profileCaps.includes(expectedCap);
const enforced = Boolean(meta?.enforceProfileHint && profile);
if (!profileAllows && enforced) {
auditEntries.push({
command,
expectedCapability: expectedCap,
sessionProfile: profile,
outcome: 'profile_denied',
});
throw new Error(
`native_control_profile_mismatch:${profile}:${expectedCap}`,
);
}
return nativeInvoke(command, payload, meta);
},
getNativeControlAuditReport: () => ({
totalEvents: auditEntries.length,
totalRecorded: auditEntries.length,
recent: [],
byOutcome: { profile_denied: auditEntries.length },
}),
clearNativeControlAuditReport: vi.fn(),
};
window.__SHADOWBROKER_DESKTOP__ = nativeRuntime;
const { installDesktopControlBridge } = await import('@/lib/desktopBridge');
installDesktopControlBridge(nativeRuntime);
// settings_only profile cannot access wormhole_gate_key commands
await expect(
window.__SHADOWBROKER_LOCAL_CONTROL__!.invoke!({
command: 'wormhole.gate.key.rotate',
payload: { gate_id: 'infonet', reason: 'test' },
meta: {
capability: 'wormhole_gate_key',
sessionProfileHint: 'settings_only',
enforceProfileHint: true,
},
}),
).rejects.toThrow('native_control_profile_mismatch');
expect(nativeInvoke).not.toHaveBeenCalled();
expect(auditEntries).toHaveLength(1);
expect(auditEntries[0]).toEqual(
expect.objectContaining({
command: 'wormhole.gate.key.rotate',
expectedCapability: 'wormhole_gate_key',
sessionProfile: 'settings_only',
outcome: 'profile_denied',
}),
);
});
it('native runtime audit report populates on allowed invocations', async () => {
let auditCallCount = 0;
const nativeInvoke = vi.fn().mockResolvedValue({ ok: true });
const nativeRuntime: ShadowbrokerDesktopRuntime = {
invokeLocalControl: async (command, payload, meta) => {
auditCallCount++;
return nativeInvoke(command, payload, meta);
},
getNativeControlAuditReport: () => ({
totalEvents: auditCallCount,
totalRecorded: auditCallCount,
recent: [],
byOutcome: { allowed: auditCallCount },
}),
clearNativeControlAuditReport: () => { auditCallCount = 0; },
};
window.__SHADOWBROKER_DESKTOP__ = nativeRuntime;
const { installDesktopControlBridge, getDesktopNativeControlAuditReport } =
await import('@/lib/desktopBridge');
installDesktopControlBridge(nativeRuntime);
await window.__SHADOWBROKER_LOCAL_CONTROL__!.invoke!({
command: 'wormhole.status',
payload: undefined,
});
await window.__SHADOWBROKER_LOCAL_CONTROL__!.invoke!({
command: 'settings.privacy.get',
payload: undefined,
});
const report = getDesktopNativeControlAuditReport();
expect(report).toBeDefined();
expect(report!.totalEvents).toBe(2);
expect(report!.totalRecorded).toBe(2);
expect(report!.byOutcome).toEqual(expect.objectContaining({ allowed: 2 }));
});
it('injected JS capability map covers every contract command', async () => {
const { DESKTOP_CONTROL_COMMANDS, controlCommandCapability } = await import(
'@/lib/desktopControlContract'
);
// The capability map embedded in the Tauri injected JS (main.rs) must
// cover every command. This test verifies the TypeScript contract source
// which the JS map mirrors — if the contract grows, this catches drift.
for (const command of DESKTOP_CONTROL_COMMANDS) {
const cap = controlCommandCapability(command);
expect(cap).toBeDefined();
expect(typeof cap).toBe('string');
}
});
it('profile capability resolution matches between TS and expected Tauri JS tables', async () => {
const { sessionProfileCapabilities } = await import(
'@/lib/desktopControlContract'
);
// Verify the profile→capabilities mapping that the Tauri JS mirrors
const profiles = [
'full_app', 'gate_observe', 'gate_operator', 'wormhole_runtime', 'settings_only',
] as const;
for (const profile of profiles) {
const caps = sessionProfileCapabilities(profile);
expect(Array.isArray(caps)).toBe(true);
expect(caps.length).toBeGreaterThan(0);
}
// Specific assertions matching the Tauri JS table
expect(sessionProfileCapabilities('settings_only')).toEqual(['settings']);
expect(sessionProfileCapabilities('gate_observe')).toEqual(['wormhole_gate_content']);
expect(sessionProfileCapabilities('full_app')).toHaveLength(5);
});
});
@@ -0,0 +1,139 @@
/**
* Tests for the desktop companion mode helper (desktopCompanion.ts).
*
* Validates runtime detection, Tauri invoke delegation, and browser-mode
* fallback behavior without requiring a live Tauri runtime.
*/
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import {
isNativeDesktop,
companionStatus,
companionEnable,
companionDisable,
companionOpenBrowser,
} from '@/lib/desktopCompanion';
const MOCK_STATUS = {
enabled: false,
url: null,
warning: 'Browser companion mode is less secure than the native desktop window.',
};
const MOCK_ENABLED = {
enabled: true,
url: 'http://127.0.0.1:3000',
warning: 'Browser companion mode is less secure than the native desktop window.',
};
describe('desktopCompanion', () => {
afterEach(() => {
// Clean up __TAURI__ mock
delete (window as Record<string, unknown>).__TAURI__;
});
// -------------------------------------------------------------------------
// Runtime detection
// -------------------------------------------------------------------------
describe('isNativeDesktop', () => {
it('returns false when __TAURI__ is not present', () => {
expect(isNativeDesktop()).toBe(false);
});
it('returns false when __TAURI__.core.invoke is missing', () => {
(window as Record<string, unknown>).__TAURI__ = { core: {} };
expect(isNativeDesktop()).toBe(false);
});
it('returns true when __TAURI__.core.invoke is available', () => {
(window as Record<string, unknown>).__TAURI__ = { core: { invoke: vi.fn() } };
expect(isNativeDesktop()).toBe(true);
});
});
// -------------------------------------------------------------------------
// Browser-mode fallback (all commands return null)
// -------------------------------------------------------------------------
describe('browser mode (no Tauri)', () => {
it('companionStatus returns null', async () => {
expect(await companionStatus()).toBeNull();
});
it('companionEnable returns null', async () => {
expect(await companionEnable()).toBeNull();
});
it('companionDisable returns null', async () => {
expect(await companionDisable()).toBeNull();
});
it('companionOpenBrowser returns null', async () => {
expect(await companionOpenBrowser()).toBeNull();
});
});
// -------------------------------------------------------------------------
// Desktop mode (mocked Tauri invoke)
// -------------------------------------------------------------------------
describe('desktop mode (Tauri present)', () => {
let mockInvoke: ReturnType<typeof vi.fn>;
beforeEach(() => {
mockInvoke = vi.fn();
(window as Record<string, unknown>).__TAURI__ = { core: { invoke: mockInvoke } };
});
it('companionStatus invokes companion_status', async () => {
mockInvoke.mockResolvedValue(MOCK_STATUS);
const result = await companionStatus();
expect(mockInvoke).toHaveBeenCalledWith('companion_status');
expect(result).toEqual(MOCK_STATUS);
});
it('companionEnable invokes companion_enable', async () => {
mockInvoke.mockResolvedValue(MOCK_ENABLED);
const result = await companionEnable();
expect(mockInvoke).toHaveBeenCalledWith('companion_enable');
expect(result).toEqual(MOCK_ENABLED);
});
it('companionDisable invokes companion_disable', async () => {
mockInvoke.mockResolvedValue(MOCK_STATUS);
const result = await companionDisable();
expect(mockInvoke).toHaveBeenCalledWith('companion_disable');
expect(result).toEqual(MOCK_STATUS);
});
it('companionOpenBrowser invokes companion_open_browser', async () => {
mockInvoke.mockResolvedValue(MOCK_ENABLED);
const result = await companionOpenBrowser();
expect(mockInvoke).toHaveBeenCalledWith('companion_open_browser');
expect(result).toEqual(MOCK_ENABLED);
});
it('propagates Tauri invoke errors', async () => {
mockInvoke.mockRejectedValue(new Error('companion_not_enabled'));
await expect(companionOpenBrowser()).rejects.toThrow('companion_not_enabled');
});
});
// -------------------------------------------------------------------------
// Status shape
// -------------------------------------------------------------------------
describe('CompanionStatus shape', () => {
it('disabled status has null url', () => {
expect(MOCK_STATUS.enabled).toBe(false);
expect(MOCK_STATUS.url).toBeNull();
expect(MOCK_STATUS.warning).toBeTruthy();
});
it('enabled status has a url', () => {
expect(MOCK_ENABLED.enabled).toBe(true);
expect(MOCK_ENABLED.url).toBe('http://127.0.0.1:3000');
});
});
});
@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest';
import {
describeNativeControlError,
extractNativeGateResyncTarget,
extractGateTargetRef,
} from '../../lib/desktopControlContract';
@@ -22,6 +23,12 @@ describe('extractGateTargetRef', () => {
expect(extractGateTargetRef('wormhole.gate.proof', { gate_id: 'alpha' })).toBe('alpha');
});
it('extracts gate_id from gate state resync payload', () => {
expect(extractGateTargetRef('wormhole.gate.state.resync', { gate_id: 'alpha' })).toBe(
'alpha',
);
});
it('extracts gate_id from gate message post payload', () => {
expect(
extractGateTargetRef('wormhole.gate.message.post', { gate_id: 'ops', plaintext: 'hi' }),
@@ -86,9 +93,30 @@ describe('describeNativeControlError', () => {
expect(describeNativeControlError(undefined)).toBeNull();
});
it('describes native gate resync requirement errors', () => {
expect(
describeNativeControlError('native_gate_state_resync_required:ops'),
).toContain('gate resync');
});
it('handles plain string errors', () => {
expect(
describeNativeControlError('native_control_profile_mismatch:foo'),
).toContain('Denied');
});
});
describe('extractNativeGateResyncTarget', () => {
it('extracts the gate id from native resync-required errors', () => {
expect(extractNativeGateResyncTarget('native_gate_state_resync_required:ops')).toBe('ops');
expect(extractNativeGateResyncTarget(new Error('native_gate_state_resync_required:infonet'))).toBe(
'infonet',
);
});
it('returns null for unrelated errors', () => {
expect(extractNativeGateResyncTarget(new Error('network_error'))).toBeNull();
expect(extractNativeGateResyncTarget('native_control_profile_mismatch:foo')).toBeNull();
expect(extractNativeGateResyncTarget(null)).toBeNull();
});
});
@@ -14,6 +14,11 @@ describe('desktopControlRouting', () => {
path: '/api/wormhole/gate/infonet/key',
method: 'GET',
});
expect(commandToHttpRequest('wormhole.gate.state.resync', { gate_id: 'infonet' })).toEqual({
path: '/api/wormhole/gate/state/export',
method: 'POST',
payload: { gate_id: 'infonet' },
});
expect(commandToHttpRequest('settings.news.reset')).toEqual({
path: '/api/settings/news-feeds/reset',
method: 'POST',
@@ -27,11 +32,12 @@ describe('desktopControlRouting', () => {
commandToHttpRequest('wormhole.gate.message.post', {
gate_id: 'ops',
plaintext: 'hello',
reply_to: 'evt-parent-1',
}),
).toEqual({
path: '/api/wormhole/gate/message/post',
method: 'POST',
payload: { gate_id: 'ops', plaintext: 'hello' },
payload: { gate_id: 'ops', plaintext: 'hello', reply_to: 'evt-parent-1' },
});
});
@@ -53,8 +59,18 @@ describe('desktopControlRouting', () => {
JSON.stringify({ gate_id: 'infonet', reason: 'operator_reset' }),
),
).toEqual({
command: 'wormhole.gate.key.rotate',
payload: { gate_id: 'infonet', reason: 'operator_reset' },
command: 'wormhole.gate.key.rotate',
payload: { gate_id: 'infonet', reason: 'operator_reset' },
});
expect(
httpRequestToInvokeRequest(
'/api/wormhole/gate/state/export',
'POST',
JSON.stringify({ gate_id: 'infonet' }),
),
).toEqual({
command: 'wormhole.gate.state.resync',
payload: { gate_id: 'infonet' },
});
expect(
httpRequestToInvokeRequest(
@@ -96,6 +112,16 @@ describe('desktopControlRouting', () => {
],
},
});
expect(
httpRequestToInvokeRequest(
'/api/wormhole/gate/message/post',
'POST',
JSON.stringify({ gate_id: 'ops', plaintext: 'hello', reply_to: 'evt-parent-2' }),
),
).toEqual({
command: 'wormhole.gate.message.post',
payload: { gate_id: 'ops', plaintext: 'hello', reply_to: 'evt-parent-2' },
});
});
it('returns null for unsupported paths', () => {
@@ -0,0 +1,137 @@
/**
* Tests for native desktop protected-settings readiness bypass.
*
* Verifies that:
* - isNativeProtectedSettingsReady() correctly reflects native bridge presence
* - When the native bridge is present, admin-session browser flow is bypassed
* - When no native bridge, existing admin-session gating is preserved
*
* These are unit tests for the extracted readiness logic. They do NOT render
* SettingsPanel — they test the decision layer that SettingsPanel depends on.
* Full component render coverage is not claimed.
*/
import { beforeEach, describe, expect, it, vi } from 'vitest';
// Mock the bridge detection used by nativeProtectedSettings
const mockHasLocalControlBridge = vi.fn();
vi.mock('@/lib/localControlTransport', () => ({
hasLocalControlBridge: () => mockHasLocalControlBridge(),
canInvokeLocalControl: vi.fn(),
localControlFetch: vi.fn(),
}));
// Mock adminSession to verify it's bypassed or called as expected
const mockHasAdminSession = vi.fn();
const mockPrimeAdminSession = vi.fn();
vi.mock('@/lib/adminSession', () => ({
hasAdminSession: () => mockHasAdminSession(),
primeAdminSession: (...args: unknown[]) => mockPrimeAdminSession(...args),
clearAdminSession: vi.fn(),
}));
describe('isNativeProtectedSettingsReady', () => {
beforeEach(() => {
vi.resetModules();
mockHasLocalControlBridge.mockReset();
});
it('returns true when native local-control bridge is present', async () => {
mockHasLocalControlBridge.mockReturnValue(true);
const mod = await import('@/lib/nativeProtectedSettings');
expect(mod.isNativeProtectedSettingsReady()).toBe(true);
});
it('returns false when no native bridge (browser mode)', async () => {
mockHasLocalControlBridge.mockReturnValue(false);
const mod = await import('@/lib/nativeProtectedSettings');
expect(mod.isNativeProtectedSettingsReady()).toBe(false);
});
});
describe('controlPlaneFetch admin-session bypass with native bridge', () => {
beforeEach(() => {
vi.resetModules();
mockHasLocalControlBridge.mockReset();
mockHasAdminSession.mockReset();
mockPrimeAdminSession.mockReset();
});
it('skips primeAdminSession when native bridge handles the request', async () => {
mockHasLocalControlBridge.mockReturnValue(true);
// canInvokeLocalControl is mocked to be truthy via the mock setup
const { canInvokeLocalControl, localControlFetch } = await import(
'@/lib/localControlTransport'
);
(canInvokeLocalControl as ReturnType<typeof vi.fn>).mockReturnValue(true);
(localControlFetch as ReturnType<typeof vi.fn>).mockResolvedValue(
new Response(JSON.stringify({ ok: true }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
}),
);
const mod = await import('@/lib/controlPlane');
await mod.controlPlaneFetch('/api/settings/api-keys', {
method: 'GET',
});
expect(mockPrimeAdminSession).not.toHaveBeenCalled();
expect(localControlFetch).toHaveBeenCalledTimes(1);
});
it('still primes admin session in browser mode (no native bridge)', async () => {
mockHasLocalControlBridge.mockReturnValue(false);
const { canInvokeLocalControl, localControlFetch } = await import(
'@/lib/localControlTransport'
);
(canInvokeLocalControl as ReturnType<typeof vi.fn>).mockReturnValue(false);
(localControlFetch as ReturnType<typeof vi.fn>).mockResolvedValue(
new Response(JSON.stringify({ ok: true }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
}),
);
mockPrimeAdminSession.mockResolvedValue(undefined);
const mod = await import('@/lib/controlPlane');
await mod.controlPlaneFetch('/api/settings/api-keys', {
method: 'GET',
});
expect(mockPrimeAdminSession).toHaveBeenCalledTimes(1);
});
});
describe('native protected-settings readiness in SettingsPanel context', () => {
beforeEach(() => {
vi.resetModules();
mockHasLocalControlBridge.mockReset();
mockHasAdminSession.mockReset();
});
it('native bridge present: hasAdminSession is NOT called by refreshAdminSession logic', async () => {
mockHasLocalControlBridge.mockReturnValue(true);
// The helper returns true — SettingsPanel's refreshAdminSession should
// short-circuit and never call hasAdminSession()
const mod = await import('@/lib/nativeProtectedSettings');
expect(mod.isNativeProtectedSettingsReady()).toBe(true);
// hasAdminSession should not have been called
expect(mockHasAdminSession).not.toHaveBeenCalled();
});
it('no native bridge: hasAdminSession is the readiness source', async () => {
mockHasLocalControlBridge.mockReturnValue(false);
const mod = await import('@/lib/nativeProtectedSettings');
expect(mod.isNativeProtectedSettingsReady()).toBe(false);
// In this scenario, SettingsPanel would call hasAdminSession() — we
// verify the helper returns false so the browser flow is used.
mockHasAdminSession.mockResolvedValue(true);
const adminMod = await import('@/lib/adminSession');
const ready = await adminMod.hasAdminSession();
expect(ready).toBe(true);
expect(mockHasAdminSession).toHaveBeenCalledTimes(1);
});
});
@@ -0,0 +1,106 @@
import { afterEach, describe, expect, it, vi } from 'vitest';
import {
classifyUpdateRuntime,
getDesktopUpdateContext,
getPreferredManualUpdateUrl,
getUpdateAction,
pickDesktopInstallerUrl,
type GitHubLatestRelease,
} from '@/lib/updateRuntime';
const RELEASE: GitHubLatestRelease = {
html_url: 'https://github.com/BigBodyCobain/Shadowbroker/releases/tag/v0.9.7',
assets: [
{ name: 'ShadowBroker_0.9.7_x64_en-US.msi', browser_download_url: 'https://example.test/windows.msi' },
{ name: 'ShadowBroker_0.9.7_x64-setup.exe', browser_download_url: 'https://example.test/windows-setup.exe' },
{ name: 'ShadowBroker_0.9.7_aarch64.dmg', browser_download_url: 'https://example.test/macos.dmg' },
{ name: 'ShadowBroker_0.9.7_amd64.AppImage', browser_download_url: 'https://example.test/linux.AppImage' },
],
};
describe('updateRuntime', () => {
afterEach(() => {
delete (window as Record<string, unknown>).__TAURI__;
});
describe('getDesktopUpdateContext', () => {
it('returns null when Tauri is not present', async () => {
expect(await getDesktopUpdateContext()).toBeNull();
});
it('invokes desktop_update_context when Tauri is present', async () => {
const invoke = vi.fn().mockResolvedValue({
mode: 'packaged',
platform: 'windows',
is_packaged_build: true,
backend_mode: 'managed',
owns_local_backend: true,
});
(window as Record<string, unknown>).__TAURI__ = { core: { invoke } };
const result = await getDesktopUpdateContext();
expect(invoke).toHaveBeenCalledWith('desktop_update_context');
expect(result).toEqual({
mode: 'packaged',
platform: 'windows',
is_packaged_build: true,
backend_mode: 'managed',
owns_local_backend: true,
});
});
});
describe('runtime classification', () => {
it('classifies browser mode when no desktop context exists', () => {
expect(classifyUpdateRuntime(null)).toBe('browser');
expect(getUpdateAction('browser')).toBe('auto_apply');
});
it('classifies desktop dev mode as auto-apply', () => {
expect(
classifyUpdateRuntime({
mode: 'dev',
platform: 'windows',
is_packaged_build: false,
}),
).toBe('desktop_dev');
expect(getUpdateAction('desktop_dev')).toBe('auto_apply');
});
it('classifies packaged desktop mode as manual-download', () => {
expect(
classifyUpdateRuntime({
mode: 'packaged',
platform: 'windows',
is_packaged_build: true,
}),
).toBe('desktop_packaged');
expect(getUpdateAction('desktop_packaged')).toBe('manual_download');
});
});
describe('installer asset selection', () => {
it('prefers msi installers on windows', () => {
expect(pickDesktopInstallerUrl(RELEASE, 'windows')).toBe('https://example.test/windows.msi');
});
it('prefers dmg installers on macos', () => {
expect(pickDesktopInstallerUrl(RELEASE, 'macos')).toBe('https://example.test/macos.dmg');
});
it('prefers appimage installers on linux', () => {
expect(pickDesktopInstallerUrl(RELEASE, 'linux')).toBe('https://example.test/linux.AppImage');
});
it('falls back to the release page when no platform asset matches', () => {
expect(getPreferredManualUpdateUrl(RELEASE, 'desktop_packaged', 'unknown')).toBe(
RELEASE.html_url,
);
});
it('uses release page for non-packaged runtimes', () => {
expect(getPreferredManualUpdateUrl(RELEASE, 'browser', 'windows')).toBe(RELEASE.html_url);
});
});
});