fix(dashboard-tests): finish the FN-8491 mock backlog; contain FN-8557 innerWidth leakage
Nine more api-lane files get the established getProjectScopedPluginMcpServers stub (includes shared-branch-group-entry-points, whose two current failures were FN-8491 500s — the historical per-task-derived pair is gone). App lane: FN-8557 made window.innerWidth<=768 a mobile signal, so leaked innerWidth=375 defineProperty stamps flipped later ListView/settings tests into mobile layout (reset in beforeEach), and useModalResizePersist's 700px "mobile" fixture became tablet-class (now a phone-class 375px viewport). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -420,6 +420,16 @@ describe("ListView", () => {
|
||||
localStorage.clear();
|
||||
showAllColumnsByDefault();
|
||||
ensureMatchMedia();
|
||||
/*
|
||||
FNXC:ViewportMode 2026-07-24-02:30:
|
||||
FN-8557 (973c978f9) made isMobileViewport treat `window.innerWidth <= 768`
|
||||
as a mobile signal alongside matchMedia. mockMobileViewport stamps
|
||||
innerWidth=375 via defineProperty and its spy restore only resets
|
||||
matchMedia, so the leaked width flipped every later test into the mobile
|
||||
card layout (no <tr> rows). Reset innerWidth to a desktop width here so the
|
||||
per-test viewport helpers stay authoritative.
|
||||
*/
|
||||
Object.defineProperty(window, "innerWidth", { value: 1280, configurable: true });
|
||||
vi.spyOn(window, "matchMedia").mockImplementation((query: string) => ({
|
||||
matches: false,
|
||||
media: query,
|
||||
@@ -4221,6 +4231,8 @@ describe("ListView - Bulk Selection", () => {
|
||||
for (const key of Object.keys(listViewSseHandlers)) delete listViewSseHandlers[key];
|
||||
localStorage.clear();
|
||||
ensureMatchMedia();
|
||||
// FNXC:ViewportMode 2026-07-24-02:30: FN-8557 innerWidth leak reset (see the main ListView beforeEach comment).
|
||||
Object.defineProperty(window, "innerWidth", { value: 1280, configurable: true });
|
||||
vi.spyOn(window, "matchMedia").mockImplementation((query: string) => ({
|
||||
matches: false,
|
||||
media: query,
|
||||
|
||||
@@ -163,6 +163,15 @@ function setDocumentHidden(hidden: boolean): void {
|
||||
}
|
||||
|
||||
function mockSettingsViewport(matches: boolean): void {
|
||||
/*
|
||||
FNXC:ViewportMode 2026-07-24-02:20:
|
||||
FN-8557 (973c978f9) made isMobileViewport treat `window.innerWidth <= 768` as a
|
||||
mobile signal alongside matchMedia. Individual mobile tests here stamp
|
||||
innerWidth=375 via defineProperty without restoring it, which leaked mobile
|
||||
mode into later desktop assertions. The viewport mock now owns innerWidth in
|
||||
both directions so each test's declared viewport is authoritative.
|
||||
*/
|
||||
Object.defineProperty(window, "innerWidth", { configurable: true, value: matches ? 375 : 1280 });
|
||||
Object.defineProperty(window, "matchMedia", {
|
||||
writable: true,
|
||||
value: vi.fn().mockImplementation((query: string) => ({
|
||||
|
||||
@@ -181,7 +181,15 @@ describe("useModalResizePersist", () => {
|
||||
});
|
||||
|
||||
it("clears inline size and does not inject a grip on mobile", () => {
|
||||
setViewport(700);
|
||||
/*
|
||||
FNXC:ViewportMode 2026-07-24-02:25:
|
||||
FN-8557 (973c978f9) classifies a narrow touch viewport with a tablet-class
|
||||
physical screen (min edge > 480px) as tablet, which keeps the FN-6377 touch
|
||||
grip. jsdom reports `"ontouchstart" in window === true`, so the old 700x800
|
||||
fixture became a tablet. Use a phone-class screen (375px min edge) so this
|
||||
test still exercises the true mobile contract: no grip, inline size cleared.
|
||||
*/
|
||||
setViewport(375);
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify({ width: 610, height: 480 }));
|
||||
|
||||
render(<Harness initialWidth="610px" initialHeight="480px" />);
|
||||
|
||||
@@ -20,6 +20,14 @@ class MockStore extends EventEmitter {
|
||||
addTask(task: Task): void { this.tasks.set(task.id, task); }
|
||||
getMissionStore() { return new EventEmitter(); }
|
||||
async listTasks(): Promise<Task[]> { return []; }
|
||||
/*
|
||||
FNXC:PluginMcpServers 2026-07-24-02:05:
|
||||
FN-8491 (3cd023fa4) made resolveProjectContext bind a project-scoped plugin
|
||||
MCP provider on every getProjectContext call; a store exposing
|
||||
getProjectScopedPluginMcpServers is treated as runtime-owned and skips the
|
||||
binder (which would otherwise 500 on getPluginStore()).
|
||||
*/
|
||||
getProjectScopedPluginMcpServers = vi.fn().mockResolvedValue([]);
|
||||
}
|
||||
|
||||
function createTask(overrides: Partial<Task> = {}): Task {
|
||||
|
||||
@@ -68,6 +68,14 @@ function createMockStore(overrides: Partial<TaskStore> = {}): TaskStore {
|
||||
updateWorkflowStep: vi.fn(),
|
||||
deleteWorkflowStep: vi.fn(),
|
||||
getMissionStore: vi.fn().mockReturnValue(createMockMissionStore()),
|
||||
/*
|
||||
FNXC:PluginMcpServers 2026-07-24-02:05:
|
||||
FN-8491 (3cd023fa4) made resolveProjectContext bind a project-scoped plugin
|
||||
MCP provider on every getProjectContext call; a store exposing
|
||||
getProjectScopedPluginMcpServers is treated as runtime-owned and skips the
|
||||
binder (which would otherwise 500 on getPluginStore()).
|
||||
*/
|
||||
getProjectScopedPluginMcpServers: vi.fn().mockResolvedValue([]),
|
||||
...overrides,
|
||||
} as unknown as TaskStore;
|
||||
}
|
||||
|
||||
@@ -237,6 +237,14 @@ function createMockStore(): TaskStore {
|
||||
getMissionTask: vi.fn(),
|
||||
deleteMissionTask: vi.fn(),
|
||||
}),
|
||||
/*
|
||||
FNXC:PluginMcpServers 2026-07-24-02:05:
|
||||
FN-8491 (3cd023fa4) made resolveProjectContext bind a project-scoped plugin
|
||||
MCP provider on every getProjectContext call; a store exposing
|
||||
getProjectScopedPluginMcpServers is treated as runtime-owned and skips the
|
||||
binder (which would otherwise 500 on getPluginStore()).
|
||||
*/
|
||||
getProjectScopedPluginMcpServers: vi.fn().mockResolvedValue([]),
|
||||
};
|
||||
|
||||
return store as unknown as TaskStore;
|
||||
|
||||
@@ -20,6 +20,14 @@ function createMockStore(overrides: Partial<TaskStore> = {}): TaskStore {
|
||||
logEntry: vi.fn().mockResolvedValue(undefined),
|
||||
on: vi.fn(),
|
||||
off: vi.fn(),
|
||||
/*
|
||||
FNXC:PluginMcpServers 2026-07-24-02:05:
|
||||
FN-8491 (3cd023fa4) made resolveProjectContext bind a project-scoped plugin
|
||||
MCP provider on every getProjectContext call; a store exposing
|
||||
getProjectScopedPluginMcpServers is treated as runtime-owned and skips the
|
||||
binder (which would otherwise 500 on getPluginStore()).
|
||||
*/
|
||||
getProjectScopedPluginMcpServers: vi.fn().mockResolvedValue([]),
|
||||
...overrides,
|
||||
} as unknown as TaskStore;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,14 @@ class MockStore extends EventEmitter {
|
||||
getWorkflowDefinition = vi.fn(async () => undefined);
|
||||
getWorkflowSettingValues = vi.fn((workflowId: string, projectId: string) => this.workflowValues.get(`${workflowId}::${projectId}`) ?? {});
|
||||
getWorkflowSettingsProjectId = vi.fn(() => "default");
|
||||
/*
|
||||
FNXC:PluginMcpServers 2026-07-24-02:05:
|
||||
FN-8491 (3cd023fa4) made resolveProjectContext bind a project-scoped plugin
|
||||
MCP provider on every getProjectContext call; a store exposing
|
||||
getProjectScopedPluginMcpServers is treated as runtime-owned and skips the
|
||||
binder (which would otherwise 500 on getPluginStore()).
|
||||
*/
|
||||
getProjectScopedPluginMcpServers = vi.fn().mockResolvedValue([]);
|
||||
|
||||
setSelection(taskId: string, workflowId: string): void {
|
||||
this.workflowSelections.set(taskId, { workflowId, stepIds: [] });
|
||||
|
||||
@@ -99,6 +99,14 @@ function createMockStore(fusionDir: string) {
|
||||
getAllDocuments: vi.fn().mockResolvedValue([]),
|
||||
listWorkflowSteps: vi.fn().mockResolvedValue([]),
|
||||
getMissionStore: vi.fn(),
|
||||
/*
|
||||
FNXC:PluginMcpServers 2026-07-24-02:05:
|
||||
FN-8491 (3cd023fa4) made resolveProjectContext bind a project-scoped plugin
|
||||
MCP provider on every getProjectContext call; a store exposing
|
||||
getProjectScopedPluginMcpServers is treated as runtime-owned and skips the
|
||||
binder (which would otherwise 500 on getPluginStore()).
|
||||
*/
|
||||
getProjectScopedPluginMcpServers: vi.fn().mockResolvedValue([]),
|
||||
} as any;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,14 @@ function createMockStore(): TaskStore {
|
||||
updateWorkflowStep: vi.fn(),
|
||||
deleteWorkflowStep: vi.fn(),
|
||||
getMissionStore: vi.fn(),
|
||||
/*
|
||||
FNXC:PluginMcpServers 2026-07-24-02:05:
|
||||
FN-8491 (3cd023fa4) made resolveProjectContext bind a project-scoped plugin
|
||||
MCP provider on every getProjectContext call; a store exposing
|
||||
getProjectScopedPluginMcpServers is treated as runtime-owned and skips the
|
||||
binder (which would otherwise 500 on getPluginStore()).
|
||||
*/
|
||||
getProjectScopedPluginMcpServers: vi.fn().mockResolvedValue([]),
|
||||
} as unknown as TaskStore;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,14 @@ describe("task workflow merge route", () => {
|
||||
const store: TaskStore = {
|
||||
getRootDir: vi.fn(() => process.cwd()),
|
||||
mergeTask: vi.fn(),
|
||||
/*
|
||||
FNXC:PluginMcpServers 2026-07-24-02:05:
|
||||
FN-8491 (3cd023fa4) made resolveProjectContext bind a project-scoped plugin
|
||||
MCP provider on every getProjectContext call; a store exposing
|
||||
getProjectScopedPluginMcpServers is treated as runtime-owned and skips the
|
||||
binder (which would otherwise 500 on getPluginStore()).
|
||||
*/
|
||||
getProjectScopedPluginMcpServers: vi.fn().mockResolvedValue([]),
|
||||
} as unknown as TaskStore;
|
||||
|
||||
const onMerge = vi.fn(async (id: string) => ({
|
||||
|
||||
@@ -58,6 +58,14 @@ const createHarness = (taskState: any, events: RunAuditEvent[]) => {
|
||||
}
|
||||
return filtered;
|
||||
}),
|
||||
/*
|
||||
FNXC:PluginMcpServers 2026-07-24-02:05:
|
||||
FN-8491 (3cd023fa4) made resolveProjectContext bind a project-scoped plugin
|
||||
MCP provider on every getProjectContext call; a store exposing
|
||||
getProjectScopedPluginMcpServers is treated as runtime-owned and skips the
|
||||
binder (which would otherwise 500 on getPluginStore()).
|
||||
*/
|
||||
getProjectScopedPluginMcpServers: vi.fn().mockResolvedValue([]),
|
||||
} as unknown as TaskStore;
|
||||
|
||||
const app = express();
|
||||
|
||||
Reference in New Issue
Block a user