@atlassian-dc-mcp/bitbucket 0.12.2 → 0.14.0
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/CHANGELOG.md +23 -0
- package/README.md +45 -2
- package/build/__tests__/bitbucket-service.test.js +106 -17
- package/build/__tests__/bitbucket-service.test.js.map +1 -1
- package/build/__tests__/bitbucket-token-optimization.test.d.ts +2 -0
- package/build/__tests__/bitbucket-token-optimization.test.d.ts.map +1 -0
- package/build/__tests__/bitbucket-token-optimization.test.js +375 -0
- package/build/__tests__/bitbucket-token-optimization.test.js.map +1 -0
- package/build/__tests__/config.test.d.ts +2 -0
- package/build/__tests__/config.test.d.ts.map +1 -0
- package/build/__tests__/config.test.js +49 -0
- package/build/__tests__/config.test.js.map +1 -0
- package/build/__tests__/pr-comment-mapper.test.js +152 -1
- package/build/__tests__/pr-comment-mapper.test.js.map +1 -1
- package/build/bitbucket-response-mapper.d.ts +8 -0
- package/build/bitbucket-response-mapper.d.ts.map +1 -0
- package/build/bitbucket-response-mapper.js +96 -0
- package/build/bitbucket-response-mapper.js.map +1 -0
- package/build/bitbucket-service.d.ts +25 -22
- package/build/bitbucket-service.d.ts.map +1 -1
- package/build/bitbucket-service.js +89 -54
- package/build/bitbucket-service.js.map +1 -1
- package/build/config.d.ts +4 -0
- package/build/config.d.ts.map +1 -0
- package/build/config.js +11 -0
- package/build/config.js.map +1 -0
- package/build/index.js +15 -15
- package/build/index.js.map +1 -1
- package/build/pr-comment-mapper.d.ts +6 -2
- package/build/pr-comment-mapper.d.ts.map +1 -1
- package/build/pr-comment-mapper.js +47 -7
- package/build/pr-comment-mapper.js.map +1 -1
- package/package.json +3 -3
- package/server.json +11 -4
- package/src/__tests__/bitbucket-service.test.ts +109 -17
- package/src/__tests__/bitbucket-token-optimization.test.ts +412 -0
- package/src/__tests__/config.test.ts +64 -0
- package/src/__tests__/pr-comment-mapper.test.ts +160 -0
- package/src/bitbucket-response-mapper.ts +121 -0
- package/src/bitbucket-service.ts +119 -57
- package/src/config.ts +13 -0
- package/src/index.ts +26 -17
- package/src/pr-comment-mapper.ts +66 -7
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -77,6 +77,44 @@ function simplifyComment(comment, ancestorIds = new Set()) {
|
|
|
77
77
|
state: comment.state
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
|
+
function filterComment(comment, includeResolved, ancestorIds = new Set()) {
|
|
81
|
+
if (!includeResolved && comment.threadResolved) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const nextAncestorIds = new Set(ancestorIds);
|
|
85
|
+
nextAncestorIds.add(comment.id);
|
|
86
|
+
const comments = comment.comments
|
|
87
|
+
.filter(isComment)
|
|
88
|
+
.filter(childComment => !nextAncestorIds.has(childComment.id))
|
|
89
|
+
.map(childComment => filterComment(childComment, includeResolved, nextAncestorIds))
|
|
90
|
+
.filter((childComment) => childComment !== null);
|
|
91
|
+
return {
|
|
92
|
+
...comment,
|
|
93
|
+
comments,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export function filterPullRequestComments(response, options = {}) {
|
|
97
|
+
const includeResolved = options.includeResolved ?? false;
|
|
98
|
+
if (includeResolved) {
|
|
99
|
+
return response;
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
...response,
|
|
103
|
+
values: (response.values || []).flatMap(activity => {
|
|
104
|
+
if (!isPRActivity(activity) || activity.action !== 'COMMENTED' || !activity.comment || !isComment(activity.comment)) {
|
|
105
|
+
return [activity];
|
|
106
|
+
}
|
|
107
|
+
const filteredComment = filterComment(activity.comment, includeResolved);
|
|
108
|
+
if (!filteredComment) {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
return [{
|
|
112
|
+
...activity,
|
|
113
|
+
comment: filteredComment,
|
|
114
|
+
}];
|
|
115
|
+
})
|
|
116
|
+
};
|
|
117
|
+
}
|
|
80
118
|
function simplifyActivity(activity) {
|
|
81
119
|
return {
|
|
82
120
|
id: activity.id,
|
|
@@ -89,18 +127,19 @@ function simplifyActivity(activity) {
|
|
|
89
127
|
})
|
|
90
128
|
};
|
|
91
129
|
}
|
|
92
|
-
export function simplifyBitbucketPRComments(response) {
|
|
130
|
+
export function simplifyBitbucketPRComments(response, options = {}) {
|
|
131
|
+
const filteredResponse = filterPullRequestComments(response, options);
|
|
93
132
|
const activities = [];
|
|
94
133
|
// Process each activity with type guard validation
|
|
95
|
-
for (const activity of
|
|
134
|
+
for (const activity of filteredResponse.values || []) {
|
|
96
135
|
if (isPRActivity(activity)) {
|
|
97
136
|
activities.push(simplifyActivity(activity));
|
|
98
137
|
}
|
|
99
138
|
// If type guard fails, we skip the invalid activity but continue processing
|
|
100
139
|
}
|
|
101
140
|
// If no valid activities were found, return the original response
|
|
102
|
-
if (activities.length === 0 && (
|
|
103
|
-
return
|
|
141
|
+
if (activities.length === 0 && (filteredResponse.values || []).length > 0) {
|
|
142
|
+
return filteredResponse;
|
|
104
143
|
}
|
|
105
144
|
// Find PR author (usually the one who OPENED the PR)
|
|
106
145
|
const prAuthor = activities.find(a => a.action === 'OPENED')?.user;
|
|
@@ -108,7 +147,7 @@ export function simplifyBitbucketPRComments(response) {
|
|
|
108
147
|
const comments = activities.filter(a => a.action === 'COMMENTED' && a.comment);
|
|
109
148
|
const unresolvedCount = comments.filter(a => a.comment && !a.comment.threadResolved).length;
|
|
110
149
|
return {
|
|
111
|
-
isLastPage:
|
|
150
|
+
isLastPage: filteredResponse.isLastPage ?? true,
|
|
112
151
|
activities,
|
|
113
152
|
summary: {
|
|
114
153
|
totalActivities: activities.length,
|
|
@@ -118,9 +157,10 @@ export function simplifyBitbucketPRComments(response) {
|
|
|
118
157
|
}
|
|
119
158
|
};
|
|
120
159
|
}
|
|
121
|
-
export function getCommentSummary(response) {
|
|
160
|
+
export function getCommentSummary(response, options = {}) {
|
|
161
|
+
const filteredResponse = filterPullRequestComments(response, options);
|
|
122
162
|
const commentSummaries = [];
|
|
123
|
-
for (const activity of
|
|
163
|
+
for (const activity of filteredResponse.values || []) {
|
|
124
164
|
// Use type guard to validate activity structure
|
|
125
165
|
if (isPRActivity(activity) && activity.action === 'COMMENTED' && activity.comment) {
|
|
126
166
|
// Additional validation for comment structure
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pr-comment-mapper.js","sourceRoot":"","sources":["../src/pr-comment-mapper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pr-comment-mapper.js","sourceRoot":"","sources":["../src/pr-comment-mapper.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlassian-dc-mcp/bitbucket",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"main": "build/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": "./bin/run.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"test": "jest"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@atlassian-dc-mcp/common": "^0.
|
|
17
|
+
"@atlassian-dc-mcp/common": "^0.14.0",
|
|
18
18
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
19
19
|
"dotenv": "^16.4.7",
|
|
20
20
|
"node-fetch": "^3.3.2",
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "cddfcbf3cb1404e69957277fd988c28e08700fae"
|
|
36
36
|
}
|
package/server.json
CHANGED
|
@@ -18,22 +18,29 @@
|
|
|
18
18
|
},
|
|
19
19
|
"environmentVariables": [
|
|
20
20
|
{
|
|
21
|
-
"description": "
|
|
21
|
+
"description": "Absolute path to a shared dotenv-style config file. When set, values are read from this file before direct environment variable overrides are applied.",
|
|
22
|
+
"isRequired": false,
|
|
23
|
+
"format": "string",
|
|
24
|
+
"isSecret": false,
|
|
25
|
+
"name": "ATLASSIAN_DC_MCP_CONFIG_FILE"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"description": "Bitbucket host domain (e.g. your-instance.atlassian.net). Required unless provided through ATLASSIAN_DC_MCP_CONFIG_FILE or BITBUCKET_API_BASE_PATH.",
|
|
22
29
|
"isRequired": false,
|
|
23
30
|
"format": "string",
|
|
24
31
|
"isSecret": false,
|
|
25
32
|
"name": "BITBUCKET_HOST"
|
|
26
33
|
},
|
|
27
34
|
{
|
|
28
|
-
"description": "Bitbucket API base path (alternative to BITBUCKET_HOST)",
|
|
35
|
+
"description": "Bitbucket API base path (alternative to BITBUCKET_HOST). Required unless provided through ATLASSIAN_DC_MCP_CONFIG_FILE or BITBUCKET_HOST.",
|
|
29
36
|
"isRequired": false,
|
|
30
37
|
"format": "string",
|
|
31
38
|
"isSecret": false,
|
|
32
39
|
"name": "BITBUCKET_API_BASE_PATH"
|
|
33
40
|
},
|
|
34
41
|
{
|
|
35
|
-
"description": "Bitbucket Personal Access Token or API token",
|
|
36
|
-
"isRequired":
|
|
42
|
+
"description": "Bitbucket Personal Access Token or API token. Required unless provided through ATLASSIAN_DC_MCP_CONFIG_FILE.",
|
|
43
|
+
"isRequired": false,
|
|
37
44
|
"format": "string",
|
|
38
45
|
"isSecret": true,
|
|
39
46
|
"name": "BITBUCKET_API_TOKEN"
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { initializeRuntimeConfig } from '@atlassian-dc-mcp/common';
|
|
1
5
|
import { BitbucketService } from '../bitbucket-service.js';
|
|
2
6
|
import { PullRequestsService } from '../bitbucket-client/index.js';
|
|
3
7
|
import { request as mockRequest } from '../bitbucket-client/core/request.js';
|
|
@@ -709,7 +713,10 @@ describe('BitbucketService', () => {
|
|
|
709
713
|
);
|
|
710
714
|
|
|
711
715
|
expect(result.success).toBe(true);
|
|
712
|
-
expect(result.data).
|
|
716
|
+
expect(result.data).toEqual({
|
|
717
|
+
id: 12345,
|
|
718
|
+
pending: false,
|
|
719
|
+
});
|
|
713
720
|
expect(PullRequestsService.createComment2).toHaveBeenCalledWith(
|
|
714
721
|
mockProjectKey,
|
|
715
722
|
mockPullRequestId,
|
|
@@ -735,7 +742,10 @@ describe('BitbucketService', () => {
|
|
|
735
742
|
);
|
|
736
743
|
|
|
737
744
|
expect(result.success).toBe(true);
|
|
738
|
-
expect(result.data).
|
|
745
|
+
expect(result.data).toEqual({
|
|
746
|
+
id: 12346,
|
|
747
|
+
pending: false,
|
|
748
|
+
});
|
|
739
749
|
expect(PullRequestsService.createComment2).toHaveBeenCalledWith(
|
|
740
750
|
mockProjectKey,
|
|
741
751
|
mockPullRequestId,
|
|
@@ -765,7 +775,10 @@ describe('BitbucketService', () => {
|
|
|
765
775
|
);
|
|
766
776
|
|
|
767
777
|
expect(result.success).toBe(true);
|
|
768
|
-
expect(result.data).
|
|
778
|
+
expect(result.data).toEqual({
|
|
779
|
+
id: 12347,
|
|
780
|
+
pending: false,
|
|
781
|
+
});
|
|
769
782
|
expect(PullRequestsService.createComment2).toHaveBeenCalledWith(
|
|
770
783
|
mockProjectKey,
|
|
771
784
|
mockPullRequestId,
|
|
@@ -800,7 +813,10 @@ describe('BitbucketService', () => {
|
|
|
800
813
|
);
|
|
801
814
|
|
|
802
815
|
expect(result.success).toBe(true);
|
|
803
|
-
expect(result.data).
|
|
816
|
+
expect(result.data).toEqual({
|
|
817
|
+
id: 12348,
|
|
818
|
+
pending: false,
|
|
819
|
+
});
|
|
804
820
|
expect(PullRequestsService.createComment2).toHaveBeenCalledWith(
|
|
805
821
|
mockProjectKey,
|
|
806
822
|
mockPullRequestId,
|
|
@@ -982,7 +998,15 @@ describe('BitbucketService', () => {
|
|
|
982
998
|
);
|
|
983
999
|
|
|
984
1000
|
expect(result.success).toBe(true);
|
|
985
|
-
expect(result.data).
|
|
1001
|
+
expect(result.data).toEqual({
|
|
1002
|
+
id: 1,
|
|
1003
|
+
version: 0,
|
|
1004
|
+
title: 'Test PR',
|
|
1005
|
+
state: 'OPEN',
|
|
1006
|
+
fromRefId: 'refs/heads/feature-branch',
|
|
1007
|
+
toRefId: 'refs/heads/main',
|
|
1008
|
+
reviewerCount: 0,
|
|
1009
|
+
});
|
|
986
1010
|
expect(PullRequestsService.create).toHaveBeenCalledWith(
|
|
987
1011
|
mockProjectKey,
|
|
988
1012
|
mockRepositorySlug,
|
|
@@ -1040,7 +1064,15 @@ describe('BitbucketService', () => {
|
|
|
1040
1064
|
);
|
|
1041
1065
|
|
|
1042
1066
|
expect(result.success).toBe(true);
|
|
1043
|
-
expect(result.data).
|
|
1067
|
+
expect(result.data).toEqual({
|
|
1068
|
+
id: 2,
|
|
1069
|
+
version: 0,
|
|
1070
|
+
title: 'Test PR without description',
|
|
1071
|
+
state: 'OPEN',
|
|
1072
|
+
fromRefId: 'refs/heads/feature-branch',
|
|
1073
|
+
toRefId: 'refs/heads/main',
|
|
1074
|
+
reviewerCount: 0,
|
|
1075
|
+
});
|
|
1044
1076
|
expect(PullRequestsService.create).toHaveBeenCalledWith(
|
|
1045
1077
|
mockProjectKey,
|
|
1046
1078
|
mockRepositorySlug,
|
|
@@ -1090,7 +1122,15 @@ describe('BitbucketService', () => {
|
|
|
1090
1122
|
);
|
|
1091
1123
|
|
|
1092
1124
|
expect(result.success).toBe(true);
|
|
1093
|
-
expect(result.data).
|
|
1125
|
+
expect(result.data).toEqual({
|
|
1126
|
+
id: 3,
|
|
1127
|
+
version: 0,
|
|
1128
|
+
title: 'Test PR with reviewers',
|
|
1129
|
+
state: 'OPEN',
|
|
1130
|
+
fromRefId: 'refs/heads/feature-branch',
|
|
1131
|
+
toRefId: 'refs/heads/main',
|
|
1132
|
+
reviewerCount: 2,
|
|
1133
|
+
});
|
|
1094
1134
|
expect(PullRequestsService.create).toHaveBeenCalledWith(
|
|
1095
1135
|
mockProjectKey,
|
|
1096
1136
|
mockRepositorySlug,
|
|
@@ -1172,7 +1212,13 @@ describe('BitbucketService', () => {
|
|
|
1172
1212
|
);
|
|
1173
1213
|
|
|
1174
1214
|
expect(result.success).toBe(true);
|
|
1175
|
-
expect(result.data).
|
|
1215
|
+
expect(result.data).toEqual({
|
|
1216
|
+
id: 1,
|
|
1217
|
+
version: 1,
|
|
1218
|
+
title: 'Updated Title',
|
|
1219
|
+
state: 'OPEN',
|
|
1220
|
+
reviewerCount: 0,
|
|
1221
|
+
});
|
|
1176
1222
|
expect(PullRequestsService.update).toHaveBeenCalledWith(
|
|
1177
1223
|
mockProjectKey,
|
|
1178
1224
|
mockPullRequestId,
|
|
@@ -1204,7 +1250,13 @@ describe('BitbucketService', () => {
|
|
|
1204
1250
|
);
|
|
1205
1251
|
|
|
1206
1252
|
expect(result.success).toBe(true);
|
|
1207
|
-
expect(result.data).
|
|
1253
|
+
expect(result.data).toEqual({
|
|
1254
|
+
id: 1,
|
|
1255
|
+
version: 1,
|
|
1256
|
+
title: 'Original Title',
|
|
1257
|
+
state: 'OPEN',
|
|
1258
|
+
reviewerCount: 0,
|
|
1259
|
+
});
|
|
1208
1260
|
expect(PullRequestsService.update).toHaveBeenCalledWith(
|
|
1209
1261
|
mockProjectKey,
|
|
1210
1262
|
mockPullRequestId,
|
|
@@ -1236,7 +1288,13 @@ describe('BitbucketService', () => {
|
|
|
1236
1288
|
);
|
|
1237
1289
|
|
|
1238
1290
|
expect(result.success).toBe(true);
|
|
1239
|
-
expect(result.data).
|
|
1291
|
+
expect(result.data).toEqual({
|
|
1292
|
+
id: 1,
|
|
1293
|
+
version: 1,
|
|
1294
|
+
title: 'Updated Title',
|
|
1295
|
+
state: 'OPEN',
|
|
1296
|
+
reviewerCount: 0,
|
|
1297
|
+
});
|
|
1240
1298
|
expect(PullRequestsService.update).toHaveBeenCalledWith(
|
|
1241
1299
|
mockProjectKey,
|
|
1242
1300
|
mockPullRequestId,
|
|
@@ -1275,7 +1333,13 @@ describe('BitbucketService', () => {
|
|
|
1275
1333
|
);
|
|
1276
1334
|
|
|
1277
1335
|
expect(result.success).toBe(true);
|
|
1278
|
-
expect(result.data).
|
|
1336
|
+
expect(result.data).toEqual({
|
|
1337
|
+
id: 1,
|
|
1338
|
+
version: 1,
|
|
1339
|
+
title: 'Test PR',
|
|
1340
|
+
state: 'OPEN',
|
|
1341
|
+
reviewerCount: 3,
|
|
1342
|
+
});
|
|
1279
1343
|
expect(PullRequestsService.update).toHaveBeenCalledWith(
|
|
1280
1344
|
mockProjectKey,
|
|
1281
1345
|
mockPullRequestId,
|
|
@@ -1316,7 +1380,13 @@ describe('BitbucketService', () => {
|
|
|
1316
1380
|
);
|
|
1317
1381
|
|
|
1318
1382
|
expect(result.success).toBe(true);
|
|
1319
|
-
expect(result.data).
|
|
1383
|
+
expect(result.data).toEqual({
|
|
1384
|
+
id: 1,
|
|
1385
|
+
version: 2,
|
|
1386
|
+
title: 'Updated Title',
|
|
1387
|
+
state: 'OPEN',
|
|
1388
|
+
reviewerCount: 2,
|
|
1389
|
+
});
|
|
1320
1390
|
expect(PullRequestsService.update).toHaveBeenCalledWith(
|
|
1321
1391
|
mockProjectKey,
|
|
1322
1392
|
mockPullRequestId,
|
|
@@ -1351,7 +1421,13 @@ describe('BitbucketService', () => {
|
|
|
1351
1421
|
);
|
|
1352
1422
|
|
|
1353
1423
|
expect(result.success).toBe(true);
|
|
1354
|
-
expect(result.data).
|
|
1424
|
+
expect(result.data).toEqual({
|
|
1425
|
+
id: 1,
|
|
1426
|
+
version: 1,
|
|
1427
|
+
title: 'Original Title',
|
|
1428
|
+
state: 'OPEN',
|
|
1429
|
+
reviewerCount: 0,
|
|
1430
|
+
});
|
|
1355
1431
|
expect(PullRequestsService.update).toHaveBeenCalledWith(
|
|
1356
1432
|
mockProjectKey,
|
|
1357
1433
|
mockPullRequestId,
|
|
@@ -1510,7 +1586,7 @@ describe('BitbucketService', () => {
|
|
|
1510
1586
|
describe('getDashboardPullRequests', () => {
|
|
1511
1587
|
const { request: mockRequest } = require('../bitbucket-client/core/request.js');
|
|
1512
1588
|
|
|
1513
|
-
it('should default to AUTHOR role and
|
|
1589
|
+
it('should default to AUTHOR role and the package page size', async () => {
|
|
1514
1590
|
const mockData = {
|
|
1515
1591
|
values: [
|
|
1516
1592
|
{ id: 1, title: 'PR 1', state: 'OPEN' },
|
|
@@ -1536,7 +1612,7 @@ describe('BitbucketService', () => {
|
|
|
1536
1612
|
'closedSince': undefined,
|
|
1537
1613
|
'order': 'NEWEST',
|
|
1538
1614
|
'start': undefined,
|
|
1539
|
-
'limit':
|
|
1615
|
+
'limit': 25,
|
|
1540
1616
|
},
|
|
1541
1617
|
errors: {
|
|
1542
1618
|
401: 'The currently authenticated user is not permitted to access the dashboard.',
|
|
@@ -1612,7 +1688,7 @@ describe('BitbucketService', () => {
|
|
|
1612
1688
|
'closedSince': closedSince,
|
|
1613
1689
|
'order': 'NEWEST',
|
|
1614
1690
|
'start': undefined,
|
|
1615
|
-
'limit':
|
|
1691
|
+
'limit': 25,
|
|
1616
1692
|
},
|
|
1617
1693
|
errors: {
|
|
1618
1694
|
401: 'The currently authenticated user is not permitted to access the dashboard.',
|
|
@@ -1732,10 +1808,17 @@ describe('BitbucketService', () => {
|
|
|
1732
1808
|
|
|
1733
1809
|
describe('validateConfig', () => {
|
|
1734
1810
|
const originalEnv = process.env;
|
|
1811
|
+
let tempDir: string;
|
|
1735
1812
|
|
|
1736
1813
|
beforeEach(() => {
|
|
1737
|
-
jest.resetModules();
|
|
1738
1814
|
process.env = { ...originalEnv };
|
|
1815
|
+
delete process.env.ATLASSIAN_DC_MCP_CONFIG_FILE;
|
|
1816
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'bitbucket-validate-config-'));
|
|
1817
|
+
initializeRuntimeConfig({ cwd: tempDir });
|
|
1818
|
+
});
|
|
1819
|
+
|
|
1820
|
+
afterEach(() => {
|
|
1821
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
1739
1822
|
});
|
|
1740
1823
|
|
|
1741
1824
|
afterAll(() => {
|
|
@@ -1775,6 +1858,15 @@ describe('BitbucketService', () => {
|
|
|
1775
1858
|
const missingVars = BitbucketService.validateConfig();
|
|
1776
1859
|
expect(missingVars).toEqual([]);
|
|
1777
1860
|
});
|
|
1861
|
+
|
|
1862
|
+
it('should accept required config from the shared config file', () => {
|
|
1863
|
+
const sharedConfigPath = path.join(tempDir, 'shared.env');
|
|
1864
|
+
fs.writeFileSync(sharedConfigPath, 'BITBUCKET_HOST=file-host\nBITBUCKET_API_TOKEN=file-token\n');
|
|
1865
|
+
process.env.ATLASSIAN_DC_MCP_CONFIG_FILE = sharedConfigPath;
|
|
1866
|
+
|
|
1867
|
+
const missingVars = BitbucketService.validateConfig();
|
|
1868
|
+
expect(missingVars).toEqual([]);
|
|
1869
|
+
});
|
|
1778
1870
|
});
|
|
1779
1871
|
|
|
1780
1872
|
describe('postPullRequestComment - pending flag', () => {
|