@cliangdev/flux-plugin 0.0.0-dev.cbdf207 → 0.0.0-dev.df3e9bb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/bin/install.cjs +150 -16
- package/package.json +7 -11
- package/src/__tests__/version.test.ts +37 -0
- package/src/adapters/local/.gitkeep +0 -0
- package/src/server/__tests__/config.test.ts +163 -0
- package/src/server/adapters/__tests__/a-client-linear.test.ts +197 -0
- package/src/server/adapters/__tests__/adapter-factory.test.ts +230 -0
- package/src/server/adapters/__tests__/dependency-ops.test.ts +395 -0
- package/src/server/adapters/__tests__/document-ops.test.ts +306 -0
- package/src/server/adapters/__tests__/linear-adapter.test.ts +91 -0
- package/src/server/adapters/__tests__/linear-config.test.ts +425 -0
- package/src/server/adapters/__tests__/linear-criteria-parser.test.ts +287 -0
- package/src/server/adapters/__tests__/linear-description-test.ts +238 -0
- package/src/server/adapters/__tests__/linear-epic-crud.test.ts +496 -0
- package/src/server/adapters/__tests__/linear-mappers-description.test.ts +276 -0
- package/src/server/adapters/__tests__/linear-mappers-epic.test.ts +294 -0
- package/src/server/adapters/__tests__/linear-mappers-prd.test.ts +300 -0
- package/src/server/adapters/__tests__/linear-mappers-task.test.ts +197 -0
- package/src/server/adapters/__tests__/linear-prd-crud.test.ts +620 -0
- package/src/server/adapters/__tests__/linear-stats.test.ts +450 -0
- package/src/server/adapters/__tests__/linear-task-crud.test.ts +534 -0
- package/src/server/adapters/__tests__/linear-types.test.ts +243 -0
- package/src/server/adapters/__tests__/status-ops.test.ts +441 -0
- package/src/server/adapters/factory.ts +90 -0
- package/src/server/adapters/index.ts +9 -0
- package/src/server/adapters/linear/adapter.ts +1136 -0
- package/src/server/adapters/linear/client.ts +169 -0
- package/src/server/adapters/linear/config.ts +152 -0
- package/src/server/adapters/linear/helpers/criteria-parser.ts +197 -0
- package/src/server/adapters/linear/helpers/index.ts +7 -0
- package/src/server/adapters/linear/index.ts +16 -0
- package/src/server/adapters/linear/mappers/description.ts +136 -0
- package/src/server/adapters/linear/mappers/epic.ts +81 -0
- package/src/server/adapters/linear/mappers/index.ts +27 -0
- package/src/server/adapters/linear/mappers/prd.ts +178 -0
- package/src/server/adapters/linear/mappers/task.ts +82 -0
- package/src/server/adapters/linear/types.ts +264 -0
- package/src/server/adapters/local-adapter.ts +968 -0
- package/src/server/adapters/types.ts +293 -0
- package/src/server/config.ts +73 -0
- package/src/server/db/__tests__/queries.test.ts +472 -0
- package/src/server/db/ids.ts +17 -0
- package/src/server/db/index.ts +69 -0
- package/src/server/db/queries.ts +142 -0
- package/src/server/db/refs.ts +60 -0
- package/src/server/db/schema.ts +88 -0
- package/src/server/db/sqlite.ts +10 -0
- package/src/server/index.ts +83 -0
- package/src/server/tools/__tests__/crud.test.ts +301 -0
- package/src/server/tools/__tests__/get-version.test.ts +27 -0
- package/src/server/tools/__tests__/mcp-interface.test.ts +388 -0
- package/src/server/tools/__tests__/query.test.ts +353 -0
- package/src/server/tools/__tests__/z-configure-linear.test.ts +511 -0
- package/src/server/tools/__tests__/z-get-linear-url.test.ts +108 -0
- package/src/server/tools/configure-linear.ts +373 -0
- package/src/server/tools/create-epic.ts +35 -0
- package/src/server/tools/create-prd.ts +31 -0
- package/src/server/tools/create-task.ts +38 -0
- package/src/server/tools/criteria.ts +50 -0
- package/src/server/tools/delete-entity.ts +76 -0
- package/src/server/tools/dependencies.ts +55 -0
- package/src/server/tools/get-entity.ts +238 -0
- package/src/server/tools/get-linear-url.ts +28 -0
- package/src/server/tools/get-project-context.ts +33 -0
- package/src/server/tools/get-stats.ts +52 -0
- package/src/server/tools/get-version.ts +20 -0
- package/src/server/tools/index.ts +114 -0
- package/src/server/tools/init-project.ts +108 -0
- package/src/server/tools/query-entities.ts +167 -0
- package/src/server/tools/render-status.ts +201 -0
- package/src/server/tools/update-entity.ts +140 -0
- package/src/server/tools/update-status.ts +166 -0
- package/src/server/utils/__tests__/mcp-response.test.ts +331 -0
- package/src/server/utils/logger.ts +9 -0
- package/src/server/utils/mcp-response.ts +254 -0
- package/src/server/utils/status-transitions.ts +160 -0
- package/src/status-line/__tests__/status-line.test.ts +215 -0
- package/src/status-line/index.ts +147 -0
- package/src/utils/__tests__/chalk-import.test.ts +32 -0
- package/src/utils/__tests__/display.test.ts +97 -0
- package/src/utils/__tests__/status-renderer.test.ts +310 -0
- package/src/utils/display.ts +62 -0
- package/src/utils/status-renderer.ts +188 -0
- package/src/version.ts +5 -0
- package/dist/server/index.js +0 -87063
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
// Set up test environment BEFORE any imports
|
|
6
|
+
const TEST_DIR = `/tmp/flux-test-mcp-${Date.now()}`;
|
|
7
|
+
const FLUX_DIR = join(TEST_DIR, ".flux");
|
|
8
|
+
process.env.FLUX_PROJECT_ROOT = TEST_DIR;
|
|
9
|
+
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { config } from "../../config.js";
|
|
12
|
+
import { closeDb, initDb } from "../../db/index.js";
|
|
13
|
+
import { createError, registerTools, type ToolDefinition } from "../index.js";
|
|
14
|
+
|
|
15
|
+
describe("MCP Interface", () => {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
config.clearCache();
|
|
18
|
+
process.env.FLUX_PROJECT_ROOT = TEST_DIR;
|
|
19
|
+
|
|
20
|
+
mkdirSync(FLUX_DIR, { recursive: true });
|
|
21
|
+
writeFileSync(
|
|
22
|
+
join(FLUX_DIR, "project.json"),
|
|
23
|
+
JSON.stringify({ name: "test-project", ref_prefix: "TEST" }),
|
|
24
|
+
);
|
|
25
|
+
initDb();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
closeDb();
|
|
30
|
+
config.clearCache();
|
|
31
|
+
if (existsSync(TEST_DIR)) {
|
|
32
|
+
rmSync(TEST_DIR, { recursive: true, force: true });
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe("createError", () => {
|
|
37
|
+
test("creates error object with message and code", () => {
|
|
38
|
+
const error = createError("Test error", "TEST_ERROR");
|
|
39
|
+
expect(error).toEqual({
|
|
40
|
+
error: true,
|
|
41
|
+
message: "Test error",
|
|
42
|
+
code: "TEST_ERROR",
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe("registerTools", () => {
|
|
48
|
+
test("sets up list tools handler", () => {
|
|
49
|
+
const handlers: Record<string, Function> = {};
|
|
50
|
+
const mockServer = {
|
|
51
|
+
setRequestHandler: mock((schema: any, handler: Function) => {
|
|
52
|
+
handlers[schema.method || "unknown"] = handler;
|
|
53
|
+
}),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const testTool: ToolDefinition = {
|
|
57
|
+
name: "test_tool",
|
|
58
|
+
description: "A test tool",
|
|
59
|
+
inputSchema: z.object({ input: z.string() }),
|
|
60
|
+
handler: async () => ({ success: true }),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
registerTools(mockServer as any, [testTool]);
|
|
64
|
+
|
|
65
|
+
// Should have registered two handlers
|
|
66
|
+
expect(mockServer.setRequestHandler).toHaveBeenCalledTimes(2);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test("list tools returns tool definitions with JSON schema", async () => {
|
|
70
|
+
const handlers: Record<string, Function> = {};
|
|
71
|
+
const mockServer = {
|
|
72
|
+
setRequestHandler: mock((schema: any, handler: Function) => {
|
|
73
|
+
// Store handler by a key we can identify
|
|
74
|
+
if (schema.shape?.method?.value === "tools/list") {
|
|
75
|
+
handlers.list = handler;
|
|
76
|
+
} else if (schema.shape?.method?.value === "tools/call") {
|
|
77
|
+
handlers.call = handler;
|
|
78
|
+
}
|
|
79
|
+
}),
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const testTool: ToolDefinition = {
|
|
83
|
+
name: "test_tool",
|
|
84
|
+
description: "A test tool",
|
|
85
|
+
inputSchema: z.object({
|
|
86
|
+
input: z.string(),
|
|
87
|
+
optional: z.number().optional(),
|
|
88
|
+
}),
|
|
89
|
+
handler: async () => ({ success: true }),
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
registerTools(mockServer as any, [testTool]);
|
|
93
|
+
|
|
94
|
+
// Call the list handler
|
|
95
|
+
const listHandler = handlers.list;
|
|
96
|
+
expect(listHandler).toBeDefined();
|
|
97
|
+
|
|
98
|
+
const result = await listHandler();
|
|
99
|
+
expect(result.tools).toBeDefined();
|
|
100
|
+
expect(result.tools.length).toBe(1);
|
|
101
|
+
expect(result.tools[0].name).toBe("test_tool");
|
|
102
|
+
expect(result.tools[0].description).toBe("A test tool");
|
|
103
|
+
expect(result.tools[0].inputSchema).toBeDefined();
|
|
104
|
+
// JSON schema should have properties
|
|
105
|
+
expect(result.tools[0].inputSchema.type).toBe("object");
|
|
106
|
+
expect(result.tools[0].inputSchema.properties).toBeDefined();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("call tool executes handler with arguments", async () => {
|
|
110
|
+
const handlers: Record<string, Function> = {};
|
|
111
|
+
const mockServer = {
|
|
112
|
+
setRequestHandler: mock((schema: any, handler: Function) => {
|
|
113
|
+
if (schema.shape?.method?.value === "tools/list") {
|
|
114
|
+
handlers.list = handler;
|
|
115
|
+
} else if (schema.shape?.method?.value === "tools/call") {
|
|
116
|
+
handlers.call = handler;
|
|
117
|
+
}
|
|
118
|
+
}),
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const handlerMock = mock(async (input: any) => ({
|
|
122
|
+
received: input.input,
|
|
123
|
+
}));
|
|
124
|
+
|
|
125
|
+
const testTool: ToolDefinition = {
|
|
126
|
+
name: "test_tool",
|
|
127
|
+
description: "A test tool",
|
|
128
|
+
inputSchema: z.object({ input: z.string() }),
|
|
129
|
+
handler: handlerMock,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
registerTools(mockServer as any, [testTool]);
|
|
133
|
+
|
|
134
|
+
const callHandler = handlers.call;
|
|
135
|
+
expect(callHandler).toBeDefined();
|
|
136
|
+
|
|
137
|
+
const result = await callHandler({
|
|
138
|
+
params: {
|
|
139
|
+
name: "test_tool",
|
|
140
|
+
arguments: { input: "hello" },
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
expect(handlerMock).toHaveBeenCalledWith({ input: "hello" });
|
|
145
|
+
expect(result.content).toBeDefined();
|
|
146
|
+
expect(result.content[0].type).toBe("text");
|
|
147
|
+
const parsedResult = JSON.parse(result.content[0].text);
|
|
148
|
+
expect(parsedResult.received).toBe("hello");
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test("call unknown tool returns error", async () => {
|
|
152
|
+
const handlers: Record<string, Function> = {};
|
|
153
|
+
const mockServer = {
|
|
154
|
+
setRequestHandler: mock((schema: any, handler: Function) => {
|
|
155
|
+
if (schema.shape?.method?.value === "tools/list") {
|
|
156
|
+
handlers.list = handler;
|
|
157
|
+
} else if (schema.shape?.method?.value === "tools/call") {
|
|
158
|
+
handlers.call = handler;
|
|
159
|
+
}
|
|
160
|
+
}),
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
registerTools(mockServer as any, []);
|
|
164
|
+
|
|
165
|
+
const callHandler = handlers.call;
|
|
166
|
+
const result = await callHandler({
|
|
167
|
+
params: {
|
|
168
|
+
name: "nonexistent_tool",
|
|
169
|
+
arguments: {},
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
expect(result.isError).toBe(true);
|
|
174
|
+
const parsedError = JSON.parse(result.content[0].text);
|
|
175
|
+
expect(parsedError.error).toBe(true);
|
|
176
|
+
expect(parsedError.code).toBe("UNKNOWN_TOOL");
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test("call tool with handler error returns error response", async () => {
|
|
180
|
+
const handlers: Record<string, Function> = {};
|
|
181
|
+
const mockServer = {
|
|
182
|
+
setRequestHandler: mock((schema: any, handler: Function) => {
|
|
183
|
+
if (schema.shape?.method?.value === "tools/list") {
|
|
184
|
+
handlers.list = handler;
|
|
185
|
+
} else if (schema.shape?.method?.value === "tools/call") {
|
|
186
|
+
handlers.call = handler;
|
|
187
|
+
}
|
|
188
|
+
}),
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const testTool: ToolDefinition = {
|
|
192
|
+
name: "failing_tool",
|
|
193
|
+
description: "A tool that fails",
|
|
194
|
+
inputSchema: z.object({}),
|
|
195
|
+
handler: async () => {
|
|
196
|
+
throw new Error("Something went wrong");
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
registerTools(mockServer as any, [testTool]);
|
|
201
|
+
|
|
202
|
+
const callHandler = handlers.call;
|
|
203
|
+
const result = await callHandler({
|
|
204
|
+
params: {
|
|
205
|
+
name: "failing_tool",
|
|
206
|
+
arguments: {},
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
expect(result.isError).toBe(true);
|
|
211
|
+
const parsedError = JSON.parse(result.content[0].text);
|
|
212
|
+
expect(parsedError.error).toBe(true);
|
|
213
|
+
expect(parsedError.code).toBe("TOOL_ERROR");
|
|
214
|
+
expect(parsedError.message).toBe("Something went wrong");
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
test("call tool with non-Error throw returns string error", async () => {
|
|
218
|
+
const handlers: Record<string, Function> = {};
|
|
219
|
+
const mockServer = {
|
|
220
|
+
setRequestHandler: mock((schema: any, handler: Function) => {
|
|
221
|
+
if (schema.shape?.method?.value === "tools/list") {
|
|
222
|
+
handlers.list = handler;
|
|
223
|
+
} else if (schema.shape?.method?.value === "tools/call") {
|
|
224
|
+
handlers.call = handler;
|
|
225
|
+
}
|
|
226
|
+
}),
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const testTool: ToolDefinition = {
|
|
230
|
+
name: "string_throw_tool",
|
|
231
|
+
description: "A tool that throws a string",
|
|
232
|
+
inputSchema: z.object({}),
|
|
233
|
+
handler: async () => {
|
|
234
|
+
throw "String error message";
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
registerTools(mockServer as any, [testTool]);
|
|
239
|
+
|
|
240
|
+
const callHandler = handlers.call;
|
|
241
|
+
const result = await callHandler({
|
|
242
|
+
params: {
|
|
243
|
+
name: "string_throw_tool",
|
|
244
|
+
arguments: {},
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
expect(result.isError).toBe(true);
|
|
249
|
+
const parsedError = JSON.parse(result.content[0].text);
|
|
250
|
+
expect(parsedError.message).toBe("String error message");
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe("Tool JSON Schema Generation", () => {
|
|
256
|
+
test("generates correct JSON schema for complex input", () => {
|
|
257
|
+
const complexSchema = z.object({
|
|
258
|
+
required_string: z.string().min(1),
|
|
259
|
+
optional_number: z.number().optional(),
|
|
260
|
+
enum_field: z.enum(["A", "B", "C"]),
|
|
261
|
+
array_field: z.array(z.string()).optional(),
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const jsonSchema = z.toJSONSchema(complexSchema);
|
|
265
|
+
|
|
266
|
+
expect(jsonSchema.type).toBe("object");
|
|
267
|
+
expect(jsonSchema.properties).toBeDefined();
|
|
268
|
+
expect(jsonSchema.required).toContain("required_string");
|
|
269
|
+
expect(jsonSchema.required).toContain("enum_field");
|
|
270
|
+
expect(jsonSchema.required).not.toContain("optional_number");
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
describe("Project Validation", () => {
|
|
275
|
+
const NO_PROJECT_DIR = `/tmp/flux-test-no-project-${Date.now()}`;
|
|
276
|
+
|
|
277
|
+
beforeEach(() => {
|
|
278
|
+
config.clearCache();
|
|
279
|
+
process.env.FLUX_PROJECT_ROOT = NO_PROJECT_DIR;
|
|
280
|
+
mkdirSync(NO_PROJECT_DIR, { recursive: true });
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
afterEach(() => {
|
|
284
|
+
config.clearCache();
|
|
285
|
+
if (existsSync(NO_PROJECT_DIR)) {
|
|
286
|
+
rmSync(NO_PROJECT_DIR, { recursive: true, force: true });
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
test("returns PROJECT_NOT_FOUND for tools requiring project", async () => {
|
|
291
|
+
const handlers: Record<string, Function> = {};
|
|
292
|
+
const mockServer = {
|
|
293
|
+
setRequestHandler: mock((schema: any, handler: Function) => {
|
|
294
|
+
if (schema.shape?.method?.value === "tools/call") {
|
|
295
|
+
handlers.call = handler;
|
|
296
|
+
}
|
|
297
|
+
}),
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const testTool: ToolDefinition = {
|
|
301
|
+
name: "create_prd",
|
|
302
|
+
description: "Creates a PRD",
|
|
303
|
+
inputSchema: z.object({ title: z.string() }),
|
|
304
|
+
handler: async () => ({ success: true }),
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
registerTools(mockServer as any, [testTool]);
|
|
308
|
+
|
|
309
|
+
const callHandler = handlers.call;
|
|
310
|
+
const result = await callHandler({
|
|
311
|
+
params: {
|
|
312
|
+
name: "create_prd",
|
|
313
|
+
arguments: { title: "Test" },
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
expect(result.isError).toBe(true);
|
|
318
|
+
const parsedError = JSON.parse(result.content[0].text);
|
|
319
|
+
expect(parsedError.error).toBe(true);
|
|
320
|
+
expect(parsedError.code).toBe("PROJECT_NOT_FOUND");
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
test("allows init_project without existing project", async () => {
|
|
324
|
+
const handlers: Record<string, Function> = {};
|
|
325
|
+
const mockServer = {
|
|
326
|
+
setRequestHandler: mock((schema: any, handler: Function) => {
|
|
327
|
+
if (schema.shape?.method?.value === "tools/call") {
|
|
328
|
+
handlers.call = handler;
|
|
329
|
+
}
|
|
330
|
+
}),
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const handlerMock = mock(async () => ({ success: true }));
|
|
334
|
+
|
|
335
|
+
const testTool: ToolDefinition = {
|
|
336
|
+
name: "init_project",
|
|
337
|
+
description: "Initialize project",
|
|
338
|
+
inputSchema: z.object({ name: z.string() }),
|
|
339
|
+
handler: handlerMock,
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
registerTools(mockServer as any, [testTool]);
|
|
343
|
+
|
|
344
|
+
const callHandler = handlers.call;
|
|
345
|
+
const result = await callHandler({
|
|
346
|
+
params: {
|
|
347
|
+
name: "init_project",
|
|
348
|
+
arguments: { name: "test" },
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
expect(result.isError).toBeUndefined();
|
|
353
|
+
expect(handlerMock).toHaveBeenCalled();
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
test("allows get_project_context without existing project", async () => {
|
|
357
|
+
const handlers: Record<string, Function> = {};
|
|
358
|
+
const mockServer = {
|
|
359
|
+
setRequestHandler: mock((schema: any, handler: Function) => {
|
|
360
|
+
if (schema.shape?.method?.value === "tools/call") {
|
|
361
|
+
handlers.call = handler;
|
|
362
|
+
}
|
|
363
|
+
}),
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
const handlerMock = mock(async () => ({ initialized: false }));
|
|
367
|
+
|
|
368
|
+
const testTool: ToolDefinition = {
|
|
369
|
+
name: "get_project_context",
|
|
370
|
+
description: "Get project context",
|
|
371
|
+
inputSchema: z.object({}),
|
|
372
|
+
handler: handlerMock,
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
registerTools(mockServer as any, [testTool]);
|
|
376
|
+
|
|
377
|
+
const callHandler = handlers.call;
|
|
378
|
+
const result = await callHandler({
|
|
379
|
+
params: {
|
|
380
|
+
name: "get_project_context",
|
|
381
|
+
arguments: {},
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
expect(result.isError).toBeUndefined();
|
|
386
|
+
expect(handlerMock).toHaveBeenCalled();
|
|
387
|
+
});
|
|
388
|
+
});
|