Skip to content

Commit 109f596

Browse files
authored
add work tests to improve code coverage (#245)
Improve Work code coverage from; ```sh ----------------|---------|----------|---------|---------|------------------------------------------------------ File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------------|---------|----------|---------|---------|------------------------------------------------------ work.ts | 100 | 75 | 100 | 100 | 39-77,97,145 ----------------|---------|----------|---------|---------|------------------------------------------------------ ``` to ```sh ----------------|---------|----------|---------|---------|------------------------------------------------------ File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------------|---------|----------|---------|---------|------------------------------------------------------ work.ts | 100 | 100 | 100 | 100 | ----------------|---------|----------|---------|---------|------------------------------------------------------ ``` ## GitHub issue number #57 (Don't close the issue, there are other tools to improve test coverages) ## **Associated Risks** None ## ✅ **PR Checklist** - [x] **I have read the [contribution guidelines](https://github.com/microsoft/azure-devops-mcp/blob/main/CONTRIBUTING.md)** - [x] **I have read the [code of conduct guidelines](https://github.com/microsoft/azure-devops-mcp/blob/main/CODE_OF_CONDUCT.md)** - [x] Title of the pull request is clear and informative. - [x] 👌 Code hygiene - [x] 🔭 Telemetry added, updated, or N/A - [x] 📄 Documentation added, updated, or N/A - [x] 🛡️ Automated tests added, or N/A ## 🧪 **How did you test it?** Run `npm run test` in the project root
1 parent 45a0a5a commit 109f596

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

test/src/tools/work.test.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,28 @@ describe("configureWorkTools", () => {
146146
expect(result.isError).toBe(true);
147147
expect(result.content[0].text).toBe("No iterations found");
148148
});
149+
150+
it("should handle unknown error type correctly", async () => {
151+
configureWorkTools(server, tokenProvider, connectionProvider);
152+
153+
const call = (server.tool as jest.Mock).mock.calls.find(([toolName]) => toolName === "work_list_team_iterations");
154+
if (!call) throw new Error("work_list_team_iterations tool not registered");
155+
const [, , , handler] = call;
156+
157+
(mockWorkApi.getTeamIterations as jest.Mock).mockRejectedValue("string error");
158+
159+
const params = {
160+
project: "fabrikam",
161+
team: "Fabrikam Team",
162+
timeframe: undefined,
163+
};
164+
165+
const result = await handler(params);
166+
167+
expect(mockWorkApi.getTeamIterations).toHaveBeenCalled();
168+
expect(result.isError).toBe(true);
169+
expect(result.content[0].text).toContain("Error fetching team iterations: Unknown error occurred");
170+
});
149171
});
150172

151173
describe("assign_iterations", () => {
@@ -268,6 +290,34 @@ describe("configureWorkTools", () => {
268290
expect(result.isError).toBe(true);
269291
expect(result.content[0].text).toBe("No iterations were assigned to the team");
270292
});
293+
294+
it("should handle unknown error type correctly", async () => {
295+
configureWorkTools(server, tokenProvider, connectionProvider);
296+
297+
const call = (server.tool as jest.Mock).mock.calls.find(([toolName]) => toolName === "work_assign_iterations");
298+
299+
if (!call) throw new Error("work_assign_iterations tool not registered");
300+
const [, , , handler] = call;
301+
302+
(mockWorkApi.postTeamIteration as jest.Mock).mockRejectedValue("string error");
303+
304+
const params = {
305+
project: "Fabrikam",
306+
team: "Fabrikam Team",
307+
iterations: [
308+
{
309+
identifier: "a589a806-bf11-4d4f-a031-c19813331553",
310+
path: "Fabrikam-Fiber\\Release 1\\Sprint 2",
311+
},
312+
],
313+
};
314+
315+
const result = await handler(params);
316+
317+
expect(mockWorkApi.postTeamIteration).toHaveBeenCalled();
318+
expect(result.isError).toBe(true);
319+
expect(result.content[0].text).toContain("Error assigning iterations: Unknown error occurred");
320+
});
271321
});
272322

273323
describe("create_iterations", () => {
@@ -405,5 +455,91 @@ describe("configureWorkTools", () => {
405455
expect(result.isError).toBe(true);
406456
expect(result.content[0].text).toBe("No iterations were created");
407457
});
458+
459+
it("should handle unknown error type correctly", async () => {
460+
configureWorkTools(server, tokenProvider, connectionProvider);
461+
462+
const call = (server.tool as jest.Mock).mock.calls.find(([toolName]) => toolName === "work_create_iterations");
463+
464+
if (!call) throw new Error("work_create_iterations tool not registered");
465+
const [, , , handler] = call;
466+
467+
(mockWorkItemTrackingApi.createOrUpdateClassificationNode as jest.Mock).mockRejectedValue("string error");
468+
469+
const params = {
470+
project: "Fabrikam",
471+
iterations: [
472+
{
473+
iterationName: "Sprint 2",
474+
startDate: "2025-06-02T00:00:00Z",
475+
finishDate: "2025-06-13T00:00:00Z",
476+
},
477+
],
478+
};
479+
480+
const result = await handler(params);
481+
482+
expect(mockWorkItemTrackingApi.createOrUpdateClassificationNode).toHaveBeenCalled();
483+
expect(result.isError).toBe(true);
484+
expect(result.content[0].text).toContain("Error creating iterations: Unknown error occurred");
485+
});
486+
487+
it("should handle iterations without start and finish dates", async () => {
488+
configureWorkTools(server, tokenProvider, connectionProvider);
489+
490+
const call = (server.tool as jest.Mock).mock.calls.find(([toolName]) => toolName === "work_create_iterations");
491+
492+
if (!call) throw new Error("work_create_iterations tool not registered");
493+
const [, , , handler] = call;
494+
495+
(mockWorkItemTrackingApi.createOrUpdateClassificationNode as jest.Mock).mockResolvedValue({
496+
id: 126391,
497+
identifier: "a5c68379-3258-4d62-971c-71c1c459336e",
498+
name: "Sprint 3",
499+
structureType: "iteration",
500+
hasChildren: false,
501+
path: "\\fabrikam\\fiber\\tfvc\\iteration",
502+
});
503+
504+
const params = {
505+
project: "Fabrikam",
506+
iterations: [
507+
{
508+
iterationName: "Sprint 3",
509+
},
510+
],
511+
};
512+
513+
const result = await handler(params);
514+
515+
expect(mockWorkItemTrackingApi.createOrUpdateClassificationNode).toHaveBeenCalledWith(
516+
{
517+
name: "Sprint 3",
518+
attributes: {
519+
startDate: undefined,
520+
finishDate: undefined,
521+
},
522+
},
523+
"Fabrikam",
524+
TreeStructureGroup.Iterations
525+
);
526+
527+
expect(result.content[0].text).toBe(
528+
JSON.stringify(
529+
[
530+
{
531+
id: 126391,
532+
identifier: "a5c68379-3258-4d62-971c-71c1c459336e",
533+
name: "Sprint 3",
534+
structureType: "iteration",
535+
hasChildren: false,
536+
path: "\\fabrikam\\fiber\\tfvc\\iteration",
537+
},
538+
],
539+
null,
540+
2
541+
)
542+
);
543+
});
408544
});
409545
});

0 commit comments

Comments
 (0)