feat(FN-1958): merge fusion/fn-1958
This commit is contained in:
@@ -93,6 +93,7 @@ function createMockGlobalSettingsStore() {
|
||||
updateSettings: vi.fn().mockResolvedValue({}),
|
||||
getSettingsPath: vi.fn().mockReturnValue("/fake/home/.fusion/settings.json"),
|
||||
init: vi.fn().mockResolvedValue(false),
|
||||
invalidateCache: vi.fn(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12174,6 +12175,80 @@ describe("PUT /settings/global", () => {
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body.modelOnboardingComplete).toBe(true);
|
||||
});
|
||||
|
||||
it("invalidates all global settings caches including engine stores", async () => {
|
||||
const updated = { defaultModelId: "claude-3-5-sonnet" };
|
||||
(store.updateGlobalSettings as ReturnType<typeof vi.fn>).mockResolvedValue(updated);
|
||||
|
||||
// Create mock engine with GlobalSettingsStore spy
|
||||
const engineGlobalStore = createMockGlobalSettingsStore();
|
||||
const mockEngineStore = createMockStore();
|
||||
(mockEngineStore.getGlobalSettingsStore as ReturnType<typeof vi.fn>).mockReturnValue(engineGlobalStore);
|
||||
|
||||
const mockEngine = {
|
||||
getTaskStore: vi.fn().mockReturnValue(mockEngineStore),
|
||||
};
|
||||
|
||||
// Create mock engine manager
|
||||
const mockEngineManager = {
|
||||
getAllEngines: vi.fn().mockReturnValue(new Map([["project-1", mockEngine]])),
|
||||
getEngine: vi.fn(),
|
||||
ensureEngine: vi.fn(),
|
||||
};
|
||||
|
||||
// Spy on invalidateAllGlobalSettingsCaches
|
||||
const invalidateAllSpy = vi.spyOn(projectStoreResolver, "invalidateAllGlobalSettingsCaches");
|
||||
|
||||
// Build app with engineManager option
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
app.use("/api", createApiRoutes(store, { engineManager: mockEngineManager as any }));
|
||||
|
||||
const res = await REQUEST(
|
||||
app,
|
||||
"PUT",
|
||||
"/api/settings/global",
|
||||
JSON.stringify(updated),
|
||||
{ "Content-Type": "application/json" },
|
||||
);
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(store.updateGlobalSettings).toHaveBeenCalledWith(updated);
|
||||
|
||||
// Verify project-store-resolver caches are invalidated
|
||||
expect(invalidateAllSpy).toHaveBeenCalledOnce();
|
||||
|
||||
// Verify engine store cache is invalidated
|
||||
expect(mockEngine.getTaskStore).toHaveBeenCalled();
|
||||
expect(engineGlobalStore.invalidateCache).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("handles missing engineManager gracefully", async () => {
|
||||
const updated = { defaultModelId: "claude-3-5-sonnet" };
|
||||
(store.updateGlobalSettings as ReturnType<typeof vi.fn>).mockResolvedValue(updated);
|
||||
|
||||
// Spy on invalidateAllGlobalSettingsCaches
|
||||
const invalidateAllSpy = vi.spyOn(projectStoreResolver, "invalidateAllGlobalSettingsCaches");
|
||||
|
||||
// Build app WITHOUT engineManager option
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
app.use("/api", createApiRoutes(store));
|
||||
|
||||
const res = await REQUEST(
|
||||
app,
|
||||
"PUT",
|
||||
"/api/settings/global",
|
||||
JSON.stringify(updated),
|
||||
{ "Content-Type": "application/json" },
|
||||
);
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(store.updateGlobalSettings).toHaveBeenCalledWith(updated);
|
||||
|
||||
// Should still invalidate project-store-resolver caches
|
||||
expect(invalidateAllSpy).toHaveBeenCalledOnce();
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /settings/scopes", () => {
|
||||
|
||||
@@ -2776,6 +2776,14 @@ export function createApiRoutes(store: TaskStore, options?: ServerOptions): Rout
|
||||
// next GET /settings?projectId=xxx reads fresh values from disk rather
|
||||
// than returning a stale per-project cache.
|
||||
invalidateAllGlobalSettingsCaches();
|
||||
// Also invalidate caches in engine manager stores (separate GlobalSettingsStore
|
||||
// instances that are NOT part of the project-store-resolver cache).
|
||||
const engineManager = options?.engineManager;
|
||||
if (engineManager) {
|
||||
for (const engine of engineManager.getAllEngines().values()) {
|
||||
engine.getTaskStore().getGlobalSettingsStore().invalidateCache();
|
||||
}
|
||||
}
|
||||
res.json(settings);
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof ApiError) {
|
||||
|
||||
Reference in New Issue
Block a user