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:
@@ -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));
|
||||||
|
|||||||
@@ -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",
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -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" }),
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
Reference in New Issue
Block a user