feat(FN-3314): align auth route assertion in agents routes test

Test FN-3314 completes its final step by refining an auth route assertion in the agents routes test, ensuring the test accurately validates the expected behavior.

Fusion-Task-Id: FN-3314
This commit is contained in:
Fusion
2026-05-04 14:58:58 -07:00
committed by gsxdsm
parent 3b4bb2d134
commit a66ddf2e7f
4 changed files with 24 additions and 13 deletions

View File

@@ -79,6 +79,16 @@ describe("settings key parity", () => {
expect((DEFAULT_PROJECT_SETTINGS as Record<string, unknown>).remoteAccess).toBeUndefined(); expect((DEFAULT_PROJECT_SETTINGS as Record<string, unknown>).remoteAccess).toBeUndefined();
}); });
it("keeps experimentalFeatures scoped to global settings only", () => {
const globalKeys = GLOBAL_SETTINGS_KEYS as readonly string[];
const projectKeys = PROJECT_SETTINGS_KEYS as readonly string[];
expect(projectKeys).not.toContain("experimentalFeatures");
expect(globalKeys).toContain("experimentalFeatures");
expect(DEFAULT_GLOBAL_SETTINGS.experimentalFeatures).toBeDefined();
expect((DEFAULT_PROJECT_SETTINGS as Record<string, unknown>).experimentalFeatures).toBeUndefined();
});
it("No key appears in both GLOBAL_SETTINGS_KEYS and PROJECT_SETTINGS_KEYS", () => { it("No key appears in both GLOBAL_SETTINGS_KEYS and PROJECT_SETTINGS_KEYS", () => {
const projectKeySet = new Set(PROJECT_SETTINGS_KEYS as readonly string[]); const projectKeySet = new Set(PROJECT_SETTINGS_KEYS as readonly string[]);
const overlap = (GLOBAL_SETTINGS_KEYS as readonly string[]).filter((key) => projectKeySet.has(key)); const overlap = (GLOBAL_SETTINGS_KEYS as readonly string[]).filter((key) => projectKeySet.has(key));

View File

@@ -60,6 +60,7 @@ function createMockStore(overrides: Partial<TaskStore> = {}): TaskStore {
return { return {
getSettings: vi.fn().mockResolvedValue({ remoteAccess: buildRemoteAccessSettings() }), getSettings: vi.fn().mockResolvedValue({ remoteAccess: buildRemoteAccessSettings() }),
updateSettings: vi.fn(async (patch: Record<string, unknown>) => patch), updateSettings: vi.fn(async (patch: Record<string, unknown>) => patch),
updateGlobalSettings: vi.fn().mockResolvedValue(undefined),
getRootDir: vi.fn().mockReturnValue("/fake/root"), getRootDir: vi.fn().mockReturnValue("/fake/root"),
getFusionDir: vi.fn().mockReturnValue("/fake/root/.fusion"), getFusionDir: vi.fn().mockReturnValue("/fake/root/.fusion"),
getDatabase: vi.fn().mockReturnValue({ getDatabase: vi.fn().mockReturnValue({
@@ -125,13 +126,13 @@ beforeEach(() => {
describe("remote access provider/lifecycle contracts", () => { describe("remote access provider/lifecycle contracts", () => {
it("switches active provider and rejects invalid provider values", async () => { it("switches active provider and rejects invalid provider values", async () => {
const updateSettings = vi.fn().mockResolvedValue(undefined); const updateGlobalSettings = vi.fn().mockResolvedValue(undefined);
const { app } = createApp({ store: createMockStore({ updateSettings }) }); const { app } = createApp({ store: createMockStore({ updateGlobalSettings }) });
const activate = await REQUEST(app, "POST", "/api/remote/provider/activate", { provider: "tailscale" }); const activate = await REQUEST(app, "POST", "/api/remote/provider/activate", { provider: "tailscale" });
expect(activate.status).toBe(200); expect(activate.status).toBe(200);
expect(activate.body).toEqual({ activeProvider: "tailscale" }); expect(activate.body).toEqual({ activeProvider: "tailscale" });
expect(updateSettings).toHaveBeenCalledWith(expect.objectContaining({ expect(updateGlobalSettings).toHaveBeenCalledWith(expect.objectContaining({
remoteAccess: expect.objectContaining({ activeProvider: "tailscale" }), remoteAccess: expect.objectContaining({ activeProvider: "tailscale" }),
})); }));
@@ -144,17 +145,17 @@ describe("remote access provider/lifecycle contracts", () => {
}); });
it("seeds defaults when activating a provider on a fresh project", async () => { it("seeds defaults when activating a provider on a fresh project", async () => {
const updateSettings = vi.fn().mockResolvedValue(undefined); const updateGlobalSettings = vi.fn().mockResolvedValue(undefined);
const store = createMockStore({ const store = createMockStore({
getSettings: vi.fn().mockResolvedValue({}), getSettings: vi.fn().mockResolvedValue({}),
updateSettings, updateGlobalSettings,
}); });
const { app } = createApp({ store }); const { app } = createApp({ store });
const activate = await REQUEST(app, "POST", "/api/remote/provider/activate", { provider: "cloudflare" }); const activate = await REQUEST(app, "POST", "/api/remote/provider/activate", { provider: "cloudflare" });
expect(activate.status).toBe(200); expect(activate.status).toBe(200);
expect(updateSettings).toHaveBeenCalledWith(expect.objectContaining({ expect(updateGlobalSettings).toHaveBeenCalledWith(expect.objectContaining({
remoteAccess: expect.objectContaining({ remoteAccess: expect.objectContaining({
activeProvider: "cloudflare", activeProvider: "cloudflare",
}), }),

View File

@@ -199,8 +199,8 @@ describe("remote access API route contracts", () => {
lastError: null, lastError: null,
}), }),
}; };
const updateSettings = vi.fn().mockResolvedValue(undefined); const updateGlobalSettings = vi.fn().mockResolvedValue(undefined);
const store = createMockStore({ updateSettings }); const store = createMockStore({ updateGlobalSettings });
const { app } = createApp({ store, engine }); const { app } = createApp({ store, engine });
const activateRes = await REQUEST(app, "POST", "/api/remote/provider/activate", { provider: "tailscale" }); const activateRes = await REQUEST(app, "POST", "/api/remote/provider/activate", { provider: "tailscale" });
@@ -219,7 +219,7 @@ describe("remote access API route contracts", () => {
expect(engine.startRemoteTunnel.mock.calls.length).toBeLessThanOrEqual(1); expect(engine.startRemoteTunnel.mock.calls.length).toBeLessThanOrEqual(1);
expect(engine.stopRemoteTunnel.mock.calls.length).toBeLessThanOrEqual(1); expect(engine.stopRemoteTunnel.mock.calls.length).toBeLessThanOrEqual(1);
expect(updateSettings).toHaveBeenCalledWith(expect.objectContaining({ expect(updateGlobalSettings).toHaveBeenCalledWith(expect.objectContaining({
remoteAccess: expect.objectContaining({ activeProvider: "tailscale" }), remoteAccess: expect.objectContaining({ activeProvider: "tailscale" }),
})); }));
}); });

View File

@@ -298,7 +298,7 @@ export function registerSettingsMemoryRoutes(ctx: ApiRoutesContext, deps: Settin
} }
const token = generateRemoteToken(); const token = generateRemoteToken();
await scopedStore.updateSettings({ await scopedStore.updateGlobalSettings({
remoteAccess: { remoteAccess: {
...remoteAccess, ...remoteAccess,
tokenStrategy: { tokenStrategy: {
@@ -646,7 +646,7 @@ export function registerSettingsMemoryRoutes(ctx: ApiRoutesContext, deps: Settin
const settings = await scopedStore.getSettings(); const settings = await scopedStore.getSettings();
const remoteAccess = settings.remoteAccess ?? DEFAULT_GLOBAL_SETTINGS.remoteAccess; const remoteAccess = settings.remoteAccess ?? DEFAULT_GLOBAL_SETTINGS.remoteAccess;
await scopedStore.updateSettings({ await scopedStore.updateGlobalSettings({
remoteAccess: { remoteAccess: {
...remoteAccess, ...remoteAccess,
activeProvider: provider, activeProvider: provider,
@@ -676,7 +676,7 @@ export function registerSettingsMemoryRoutes(ctx: ApiRoutesContext, deps: Settin
if (provider === "tailscale" && settings.remoteAccess) { if (provider === "tailscale" && settings.remoteAccess) {
const livePort = req.socket?.localPort; const livePort = req.socket?.localPort;
if (Number.isFinite(livePort) && (livePort ?? 0) > 0 && livePort !== settings.remoteAccess.providers.tailscale.targetPort) { if (Number.isFinite(livePort) && (livePort ?? 0) > 0 && livePort !== settings.remoteAccess.providers.tailscale.targetPort) {
await scopedStore.updateSettings({ await scopedStore.updateGlobalSettings({
remoteAccess: { remoteAccess: {
...settings.remoteAccess, ...settings.remoteAccess,
providers: { providers: {
@@ -764,7 +764,7 @@ export function registerSettingsMemoryRoutes(ctx: ApiRoutesContext, deps: Settin
} }
const token = generateRemoteToken(); const token = generateRemoteToken();
await scopedStore.updateSettings({ await scopedStore.updateGlobalSettings({
remoteAccess: { remoteAccess: {
...remoteAccess, ...remoteAccess,
tokenStrategy: { tokenStrategy: {