targetprocess-mcp-server 2.2.3 → 2.2.5
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 +6 -1
- package/build/config.js +3 -0
- package/build/index.js +98 -49
- package/build/tp.js +101 -59
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,6 +46,7 @@ Features
|
|
|
46
46
|
- `get_not_covered_user_stories_in_feature` — Get user stories in a feature not yet covered by tests, includes `covered` field based on "Test Automation" custom field (id)
|
|
47
47
|
|
|
48
48
|
Cards — Read
|
|
49
|
+
- `get_card_current_status` — Get EntityState, TeamState, and assigned teams for a card (id, optional resourceType: UserStory | Bug | Feature, default: UserStory)
|
|
49
50
|
- `get_bug_content` — Fetch full content of a bug by ID (id)
|
|
50
51
|
- `get_user_story_content` — Fetch full content of a user story by ID (id)
|
|
51
52
|
- `get_bug_comments` — Get comments on a bug (id, optional results)
|
|
@@ -55,7 +56,7 @@ Cards — Read
|
|
|
55
56
|
|
|
56
57
|
Cards — Write
|
|
57
58
|
- `add_comment` — Post a comment to any card (id, comment)
|
|
58
|
-
- `create_bug` — Create a standalone bug (title, bugContent, optional origin, optional projectId, optional teamId)
|
|
59
|
+
- `create_bug` — Create a standalone bug (title, bugContent, optional origin, optional projectId, optional teamId, optional entityStateId)
|
|
59
60
|
> `origin` accepted values: `Production - Customer`, `Production - Internal`, `Pre-Release - Customer`, `Pre-Release - Internal`, `Regression - Dev01`, `Regression - Team Env`, `Manual QA` *(default)*, `Developer Raised`, `Operations`
|
|
60
61
|
> [!NOTE]
|
|
61
62
|
> `projectId` and `teamId` are optional — fall back to `TP_PROJECT_ID` and `TP_TEAM_ID` from config
|
|
@@ -76,6 +77,10 @@ Test Case Workflows
|
|
|
76
77
|
- `write_test_cases` — Fetch a card (UserStory, Bug, or Feature) by ID and trigger the full test case writing workflow: Claude analyzes the card, generates detailed test cases covering happy path, edge cases, and error scenarios, creates a linked test plan via `create_test_plan`, then calls `add_test_cases_to_test_plan`. Each test case description contains Preconditions and Test Type as HTML; steps are passed as a structured array (resourceId, optional resourceType)
|
|
77
78
|
- `add_test_cases_to_test_plan` — Add pre-generated test cases to an existing test plan. Each test case has a `name`, an HTML `description` (Preconditions and Test Type only), and a `steps` array of `{ description, result }` objects — steps are created via the TP test step API rather than embedded in the description (testPlanId, testCases array of {name, description, steps})
|
|
78
79
|
|
|
80
|
+
Processes
|
|
81
|
+
- `get_processes` — Get all Targetprocess processes (no params needed)
|
|
82
|
+
- `get_process_workflows` — Get workflows for a specific process (processId)
|
|
83
|
+
|
|
79
84
|
Projects
|
|
80
85
|
- `get_projects` — Get all Targetprocess projects (no params needed)
|
|
81
86
|
|
package/build/config.js
CHANGED
|
@@ -6,5 +6,8 @@ export const config = {
|
|
|
6
6
|
ownerId: process.env.TP_OWNER_ID || "1504",
|
|
7
7
|
projectId: process.env.TP_PROJECT_ID || "",
|
|
8
8
|
teamId: process.env.TP_TEAM_ID || "",
|
|
9
|
+
processId: process.env.TP_PROCESS_ID || "",
|
|
10
|
+
userStoryWorkflowId: process.env.TP_USER_STORY_WORKFLOW_ID || "",
|
|
11
|
+
bugWorkflowId: process.env.TP_BUG_WORKFLOW_ID || "",
|
|
9
12
|
}
|
|
10
13
|
};
|
package/build/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { z } from "zod";
|
|
|
4
4
|
import { JSDOM } from "jsdom";
|
|
5
5
|
import { TpClient } from "./tp.js";
|
|
6
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
|
+
import { config } from "./config.js";
|
|
7
8
|
const server = new McpServer({
|
|
8
9
|
name: "tp",
|
|
9
10
|
version: "1.0.0"
|
|
@@ -374,6 +375,7 @@ server.registerTool('search_tp_cards', {
|
|
|
374
375
|
title: item.Name,
|
|
375
376
|
id: item.Id,
|
|
376
377
|
description: descriptionText,
|
|
378
|
+
url: `${config.tp.url}/entity/${item.Id}`,
|
|
377
379
|
};
|
|
378
380
|
});
|
|
379
381
|
return {
|
|
@@ -598,11 +600,13 @@ server.registerTool('create_bug_based_on_card', {
|
|
|
598
600
|
title: 'Create a new bug card based on provided card id',
|
|
599
601
|
description: `Create a new bug card based on provided card id that summarizes the problem in concise, descriptive manner answering questions What? Where? When?, and content explaining what happened in detail.
|
|
600
602
|
NOTE: this tool requires a user story or bug card as a reference (i.e. card ID).
|
|
601
|
-
CRITICAL WORKFLOW: Before calling this tool, you MUST follow these steps:
|
|
603
|
+
CRITICAL WORKFLOW: Before calling this tool, you MUST follow these steps:
|
|
602
604
|
1) IF you already have user story or bug card content, proceed to step 3 skipping step 2;
|
|
603
605
|
2) ELSE call "get_user_story_content" tool or "get_bug_content" tool to get user story or bug card content;
|
|
604
606
|
3) format the new bug inside html <div> tags with Issue Description, Steps to Reproduce, Expected Behavior, Actual Behavior sections (note: section titles should be wrapped in <h3> tags, e.g. <h3>Issue Description</h3>);
|
|
605
|
-
4)
|
|
607
|
+
4) IF the user specified a team by name (not ID), call "get_teams" to find the matching team and use its ID as teamId;
|
|
608
|
+
5) IF the user specified a project by name (not ID), call "get_projects" to find the matching project and use its ID as projectId;
|
|
609
|
+
6) add a comment to the card with created bug Id and its Title`,
|
|
606
610
|
inputSchema: {
|
|
607
611
|
title: z.string()
|
|
608
612
|
.describe('Bug card title that summarizes the problem in concise, descriptive, and actionable manner, enabling a developer to understand the issue without opening the report'),
|
|
@@ -635,10 +639,10 @@ server.registerTool('create_bug_based_on_card', {
|
|
|
635
639
|
.describe('Where the bug was found, defaults to "Manual QA"'),
|
|
636
640
|
projectId: z.string()
|
|
637
641
|
.optional()
|
|
638
|
-
.describe('Optional Project ID — defaults to TP_PROJECT_ID from config'),
|
|
642
|
+
.describe('Optional Project ID — if user gave a project name, resolve it via "get_projects" first; defaults to TP_PROJECT_ID from config'),
|
|
639
643
|
teamId: z.string()
|
|
640
644
|
.optional()
|
|
641
|
-
.describe('Optional Team ID — defaults to TP_TEAM_ID from config'),
|
|
645
|
+
.describe('Optional Team ID — if user gave a team name, resolve it via "get_teams" first; defaults to TP_TEAM_ID from config'),
|
|
642
646
|
},
|
|
643
647
|
}, async ({ title, card, bugContent, origin, projectId, teamId }) => {
|
|
644
648
|
const bugResponse = await tp.createBug({ title, card, bugContent, origin, projectId, teamId });
|
|
@@ -662,7 +666,9 @@ server.registerTool('create_bug', {
|
|
|
662
666
|
description: `Create a new bug card that summarizes the problem in concise, descriptive manner answering questions "What? Where? When?" and content explaining what happened in detail.
|
|
663
667
|
NOTE: this tool does not require a user story or bug card reference.
|
|
664
668
|
CRITICAL WORKFLOW: Before calling this tool, you MUST follow these steps:
|
|
665
|
-
1) format the new bug inside html <div> tags with Issue Description, Steps to Reproduce, Expected Behavior, Actual Behavior sections (note: section titles should be wrapped in <h3> tags, e.g. <h3>Issue Description</h3>)
|
|
669
|
+
1) format the new bug inside html <div> tags with Issue Description, Steps to Reproduce, Expected Behavior, Actual Behavior sections (note: section titles should be wrapped in <h3> tags, e.g. <h3>Issue Description</h3>, step to reproduce should be wrapped in <ol>);
|
|
670
|
+
2) IF the user specified a team by name (not ID), call "get_teams" to find the matching team and use its ID as teamId;
|
|
671
|
+
3) IF the user specified a project by name (not ID), call "get_projects" to find the matching project and use its ID as projectId;`,
|
|
666
672
|
inputSchema: {
|
|
667
673
|
title: z.string()
|
|
668
674
|
.describe('Bug card title that summarizes the problem in concise, descriptive, and actionable manner, enabling a developer to understand the issue without opening the report'),
|
|
@@ -684,10 +690,10 @@ server.registerTool('create_bug', {
|
|
|
684
690
|
.describe('Where the bug was found, defaults to "Manual QA"'),
|
|
685
691
|
projectId: z.string()
|
|
686
692
|
.optional()
|
|
687
|
-
.describe('Optional Project ID — defaults to TP_PROJECT_ID from config'),
|
|
693
|
+
.describe('Optional Project ID — if user gave a project name, resolve it via "get_projects" first; defaults to TP_PROJECT_ID from config'),
|
|
688
694
|
teamId: z.string()
|
|
689
695
|
.optional()
|
|
690
|
-
.describe('Optional Team ID — defaults to TP_TEAM_ID from config'),
|
|
696
|
+
.describe('Optional Team ID — if user gave a team name, resolve it via "get_teams" first; defaults to TP_TEAM_ID from config'),
|
|
691
697
|
},
|
|
692
698
|
}, async ({ title, bugContent, origin, projectId, teamId }) => {
|
|
693
699
|
const bugResponse = await tp.createBugOnly({ title, bugContent, origin, projectId, teamId });
|
|
@@ -1238,63 +1244,106 @@ server.registerTool('add_test_cases_to_test_plan', {
|
|
|
1238
1244
|
}]
|
|
1239
1245
|
};
|
|
1240
1246
|
});
|
|
1241
|
-
server.registerTool('
|
|
1242
|
-
title: '
|
|
1243
|
-
description:
|
|
1244
|
-
|
|
1245
|
-
|
|
1247
|
+
server.registerTool('get_process_workflows', {
|
|
1248
|
+
title: 'Get process workflows',
|
|
1249
|
+
description: 'Get all Targetprocess process workflows',
|
|
1250
|
+
inputSchema: {
|
|
1251
|
+
processId: z.string()
|
|
1252
|
+
.describe('Process ID (e.g. 145636)'),
|
|
1253
|
+
},
|
|
1254
|
+
}, async ({ processId }) => {
|
|
1255
|
+
const response = await tp.getProcessWorkflows({ processId });
|
|
1256
|
+
if (!response) {
|
|
1257
|
+
return {
|
|
1258
|
+
content: [{
|
|
1259
|
+
type: 'text',
|
|
1260
|
+
text: `Failed to get process workflows, JSON: ${JSON.stringify(response, null, 2)}`
|
|
1261
|
+
}],
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
const items = response.items || [];
|
|
1265
|
+
if (items.length === 0) {
|
|
1266
|
+
return {
|
|
1267
|
+
content: [{
|
|
1268
|
+
type: 'text',
|
|
1269
|
+
text: `No process workflows found`,
|
|
1270
|
+
}],
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
return {
|
|
1274
|
+
content: [{
|
|
1275
|
+
type: 'text',
|
|
1276
|
+
text: JSON.stringify(items)
|
|
1277
|
+
}],
|
|
1278
|
+
};
|
|
1279
|
+
});
|
|
1280
|
+
server.registerTool('get_processes', {
|
|
1281
|
+
title: 'Get processes',
|
|
1282
|
+
description: 'Get all Targetprocess processes',
|
|
1283
|
+
}, async ({}) => {
|
|
1284
|
+
const response = await tp.getProcesses();
|
|
1285
|
+
if (!response) {
|
|
1286
|
+
return {
|
|
1287
|
+
content: [{
|
|
1288
|
+
type: 'text',
|
|
1289
|
+
text: `Failed to get processes, JSON: ${JSON.stringify(response, null, 2)}`
|
|
1290
|
+
}],
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
const items = response.items || [];
|
|
1294
|
+
if (items.length === 0) {
|
|
1295
|
+
return {
|
|
1296
|
+
content: [{
|
|
1297
|
+
type: 'text',
|
|
1298
|
+
text: `No processes found`,
|
|
1299
|
+
}],
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
return {
|
|
1303
|
+
content: [{
|
|
1304
|
+
type: 'text',
|
|
1305
|
+
text: JSON.stringify(items)
|
|
1306
|
+
}],
|
|
1307
|
+
};
|
|
1308
|
+
});
|
|
1309
|
+
server.registerTool('get_card_current_status', {
|
|
1310
|
+
title: 'Get card status',
|
|
1311
|
+
description: 'Get the EntityState, TeamState, and assigned teams for a TP card (UserStory, Bug, or Feature) by ID',
|
|
1246
1312
|
inputSchema: {
|
|
1247
|
-
|
|
1313
|
+
id: z.string()
|
|
1248
1314
|
.min(5)
|
|
1249
1315
|
.max(6)
|
|
1250
|
-
.describe('TP
|
|
1251
|
-
|
|
1252
|
-
.
|
|
1253
|
-
.describe('Absolute path to a local file (mode 1). Mutually exclusive with fileContent/fileName.'),
|
|
1254
|
-
fileContent: z.string()
|
|
1255
|
-
.optional()
|
|
1256
|
-
.describe('Base64-encoded file content (mode 2). Must be paired with fileName.'),
|
|
1257
|
-
fileName: z.string()
|
|
1316
|
+
.describe('TP card ID (e.g. 146055)'),
|
|
1317
|
+
resourceType: z.enum(['UserStory', 'Bug', 'Feature'])
|
|
1318
|
+
.default('UserStory')
|
|
1258
1319
|
.optional()
|
|
1259
|
-
.describe('
|
|
1320
|
+
.describe('Type of the TP card — UserStory, Bug, or Feature (default: UserStory)'),
|
|
1260
1321
|
},
|
|
1261
|
-
}, async ({
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
return {
|
|
1265
|
-
content: [{
|
|
1266
|
-
type: 'text',
|
|
1267
|
-
text: 'Provide either filePath, or both fileContent and fileName.'
|
|
1268
|
-
}]
|
|
1269
|
-
};
|
|
1270
|
-
}
|
|
1271
|
-
const source = filePath
|
|
1272
|
-
? { filePath }
|
|
1273
|
-
: { fileContent: fileContent, fileName: fileName };
|
|
1274
|
-
const result = await tp.addAttachedFile(generalId, source);
|
|
1275
|
-
if (!result) {
|
|
1276
|
-
return {
|
|
1277
|
-
content: [{
|
|
1278
|
-
type: 'text',
|
|
1279
|
-
text: `Failed to attach file to card id: ${generalId}`
|
|
1280
|
-
}]
|
|
1281
|
-
};
|
|
1282
|
-
}
|
|
1322
|
+
}, async ({ id, resourceType = 'UserStory' }) => {
|
|
1323
|
+
const response = await tp.getCardStatus(id, resourceType);
|
|
1324
|
+
if (!response) {
|
|
1283
1325
|
return {
|
|
1284
1326
|
content: [{
|
|
1285
1327
|
type: 'text',
|
|
1286
|
-
text:
|
|
1287
|
-
}]
|
|
1328
|
+
text: `Failed to get card status for ${resourceType} id: ${id}`
|
|
1329
|
+
}],
|
|
1288
1330
|
};
|
|
1289
1331
|
}
|
|
1290
|
-
|
|
1332
|
+
const items = response.items || [];
|
|
1333
|
+
if (items.length === 0) {
|
|
1291
1334
|
return {
|
|
1292
1335
|
content: [{
|
|
1293
1336
|
type: 'text',
|
|
1294
|
-
text: `
|
|
1295
|
-
}]
|
|
1337
|
+
text: `No status data found for ${resourceType} id: ${id}`,
|
|
1338
|
+
}],
|
|
1296
1339
|
};
|
|
1297
1340
|
}
|
|
1341
|
+
return {
|
|
1342
|
+
content: [{
|
|
1343
|
+
type: 'text',
|
|
1344
|
+
text: JSON.stringify(items[0])
|
|
1345
|
+
}],
|
|
1346
|
+
};
|
|
1298
1347
|
});
|
|
1299
1348
|
async function main() {
|
|
1300
1349
|
const transport = new StdioServerTransport();
|
package/build/tp.js
CHANGED
|
@@ -15,8 +15,8 @@ export class TpClient {
|
|
|
15
15
|
}
|
|
16
16
|
params(params) {
|
|
17
17
|
let _url = this.baseUrl + (params.apiVersion || this.v1);
|
|
18
|
-
for (const
|
|
19
|
-
_url +=
|
|
18
|
+
for (const segment of params.pathParam) {
|
|
19
|
+
_url += `/${segment}`;
|
|
20
20
|
}
|
|
21
21
|
let _urlParams = [];
|
|
22
22
|
for (const [key, value] of Object.entries(params.param)) {
|
|
@@ -83,21 +83,21 @@ export class TpClient {
|
|
|
83
83
|
}
|
|
84
84
|
async getUserStory(userStoryId) {
|
|
85
85
|
const response = await this.get({
|
|
86
|
-
pathParam:
|
|
86
|
+
pathParam: ["userStories", userStoryId],
|
|
87
87
|
param: { "format": "json" },
|
|
88
88
|
});
|
|
89
89
|
return response;
|
|
90
90
|
}
|
|
91
91
|
async getBug(bugId) {
|
|
92
92
|
const response = await this.get({
|
|
93
|
-
pathParam:
|
|
93
|
+
pathParam: ["bugs", bugId],
|
|
94
94
|
param: { "format": "json" }
|
|
95
95
|
});
|
|
96
96
|
return response;
|
|
97
97
|
}
|
|
98
98
|
async getFeature(featureId) {
|
|
99
99
|
const response = await this.get({
|
|
100
|
-
pathParam:
|
|
100
|
+
pathParam: ["features", featureId],
|
|
101
101
|
param: { "format": "json" }
|
|
102
102
|
});
|
|
103
103
|
return response;
|
|
@@ -126,10 +126,34 @@ export class TpClient {
|
|
|
126
126
|
};
|
|
127
127
|
}
|
|
128
128
|
return this.post({
|
|
129
|
-
pathParam:
|
|
129
|
+
pathParam: ["bugs"],
|
|
130
130
|
param: { "format": "json" },
|
|
131
131
|
}, bug);
|
|
132
132
|
}
|
|
133
|
+
async updateUserStory({ title, description, projectId, teamId }) {
|
|
134
|
+
const userStory = {
|
|
135
|
+
"Name": title,
|
|
136
|
+
"Description": description,
|
|
137
|
+
"Project": {
|
|
138
|
+
"Id": projectId || config.tp.projectId
|
|
139
|
+
},
|
|
140
|
+
"assignedTeams": [
|
|
141
|
+
{
|
|
142
|
+
"entityState": {
|
|
143
|
+
"id": 7407
|
|
144
|
+
},
|
|
145
|
+
"id": 84252,
|
|
146
|
+
"team": {
|
|
147
|
+
"id": teamId || config.tp.teamId
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
};
|
|
152
|
+
return this.post({
|
|
153
|
+
pathParam: ["UserStories"],
|
|
154
|
+
param: { "format": "json" },
|
|
155
|
+
}, userStory);
|
|
156
|
+
}
|
|
133
157
|
async createBugOnly({ title, bugContent, origin = "Manual QA", projectId, teamId }) {
|
|
134
158
|
const bug = {
|
|
135
159
|
"Name": title,
|
|
@@ -149,7 +173,7 @@ export class TpClient {
|
|
|
149
173
|
"Description": bugContent,
|
|
150
174
|
};
|
|
151
175
|
return this.post({
|
|
152
|
-
pathParam:
|
|
176
|
+
pathParam: ["bugs"],
|
|
153
177
|
param: { "format": "json" },
|
|
154
178
|
}, bug);
|
|
155
179
|
}
|
|
@@ -166,7 +190,7 @@ export class TpClient {
|
|
|
166
190
|
if (releaseId)
|
|
167
191
|
userStory["Release"] = { "Id": releaseId };
|
|
168
192
|
return this.post({
|
|
169
|
-
pathParam:
|
|
193
|
+
pathParam: ["UserStories"],
|
|
170
194
|
param: { "format": "json" },
|
|
171
195
|
}, userStory);
|
|
172
196
|
}
|
|
@@ -183,7 +207,7 @@ export class TpClient {
|
|
|
183
207
|
if (releaseId)
|
|
184
208
|
feature["Release"] = { "Id": releaseId };
|
|
185
209
|
return this.post({
|
|
186
|
-
pathParam:
|
|
210
|
+
pathParam: ["Features"],
|
|
187
211
|
param: { "format": "json" },
|
|
188
212
|
}, feature);
|
|
189
213
|
}
|
|
@@ -209,7 +233,7 @@ export class TpClient {
|
|
|
209
233
|
"Description": bugContent,
|
|
210
234
|
};
|
|
211
235
|
return this.post({
|
|
212
|
-
pathParam:
|
|
236
|
+
pathParam: ["bugs"],
|
|
213
237
|
param: { "format": "json" },
|
|
214
238
|
}, bug);
|
|
215
239
|
}
|
|
@@ -223,7 +247,7 @@ export class TpClient {
|
|
|
223
247
|
}],
|
|
224
248
|
};
|
|
225
249
|
return this.post({
|
|
226
|
-
pathParam:
|
|
250
|
+
pathParam: ["testCases"],
|
|
227
251
|
param: { "format": "json" },
|
|
228
252
|
}, testCase);
|
|
229
253
|
}
|
|
@@ -260,7 +284,7 @@ export class TpClient {
|
|
|
260
284
|
if (options?.endDate)
|
|
261
285
|
testPlan["EndDate"] = options.endDate;
|
|
262
286
|
return this.post({
|
|
263
|
-
pathParam:
|
|
287
|
+
pathParam: ["testPlans"],
|
|
264
288
|
param: { "format": "json" },
|
|
265
289
|
}, testPlan);
|
|
266
290
|
}
|
|
@@ -275,7 +299,7 @@ export class TpClient {
|
|
|
275
299
|
},
|
|
276
300
|
};
|
|
277
301
|
return this.post({
|
|
278
|
-
pathParam:
|
|
302
|
+
pathParam: ["comments"],
|
|
279
303
|
param: { "format": "json" },
|
|
280
304
|
}, commentData);
|
|
281
305
|
}
|
|
@@ -286,16 +310,13 @@ export class TpClient {
|
|
|
286
310
|
"TestCase": { "Id": testCaseId },
|
|
287
311
|
};
|
|
288
312
|
return this.post({
|
|
289
|
-
pathParam:
|
|
313
|
+
pathParam: ["testSteps"],
|
|
290
314
|
param: { "format": "json" },
|
|
291
315
|
}, testStepData);
|
|
292
316
|
}
|
|
293
317
|
async getBugComments(bugId, results = 25) {
|
|
294
318
|
const response = await this.get({
|
|
295
|
-
pathParam:
|
|
296
|
-
"Bugs": bugId,
|
|
297
|
-
"Comments": "",
|
|
298
|
-
},
|
|
319
|
+
pathParam: ["Bugs", bugId, "Comments"],
|
|
299
320
|
param: {
|
|
300
321
|
"format": "json",
|
|
301
322
|
"take": results,
|
|
@@ -305,10 +326,7 @@ export class TpClient {
|
|
|
305
326
|
}
|
|
306
327
|
async getUserStoryComments(userStoryId, results = 25) {
|
|
307
328
|
const response = await this.get({
|
|
308
|
-
pathParam:
|
|
309
|
-
"UserStories": userStoryId,
|
|
310
|
-
"Comments": "",
|
|
311
|
-
},
|
|
329
|
+
pathParam: ["UserStories", userStoryId, "Comments"],
|
|
312
330
|
param: {
|
|
313
331
|
"format": "json",
|
|
314
332
|
"take": results,
|
|
@@ -318,7 +336,7 @@ export class TpClient {
|
|
|
318
336
|
}
|
|
319
337
|
async searchContainsNameText({ text, entityType }) {
|
|
320
338
|
return this.get({
|
|
321
|
-
pathParam:
|
|
339
|
+
pathParam: [entityType],
|
|
322
340
|
param: {
|
|
323
341
|
"format": "json",
|
|
324
342
|
"take": "25",
|
|
@@ -329,7 +347,7 @@ export class TpClient {
|
|
|
329
347
|
}
|
|
330
348
|
async searchContainsDescriptionText({ text, entityType }) {
|
|
331
349
|
return this.get({
|
|
332
|
-
pathParam:
|
|
350
|
+
pathParam: [entityType],
|
|
333
351
|
param: {
|
|
334
352
|
"where": `Description contains '${text}' and EntityState.Name eq 'Done'`,
|
|
335
353
|
"format": "json",
|
|
@@ -339,7 +357,7 @@ export class TpClient {
|
|
|
339
357
|
}
|
|
340
358
|
async getCurrentReleases() {
|
|
341
359
|
return this.get({
|
|
342
|
-
pathParam:
|
|
360
|
+
pathParam: ["Releases"],
|
|
343
361
|
param: {
|
|
344
362
|
"format": "json",
|
|
345
363
|
"where": `IsCurrent eq 'true'`,
|
|
@@ -349,7 +367,7 @@ export class TpClient {
|
|
|
349
367
|
async getReleaseUserStories({ name, results = 50, withDescription = false }) {
|
|
350
368
|
const includeFilter = withDescription ? "[Name, Description, Id]" : "[Name, Id]";
|
|
351
369
|
return this.get({
|
|
352
|
-
pathParam:
|
|
370
|
+
pathParam: ["UserStories"],
|
|
353
371
|
param: {
|
|
354
372
|
"format": "json",
|
|
355
373
|
"take": results,
|
|
@@ -361,11 +379,11 @@ export class TpClient {
|
|
|
361
379
|
async getReleaseOpenUserStories({ name, results = 100, withDescription = false }) {
|
|
362
380
|
const includeFilter = withDescription ? "[Name, Description, Id]" : "[Name, Id]";
|
|
363
381
|
return this.get({
|
|
364
|
-
pathParam:
|
|
382
|
+
pathParam: ["UserStories"],
|
|
365
383
|
param: {
|
|
366
384
|
"format": "json",
|
|
367
385
|
"take": results,
|
|
368
|
-
"where": `Release.Name eq '${name}' and EntityState.Name ne 'Closed' and EntityState.Name ne 'Done' and EntityState.Name ne 'Passed Dev01
|
|
386
|
+
"where": `Release.Name eq '${name}' and EntityState.Name ne 'Closed' and EntityState.Name ne 'Done' and EntityState.Name ne 'Passed Dev01 QA' and EntityState.Name ne 'Ready to Deploy to prod'`,
|
|
369
387
|
"include": includeFilter,
|
|
370
388
|
}
|
|
371
389
|
});
|
|
@@ -373,11 +391,11 @@ export class TpClient {
|
|
|
373
391
|
async getReleaseOpenBugs({ name, results = 200, withDescription = false }) {
|
|
374
392
|
const includeFilter = withDescription ? "[Name, Description, Id]" : "[Name, Id]";
|
|
375
393
|
return this.get({
|
|
376
|
-
pathParam:
|
|
394
|
+
pathParam: ["Bugs"],
|
|
377
395
|
param: {
|
|
378
396
|
"format": "json",
|
|
379
397
|
"take": results,
|
|
380
|
-
"where": `Release.Name eq '${name}' and EntityState.Name ne 'Closed' and EntityState.Name ne 'Done' and EntityState.Name ne 'Passed Dev01
|
|
398
|
+
"where": `Release.Name eq '${name}' and EntityState.Name ne 'Closed' and EntityState.Name ne 'Done' and EntityState.Name ne 'Passed Dev01 QA' and EntityState.Name ne 'Ready to Deploy to prod'`,
|
|
381
399
|
"include": includeFilter,
|
|
382
400
|
}
|
|
383
401
|
});
|
|
@@ -385,7 +403,7 @@ export class TpClient {
|
|
|
385
403
|
async getReleaseBugs({ name, results = 100, withDescription = false }) {
|
|
386
404
|
const includeFilter = withDescription ? "[Name, Description, Id]" : "[Name, Id]";
|
|
387
405
|
return this.get({
|
|
388
|
-
pathParam:
|
|
406
|
+
pathParam: ["Bugs"],
|
|
389
407
|
param: {
|
|
390
408
|
"format": "json",
|
|
391
409
|
"take": results,
|
|
@@ -397,7 +415,7 @@ export class TpClient {
|
|
|
397
415
|
async getReleaseFeatures({ name, results = 50, withDescription = false }) {
|
|
398
416
|
const includeFilter = withDescription ? "[Name, Description, Id]" : "[Name, Id]";
|
|
399
417
|
return this.get({
|
|
400
|
-
pathParam:
|
|
418
|
+
pathParam: ["Features"],
|
|
401
419
|
param: {
|
|
402
420
|
"format": "json",
|
|
403
421
|
"take": results,
|
|
@@ -408,7 +426,7 @@ export class TpClient {
|
|
|
408
426
|
}
|
|
409
427
|
async getFeatureUserStories(featureId) {
|
|
410
428
|
return this.get({
|
|
411
|
-
pathParam:
|
|
429
|
+
pathParam: ["features"],
|
|
412
430
|
param: {
|
|
413
431
|
"format": "json",
|
|
414
432
|
"where": `(id==${featureId})`,
|
|
@@ -419,7 +437,7 @@ export class TpClient {
|
|
|
419
437
|
}
|
|
420
438
|
async getUserStoriesIdsByFeatureId(featureId) {
|
|
421
439
|
return this.get({
|
|
422
|
-
pathParam:
|
|
440
|
+
pathParam: ["userstories"],
|
|
423
441
|
param: {
|
|
424
442
|
"format": "json",
|
|
425
443
|
"where": `(Feature.Id==${featureId})`,
|
|
@@ -430,7 +448,7 @@ export class TpClient {
|
|
|
430
448
|
}
|
|
431
449
|
async getUserStoryTestPlan(userStoryId) {
|
|
432
450
|
return this.get({
|
|
433
|
-
pathParam:
|
|
451
|
+
pathParam: ["userStories", userStoryId],
|
|
434
452
|
param: {
|
|
435
453
|
"format": "json",
|
|
436
454
|
"select": `{id,storyName:name,linkedtestplan}`,
|
|
@@ -439,18 +457,9 @@ export class TpClient {
|
|
|
439
457
|
});
|
|
440
458
|
}
|
|
441
459
|
async getCardTestPlan(cardId, resourceType = 'UserStory') {
|
|
442
|
-
|
|
443
|
-
if (resourceType === 'UserStory') {
|
|
444
|
-
requestPath = "userStories";
|
|
445
|
-
}
|
|
446
|
-
else if (resourceType === 'Bug') {
|
|
447
|
-
requestPath = "bugs";
|
|
448
|
-
}
|
|
449
|
-
else if (resourceType === 'Feature') {
|
|
450
|
-
requestPath = "features";
|
|
451
|
-
}
|
|
460
|
+
const pathMap = { UserStory: "userStories", Bug: "bugs", Feature: "features" };
|
|
452
461
|
return this.get({
|
|
453
|
-
pathParam:
|
|
462
|
+
pathParam: [pathMap[resourceType], cardId],
|
|
454
463
|
param: {
|
|
455
464
|
"format": "json",
|
|
456
465
|
"select": `{id,linkedtestplan}`,
|
|
@@ -459,38 +468,71 @@ export class TpClient {
|
|
|
459
468
|
}
|
|
460
469
|
async getTestPlanTestCases(testPlanId) {
|
|
461
470
|
return this.get({
|
|
462
|
-
pathParam:
|
|
463
|
-
"testPlans": testPlanId,
|
|
464
|
-
"testcases": "",
|
|
465
|
-
},
|
|
471
|
+
pathParam: ["testPlans", testPlanId, "testcases"],
|
|
466
472
|
param: { "format": "json" },
|
|
467
473
|
});
|
|
468
474
|
}
|
|
469
475
|
async getTestCaseSteps(testCaseId) {
|
|
470
476
|
return this.get({
|
|
471
|
-
pathParam:
|
|
472
|
-
|
|
473
|
-
"teststeps": "",
|
|
474
|
-
},
|
|
475
|
-
param: { "format": "json", },
|
|
477
|
+
pathParam: ["testCases", testCaseId, "teststeps"],
|
|
478
|
+
param: { "format": "json" },
|
|
476
479
|
});
|
|
477
480
|
}
|
|
478
481
|
async getProjects() {
|
|
479
482
|
return this.get({
|
|
480
|
-
pathParam:
|
|
483
|
+
pathParam: ["Projects"],
|
|
484
|
+
param: { "format": "json" },
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
async getProcessWorkflows({ processId }) {
|
|
488
|
+
return this.get({
|
|
489
|
+
pathParam: ["Process"],
|
|
490
|
+
param: {
|
|
491
|
+
"format": "json",
|
|
492
|
+
"where": `id=(${processId})`,
|
|
493
|
+
"select": `{Workflows}`
|
|
494
|
+
},
|
|
495
|
+
apiVersion: this.v2
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
async getUserStories({ take = 100 }) {
|
|
499
|
+
return this.get({
|
|
500
|
+
pathParam: ["userStories"],
|
|
501
|
+
param: {
|
|
502
|
+
"format": "json",
|
|
503
|
+
"take": take,
|
|
504
|
+
},
|
|
505
|
+
apiVersion: this.v2
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
async getProcesses() {
|
|
509
|
+
return this.get({
|
|
510
|
+
pathParam: ["Processes"],
|
|
481
511
|
param: { "format": "json" },
|
|
482
512
|
});
|
|
483
513
|
}
|
|
484
514
|
async getTeams() {
|
|
485
515
|
return this.get({
|
|
486
|
-
pathParam:
|
|
516
|
+
pathParam: ["Teams"],
|
|
487
517
|
param: { "format": "json" },
|
|
488
518
|
});
|
|
489
519
|
}
|
|
520
|
+
async getCardStatus(cardId, resourceType = 'UserStory') {
|
|
521
|
+
const pathMap = { UserStory: 'userStory', Bug: 'bug', Feature: 'feature' };
|
|
522
|
+
return this.get({
|
|
523
|
+
pathParam: [pathMap[resourceType]],
|
|
524
|
+
param: {
|
|
525
|
+
"select": `{Project:{Project.Id},EntityState:{EntityState.Id,EntityState.Name,EntityState.NextStates,EntityState.Workflow.Id as WorkflowId},TeamState:{ResponsibleTeam.Id,Team:{ResponsibleTeam.Team.Id,ResponsibleTeam.Team.Name},EntityState:{ResponsibleTeam.EntityState.Id,ResponsibleTeam.EntityState.Name,ResponsibleTeam.EntityState.Workflow.Id as WorkflowId}},AssignedTeams.Select({TeamAssignmentId:Id,Id:Team.Id,Name:Team.Name}) as Teams}`,
|
|
526
|
+
"where": `(id=${cardId})`,
|
|
527
|
+
"take": "1",
|
|
528
|
+
},
|
|
529
|
+
apiVersion: this.v2
|
|
530
|
+
});
|
|
531
|
+
}
|
|
490
532
|
async getContext() {
|
|
491
533
|
return this.get({
|
|
492
|
-
pathParam:
|
|
493
|
-
param: { "format": "json"
|
|
534
|
+
pathParam: ["Context"],
|
|
535
|
+
param: { "format": "json" }
|
|
494
536
|
});
|
|
495
537
|
}
|
|
496
538
|
async addAttachedFile(generalId, source) {
|