feat(FN-3009): migrate remote settings to global scope
This merge migrates Fusion's settings architecture to a unified global scope (FN-3009), consolidating settings types, defaults, merge semantics, updater logic, and routing into a centralized system that aligns dashboard remote settings with global configuration. Secondary changes include adding the Fusion-Task-Id: FN-3009
This commit is contained in:
@@ -157,10 +157,6 @@ describe("remote access provider/lifecycle contracts", () => {
|
||||
expect(updateSettings).toHaveBeenCalledWith(expect.objectContaining({
|
||||
remoteAccess: expect.objectContaining({
|
||||
activeProvider: "cloudflare",
|
||||
providers: expect.objectContaining({
|
||||
tailscale: expect.objectContaining({ enabled: false }),
|
||||
cloudflare: expect.objectContaining({ enabled: false }),
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import express from "express";
|
||||
import { DEFAULT_PROJECT_SETTINGS, type TaskStore } from "@fusion/core";
|
||||
import { DEFAULT_GLOBAL_SETTINGS, type TaskStore } from "@fusion/core";
|
||||
import { createApiRoutes } from "../routes.js";
|
||||
import { request as performRequest } from "../test-request.js";
|
||||
|
||||
@@ -47,6 +47,7 @@ function createMockStore(overrides: Partial<TaskStore> = {}): TaskStore {
|
||||
return {
|
||||
getSettings: vi.fn().mockResolvedValue({ remoteAccess: buildRemoteAccessSettings() }),
|
||||
updateSettings: vi.fn(async (patch: Record<string, unknown>) => patch),
|
||||
updateGlobalSettings: vi.fn(async (patch: Record<string, unknown>) => patch),
|
||||
getRootDir: vi.fn().mockReturnValue("/fake/root"),
|
||||
getFusionDir: vi.fn().mockReturnValue("/fake/root/.fusion"),
|
||||
getDatabase: vi.fn().mockReturnValue({
|
||||
@@ -86,7 +87,7 @@ async function REQUEST(app: express.Express, method: string, path: string, body?
|
||||
describe("remote access API route contracts", () => {
|
||||
it("supports GET and PUT /api/remote/settings", async () => {
|
||||
const store = createMockStore({
|
||||
updateSettings: vi.fn().mockResolvedValue({ remoteAccess: buildRemoteAccessSettings() }),
|
||||
updateGlobalSettings: vi.fn().mockResolvedValue({ remoteAccess: buildRemoteAccessSettings() }),
|
||||
getSettings: vi.fn()
|
||||
.mockResolvedValueOnce({ remoteAccess: buildRemoteAccessSettings() })
|
||||
.mockResolvedValueOnce({ remoteAccess: { ...buildRemoteAccessSettings(), activeProvider: "tailscale" } }),
|
||||
@@ -122,7 +123,7 @@ describe("remote access API route contracts", () => {
|
||||
}),
|
||||
});
|
||||
|
||||
expect(store.updateSettings).toHaveBeenCalledWith(expect.objectContaining({
|
||||
expect(store.updateGlobalSettings).toHaveBeenCalledWith(expect.objectContaining({
|
||||
remoteAccess: expect.objectContaining({
|
||||
providers: expect.objectContaining({
|
||||
cloudflare: expect.objectContaining({ quickTunnel: true }),
|
||||
@@ -152,10 +153,10 @@ describe("remote access API route contracts", () => {
|
||||
});
|
||||
|
||||
it("seeds defaults when saving remote settings on a fresh project", async () => {
|
||||
const updateSettings = vi.fn().mockResolvedValue(undefined);
|
||||
const updateGlobalSettings = vi.fn().mockResolvedValue(undefined);
|
||||
const store = createMockStore({
|
||||
getSettings: vi.fn().mockResolvedValue({}),
|
||||
updateSettings,
|
||||
updateGlobalSettings,
|
||||
});
|
||||
const { app } = createApp({ store });
|
||||
|
||||
@@ -166,9 +167,9 @@ describe("remote access API route contracts", () => {
|
||||
});
|
||||
|
||||
expect(putRes.status).toBe(200);
|
||||
expect(updateSettings).toHaveBeenCalledWith({
|
||||
expect(updateGlobalSettings).toHaveBeenCalledWith({
|
||||
remoteAccess: expect.objectContaining({
|
||||
...DEFAULT_PROJECT_SETTINGS.remoteAccess,
|
||||
...DEFAULT_GLOBAL_SETTINGS.remoteAccess,
|
||||
activeProvider: "tailscale",
|
||||
providers: expect.objectContaining({
|
||||
tailscale: expect.objectContaining({ enabled: true, hostname: "first-use.ts.net" }),
|
||||
|
||||
@@ -14415,7 +14415,7 @@ describe("PUT /settings", () => {
|
||||
remoteAccess: mergedRemoteAccess,
|
||||
};
|
||||
|
||||
(store.updateSettings as ReturnType<typeof vi.fn>).mockResolvedValue(updatedSettings);
|
||||
(store.updateGlobalSettings as ReturnType<typeof vi.fn>).mockResolvedValue(updatedSettings);
|
||||
(store.getSettingsFast as ReturnType<typeof vi.fn>).mockResolvedValue(updatedSettings);
|
||||
|
||||
const app = buildApp();
|
||||
@@ -14436,13 +14436,13 @@ describe("PUT /settings", () => {
|
||||
const updateRes = await REQUEST(
|
||||
app,
|
||||
"PUT",
|
||||
"/api/settings",
|
||||
"/api/settings/global",
|
||||
JSON.stringify(patch),
|
||||
{ "Content-Type": "application/json" },
|
||||
);
|
||||
|
||||
expect(updateRes.status).toBe(200);
|
||||
expect(store.updateSettings).toHaveBeenCalledWith(patch);
|
||||
expect(store.updateGlobalSettings).toHaveBeenCalledWith(patch);
|
||||
|
||||
const getRes = await GET(app, "/api/settings");
|
||||
expect(getRes.status).toBe(200);
|
||||
|
||||
Reference in New Issue
Block a user