@atlassian-dc-mcp/bitbucket 0.12.2 → 0.13.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 +12 -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 +281 -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/bitbucket-response-mapper.d.ts +8 -0
- package/build/bitbucket-response-mapper.d.ts.map +1 -0
- package/build/bitbucket-response-mapper.js +95 -0
- package/build/bitbucket-response-mapper.js.map +1 -0
- package/build/bitbucket-service.d.ts +24 -22
- package/build/bitbucket-service.d.ts.map +1 -1
- package/build/bitbucket-service.js +88 -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/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 +314 -0
- package/src/__tests__/config.test.ts +64 -0
- package/src/bitbucket-response-mapper.ts +112 -0
- package/src/bitbucket-service.ts +117 -57
- package/src/config.ts +13 -0
- package/src/index.ts +18 -17
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,wBAAgB,yBAAyB,4DAExC;AAED,wBAAgB,kBAAkB,WAEjC;AAED,wBAAgB,gBAAgB,aAE/B"}
|
package/build/config.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getProductRuntimeConfig, validateProductRuntimeConfig } from '@atlassian-dc-mcp/common';
|
|
2
|
+
export function getBitbucketRuntimeConfig() {
|
|
3
|
+
return getProductRuntimeConfig('bitbucket');
|
|
4
|
+
}
|
|
5
|
+
export function getDefaultPageSize() {
|
|
6
|
+
return getBitbucketRuntimeConfig().defaultPageSize;
|
|
7
|
+
}
|
|
8
|
+
export function getMissingConfig() {
|
|
9
|
+
return validateProductRuntimeConfig('bitbucket');
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAEjG,MAAM,UAAU,yBAAyB;IACvC,OAAO,uBAAuB,CAAC,WAAW,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,yBAAyB,EAAE,CAAC,eAAe,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,4BAA4B,CAAC,WAAW,CAAC,CAAC;AACnD,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { connectServer, createMcpServer, formatToolResponse } from '@atlassian-dc-mcp/common';
|
|
2
|
-
import dotenv from 'dotenv';
|
|
1
|
+
import { connectServer, createMcpServer, formatToolResponse, initializeRuntimeConfig } from '@atlassian-dc-mcp/common';
|
|
3
2
|
import { BitbucketService, bitbucketToolSchemas } from './bitbucket-service.js';
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { getBitbucketRuntimeConfig, getDefaultPageSize } from './config.js';
|
|
4
|
+
initializeRuntimeConfig();
|
|
6
5
|
const missingVars = BitbucketService.validateConfig();
|
|
7
6
|
if (missingVars.length > 0) {
|
|
8
7
|
console.error(`Missing required environment variables: ${missingVars.join(', ')}`);
|
|
9
8
|
process.exit(1);
|
|
10
9
|
}
|
|
11
|
-
const
|
|
10
|
+
const bitbucketConfig = getBitbucketRuntimeConfig();
|
|
11
|
+
const bitbucketService = new BitbucketService(bitbucketConfig.host, () => getBitbucketRuntimeConfig().token, bitbucketConfig.apiBasePath, getDefaultPageSize);
|
|
12
12
|
const server = createMcpServer({
|
|
13
13
|
name: "atlassian-bitbucket-mcp",
|
|
14
14
|
version: "0.1.0"
|
|
@@ -41,20 +41,20 @@ server.tool("bitbucket_getPullRequest", "Get a specific pull request by ID. Retu
|
|
|
41
41
|
const result = await bitbucketService.getPullRequest(projectKey, repositorySlug, pullRequestId);
|
|
42
42
|
return formatToolResponse(result);
|
|
43
43
|
});
|
|
44
|
-
server.tool("bitbucket_getPR_CommentsAndAction", "Get comments for a Bitbucket pull request and other actions, like approvals", bitbucketToolSchemas.getPullRequestComments, async ({ projectKey, repositorySlug, pullRequestId, start, limit }) => {
|
|
45
|
-
const result = await bitbucketService.getPullRequestCommentsAndActions(projectKey, repositorySlug, pullRequestId, start, limit);
|
|
44
|
+
server.tool("bitbucket_getPR_CommentsAndAction", "Get comments for a Bitbucket pull request and other actions, like approvals", bitbucketToolSchemas.getPullRequestComments, async ({ projectKey, repositorySlug, pullRequestId, start, limit, output }) => {
|
|
45
|
+
const result = await bitbucketService.getPullRequestCommentsAndActions(projectKey, repositorySlug, pullRequestId, start, limit, output);
|
|
46
46
|
return formatToolResponse(result);
|
|
47
47
|
});
|
|
48
|
-
server.tool("bitbucket_getPullRequestChanges", "Get the changes for a Bitbucket pull request", bitbucketToolSchemas.getPullRequestChanges, async ({ projectKey, repositorySlug, pullRequestId, sinceId, changeScope, untilId, withComments, start, limit }) => {
|
|
49
|
-
const result = await bitbucketService.getPullRequestChanges(projectKey, repositorySlug, pullRequestId, sinceId, changeScope, untilId, withComments, start, limit);
|
|
48
|
+
server.tool("bitbucket_getPullRequestChanges", "Get the changes for a Bitbucket pull request", bitbucketToolSchemas.getPullRequestChanges, async ({ projectKey, repositorySlug, pullRequestId, sinceId, changeScope, untilId, withComments, start, limit, output }) => {
|
|
49
|
+
const result = await bitbucketService.getPullRequestChanges(projectKey, repositorySlug, pullRequestId, sinceId, changeScope, untilId, withComments, start, limit, output);
|
|
50
50
|
return formatToolResponse(result);
|
|
51
51
|
});
|
|
52
52
|
server.tool("bitbucket_getUser", "Get a Bitbucket user by their slug, or search for users by name/email to discover their slug. Use this to resolve userSlug for bitbucket_submitPullRequestReview when it is not already known from a comment response or PR participant list.", bitbucketToolSchemas.getUser, async ({ userSlug, filter }) => {
|
|
53
53
|
const result = await bitbucketService.getUser(userSlug, filter);
|
|
54
54
|
return formatToolResponse(result);
|
|
55
55
|
});
|
|
56
|
-
server.tool("bitbucket_postPullRequestComment", "Post a comment to a Bitbucket pull request. Use pending: true to create a draft comment that is only visible to you until you call bitbucket_submitPullRequestReview. NOTE: pending only works when filePath is provided (file-level or inline comments). True top-level PR comments (no filePath) are always posted live and cannot be drafted.", bitbucketToolSchemas.postPullRequestComment, async ({ projectKey, repositorySlug, pullRequestId, text, parentId, filePath, line, lineType, pending }) => {
|
|
57
|
-
const result = await bitbucketService.postPullRequestComment(projectKey, repositorySlug, pullRequestId, text, parentId, filePath, line, lineType, pending);
|
|
56
|
+
server.tool("bitbucket_postPullRequestComment", "Post a comment to a Bitbucket pull request. Use pending: true to create a draft comment that is only visible to you until you call bitbucket_submitPullRequestReview. NOTE: pending only works when filePath is provided (file-level or inline comments). True top-level PR comments (no filePath) are always posted live and cannot be drafted.", bitbucketToolSchemas.postPullRequestComment, async ({ projectKey, repositorySlug, pullRequestId, text, parentId, filePath, line, lineType, pending, output }) => {
|
|
57
|
+
const result = await bitbucketService.postPullRequestComment(projectKey, repositorySlug, pullRequestId, text, parentId, filePath, line, lineType, pending, output);
|
|
58
58
|
return formatToolResponse(result);
|
|
59
59
|
});
|
|
60
60
|
server.tool("bitbucket_submitPullRequestReview", "Submit a pull request review, publishing all pending (draft) comments and setting the reviewer's verdict. This is equivalent to clicking 'Submit Review' in the Bitbucket UI. Use after posting comments with pending: true. To resolve userSlug: (1) check author.slug in any comment you posted this session, (2) check the reviewers/participants array from bitbucket_getPullRequest, or (3) call bitbucket_getUser with a name/email filter as a last resort.", bitbucketToolSchemas.submitPullRequestReview, async ({ projectKey, repositorySlug, pullRequestId, userSlug, status, lastReviewedCommit }) => {
|
|
@@ -65,12 +65,12 @@ server.tool("bitbucket_getPullRequestDiff", "Get text diff for a specific file i
|
|
|
65
65
|
const result = await bitbucketService.getPullRequestDiff(projectKey, repositorySlug, pullRequestId, path, contextLines, sinceId, srcPath, diffType, untilId, whitespace);
|
|
66
66
|
return formatToolResponse(result);
|
|
67
67
|
});
|
|
68
|
-
server.tool("bitbucket_createPullRequest", "Create a new pull request in a Bitbucket repository. IMPORTANT: Before creating a PR, use bitbucket_getRequiredReviewers to fetch required reviewers for the source and target branches to ensure the PR is not created without mandatory reviewers.", bitbucketToolSchemas.createPullRequest, async ({ projectKey, repositorySlug, title, description, fromRefId, toRefId, reviewers }) => {
|
|
69
|
-
const result = await bitbucketService.createPullRequest(projectKey, repositorySlug, title, description, fromRefId, toRefId, reviewers);
|
|
68
|
+
server.tool("bitbucket_createPullRequest", "Create a new pull request in a Bitbucket repository. IMPORTANT: Before creating a PR, use bitbucket_getRequiredReviewers to fetch required reviewers for the source and target branches to ensure the PR is not created without mandatory reviewers.", bitbucketToolSchemas.createPullRequest, async ({ projectKey, repositorySlug, title, description, fromRefId, toRefId, reviewers, output }) => {
|
|
69
|
+
const result = await bitbucketService.createPullRequest(projectKey, repositorySlug, title, description, fromRefId, toRefId, reviewers, output);
|
|
70
70
|
return formatToolResponse(result);
|
|
71
71
|
});
|
|
72
|
-
server.tool("bitbucket_updatePullRequest", "Update the title, description, reviewers, destination branch or draft status of an existing pull request. IMPORTANT: The reviewers parameter replaces ALL existing reviewers. If you want to preserve existing reviewers, first fetch the current PR details (using bitbucket_getPullRequests filtered by ID) and include those reviewers along with any new ones you want to add.", bitbucketToolSchemas.updatePullRequest, async ({ projectKey, repositorySlug, pullRequestId, version, title, description, reviewers }) => {
|
|
73
|
-
const result = await bitbucketService.updatePullRequest(projectKey, repositorySlug, pullRequestId, version, title, description, reviewers);
|
|
72
|
+
server.tool("bitbucket_updatePullRequest", "Update the title, description, reviewers, destination branch or draft status of an existing pull request. IMPORTANT: The reviewers parameter replaces ALL existing reviewers. If you want to preserve existing reviewers, first fetch the current PR details (using bitbucket_getPullRequests filtered by ID) and include those reviewers along with any new ones you want to add.", bitbucketToolSchemas.updatePullRequest, async ({ projectKey, repositorySlug, pullRequestId, version, title, description, reviewers, output }) => {
|
|
73
|
+
const result = await bitbucketService.updatePullRequest(projectKey, repositorySlug, pullRequestId, version, title, description, reviewers, output);
|
|
74
74
|
return formatToolResponse(result);
|
|
75
75
|
});
|
|
76
76
|
server.tool("bitbucket_getRequiredReviewers", "Get required reviewers for pull request creation. Returns a set of users who are required reviewers for pull requests created from the given source repository and ref to the given target ref in this repository.", bitbucketToolSchemas.getRequiredReviewers, async ({ projectKey, repositorySlug, sourceRefId, targetRefId, sourceRepoId, targetRepoId }) => {
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.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.13.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.13.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": "2f5845bf1c5837d547bcc957dcf01c4f9865c83a"
|
|
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', () => {
|