diff --git a/lib/platform/bitbucket/__snapshots__/bb-got-wrapper.spec.ts.snap b/lib/platform/bitbucket/__snapshots__/bb-got-wrapper.spec.ts.snap index 39af435181794fe50274fa0c5c1d74d28ab18c7d..895899be6e74009964ee3ce9178ee0ed5a00c838 100644 --- a/lib/platform/bitbucket/__snapshots__/bb-got-wrapper.spec.ts.snap +++ b/lib/platform/bitbucket/__snapshots__/bb-got-wrapper.spec.ts.snap @@ -1,7 +1,61 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`platform/gl-got-wrapper returns cached 1`] = ` -Object { - "body": Object {}, -} +exports[`platform/gl-got-wrapper accepts custom baseUrl 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer token", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://api.bitbucket.org/some-url", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-test.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://api-test.bitbucket.org/some-url", + }, +] +`; + +exports[`platform/gl-got-wrapper posts 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer token", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://api.bitbucket.org/some-url", + }, +] +`; + +exports[`platform/gl-got-wrapper returns cached 1`] = `Object {}`; + +exports[`platform/gl-got-wrapper returns cached 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer token", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/projects/foo", + }, +] `; diff --git a/lib/platform/bitbucket/__snapshots__/comments.spec.ts.snap b/lib/platform/bitbucket/__snapshots__/comments.spec.ts.snap index bb1301f380dddfa2b266ea98f227fa8a28479fc1..1a06ec05412b520f57a8d3066f19c2087bee6200 100644 --- a/lib/platform/bitbucket/__snapshots__/comments.spec.ts.snap +++ b/lib/platform/bitbucket/__snapshots__/comments.spec.ts.snap @@ -2,99 +2,166 @@ exports[`platform/comments ensureComment() add comment if not found 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", - undefined, - ], -] -`; - -exports[`platform/comments ensureComment() add comment if not found 2`] = ` -Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", - undefined, - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", + }, + Object { + "body": "{\\"content\\":{\\"raw\\":\\"### topic\\\\n\\\\ncontent\\"}}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "content-length": 42, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments", + }, ] `; exports[`platform/comments ensureComment() add updates comment if necessary 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", - undefined, - ], -] -`; - -exports[`platform/comments ensureComment() add updates comment if necessary 2`] = ` -Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", - undefined, - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", + }, + Object { + "body": "{\\"content\\":{\\"raw\\":\\"### some-subject\\\\n\\\\nsome\\\\ncontent\\"}}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "content-length": 55, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "PUT", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments/5", + }, ] `; exports[`platform/comments ensureComment() does not throw 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/3/comments?pagelen=100", - undefined, - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/3/comments?pagelen=100", + }, ] `; exports[`platform/comments ensureComment() skips comment 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", - undefined, - ], -] -`; - -exports[`platform/comments ensureComment() skips comment 2`] = ` -Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", - undefined, - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", + }, ] `; exports[`platform/comments ensureCommentRemoval() deletes comment by content if found 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", - undefined, - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "DELETE", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments/5", + }, ] `; exports[`platform/comments ensureCommentRemoval() deletes comment by topic if found 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", - undefined, - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "DELETE", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments/5", + }, ] `; exports[`platform/comments ensureCommentRemoval() deletes nothing 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", - undefined, - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", + }, ] `; exports[`platform/comments ensureCommentRemoval() does not throw 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", - undefined, - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100", + }, ] `; diff --git a/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap b/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap index 041bca3797f3a6d94abd716bb378d870a97e7326..3dd3d8aed5f32160570cbaaf232e8f074b8ec595 100644 --- a/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap +++ b/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap @@ -4,66 +4,221 @@ exports[`platform/bitbucket addAssignees() does not throw 1`] = `undefined`; exports[`platform/bitbucket addReviewers should add the given reviewers to the PR 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5", - Object { - "body": Object { - "reviewers": Array [ - Object { - "username": "someuser", - }, - Object { - "username": "someotheruser", - }, - ], - "title": "title", - }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", }, - ], + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/diff", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2", + }, + Object { + "body": "{\\"title\\":\\"title\\",\\"reviewers\\":[{\\"username\\":\\"someuser\\"},{\\"username\\":\\"someotheruser\\"}]}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 84, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "PUT", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5", + }, +] +`; + +exports[`platform/bitbucket branchExists() getFileList() sends to gitFs 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, ] `; exports[`platform/bitbucket commitFiles() sends to gitFs 1`] = `undefined`; +exports[`platform/bitbucket commitFiles() sends to gitFs 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + exports[`platform/bitbucket createPr() posts PR 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests", - Object { - "body": Object { - "close_source_branch": true, - "description": "body", - "destination": Object { - "branch": Object { - "name": "master", - }, - }, - "reviewers": Array [ - Object { - "uuid": "{1234-5678}", - }, - ], - "source": Object { - "branch": Object { - "name": "branch", - }, - }, - "title": "title", - }, - }, - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/default-reviewers", + }, + Object { + "body": "{\\"title\\":\\"title\\",\\"description\\":\\"body\\",\\"source\\":{\\"branch\\":{\\"name\\":\\"branch\\"}},\\"destination\\":{\\"branch\\":{\\"name\\":\\"master\\"}},\\"close_source_branch\\":true,\\"reviewers\\":[{\\"uuid\\":\\"{1234-5678}\\"}]}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 183, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests", + }, ] `; exports[`platform/bitbucket deleteBranch() sends to gitFs 1`] = `undefined`; -exports[`platform/bitbucket deleteBranch() should handle closing PRs when none exist 1`] = `Array []`; +exports[`platform/bitbucket deleteBranch() sends to gitFs 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + +exports[`platform/bitbucket deleteBranch() should handle closing PRs when none exist 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&pagelen=50", + }, +] +`; exports[`platform/bitbucket deleteBranch() should handle closing PRs when some exist 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/decline", - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&pagelen=50", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/decline", + }, ] `; @@ -73,60 +228,212 @@ exports[`platform/bitbucket ensureCommentRemoval() does not throw 1`] = `undefin exports[`platform/bitbucket ensureIssue() creates new issue 1`] = ` Array [ - Array [ - "/2.0/repositories/some/empty", - ], - Array [ - "/2.0/repositories/some/empty/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/empty", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/empty/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", + }, + Object { + "body": "{\\"title\\":\\"title\\",\\"content\\":{\\"raw\\":\\"body\\",\\"markup\\":\\"markdown\\"}}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 62, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://api.bitbucket.org/2.0/repositories/some/empty/issues", + }, ] `; -exports[`platform/bitbucket ensureIssue() creates new issue 2`] = ` +exports[`platform/bitbucket ensureIssue() noop for existing issue 1`] = ` Array [ - Array [ - "/2.0/repositories/some/empty/issues", - Object { - "body": Object { - "content": Object { - "markup": "markdown", - "raw": "body", - }, - "title": "title", - }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", }, - ], + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", + }, + Object { + "body": "{\\"state\\":\\"closed\\"}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 18, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "PUT", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/issues/26", + }, ] `; -exports[`platform/bitbucket ensureIssue() noop for existing issue 1`] = ` +exports[`platform/bitbucket ensureIssue() updates existing issues 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", + }, + Object { + "body": "{\\"state\\":\\"closed\\"}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 18, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "PUT", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/issues/26", + }, + Object { + "body": "{\\"content\\":{\\"raw\\":\\"body\\",\\"markup\\":\\"markdown\\"}}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 46, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "PUT", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/issues/25", + }, ] `; -exports[`platform/bitbucket ensureIssue() updates existing issues 1`] = ` +exports[`platform/bitbucket ensureIssueClosing() closes issue 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", + }, + Object { + "body": "{\\"state\\":\\"closed\\"}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 18, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "PUT", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/issues/25", + }, + Object { + "body": "{\\"state\\":\\"closed\\"}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 18, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "PUT", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/issues/26", + }, ] `; -exports[`platform/bitbucket ensureIssue() updates existing issues 2`] = `Array []`; - exports[`platform/bitbucket ensureIssueClosing() does not throw 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, ] `; -exports[`platform/bitbucket ensureIssueClosing() does not throw 2`] = `Array []`; - exports[`platform/bitbucket findIssue() does not throw 1`] = ` Object { "body": "content", @@ -136,9 +443,55 @@ Object { exports[`platform/bitbucket findIssue() does not throw 2`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", + }, +] +`; + +exports[`platform/bitbucket findIssue() returns null if no issues 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/empty", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/empty/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22", + }, ] `; @@ -154,10 +507,69 @@ Object { } `; +exports[`platform/bitbucket findPr() finds pr 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&pagelen=50", + }, +] +`; + exports[`platform/bitbucket getAllRenovateBranches() sends to gitFs 1`] = `undefined`; +exports[`platform/bitbucket getAllRenovateBranches() sends to gitFs 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + exports[`platform/bitbucket getBranchLastCommitTime() sends to gitFs 1`] = `undefined`; +exports[`platform/bitbucket getBranchLastCommitTime() sends to gitFs 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + exports[`platform/bitbucket getBranchPr() bitbucket finds PR for branch 1`] = ` Object { "body": "summary", @@ -175,10 +587,442 @@ Object { } `; +exports[`platform/bitbucket getBranchPr() bitbucket finds PR for branch 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&pagelen=50", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/diff", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2", + }, +] +`; + +exports[`platform/bitbucket getBranchPr() returns null if no PR for branch 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&pagelen=50", + }, +] +`; + +exports[`platform/bitbucket getBranchStatus() getBranchStatus 1 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + +exports[`platform/bitbucket getBranchStatus() getBranchStatus 2 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + +exports[`platform/bitbucket getBranchStatus() getBranchStatus 3 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/refs/branches/master", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/commit/master_hash/statuses?pagelen=100", + }, +] +`; + +exports[`platform/bitbucket getBranchStatus() getBranchStatus 4 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/refs/branches/branch", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/commit/branch_hash/statuses?pagelen=100", + }, +] +`; + +exports[`platform/bitbucket getBranchStatus() getBranchStatus 5 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/refs/branches/pending/branch", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/commit/pending/branch_hash/statuses?pagelen=100", + }, +] +`; + +exports[`platform/bitbucket getBranchStatus() getBranchStatus 6 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/refs/branches/branch-with-empty-status", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/commit/branch-with-empty-status/statuses?pagelen=100", + }, +] +`; + +exports[`platform/bitbucket getBranchStatusCheck() getBranchStatusCheck 1 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/refs/branches/master", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/commit/master_hash/statuses?pagelen=100", + }, +] +`; + +exports[`platform/bitbucket getBranchStatusCheck() getBranchStatusCheck 2 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/refs/branches/master", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/commit/master_hash/statuses?pagelen=100", + }, +] +`; + +exports[`platform/bitbucket getBranchStatusCheck() getBranchStatusCheck 3 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/refs/branches/master", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/commit/master_hash/statuses?pagelen=100", + }, +] +`; + exports[`platform/bitbucket getCommitMessages() sends to gitFs 1`] = `undefined`; +exports[`platform/bitbucket getCommitMessages() sends to gitFs 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + exports[`platform/bitbucket getFile() sends to gitFs 1`] = `undefined`; +exports[`platform/bitbucket getFile() sends to gitFs 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + +exports[`platform/bitbucket getFileList() sends to gitFs 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + exports[`platform/bitbucket getPr() canRebase 1`] = ` Object { "body": "summary", @@ -232,42 +1076,113 @@ Object { exports[`platform/bitbucket getPr() canRebase 4`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/3", - ], - Array [ - "/2.0/repositories/some/repo/pullrequests/3/diff", - Object { - "json": false, - }, - ], - Array [ - "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/3/commits?pagelen=2", - ], - Array [ - "/2.0/repositories/some/repo/pullrequests/5", - ], - Array [ - "/2.0/repositories/some/repo/pullrequests/5/diff", - Object { - "json": false, - }, - ], - Array [ - "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2", - ], - Array [ - "/2.0/repositories/some/repo/pullrequests/5", - ], - Array [ - "/2.0/repositories/some/repo/pullrequests/5/diff", - Object { - "json": false, - }, - ], - Array [ - "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2", - ], + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/3", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/3/diff", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/3/commits?pagelen=2", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/diff", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/diff", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2", + }, ] `; @@ -288,16 +1203,123 @@ Object { } `; +exports[`platform/bitbucket getPr() exists 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/diff", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2", + }, +] +`; + exports[`platform/bitbucket getPrBody() returns diff files 1`] = `"**foo**bartext"`; exports[`platform/bitbucket getRepoStatus() sends to gitFs 1`] = `undefined`; +exports[`platform/bitbucket getRepoStatus() sends to gitFs 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + +exports[`platform/bitbucket getRepos() returns repos 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/?role=contributor&pagelen=100", + }, +] +`; + exports[`platform/bitbucket initPlatform() should init 1`] = ` Object { "endpoint": "https://api.bitbucket.org/", } `; +exports[`platform/bitbucket initRepo() throws disabled 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/empty", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/empty/src/master/renovate.json", + }, +] +`; + exports[`platform/bitbucket initRepo() works 1`] = ` Object { "baseBranch": "master", @@ -305,54 +1327,193 @@ Object { } `; +exports[`platform/bitbucket initRepo() works 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + exports[`platform/bitbucket isBranchStale() sends to gitFs 1`] = `false`; +exports[`platform/bitbucket isBranchStale() sends to gitFs 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + exports[`platform/bitbucket mergeBranch() sends to gitFs 1`] = `undefined`; +exports[`platform/bitbucket mergeBranch() sends to gitFs 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; + exports[`platform/bitbucket mergePr() posts Merge 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5/merge", - Object { - "body": Object { - "close_source_branch": true, - "merge_strategy": "merge_commit", - "message": "auto merged", - }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "body": "{\\"close_source_branch\\":true,\\"merge_strategy\\":\\"merge_commit\\",\\"message\\":\\"auto merged\\"}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 84, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", }, - ], + "method": "POST", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/merge", + }, ] `; -exports[`platform/bitbucket setBaseBranch() updates file list 1`] = `Array []`; +exports[`platform/bitbucket setBaseBranch() updates file list 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, +] +`; exports[`platform/bitbucket setBranchStatus() posts status 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/commit/branch_hash/statuses/build", - Object { - "body": Object { - "description": "description", - "key": "context", - "name": "context", - "state": "FAILED", - "url": "targetUrl", - }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/refs/branches/branch", + }, + Object { + "body": "{\\"name\\":\\"context\\",\\"state\\":\\"FAILED\\",\\"key\\":\\"context\\",\\"description\\":\\"description\\",\\"url\\":\\"targetUrl\\"}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 97, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", }, - ], + "method": "POST", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/commit/branch_hash/statuses/build", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/refs/branches/branch", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/commit/branch_hash/statuses?pagelen=100", + }, ] `; exports[`platform/bitbucket updatePr() puts PR 1`] = ` Array [ - Array [ - "/2.0/repositories/some/repo/pullrequests/5", - Object { - "body": Object { - "description": "body", - "title": "title", - }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo", + }, + Object { + "body": "{\\"title\\":\\"title\\",\\"description\\":\\"body\\"}", + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic YWJjOjEyMw==", + "content-length": 38, + "content-type": "application/json", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", }, - ], + "method": "PUT", + "url": "https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5", + }, ] `; diff --git a/lib/platform/bitbucket/__snapshots__/utils.spec.ts.snap b/lib/platform/bitbucket/__snapshots__/utils.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..7f8bd069c18373ab8a40b22cd29da2a87e4eb126 --- /dev/null +++ b/lib/platform/bitbucket/__snapshots__/utils.spec.ts.snap @@ -0,0 +1,36 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`accumulateValues() paginates 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/some-url?pagelen=10", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/?pagelen=10&after=9&role=contributor", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.bitbucket.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.bitbucket.org/2.0/repositories/?pagelen=10&after=19&role=contributor", + }, +] +`; diff --git a/lib/platform/bitbucket/bb-got-wrapper.spec.ts b/lib/platform/bitbucket/bb-got-wrapper.spec.ts index 0764de6b513fb2587ad24e89f3889f9b0dbdfeda..89bb7a9acc55ac6a52173af6c1ff2a1b9e6e1b87 100644 --- a/lib/platform/bitbucket/bb-got-wrapper.spec.ts +++ b/lib/platform/bitbucket/bb-got-wrapper.spec.ts @@ -1,53 +1,51 @@ +import * as httpMock from '../../../test/httpMock'; import { PLATFORM_TYPE_BITBUCKET } from '../../constants/platforms'; -import { GotApi } from '../common'; +import * as hostRules from '../../util/host-rules'; +import { api } from './bb-got-wrapper'; + +const baseUrl = 'https://api.bitbucket.org'; describe('platform/gl-got-wrapper', () => { - let api: GotApi; - let got: jest.Mock<typeof import('got')>; - let hostRules: typeof import('../../util/host-rules'); beforeEach(() => { // reset module jest.resetAllMocks(); - jest.mock('../../util/got'); - got = require('../../util/got').api; - hostRules = require('../../util/host-rules'); - api = require('./bb-got-wrapper').api; // clean up hostRules hostRules.clear(); hostRules.add({ hostType: PLATFORM_TYPE_BITBUCKET, - baseUrl: 'https://api.bitbucket.org', + baseUrl, token: 'token', }); + + httpMock.reset(); + httpMock.setup(); + + api.setBaseUrl(baseUrl); }); it('posts', async () => { const body = ['a', 'b']; - got.mockImplementationOnce( - () => - ({ - body, - } as any) - ); + httpMock.scope(baseUrl).post('/some-url').reply(200, body); const res = await api.post('some-url'); expect(res.body).toEqual(body); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('accepts custom baseUrl', async () => { - got.mockImplementation(() => ({} as any)); + const customBaseUrl = 'https://api-test.bitbucket.org'; + httpMock.scope(baseUrl).post('/some-url').reply(200, {}); + httpMock.scope(customBaseUrl).post('/some-url').reply(200, {}); await api.post('some-url'); - expect(got.mock.calls[0][1].baseUrl).toBe('https://api.bitbucket.org/'); - const customBaseUrl = 'https://api-test.bitbucket.org'; api.setBaseUrl(customBaseUrl); await api.post('some-url'); - expect(got.mock.calls[1][1].baseUrl).toBe(customBaseUrl); + + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns cached', async () => { - got.mockReturnValueOnce({ - body: {}, - } as any); - const res1 = await api.get('projects/foo'); - expect(res1).toMatchSnapshot(); + httpMock.scope(baseUrl).get('/projects/foo').reply(200, {}); + const { body } = await api.get('projects/foo'); + expect(body).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); diff --git a/lib/platform/bitbucket/comments.spec.ts b/lib/platform/bitbucket/comments.spec.ts index 6488be7873ce0a43bc27bccdb8ba0e6c4817a283..be923fe3b0c2f92c259253f6bce964f5720b0997 100644 --- a/lib/platform/bitbucket/comments.spec.ts +++ b/lib/platform/bitbucket/comments.spec.ts @@ -1,41 +1,28 @@ -import URL from 'url'; -import responses from './__fixtures__/responses'; -import { api as _api } from './bb-got-wrapper'; +import * as httpMock from '../../../test/httpMock'; +import { api } from './bb-got-wrapper'; import * as comments from './comments'; -jest.mock('./bb-got-wrapper'); - -const api: jest.Mocked<typeof _api> = _api as any; +const baseUrl = 'https://api.bitbucket.org'; describe('platform/comments', () => { const config: comments.CommentsConfig = { repository: 'some/repo' }; - async function mockedGet(path: string) { - const uri = URL.parse(path).pathname; - let body = (responses as any)[uri]; - if (!body) { - throw new Error('Missing request'); - } - if (typeof body === 'function') { - body = await body(); - } - return { body } as any; - } - - beforeAll(() => { - api.get.mockImplementation(mockedGet); - api.post.mockImplementation(mockedGet); - api.put.mockImplementation(mockedGet); - api.delete.mockImplementation(mockedGet); - }); - beforeEach(() => { jest.clearAllMocks(); + + httpMock.reset(); + httpMock.setup(); + + api.setBaseUrl(baseUrl); }); describe('ensureComment()', () => { it('does not throw', async () => { expect.assertions(2); + httpMock + .scope(baseUrl) + .get('/2.0/repositories/some/repo/pullrequests/3/comments?pagelen=100') + .reply(200); expect( await comments.ensureComment({ config, @@ -44,12 +31,17 @@ describe('platform/comments', () => { content: 'content', }) ).toBe(false); - expect(api.get.mock.calls).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('add comment if not found', async () => { - expect.assertions(6); - api.get.mockClear(); + expect.assertions(2); + httpMock + .scope(baseUrl) + .get('/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100') + .reply(200, { values: [] }) + .post('/2.0/repositories/some/repo/pullrequests/5/comments') + .reply(200); expect( await comments.ensureComment({ @@ -59,119 +51,119 @@ describe('platform/comments', () => { content: 'content', }) ).toBe(true); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.post).toHaveBeenCalledTimes(1); - - api.get.mockClear(); - api.post.mockClear(); - - expect( - await comments.ensureComment({ - config, - number: 5, - topic: null, - content: 'content', - }) - ).toBe(true); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.post).toHaveBeenCalledTimes(1); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('add updates comment if necessary', async () => { - expect.assertions(8); - api.get.mockClear(); - - expect( - await comments.ensureComment({ - config, - number: 5, - topic: 'some-subject', - content: 'some\ncontent', - }) - ).toBe(true); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.post).toHaveBeenCalledTimes(0); - expect(api.put).toHaveBeenCalledTimes(1); - - api.get.mockClear(); - api.put.mockClear(); - - expect( - await comments.ensureComment({ - config, - number: 5, - topic: null, - content: 'some\ncontent', + expect.assertions(2); + httpMock + .scope(baseUrl) + .get('/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100') + .reply(200, { + values: [ + { + id: 5, + content: { raw: '### some-subject\n\nsome\nobsolete\ncontent' }, + }, + ], }) - ).toBe(true); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.post).toHaveBeenCalledTimes(1); - expect(api.put).toHaveBeenCalledTimes(0); + .put('/2.0/repositories/some/repo/pullrequests/5/comments/5') + .reply(200); + const res = await comments.ensureComment({ + config, + number: 5, + topic: 'some-subject', + content: 'some\ncontent', + }); + httpMock.getTrace(); + expect(res).toBe(true); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('skips comment', async () => { - expect.assertions(6); - api.get.mockClear(); - - expect( - await comments.ensureComment({ - config, - number: 5, - topic: 'some-subject', - content: 'blablabla', - }) - ).toBe(true); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.put).toHaveBeenCalledTimes(0); - - api.get.mockClear(); - api.put.mockClear(); - + expect.assertions(2); + httpMock + .scope(baseUrl) + .get('/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100') + .reply(200, { + values: [ + { + id: 5, + content: { raw: 'blablabla' }, + }, + ], + }); expect( await comments.ensureComment({ config, number: 5, topic: null, - content: '!merge', + content: 'blablabla', }) ).toBe(true); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.put).toHaveBeenCalledTimes(0); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('ensureCommentRemoval()', () => { it('does not throw', async () => { expect.assertions(1); + httpMock + .scope(baseUrl) + .get('/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100') + .reply(200, { values: [] }); await comments.ensureCommentRemoval(config, 5, 'topic'); - expect(api.get.mock.calls).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('deletes comment by topic if found', async () => { - expect.assertions(2); - api.get.mockClear(); + expect.assertions(1); + httpMock + .scope(baseUrl) + .get('/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100') + .reply(200, { + values: [ + { + id: 5, + content: { raw: '### some-subject\n\nsome-content' }, + }, + ], + }) + .delete('/2.0/repositories/some/repo/pullrequests/5/comments/5') + .reply(200); await comments.ensureCommentRemoval(config, 5, 'some-subject'); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.delete).toHaveBeenCalledTimes(1); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('deletes comment by content if found', async () => { - expect.assertions(2); - api.get.mockClear(); + expect.assertions(1); + httpMock + .scope(baseUrl) + .get('/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100') + .reply(200, { + values: [ + { + id: 5, + content: { raw: '\n\nsome-content\n\n' }, + }, + ], + }) + .delete('/2.0/repositories/some/repo/pullrequests/5/comments/5') + .reply(200); - await comments.ensureCommentRemoval(config, 5, undefined, '!merge'); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.delete).toHaveBeenCalledTimes(1); + await comments.ensureCommentRemoval(config, 5, undefined, 'some-content'); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('deletes nothing', async () => { - expect.assertions(2); - api.get.mockClear(); - + expect.assertions(1); + httpMock + .scope(baseUrl) + .get('/2.0/repositories/some/repo/pullrequests/5/comments?pagelen=100') + .reply(200, { values: [] }); await comments.ensureCommentRemoval(config, 5, 'topic'); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.delete).toHaveBeenCalledTimes(0); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/platform/bitbucket/index.spec.ts b/lib/platform/bitbucket/index.spec.ts index 7d96778a75a7ef82ca638e6abe693979171dafac..41e5f1ef9500c7d8902413e62cc52634c70fa23f 100644 --- a/lib/platform/bitbucket/index.spec.ts +++ b/lib/platform/bitbucket/index.spec.ts @@ -1,26 +1,62 @@ -// TODO fix mocks -import URL from 'url'; +import nock from 'nock'; +import * as httpMock from '../../../test/httpMock'; import { REPOSITORY_DISABLED } from '../../constants/error-messages'; import { logger as _logger } from '../../logger'; import { BranchStatus } from '../../types'; -import { GotApi, Platform, RepoParams } from '../common'; -import responses from './__fixtures__/responses'; +import { Platform, RepoParams } from '../common'; + +const baseUrl = 'https://api.bitbucket.org'; + +const pr = { + id: 5, + source: { branch: { name: 'branch' } }, + destination: { branch: { name: 'master' } }, + title: 'title', + summary: { raw: 'summary' }, + state: 'OPEN', + created_on: '2018-07-02T07:02:25.275030+00:00', + links: { + commits: { + href: `https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/5/commits`, + }, + }, +}; + +const diff = ` +diff --git a/requirements.txt b/requirements.txt +index 7e08d70..f5283ca 100644 +--- a/requirements.txt ++++ b/requirements.txt +@@ -7,7 +7,7 @@ docutils==0.12 +enum34==1.1.6 +futures==3.2.0 +isort==4.3.4 +-jedi==0.11.1 ++jedi==0.12.1 +lazy-object-proxy==1.3.1 +lxml==3.6.0 +mccabe==0.6.1 +`; + +const commits = { + size: 1, + values: [{ author: { raw: 'Renovate Bot <bot@renovateapp.com>' } }], +}; describe('platform/bitbucket', () => { let bitbucket: Platform; - let api: jest.Mocked<GotApi>; let hostRules: jest.Mocked<typeof import('../../util/host-rules')>; let GitStorage: jest.Mocked<import('../git/storage').Storage> & jest.Mock; let logger: jest.Mocked<typeof _logger>; beforeEach(async () => { // reset module jest.resetModules(); - jest.mock('./bb-got-wrapper'); + httpMock.reset(); + httpMock.setup(); jest.mock('../git/storage'); jest.mock('../../util/host-rules'); jest.mock('../../logger'); hostRules = require('../../util/host-rules'); - api = require('./bb-got-wrapper').api; bitbucket = await import('.'); logger = (await import('../../logger')).logger as any; GitStorage = require('../git/storage').Storage; @@ -53,37 +89,29 @@ describe('platform/bitbucket', () => { await bitbucket.cleanRepo(); }); - async function mockedGet(path: string) { - let body = (responses as any)[URL.parse(path).pathname] || { values: [] }; - if (typeof body === 'function') { - body = await body(); - } - return { body }; - } + async function initRepoMock( + config?: Partial<RepoParams>, + repoResp?: any + ): Promise<nock.Scope> { + const repository = config?.repository || 'some/repo'; - async function mocked<T = any>(fn: () => Promise<T>) { - const oldGet = api.get; - try { - api.get = jest.fn().mockImplementation(mockedGet); - return await fn(); - } finally { - api.get = oldGet; - } - } + const scope = httpMock + .scope(baseUrl) + .get(`/2.0/repositories/${repository}`) + .reply(200, { + owner: {}, + mainbranch: { name: 'master' }, + ...repoResp, + }); - function wrap(prop: string) { - return (...args: any) => mocked(() => (bitbucket as any)[prop](...args)); - } + await bitbucket.initRepo({ + repository: 'some/repo', + localDir: '', + optimizeForDisabled: false, + ...config, + }); - function initRepo(config?: Partial<RepoParams>) { - return mocked(() => - bitbucket.initRepo({ - repository: 'some/repo', - localDir: '', - optimizeForDisabled: false, - ...config, - }) - ); + return scope; } describe('initPlatform()', () => { @@ -113,25 +141,55 @@ describe('platform/bitbucket', () => { describe('getRepos()', () => { it('returns repos', async () => { - api.get.mockReturnValueOnce({ - body: { + httpMock + .scope(baseUrl) + .get('/2.0/repositories/?role=contributor&pagelen=100') + .reply(200, { values: [{ full_name: 'foo/bar' }, { full_name: 'some/repo' }], - }, - } as any); - expect(await bitbucket.getRepos()).toEqual(['foo/bar', 'some/repo']); + }); + const res = await bitbucket.getRepos(); + expect(res).toEqual(['foo/bar', 'some/repo']); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('initRepo()', () => { it('works', async () => { - expect(await initRepo()).toMatchSnapshot(); + httpMock + .scope(baseUrl) + .get('/2.0/repositories/some/repo') + .reply(200, { owner: {}, mainbranch: { name: 'master' } }); + expect( + await bitbucket.initRepo({ + repository: 'some/repo', + localDir: '', + optimizeForDisabled: false, + }) + ).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('throws disabled', async () => { - expect.assertions(1); + expect.assertions(2); + httpMock + .scope(baseUrl) + .get('/2.0/repositories/some/empty') + .reply(200, { owner: {}, mainbranch: { name: 'master' } }) + .get('/2.0/repositories/some/empty/src/master/renovate.json') + .reply( + 200, + JSON.stringify({ + enabled: false, + }) + ); await expect( - initRepo({ repository: 'some/empty', optimizeForDisabled: true }) + bitbucket.initRepo({ + repository: 'some/empty', + optimizeForDisabled: true, + localDir: '', + }) ).rejects.toThrow(REPOSITORY_DISABLED); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); @@ -144,213 +202,473 @@ describe('platform/bitbucket', () => { describe('setBaseBranch()', () => { it('updates file list', async () => { - await initRepo(); - await mocked(async () => { - await bitbucket.setBaseBranch('branch'); - await bitbucket.setBaseBranch(); - expect(api.get.mock.calls).toMatchSnapshot(); - }); + await initRepoMock(); + await bitbucket.setBaseBranch('branch'); + await bitbucket.setBaseBranch(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('getFileList()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - const fileList = await bitbucket.getFileList(); - expect(fileList).not.toBeNull(); - }); + await initRepoMock(); + const fileList = await bitbucket.getFileList(); + expect(fileList).not.toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('branchExists()', () => { describe('getFileList()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - const branchExists = await bitbucket.branchExists('test'); - expect(branchExists).toEqual(true); - }); + await initRepoMock(); + const branchExists = await bitbucket.branchExists('test'); + expect(branchExists).toEqual(true); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); describe('isBranchStale()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - expect(await bitbucket.isBranchStale('test')).toMatchSnapshot(); - }); + await initRepoMock(); + expect(await bitbucket.isBranchStale('test')).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('getBranchPr()', () => { - const getBranchPr = wrap('getBranchPr'); it('bitbucket finds PR for branch', async () => { - await initRepo(); - expect(await getBranchPr('branch')).toMatchSnapshot(); + const scope = await initRepoMock(); + scope + .get( + '/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&pagelen=50' + ) + .reply(200, { values: [pr] }) + .get('/2.0/repositories/some/repo/pullrequests/5') + .reply(200, pr) + .get('/2.0/repositories/some/repo/pullrequests/5/diff') + .reply(200, diff) + .get('/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2') + .reply(200, commits); + + expect(await bitbucket.getBranchPr('branch')).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null if no PR for branch', async () => { - await initRepo(); - expect(await getBranchPr('branch_without_pr')).toBeNull(); + const scope = await initRepoMock(); + scope + .get( + '/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&pagelen=50' + ) + .reply(200, { values: [pr] }); + + const res = await bitbucket.getBranchPr('branch_without_pr'); + expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('getBranchStatus()', () => { - const getBranchStatus = wrap('getBranchStatus'); - it('works', async () => { - await initRepo(); - expect(await getBranchStatus('master', null)).toBe(BranchStatus.green); - expect(await getBranchStatus('master', ['foo'])).toBe(BranchStatus.red); - expect(await getBranchStatus('master', true)).toBe(BranchStatus.red); - expect(await getBranchStatus('branch', true)).toBe(BranchStatus.green); - expect(await getBranchStatus('pending/branch', true)).toBe( - BranchStatus.yellow + it('getBranchStatus 1', async () => { + await initRepoMock(); + expect(await bitbucket.getBranchStatus('master', null)).toBe( + BranchStatus.green + ); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('getBranchStatus 2', async () => { + await initRepoMock(); + expect(await bitbucket.getBranchStatus('master', ['foo'])).toBe( + BranchStatus.red + ); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('getBranchStatus 3', async () => { + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/refs/branches/master') + .reply(200, { + name: 'master', + target: { hash: 'master_hash' }, + }) + .get( + '/2.0/repositories/some/repo/commit/master_hash/statuses?pagelen=100' + ) + .reply(200, { + values: [ + { + key: 'foo', + state: 'FAILED', + }, + ], + }); + expect(await bitbucket.getBranchStatus('master', [])).toBe( + BranchStatus.red ); - expect(await getBranchStatus('branch-with-empty-status', true)).toBe( + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('getBranchStatus 4', async () => { + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/refs/branches/branch') + .reply(200, { + name: 'branch', + target: { + hash: 'branch_hash', + parents: [{ hash: 'master_hash' }], + }, + }) + .get( + '/2.0/repositories/some/repo/commit/branch_hash/statuses?pagelen=100' + ) + .reply(200, { + values: [ + { + key: 'foo', + state: 'SUCCESSFUL', + }, + ], + }); + expect(await bitbucket.getBranchStatus('branch', [])).toBe( + BranchStatus.green + ); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('getBranchStatus 5', async () => { + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/refs/branches/pending/branch') + .reply(200, { + name: 'pending/branch', + target: { + hash: 'pending/branch_hash', + parents: [{ hash: 'master_hash' }], + }, + }) + .get( + '/2.0/repositories/some/repo/commit/pending/branch_hash/statuses?pagelen=100' + ) + .reply(200, { + values: [ + { + key: 'foo', + state: 'INPROGRESS', + }, + ], + }); + expect(await bitbucket.getBranchStatus('pending/branch', [])).toBe( BranchStatus.yellow ); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('getBranchStatus 6', async () => { + const scope = await initRepoMock(); + scope + .get( + '/2.0/repositories/some/repo/refs/branches/branch-with-empty-status' + ) + .reply(200, { + name: 'branch-with-empty-status', + target: { + hash: 'branch-with-empty-status', + parents: [{ hash: 'master_hash' }], + }, + }) + .get( + '/2.0/repositories/some/repo/commit/branch-with-empty-status/statuses?pagelen=100' + ) + .reply(200, { + values: [], + }); + expect( + await bitbucket.getBranchStatus('branch-with-empty-status', []) + ).toBe(BranchStatus.yellow); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('getBranchStatusCheck()', () => { - const getBranchStatusCheck = wrap('getBranchStatusCheck'); - it('works', async () => { - await initRepo(); - expect(await getBranchStatusCheck('master', null)).toBeNull(); - expect(await getBranchStatusCheck('master', 'foo')).toBe( + beforeEach(async () => { + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/refs/branches/master') + .reply(200, { + name: 'master', + target: { hash: 'master_hash' }, + }) + .get( + '/2.0/repositories/some/repo/commit/master_hash/statuses?pagelen=100' + ) + .reply(200, { + values: [ + { + key: 'foo', + state: 'FAILED', + }, + ], + }); + }); + it('getBranchStatusCheck 1', async () => { + expect(await bitbucket.getBranchStatusCheck('master', null)).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('getBranchStatusCheck 2', async () => { + expect(await bitbucket.getBranchStatusCheck('master', 'foo')).toBe( BranchStatus.red ); - expect(await getBranchStatusCheck('master', 'bar')).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('getBranchStatusCheck 3', async () => { + expect(await bitbucket.getBranchStatusCheck('master', 'bar')).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('setBranchStatus()', () => { it('posts status', async () => { - await initRepo(); - await mocked(async () => { - await bitbucket.setBranchStatus({ - branchName: 'branch', - context: 'context', - description: 'description', - state: BranchStatus.red, - url: 'targetUrl', + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/refs/branches/branch') + .twice() + .reply(200, { + name: 'branch', + target: { + hash: 'branch_hash', + parents: [{ hash: 'master_hash' }], + }, + }) + .post('/2.0/repositories/some/repo/commit/branch_hash/statuses/build') + .reply(200) + .get( + '/2.0/repositories/some/repo/commit/branch_hash/statuses?pagelen=100' + ) + .reply(200, { + values: [ + { + key: 'foo', + state: 'SUCCESSFUL', + }, + ], }); - expect(api.post.mock.calls).toMatchSnapshot(); + await bitbucket.setBranchStatus({ + branchName: 'branch', + context: 'context', + description: 'description', + state: BranchStatus.red, + url: 'targetUrl', }); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('getRepoStatus()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - expect(await bitbucket.getRepoStatus()).toMatchSnapshot(); - }); + await initRepoMock(); + expect(await bitbucket.getRepoStatus()).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('deleteBranch()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - expect(await bitbucket.deleteBranch('test')).toMatchSnapshot(); - }); + await initRepoMock(); + expect(await bitbucket.deleteBranch('test')).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('should handle closing PRs when none exist', async () => { - await initRepo(); - await mocked(async () => { - await bitbucket.deleteBranch('some-branch', true); - expect(api.post.mock.calls).toMatchSnapshot(); - }); + const scope = await initRepoMock(); + scope + .get( + '/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&pagelen=50' + ) + .reply(200, { values: [pr] }); + await bitbucket.deleteBranch('some-branch', true); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('should handle closing PRs when some exist', async () => { - await initRepo(); - await mocked(async () => { - await bitbucket.deleteBranch('branch', true); - expect(api.post.mock.calls).toMatchSnapshot(); - }); + const scope = await initRepoMock(); + scope + .get( + '/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&pagelen=50' + ) + .reply(200, { values: [pr] }) + .post('/2.0/repositories/some/repo/pullrequests/5/decline') + .reply(200); + await bitbucket.deleteBranch('branch', true); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('mergeBranch()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - expect(await bitbucket.mergeBranch('test')).toMatchSnapshot(); - }); + await initRepoMock(); + expect(await bitbucket.mergeBranch('test')).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('getBranchLastCommitTime()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - expect( - await bitbucket.getBranchLastCommitTime('test') - ).toMatchSnapshot(); - }); + await initRepoMock(); + expect(await bitbucket.getBranchLastCommitTime('test')).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('findIssue()', () => { it('does not throw', async () => { - await initRepo(); - await mocked(async () => { - expect(await bitbucket.findIssue('title')).toMatchSnapshot(); - expect(api.get.mock.calls).toMatchSnapshot(); - }); + const scope = await initRepoMock({}, { has_issues: true }); + scope + .get( + '/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22' + ) + .reply(200, { + values: [ + { + id: 25, + title: 'title', + content: { raw: 'content' }, + }, + { + id: 26, + title: 'title', + content: { raw: 'content' }, + }, + ], + }); + expect(await bitbucket.findIssue('title')).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null if no issues', async () => { - await mocked(async () => { - await bitbucket.initRepo({ + const scope = await initRepoMock( + { repository: 'some/empty', - localDir: '', - optimizeForDisabled: false, + }, + { has_issues: true } + ); + scope + .get( + '/2.0/repositories/some/empty/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22' + ) + .reply(200, { + values: [], }); - expect(await bitbucket.findIssue('title')).toBeNull(); - }); + expect(await bitbucket.findIssue('title')).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('ensureIssue()', () => { it('updates existing issues', async () => { - await initRepo(); - await mocked(async () => { - await bitbucket.ensureIssue({ title: 'title', body: 'body' }); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.post.mock.calls).toMatchSnapshot(); - }); + const scope = await initRepoMock({}, { has_issues: true }); + scope + .get( + '/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22' + ) + .reply(200, { + values: [ + { + id: 25, + title: 'title', + content: { raw: 'content' }, + }, + { + id: 26, + title: 'title', + content: { raw: 'content' }, + }, + ], + }) + .put('/2.0/repositories/some/repo/issues/25') + .reply(200) + .put('/2.0/repositories/some/repo/issues/26') + .reply(200); + expect( + await bitbucket.ensureIssue({ title: 'title', body: 'body' }) + ).toEqual('updated'); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('creates new issue', async () => { - await mocked(async () => { - await bitbucket.initRepo({ - repository: 'some/empty', - localDir: '', - optimizeForDisabled: false, - }); - await bitbucket.ensureIssue({ title: 'title', body: 'body' }); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.post.mock.calls).toMatchSnapshot(); - }); + const scope = await initRepoMock( + { repository: 'some/empty' }, + { has_issues: true } + ); + scope + .get( + '/2.0/repositories/some/empty/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22' + ) + .reply(200, { values: [] }) + .post('/2.0/repositories/some/empty/issues') + .reply(200); + expect( + await bitbucket.ensureIssue({ title: 'title', body: 'body' }) + ).toEqual('created'); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('noop for existing issue', async () => { - await initRepo(); - await mocked(async () => { - await bitbucket.ensureIssue({ title: 'title', body: 'content\n' }); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.post).toHaveBeenCalledTimes(0); - }); + const scope = await initRepoMock({}, { has_issues: true }); + scope + .get( + '/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22' + ) + .reply(200, { + values: [ + { + id: 25, + title: 'title', + content: { raw: 'content' }, + }, + { + id: 26, + title: 'title', + content: { raw: 'content' }, + }, + ], + }) + .put('/2.0/repositories/some/repo/issues/26') + .reply(200); + expect( + await bitbucket.ensureIssue({ + title: 'title', + body: '\n content \n', + }) + ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('ensureIssueClosing()', () => { it('does not throw', async () => { - await initRepo(); - await mocked(async () => { - await bitbucket.ensureIssueClosing('title'); - expect(api.get.mock.calls).toMatchSnapshot(); - expect(api.delete.mock.calls).toMatchSnapshot(); - }); + await initRepoMock(); + await bitbucket.ensureIssueClosing('title'); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + it('closes issue', async () => { + const scope = await initRepoMock({}, { has_issues: true }); + scope + .get( + '/2.0/repositories/some/repo/issues?q=title%3D%22title%22%20AND%20(state%20%3D%20%22new%22%20OR%20state%20%3D%20%22open%22)%20AND%20reporter.username%3D%22abc%22' + ) + .reply(200, { + values: [ + { + id: 25, + title: 'title', + content: { raw: 'content' }, + }, + { + id: 26, + title: 'title', + content: { raw: 'content' }, + }, + ], + }) + .put('/2.0/repositories/some/repo/issues/25') + .reply(200) + .put('/2.0/repositories/some/repo/issues/26') + .reply(200); + await bitbucket.ensureIssueClosing('title'); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); @@ -362,11 +680,18 @@ describe('platform/bitbucket', () => { describe('addReviewers', () => { it('should add the given reviewers to the PR', async () => { - await initRepo(); - await mocked(async () => { - await bitbucket.addReviewers(5, ['someuser', 'someotheruser']); - expect(api.put.mock.calls).toMatchSnapshot(); - }); + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/pullrequests/5') + .reply(200, pr) + .get('/2.0/repositories/some/repo/pullrequests/5/diff') + .reply(200, diff) + .get('/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2') + .reply(200, commits) + .put('/2.0/repositories/some/repo/pullrequests/5') + .reply(200); + await bitbucket.addReviewers(5, ['someuser', 'someotheruser']); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); @@ -402,59 +727,101 @@ describe('platform/bitbucket', () => { }); it('finds pr', async () => { - await initRepo(); - await mocked(async () => { - expect( - await bitbucket.findPr({ branchName: 'branch', prTitle: 'title' }) - ).toMatchSnapshot(); - }); + const scope = await initRepoMock(); + scope + .get( + '/2.0/repositories/some/repo/pullrequests?state=OPEN&state=MERGED&state=DECLINED&state=SUPERSEDED&pagelen=50' + ) + .reply(200, { values: [pr] }); + expect( + await bitbucket.findPr({ + branchName: 'branch', + prTitle: 'title', + }) + ).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('createPr()', () => { it('posts PR', async () => { - await initRepo(); - api.get.mockReturnValueOnce({ - body: { + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/default-reviewers') + .reply(200, { values: [{ uuid: '{1234-5678}' }], - }, - } as any); - api.post.mockReturnValueOnce({ - body: { id: 5 }, - } as any); + }) + .post('/2.0/repositories/some/repo/pullrequests') + .reply(200, { id: 5 }); const { number } = await bitbucket.createPr({ branchName: 'branch', prTitle: 'title', prBody: 'body', }); expect(number).toBe(5); - expect(api.post.mock.calls).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('getPr()', () => { - const getPr = wrap('getPr'); it('exists', async () => { - await initRepo(); - expect(await getPr(5)).toMatchSnapshot(); + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/pullrequests/5') + .reply(200, pr) + .get('/2.0/repositories/some/repo/pullrequests/5/diff') + .reply(200, diff) + .get('/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2') + .reply(200, commits); + expect(await bitbucket.getPr(5)).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('canRebase', async () => { expect.assertions(4); - await initRepo(); const author = global.gitAuthor; + const scope = await initRepoMock(); + scope + .get('/2.0/repositories/some/repo/pullrequests/3') + .reply(200, { + id: 3, + source: { branch: { name: 'branch' } }, + destination: { branch: { name: 'master' } }, + title: 'title', + summary: { raw: 'summary' }, + state: 'OPEN', + created_on: '2018-07-02T07:02:25.275030+00:00', + links: { + commits: { + href: `https://api.bitbucket.org/2.0/repositories/some/repo/pullrequests/3/commits`, + }, + }, + }) + .get('/2.0/repositories/some/repo/pullrequests/3/diff') + .reply(200, ' ') + .get('/2.0/repositories/some/repo/pullrequests/3/commits?pagelen=2') + .reply(200, { + size: 2, + }) + .get('/2.0/repositories/some/repo/pullrequests/5') + .twice() + .reply(200, pr) + .get('/2.0/repositories/some/repo/pullrequests/5/diff') + .twice() + .reply(200, diff) + .get('/2.0/repositories/some/repo/pullrequests/5/commits?pagelen=2') + .twice() + .reply(200, commits); try { - await mocked(async () => { - expect(await bitbucket.getPr(3)).toMatchSnapshot(); + expect(await bitbucket.getPr(3)).toMatchSnapshot(); - global.gitAuthor = { email: 'bot@renovateapp.com', name: 'bot' }; - expect(await bitbucket.getPr(5)).toMatchSnapshot(); + global.gitAuthor = { email: 'bot@renovateapp.com', name: 'bot' }; + expect(await bitbucket.getPr(5)).toMatchSnapshot(); - global.gitAuthor = { email: 'jane@example.com', name: 'jane' }; - expect(await bitbucket.getPr(5)).toMatchSnapshot(); + global.gitAuthor = { email: 'jane@example.com', name: 'jane' }; + expect(await bitbucket.getPr(5)).toMatchSnapshot(); - expect(api.get.mock.calls).toMatchSnapshot(); - }); + expect(httpMock.getTrace()).toMatchSnapshot(); } finally { global.gitAuthor = author; } @@ -473,61 +840,56 @@ describe('platform/bitbucket', () => { describe('updatePr()', () => { it('puts PR', async () => { - await initRepo(); + const scope = await initRepoMock(); + scope.put('/2.0/repositories/some/repo/pullrequests/5').reply(200); await bitbucket.updatePr(5, 'title', 'body'); - expect(api.put.mock.calls).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('mergePr()', () => { it('posts Merge', async () => { - await initRepo(); + const scope = await initRepoMock(); + scope.post('/2.0/repositories/some/repo/pullrequests/5/merge').reply(200); await bitbucket.mergePr(5, 'branch'); - expect(api.post.mock.calls).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('commitFiles()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - expect( - await bitbucket.commitFiles({ - branchName: 'test', - files: [], - message: 'message', - }) - ).toMatchSnapshot(); + await initRepoMock(); + const res = await bitbucket.commitFiles({ + branchName: 'test', + files: [], + message: 'message', }); + expect(res).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('getFile()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - expect(await bitbucket.getFile('test.file')).toMatchSnapshot(); - }); + await initRepoMock(); + expect(await bitbucket.getFile('test.file')).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('getCommitMessages()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - expect(await bitbucket.getCommitMessages()).toMatchSnapshot(); - }); + await initRepoMock(); + expect(await bitbucket.getCommitMessages()).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); describe('getAllRenovateBranches()', () => { it('sends to gitFs', async () => { - await initRepo(); - await mocked(async () => { - expect( - await bitbucket.getAllRenovateBranches('test') - ).toMatchSnapshot(); - }); + await initRepoMock(); + expect(await bitbucket.getAllRenovateBranches('test')).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); diff --git a/lib/platform/bitbucket/utils.spec.ts b/lib/platform/bitbucket/utils.spec.ts index f5de17a5876245715415a4acc4ac6c35abceb51c..de9374737f060569bd299c95f26a6266359a46fe 100644 --- a/lib/platform/bitbucket/utils.spec.ts +++ b/lib/platform/bitbucket/utils.spec.ts @@ -1,35 +1,35 @@ -import { GotApi } from '../common'; +import * as httpMock from '../../../test/httpMock'; import * as utils from './utils'; -jest.mock('./bb-got-wrapper'); - -const api: jest.Mocked<GotApi> = require('./bb-got-wrapper').api; - const range = (count: number) => [...Array(count).keys()]; describe('accumulateValues()', () => { it('paginates', async () => { - api.get.mockReturnValueOnce({ - body: { + httpMock.reset(); + httpMock.setup(); + + httpMock + .scope('https://api.bitbucket.org') + .get('/some-url?pagelen=10') + .reply(200, { values: range(10), next: 'https://api.bitbucket.org/2.0/repositories/?pagelen=10&after=9&role=contributor', - }, - } as any); - api.get.mockReturnValueOnce({ - body: { + }) + .get('/2.0/repositories/?pagelen=10&after=9&role=contributor') + .reply(200, { values: range(10), next: 'https://api.bitbucket.org/2.0/repositories/?pagelen=10&after=19&role=contributor', - }, - } as any); - api.get.mockReturnValueOnce({ - body: { + }) + .get('/2.0/repositories/?pagelen=10&after=19&role=contributor') + .reply(200, { values: range(5), - }, - } as any); + }); + const res = await utils.accumulateValues('some-url', 'get', null, 10); expect(res).toHaveLength(25); - expect(api.get).toHaveBeenCalledTimes(3); + expect(httpMock.getTrace()).toHaveLength(3); + expect(httpMock.getTrace()).toMatchSnapshot(); }); });