From 987680ce672f38b74c99e14a92c363b5002703f8 Mon Sep 17 00:00:00 2001 From: Scott Walker Date: Mon, 14 Aug 2023 14:37:19 +0100 Subject: [PATCH] [IAC-941]: PR comment creation for BitBucket BitBucket doesn't implement support for PR comments or issues comments. The current implementation of "pullService" in BitBucket defers to the implementation of "issueService", which itself returns a "not implemented" error for all comment-related calls. PR comments and issue comments are separate in BitBucket so this commit adds explicit implementations of the comment functions to the "pullService". Most remain "not implemented" with the exception of comment creation which is now supported. --- go.sum | 11 ---- scm/driver/bitbucket/bitbucket.go | 2 +- scm/driver/bitbucket/pr.go | 38 +++++++++++++- scm/driver/bitbucket/pr_test.go | 50 ++++++++++++++++++ scm/driver/bitbucket/testdata/prcomment.json | 52 +++++++++++++++++++ .../bitbucket/testdata/prcomment.json.golden | 12 +++++ scm/driver/bitbucket/webhook.go | 6 +++ 7 files changed, 158 insertions(+), 13 deletions(-) create mode 100644 scm/driver/bitbucket/testdata/prcomment.json create mode 100644 scm/driver/bitbucket/testdata/prcomment.json.golden diff --git a/go.sum b/go.sum index 00f0342cb..6d69376b6 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,6 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/h2non/gock v1.0.9 h1:17gCehSo8ZOgEsFKpQgqHiR7VLyjxdAG3lkhVvO9QZU= github.com/h2non/gock v1.0.9/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/scm/driver/bitbucket/bitbucket.go b/scm/driver/bitbucket/bitbucket.go index d5afda370..f05ab670e 100644 --- a/scm/driver/bitbucket/bitbucket.go +++ b/scm/driver/bitbucket/bitbucket.go @@ -36,7 +36,7 @@ func New(uri string) (*scm.Client, error) { client.Issues = &issueService{client} client.Milestones = &milestoneService{client} client.Organizations = &organizationService{client} - client.PullRequests = &pullService{&issueService{client}} + client.PullRequests = &pullService{client} client.Repositories = &repositoryService{client} client.Releases = &releaseService{client} client.Reviews = &reviewService{client} diff --git a/scm/driver/bitbucket/pr.go b/scm/driver/bitbucket/pr.go index 5cc3e5ba9..ead47a821 100644 --- a/scm/driver/bitbucket/pr.go +++ b/scm/driver/bitbucket/pr.go @@ -13,7 +13,7 @@ import ( ) type pullService struct { - *issueService + client *wrapper } func (s *pullService) Find(ctx context.Context, repo string, number int) (*scm.PullRequest, *scm.Response, error) { @@ -69,6 +69,27 @@ func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRe return convertPullRequest(out), res, err } +func (s *pullService) FindComment(ctx context.Context, repo string, index, id int) (*scm.Comment, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) ListComments(ctx context.Context, repo string, index int, opts scm.ListOptions) ([]*scm.Comment, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + +func (s *pullService) CreateComment(ctx context.Context, repo string, number int, input *scm.CommentInput) (*scm.Comment, *scm.Response, error) { + path := fmt.Sprintf("2.0/repositories/%s/pullrequests/%d/comments", repo, number) + in := &prCommentInput{} + in.Content.Raw = input.Body + out := new(prComment) + res, err := s.client.do(ctx, "POST", path, in, out) + return convertPullRequestComment(out), res, err +} + +func (s *pullService) DeleteComment(ctx context.Context, repo string, number, id int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + type reference struct { Commit struct { Hash string `json:"hash"` @@ -180,3 +201,18 @@ func convertPullRequest(from *pr) *scm.PullRequest { Updated: from.UpdatedOn, } } + +func convertPullRequestComment(from *prComment) *scm.Comment { + return &scm.Comment{ + ID: from.ID, + Body: from.Content.Raw, + Author: scm.User{ + ID: from.User.UUID, + Login: from.User.Nickname, + Name: from.User.DisplayName, + Avatar: from.User.Links.Avatar.Href, + }, + Created: from.CreatedOn, + Updated: from.UpdatedOn, + } +} diff --git a/scm/driver/bitbucket/pr_test.go b/scm/driver/bitbucket/pr_test.go index 00f112f75..038ec1952 100644 --- a/scm/driver/bitbucket/pr_test.go +++ b/scm/driver/bitbucket/pr_test.go @@ -175,3 +175,53 @@ func TestPullListCommits(t *testing.T) { t.Log(diff) } } + +func TestPullRequestCommentFind(t *testing.T) { + _, _, err := NewDefault().PullRequests.FindComment(context.Background(), "", 0, 0) + if err != scm.ErrNotSupported { + t.Errorf("Expect Not Supported error") + } +} + +func TestPullRequestListComments(t *testing.T) { + _, _, err := NewDefault().PullRequests.ListComments(context.Background(), "", 0, scm.ListOptions{}) + if err != scm.ErrNotSupported { + t.Errorf("Expect Not Supported error") + } +} + +func TestPullRequestCreateComment(t *testing.T) { + defer gock.Off() + + gock.New("https://api.bitbucket.org"). + Post("/2.0/repositories/atlassian/atlaskit/pullrequests/12"). + Reply(201). + Type("application/json"). + File("testdata/prcomment.json") + + input := &scm.CommentInput{ + Body: "Lovely comment", + } + + client, _ := New("https://api.bitbucket.org") + got, _, err := client.PullRequests.CreateComment(context.Background(), "atlassian/atlaskit", 12, input) + if err != nil { + t.Error(err) + } + + want := new(scm.Comment) + raw, _ := ioutil.ReadFile("testdata/prcomment.json.golden") + json.Unmarshal(raw, want) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("Unexpected Results") + t.Log(diff) + } +} + +func TestPullRequestCommentDelete(t *testing.T) { + _, err := NewDefault().PullRequests.DeleteComment(context.Background(), "", 0, 0) + if err != scm.ErrNotSupported { + t.Errorf("Expect Not Supported error") + } +} diff --git a/scm/driver/bitbucket/testdata/prcomment.json b/scm/driver/bitbucket/testdata/prcomment.json new file mode 100644 index 000000000..953b2d158 --- /dev/null +++ b/scm/driver/bitbucket/testdata/prcomment.json @@ -0,0 +1,52 @@ +{ + "id": 419169807, + "created_on": "2023-08-14T11:38:53.460132+00:00", + "updated_on": "2023-08-14T11:38:53.460205+00:00", + "content": { + "type": "rendered", + "raw": "Lovely comment", + "markup": "markdown", + "html": "

