From d9b5bb4b4ed287f1bd2492b5d5235468fdea66f7 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 4 Jun 2026 04:32:46 -0700 Subject: [PATCH] fix(ci): spread real @fusion/core into partial test mocks; deterministic editor save test --- .../app/components/__tests__/WorkflowNodeEditor.test.tsx | 6 +++++- .../__tests__/auto-merge-toggle-blank.mobile.test.tsx | 1 + .../__tests__/board-mobile-initial-render.test.tsx | 1 + .../components/__tests__/board-mobile-view-switch.test.tsx | 1 + .../dashboard/src/__tests__/chat-attachment-routes.test.ts | 3 ++- packages/dashboard/src/__tests__/chat-manager.test.ts | 3 ++- packages/dashboard/src/__tests__/proxy-routes.test.ts | 4 +++- .../dashboard/src/__tests__/routes-agent-budget.test.ts | 4 +++- .../dashboard/src/__tests__/routes-agent-export.test.ts | 4 +++- packages/dashboard/src/__tests__/routes-agent-keys.test.ts | 4 +++- .../src/__tests__/routes-agent-permissions.test.ts | 4 +++- .../src/__tests__/routes-agent-prompt-sizes.test.ts | 3 ++- .../dashboard/src/__tests__/routes-agent-ratings.test.ts | 4 +++- .../dashboard/src/__tests__/routes-agent-revisions.test.ts | 4 +++- packages/dashboard/src/__tests__/routes-agent-runs.test.ts | 4 +++- .../dashboard/src/__tests__/routes-agent-skills.test.ts | 4 +++- .../src/__tests__/routes-agent-token-usage.test.ts | 3 ++- .../dashboard/src/__tests__/routes-approval-secrets.test.ts | 3 ++- packages/dashboard/src/__tests__/routes-approval.test.ts | 3 ++- .../src/__tests__/routes-nodes-sync-contract.test.ts | 4 +++- packages/dashboard/src/__tests__/routes-nodes-sync.test.ts | 4 +++- packages/dashboard/src/__tests__/routes-nodes.test.ts | 4 +++- packages/dashboard/src/__tests__/routes-org-chart.test.ts | 4 +++- .../src/__tests__/routes-run-audit-goal-events.test.ts | 3 ++- .../dashboard/src/__tests__/routes-sandbox-audit.test.ts | 3 ++- packages/dashboard/src/__tests__/usage.test.ts | 3 ++- .../__tests__/register-docker-provisioning-routes.test.ts | 3 ++- 27 files changed, 67 insertions(+), 24 deletions(-) diff --git a/packages/dashboard/app/components/__tests__/WorkflowNodeEditor.test.tsx b/packages/dashboard/app/components/__tests__/WorkflowNodeEditor.test.tsx index b713f40242..890a643c95 100644 --- a/packages/dashboard/app/components/__tests__/WorkflowNodeEditor.test.tsx +++ b/packages/dashboard/app/components/__tests__/WorkflowNodeEditor.test.tsx @@ -243,7 +243,11 @@ describe("WorkflowNodeEditor — U10 columns/traits/holds", () => { vi.mocked(compileWorkflow).mockResolvedValue({ steps: [] }); render( {}} addToast={() => {}} />); - fireEvent.click((await screen.findByText("Save")).closest("button")!); + // Wait for the column panel to hydrate before saving — saving earlier + // races the async columns state and flowToIr would emit a v1 IR. + await screen.findByText("Save"); + await waitFor(() => expect(screen.getAllByLabelText(/Column name/i).length).toBeGreaterThan(0)); + fireEvent.click(screen.getByText("Save").closest("button")!); await waitFor(() => expect(updateWorkflow).toHaveBeenCalled()); const [, updates] = vi.mocked(updateWorkflow).mock.calls[0]; diff --git a/packages/dashboard/app/components/__tests__/auto-merge-toggle-blank.mobile.test.tsx b/packages/dashboard/app/components/__tests__/auto-merge-toggle-blank.mobile.test.tsx index e93dc45750..b825adf972 100644 --- a/packages/dashboard/app/components/__tests__/auto-merge-toggle-blank.mobile.test.tsx +++ b/packages/dashboard/app/components/__tests__/auto-merge-toggle-blank.mobile.test.tsx @@ -6,6 +6,7 @@ import { PageErrorBoundary } from "../ErrorBoundary"; import type { Task } from "@fusion/core"; vi.mock("../../api", () => ({ + fetchBoardWorkflows: vi.fn().mockResolvedValue({ flagEnabled: false, defaultWorkflowId: "", workflows: [], taskWorkflowIds: {} }), fetchWorkflowSteps: vi.fn().mockResolvedValue([]), })); diff --git a/packages/dashboard/app/components/__tests__/board-mobile-initial-render.test.tsx b/packages/dashboard/app/components/__tests__/board-mobile-initial-render.test.tsx index f9dd709c6b..038e12dc0f 100644 --- a/packages/dashboard/app/components/__tests__/board-mobile-initial-render.test.tsx +++ b/packages/dashboard/app/components/__tests__/board-mobile-initial-render.test.tsx @@ -5,6 +5,7 @@ import { Board } from "../Board"; import { loadAllAppCss } from "../../test/cssFixture"; vi.mock("../../api", () => ({ + fetchBoardWorkflows: vi.fn().mockResolvedValue({ flagEnabled: false, defaultWorkflowId: "", workflows: [], taskWorkflowIds: {} }), fetchWorkflowSteps: vi.fn().mockResolvedValue([]), })); diff --git a/packages/dashboard/app/components/__tests__/board-mobile-view-switch.test.tsx b/packages/dashboard/app/components/__tests__/board-mobile-view-switch.test.tsx index 100ed3dd10..f19edd1272 100644 --- a/packages/dashboard/app/components/__tests__/board-mobile-view-switch.test.tsx +++ b/packages/dashboard/app/components/__tests__/board-mobile-view-switch.test.tsx @@ -6,6 +6,7 @@ import { ListView } from "../ListView"; import "../../styles.css"; vi.mock("../../api", () => ({ + fetchBoardWorkflows: vi.fn().mockResolvedValue({ flagEnabled: false, defaultWorkflowId: "", workflows: [], taskWorkflowIds: {} }), fetchWorkflowSteps: vi.fn().mockResolvedValue([]), fetchModels: vi.fn().mockResolvedValue({ models: [], favoriteProviders: [], favoriteModels: [] }), fetchSettings: vi.fn().mockResolvedValue({ diff --git a/packages/dashboard/src/__tests__/chat-attachment-routes.test.ts b/packages/dashboard/src/__tests__/chat-attachment-routes.test.ts index bf39f691b8..8d889a797d 100644 --- a/packages/dashboard/src/__tests__/chat-attachment-routes.test.ts +++ b/packages/dashboard/src/__tests__/chat-attachment-routes.test.ts @@ -66,7 +66,8 @@ vi.mock("../chat.js", () => ({ __resetChatState: vi.fn(), })); -vi.mock("@fusion/core", () => ({ +vi.mock("@fusion/core", async (importOriginal) => ({ + ...(await importOriginal()), ChatStore: class MockChatStore extends EventEmitter { init = mockInit; createSession = mockCreateSession; diff --git a/packages/dashboard/src/__tests__/chat-manager.test.ts b/packages/dashboard/src/__tests__/chat-manager.test.ts index 2d8159dae6..32658ba9c3 100644 --- a/packages/dashboard/src/__tests__/chat-manager.test.ts +++ b/packages/dashboard/src/__tests__/chat-manager.test.ts @@ -22,7 +22,8 @@ const { mockSummarizeTitle } = vi.hoisted(() => ({ mockSummarizeTitle: vi.fn(), })); -vi.mock("@fusion/core", () => ({ +vi.mock("@fusion/core", async (importOriginal) => ({ + ...(await importOriginal()), summarizeTitle: mockSummarizeTitle, DASHBOARD_USER_ID: "dashboard", normalizeMessageParticipant: (id: string, type: "user" | "agent" | "system") => { diff --git a/packages/dashboard/src/__tests__/proxy-routes.test.ts b/packages/dashboard/src/__tests__/proxy-routes.test.ts index 12c3fd6543..d1f9230a00 100644 --- a/packages/dashboard/src/__tests__/proxy-routes.test.ts +++ b/packages/dashboard/src/__tests__/proxy-routes.test.ts @@ -16,8 +16,10 @@ const mockGetNode = vi.fn(); const mockAgentStoreInit = vi.fn().mockResolvedValue(undefined); const mockAgentStoreGetAgent = vi.fn().mockResolvedValue(null); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, CentralCore: class MockCentralCore { init = mockInit; close = mockClose; diff --git a/packages/dashboard/src/__tests__/routes-agent-budget.test.ts b/packages/dashboard/src/__tests__/routes-agent-budget.test.ts index 8e4c9ca5ea..25ff7e13b6 100644 --- a/packages/dashboard/src/__tests__/routes-agent-budget.test.ts +++ b/packages/dashboard/src/__tests__/routes-agent-budget.test.ts @@ -11,8 +11,10 @@ const mockGetBudgetStatus = vi.fn(); const mockResetBudgetUsage = vi.fn(); const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, AgentStore: class MockAgentStore { init = mockInit; getAgent = mockGetAgent; diff --git a/packages/dashboard/src/__tests__/routes-agent-export.test.ts b/packages/dashboard/src/__tests__/routes-agent-export.test.ts index a103c0c34c..a084cd79d9 100644 --- a/packages/dashboard/src/__tests__/routes-agent-export.test.ts +++ b/packages/dashboard/src/__tests__/routes-agent-export.test.ts @@ -12,8 +12,10 @@ const mockListAgents = vi.fn().mockResolvedValue([]); const mockExportAgentsToDirectory = vi.fn(); const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, AgentStore: class MockAgentStore { init = mockInit; listAgents = mockListAgents; diff --git a/packages/dashboard/src/__tests__/routes-agent-keys.test.ts b/packages/dashboard/src/__tests__/routes-agent-keys.test.ts index 8df5bfd655..50e34fb35d 100644 --- a/packages/dashboard/src/__tests__/routes-agent-keys.test.ts +++ b/packages/dashboard/src/__tests__/routes-agent-keys.test.ts @@ -11,8 +11,10 @@ const mockRevokeApiKey = vi.fn(); const mockListAgents = vi.fn().mockResolvedValue([]); const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, AgentStore: class MockAgentStore { init = mockInit; getAgent = mockGetAgent; diff --git a/packages/dashboard/src/__tests__/routes-agent-permissions.test.ts b/packages/dashboard/src/__tests__/routes-agent-permissions.test.ts index e4cdfef864..1fe177a230 100644 --- a/packages/dashboard/src/__tests__/routes-agent-permissions.test.ts +++ b/packages/dashboard/src/__tests__/routes-agent-permissions.test.ts @@ -97,8 +97,10 @@ const mockIsValidPermission = vi.fn( ); const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, AgentStore: class MockAgentStore { init = mockInit; getAgent = mockGetAgent; diff --git a/packages/dashboard/src/__tests__/routes-agent-prompt-sizes.test.ts b/packages/dashboard/src/__tests__/routes-agent-prompt-sizes.test.ts index a646cf04a9..4f6c9e56ec 100644 --- a/packages/dashboard/src/__tests__/routes-agent-prompt-sizes.test.ts +++ b/packages/dashboard/src/__tests__/routes-agent-prompt-sizes.test.ts @@ -17,7 +17,8 @@ const { mockAll: vi.fn(), })); -vi.mock("@fusion/core", () => ({ +vi.mock("@fusion/core", async (importOriginal) => ({ + ...(await importOriginal()), AgentStore: class MockAgentStore { init = mockInit; getAgent = mockGetAgent; diff --git a/packages/dashboard/src/__tests__/routes-agent-ratings.test.ts b/packages/dashboard/src/__tests__/routes-agent-ratings.test.ts index b507d0f6dd..4f53d3e8ed 100644 --- a/packages/dashboard/src/__tests__/routes-agent-ratings.test.ts +++ b/packages/dashboard/src/__tests__/routes-agent-ratings.test.ts @@ -12,8 +12,10 @@ const mockGetRatingSummary = vi.fn(); const mockDeleteRating = vi.fn(); const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, AgentStore: class MockAgentStore { init = mockInit; addRating = mockAddRating; diff --git a/packages/dashboard/src/__tests__/routes-agent-revisions.test.ts b/packages/dashboard/src/__tests__/routes-agent-revisions.test.ts index def2300741..b2ed8f732d 100644 --- a/packages/dashboard/src/__tests__/routes-agent-revisions.test.ts +++ b/packages/dashboard/src/__tests__/routes-agent-revisions.test.ts @@ -11,8 +11,10 @@ const mockRollbackConfig = vi.fn(); const mockListAgents = vi.fn().mockResolvedValue([]); const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, AgentStore: class MockAgentStore { init = mockInit; getAgent = mockGetAgent; diff --git a/packages/dashboard/src/__tests__/routes-agent-runs.test.ts b/packages/dashboard/src/__tests__/routes-agent-runs.test.ts index 963fa40056..453a14358c 100644 --- a/packages/dashboard/src/__tests__/routes-agent-runs.test.ts +++ b/packages/dashboard/src/__tests__/routes-agent-runs.test.ts @@ -22,8 +22,10 @@ const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); // Mock getRunAuditEvents const mockGetRunAuditEvents = vi.fn().mockReturnValue([]); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, AgentStore: class MockAgentStore { init = mockInit; startHeartbeatRun = mockStartHeartbeatRun; diff --git a/packages/dashboard/src/__tests__/routes-agent-skills.test.ts b/packages/dashboard/src/__tests__/routes-agent-skills.test.ts index b441b5036b..bf94574b5c 100644 --- a/packages/dashboard/src/__tests__/routes-agent-skills.test.ts +++ b/packages/dashboard/src/__tests__/routes-agent-skills.test.ts @@ -34,8 +34,10 @@ class MockAgentCompaniesParseError extends Error { } } -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, AgentStore: class MockAgentStore { init = mockInit; createAgent = mockCreateAgent; diff --git a/packages/dashboard/src/__tests__/routes-agent-token-usage.test.ts b/packages/dashboard/src/__tests__/routes-agent-token-usage.test.ts index 993cd32e03..0bad209605 100644 --- a/packages/dashboard/src/__tests__/routes-agent-token-usage.test.ts +++ b/packages/dashboard/src/__tests__/routes-agent-token-usage.test.ts @@ -17,7 +17,8 @@ const { mockChatStoreInit: vi.fn().mockResolvedValue(undefined), })); -vi.mock("@fusion/core", () => ({ +vi.mock("@fusion/core", async (importOriginal) => ({ + ...(await importOriginal()), AgentStore: class MockAgentStore { init = mockInit; getAgent = mockGetAgent; diff --git a/packages/dashboard/src/__tests__/routes-approval-secrets.test.ts b/packages/dashboard/src/__tests__/routes-approval-secrets.test.ts index 26f6cdd5ce..34c91b605b 100644 --- a/packages/dashboard/src/__tests__/routes-approval-secrets.test.ts +++ b/packages/dashboard/src/__tests__/routes-approval-secrets.test.ts @@ -35,7 +35,8 @@ class MockApprovalRequestStore { } } -vi.mock("@fusion/core", () => ({ ApprovalRequestStore: MockApprovalRequestStore, AgentStore: class { async init() {} async getAgent() { return null; } } })); +vi.mock("@fusion/core", async (importOriginal) => ({ + ...(await importOriginal()), ApprovalRequestStore: MockApprovalRequestStore, AgentStore: class { async init() {} async getAgent() { return null; } } })); vi.mock("@fusion/engine", () => ({ executeApprovedAgentProvisioning: vi.fn(), executeApprovedWorktrunkInstall: vi.fn(), diff --git a/packages/dashboard/src/__tests__/routes-approval.test.ts b/packages/dashboard/src/__tests__/routes-approval.test.ts index 74de7fab38..c6e9b386d3 100644 --- a/packages/dashboard/src/__tests__/routes-approval.test.ts +++ b/packages/dashboard/src/__tests__/routes-approval.test.ts @@ -77,7 +77,8 @@ const executeApprovedAgentProvisioning = vi.fn(async (request: any) => { throw new Error(`Unsupported provisioning tool: ${tool}`); }); -vi.mock("@fusion/core", () => ({ +vi.mock("@fusion/core", async (importOriginal) => ({ + ...(await importOriginal()), ApprovalRequestStore: MockApprovalRequestStore, AgentStore: MockAgentStore, })); diff --git a/packages/dashboard/src/__tests__/routes-nodes-sync-contract.test.ts b/packages/dashboard/src/__tests__/routes-nodes-sync-contract.test.ts index f5f68fb3dc..ec25b3616e 100644 --- a/packages/dashboard/src/__tests__/routes-nodes-sync-contract.test.ts +++ b/packages/dashboard/src/__tests__/routes-nodes-sync-contract.test.ts @@ -34,8 +34,10 @@ const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); const mockAgentStoreInit = vi.fn().mockResolvedValue(undefined); const mockAgentStoreGetAgent = vi.fn().mockResolvedValue(null); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, CentralCore: class MockCentralCore { init = mockInit; close = mockClose; diff --git a/packages/dashboard/src/__tests__/routes-nodes-sync.test.ts b/packages/dashboard/src/__tests__/routes-nodes-sync.test.ts index 2bcdf15869..df3065a83e 100644 --- a/packages/dashboard/src/__tests__/routes-nodes-sync.test.ts +++ b/packages/dashboard/src/__tests__/routes-nodes-sync.test.ts @@ -39,8 +39,10 @@ const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); const mockAgentStoreInit = vi.fn().mockResolvedValue(undefined); const mockAgentStoreGetAgent = vi.fn().mockResolvedValue(null); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, CentralCore: class MockCentralCore { init = mockInit; close = mockClose; diff --git a/packages/dashboard/src/__tests__/routes-nodes.test.ts b/packages/dashboard/src/__tests__/routes-nodes.test.ts index cdde3d2972..cac01c30ce 100644 --- a/packages/dashboard/src/__tests__/routes-nodes.test.ts +++ b/packages/dashboard/src/__tests__/routes-nodes.test.ts @@ -21,8 +21,10 @@ const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); const mockAgentStoreInit = vi.fn().mockResolvedValue(undefined); const mockAgentStoreGetAgent = vi.fn().mockResolvedValue(null); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, CentralCore: class MockCentralCore { init = mockInit; close = mockClose; diff --git a/packages/dashboard/src/__tests__/routes-org-chart.test.ts b/packages/dashboard/src/__tests__/routes-org-chart.test.ts index 07a92646f5..74635ed11c 100644 --- a/packages/dashboard/src/__tests__/routes-org-chart.test.ts +++ b/packages/dashboard/src/__tests__/routes-org-chart.test.ts @@ -11,8 +11,10 @@ const mockResolveAgent = vi.fn(); const mockListAgents = vi.fn().mockResolvedValue([]); const mockChatStoreInit = vi.fn().mockResolvedValue(undefined); -vi.mock("@fusion/core", () => { +vi.mock("@fusion/core", async (importOriginal) => { + const __actual = await importOriginal(); return { + ...__actual, AgentStore: class MockAgentStore { init = mockInit; getAgent = mockGetAgent; diff --git a/packages/dashboard/src/__tests__/routes-run-audit-goal-events.test.ts b/packages/dashboard/src/__tests__/routes-run-audit-goal-events.test.ts index adbc89da08..6fd936d166 100644 --- a/packages/dashboard/src/__tests__/routes-run-audit-goal-events.test.ts +++ b/packages/dashboard/src/__tests__/routes-run-audit-goal-events.test.ts @@ -4,7 +4,8 @@ import { request } from "../test-request.js"; const mockGetRunDetail = vi.fn(); const mockGetRunAuditEvents = vi.fn(); -vi.mock("@fusion/core", () => ({ +vi.mock("@fusion/core", async (importOriginal) => ({ + ...(await importOriginal()), AgentStore: class MockAgentStore { init = vi.fn().mockResolvedValue(undefined); getRunDetail = mockGetRunDetail; diff --git a/packages/dashboard/src/__tests__/routes-sandbox-audit.test.ts b/packages/dashboard/src/__tests__/routes-sandbox-audit.test.ts index 789103d091..6cd37b2c77 100644 --- a/packages/dashboard/src/__tests__/routes-sandbox-audit.test.ts +++ b/packages/dashboard/src/__tests__/routes-sandbox-audit.test.ts @@ -4,7 +4,8 @@ import { request } from "../test-request.js"; const mockGetRunDetail = vi.fn(); const mockGetRunAuditEvents = vi.fn(); -vi.mock("@fusion/core", () => ({ +vi.mock("@fusion/core", async (importOriginal) => ({ + ...(await importOriginal()), AgentStore: class MockAgentStore { init = vi.fn().mockResolvedValue(undefined); getRunDetail = mockGetRunDetail; diff --git a/packages/dashboard/src/__tests__/usage.test.ts b/packages/dashboard/src/__tests__/usage.test.ts index 7ac4f6e4dc..fd7e5e285b 100644 --- a/packages/dashboard/src/__tests__/usage.test.ts +++ b/packages/dashboard/src/__tests__/usage.test.ts @@ -5,7 +5,8 @@ const coreInteropMocks = vi.hoisted(() => ({ readStoredCredentialsFromAuthFile: vi.fn(), })); -vi.mock("@fusion/core", () => ({ +vi.mock("@fusion/core", async (importOriginal) => ({ + ...(await importOriginal()), choosePreferredStoredCredential: coreInteropMocks.choosePreferredStoredCredential, readStoredCredentialsFromAuthFile: coreInteropMocks.readStoredCredentialsFromAuthFile, })); diff --git a/packages/dashboard/src/routes/__tests__/register-docker-provisioning-routes.test.ts b/packages/dashboard/src/routes/__tests__/register-docker-provisioning-routes.test.ts index 26acd616dc..b002e4f9f6 100644 --- a/packages/dashboard/src/routes/__tests__/register-docker-provisioning-routes.test.ts +++ b/packages/dashboard/src/routes/__tests__/register-docker-provisioning-routes.test.ts @@ -24,7 +24,8 @@ const dockerClientServiceMock = { getContainerInfo: vi.fn(), }; -vi.mock("@fusion/core", () => ({ +vi.mock("@fusion/core", async (importOriginal) => ({ + ...(await importOriginal()), DockerProvisioningService: vi.fn().mockImplementation(() => ({ provision: provisionMock, deprovision: deprovisionMock,