Skip to content

Commit 0afd57a

Browse files
Merge pull request #334 from SavioBS629/feat/tm-linear
feat: show linked issue type and id in listTestCases
2 parents 6f3d018 + 0f094a5 commit 0afd57a

2 files changed

Lines changed: 122 additions & 4 deletions

File tree

src/tools/testmanagement-utils/list-testcases.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,15 @@ export async function listTestCases(
8585

8686
// Summary for more focused output
8787
const summary = test_cases
88-
.map(
89-
(tc: any) =>
90-
`• ${tc.identifier}: ${tc.title} [${tc.case_type} | ${tc.priority}]`,
91-
)
88+
.map((tc: any) => {
89+
const links = (tc.issues ?? [])
90+
.filter((i: any) => i?.issue_type && i?.jira_id)
91+
.map((i: any) => `${i.issue_type}:${i.jira_id}`)
92+
.join(", ");
93+
return `• ${tc.identifier}: ${tc.title} [${tc.case_type} | ${tc.priority}]${
94+
links ? ` {linked: ${links}}` : ""
95+
}`;
96+
})
9297
.join("\n");
9398

9499
return {

tests/tools/list-testcases.test.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { describe, it, expect, vi, beforeEach } from "vitest";
2+
3+
vi.mock("../../src/lib/apiClient", () => ({
4+
apiClient: {
5+
get: vi.fn(),
6+
},
7+
}));
8+
9+
vi.mock("../../src/lib/tm-base-url", () => ({
10+
getTMBaseURL: vi
11+
.fn()
12+
.mockResolvedValue("https://test-management.browserstack.com"),
13+
}));
14+
15+
vi.mock("../../src/logger", () => ({
16+
default: { error: vi.fn(), info: vi.fn(), debug: vi.fn() },
17+
}));
18+
19+
import { apiClient } from "../../src/lib/apiClient";
20+
import { listTestCases } from "../../src/tools/testmanagement-utils/list-testcases";
21+
22+
const mockConfig = {
23+
"browserstack-username": "config-user",
24+
"browserstack-access-key": "config-key",
25+
} as any;
26+
27+
describe("listTestCases — linked issues in summary", () => {
28+
beforeEach(() => {
29+
vi.clearAllMocks();
30+
});
31+
32+
it("labels linked issues by tracker type (Linear)", async () => {
33+
(apiClient.get as any).mockResolvedValue({
34+
data: {
35+
success: true,
36+
info: { count: 1 },
37+
test_cases: [
38+
{
39+
identifier: "TC-1",
40+
title: "Login works",
41+
case_type: "Functional",
42+
priority: "Critical",
43+
issues: [{ jira_id: "TES-5", issue_type: "linear" }],
44+
},
45+
],
46+
},
47+
});
48+
49+
const result = await listTestCases(
50+
{ project_identifier: "PR-1", folder_id: "51030419" },
51+
mockConfig,
52+
);
53+
54+
expect(result.isError).toBeFalsy();
55+
expect(result.content?.[0]?.text).toContain(
56+
"• TC-1: Login works [Functional | Critical] {linked: linear:TES-5}",
57+
);
58+
});
59+
60+
it("omits the linked segment when a test case has no issues", async () => {
61+
(apiClient.get as any).mockResolvedValue({
62+
data: {
63+
success: true,
64+
info: { count: 1 },
65+
test_cases: [
66+
{
67+
identifier: "TC-2",
68+
title: "No links",
69+
case_type: "Functional",
70+
priority: "Low",
71+
issues: [],
72+
},
73+
],
74+
},
75+
});
76+
77+
const result = await listTestCases(
78+
{ project_identifier: "PR-1" },
79+
mockConfig,
80+
);
81+
82+
expect(result.content?.[0]?.text).toContain(
83+
"• TC-2: No links [Functional | Low]",
84+
);
85+
expect(result.content?.[0]?.text).not.toContain("{linked:");
86+
});
87+
88+
it("skips malformed issue entries instead of rendering undefined", async () => {
89+
(apiClient.get as any).mockResolvedValue({
90+
data: {
91+
success: true,
92+
info: { count: 1 },
93+
test_cases: [
94+
{
95+
identifier: "TC-3",
96+
title: "Malformed link",
97+
case_type: "Functional",
98+
priority: "Medium",
99+
issues: [{}, { jira_id: "TES-9", issue_type: "linear" }],
100+
},
101+
],
102+
},
103+
});
104+
105+
const result = await listTestCases(
106+
{ project_identifier: "PR-1" },
107+
mockConfig,
108+
);
109+
110+
expect(result.content?.[0]?.text).toContain("{linked: linear:TES-9}");
111+
expect(result.content?.[0]?.text).not.toContain("undefined");
112+
});
113+
});

0 commit comments

Comments
 (0)