Lovely comment<\/p>" + }, + "user": { + "display_name": "Brian Jacobson", + "links": { + "self": { + "href": "https:\/\/bitbucket.org\/!api\/2.0\/users\/%7B6dff94-1b8b-4f62-b37f-3069e13dfdf33e%7D" + }, + "avatar": { + "href": "http:\/\/localhost:3000\/avatars\/1" + }, + "html": { + "href": "https:\/\/bitbucket.org\/%7B6dff94-1b8b-4f62-b37f-3069e13dfdf33e%7D\/" + } + }, + "type": "user", + "uuid": "{6b408a94-1b8b-4f62-b37f-3069e13bc33e}", + "account_id": "60259ce8164527007100d945", + "nickname": "brian.jacobson" + }, + "deleted": false, + "type": "pullrequest_comment", + "links": { + "self": { + "href": "https:\/\/bitbucket.org\/!api\/2.0\/repositories\/brianharness\/test\/pullrequests\/3\/comments\/419169807" + }, + "html": { + "href": "https:\/\/bitbucket.org\/brianharness\/test\/pull-requests\/3\/_\/diff#comment-419169807" + } + }, + "pullrequest": { + "type": "pullrequest", + "id": 3, + "title": "README.md edited online with Bitbucket", + "links": { + "self": { + "href": "https:\/\/bitbucket.org\/!api\/2.0\/repositories\/brianharness\/test\/pullrequests\/3" + }, + "html": { + "href": "https:\/\/bitbucket.org\/brianharness\/test\/pull-requests\/3" + } + } + } +} \ No newline at end of file diff --git a/scm/driver/bitbucket/testdata/prcomment.json.golden b/scm/driver/bitbucket/testdata/prcomment.json.golden new file mode 100644 index 000000000..e6dea457a --- /dev/null +++ b/scm/driver/bitbucket/testdata/prcomment.json.golden @@ -0,0 +1,12 @@ +{ + "ID": 419169807, + "Body": "Lovely comment", + "Author": { + "ID": "{6b408a94-1b8b-4f62-b37f-3069e13bc33e}", + "Login": "brian.jacobson", + "Name": "Brian Jacobson", + "Avatar": "http://localhost:3000/avatars/1" + }, + "Created": "2023-08-14T11:38:53.460132+00:00", + "Updated": "2023-08-14T11:38:53.460205+00:00" +} diff --git a/scm/driver/bitbucket/webhook.go b/scm/driver/bitbucket/webhook.go index 6d88690ec..d254bba54 100644 --- a/scm/driver/bitbucket/webhook.go +++ b/scm/driver/bitbucket/webhook.go @@ -405,6 +405,12 @@ type ( UUID string `json:"uuid"` } + prCommentInput struct { + Content struct { + Raw string `json:"raw"` + } `json:"content"` + } + prComment struct { Links struct { Self link `json:"self"`