Files
atlantis/server/events/vcs/bitbucketcloud/client_test.go
Michel Z. Santello df0d58d29b fix: vcs-status-name hardcoded in PullIsMergeable function (#2312)
* feat: add userConfig.VCSStatusName to applyCommandRunner context

* fix: use vcsstatusname from context

* chore: normalize tests

* chore: update interface mock
2022-06-16 09:26:20 -07:00

355 lines
9.1 KiB
Go

package bitbucketcloud_test
import (
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"github.com/runatlantis/atlantis/server/events/models"
"github.com/runatlantis/atlantis/server/events/vcs/bitbucketcloud"
. "github.com/runatlantis/atlantis/testing"
)
// Should follow pagination properly.
func TestClient_GetModifiedFilesPagination(t *testing.T) {
respTemplate := `
{
"pagelen": 1,
"values": [
{
"type": "diffstat",
"status": "modified",
"lines_removed": 1,
"lines_added": 2,
"old": {
"path": "%s",
"type": "commit_file",
"links": {
"self": {
"href": "https://api.bitbucket.org/2.0/repositories/bitbucket/geordi/src/e1749643d655d7c7014001a6c0f58abaf42ad850/setup.py"
}
}
},
"new": {
"path": "%s",
"type": "commit_file",
"links": {
"self": {
"href": "https://api.bitbucket.org/2.0/repositories/bitbucket/geordi/src/d222fa235229c55dad20b190b0b571adf737d5a6/setup.py"
}
}
}
}
],
"page": 1,
"size": 1
`
firstResp := fmt.Sprintf(respTemplate, "file1.txt", "file2.txt")
secondResp := fmt.Sprintf(respTemplate, "file2.txt", "file3.txt")
var serverURL string
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.RequestURI {
// The first request should hit this URL.
case "/2.0/repositories/owner/repo/pullrequests/1/diffstat":
resp := firstResp + fmt.Sprintf(`,"next": "%s/2.0/repositories/owner/repo/pullrequests/1/diffstat?page=2"}`, serverURL)
w.Write([]byte(resp)) // nolint: errcheck
return
// The second should hit this URL.
case "/2.0/repositories/owner/repo/pullrequests/1/diffstat?page=2":
w.Write([]byte(secondResp + "}")) // nolint: errcheck
default:
t.Errorf("got unexpected request at %q", r.RequestURI)
http.Error(w, "not found", http.StatusNotFound)
return
}
}))
defer testServer.Close()
serverURL = testServer.URL
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
client.BaseURL = testServer.URL
files, err := client.GetModifiedFiles(models.Repo{
FullName: "owner/repo",
Owner: "owner",
Name: "repo",
CloneURL: "",
SanitizedCloneURL: "",
VCSHost: models.VCSHost{
Type: models.BitbucketCloud,
Hostname: "bitbucket.org",
},
}, models.PullRequest{
Num: 1,
})
Ok(t, err)
Equals(t, []string{"file1.txt", "file2.txt", "file3.txt"}, files)
}
// If the "old" key in the list of files is nil we shouldn't error.
func TestClient_GetModifiedFilesOldNil(t *testing.T) {
resp := `
{
"pagelen": 500,
"values": [
{
"status": "added",
"old": null,
"lines_removed": 0,
"lines_added": 2,
"new": {
"path": "parent/child/file1.txt",
"type": "commit_file",
"links": {
"self": {
"href": "https://api.bitbucket.org/2.0/repositories/lkysow/atlantis-example/src/1ed8205eec00dab4f1c0a8c486a4492c98c51f8e/main.tf"
}
}
},
"type": "diffstat"
}
],
"page": 1,
"size": 1
}`
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.RequestURI {
// The first request should hit this URL.
case "/2.0/repositories/owner/repo/pullrequests/1/diffstat":
w.Write([]byte(resp)) // nolint: errcheck
return
default:
t.Errorf("got unexpected request at %q", r.RequestURI)
http.Error(w, "not found", http.StatusNotFound)
return
}
}))
defer testServer.Close()
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
client.BaseURL = testServer.URL
files, err := client.GetModifiedFiles(models.Repo{
FullName: "owner/repo",
Owner: "owner",
Name: "repo",
CloneURL: "",
SanitizedCloneURL: "",
VCSHost: models.VCSHost{
Type: models.BitbucketCloud,
Hostname: "bitbucket.org",
},
}, models.PullRequest{
Num: 1,
})
Ok(t, err)
Equals(t, []string{"parent/child/file1.txt"}, files)
}
func TestClient_PullIsApproved(t *testing.T) {
cases := []struct {
description string
testdata string
exp bool
}{
{
"no approvers",
"pull-unapproved.json",
false,
},
{
"approver is the author",
"pull-approved-by-author.json",
false,
},
{
"single approver",
"pull-approved.json",
true,
},
{
"two approvers one author",
"pull-approved-multiple.json",
true,
},
}
for _, c := range cases {
t.Run(c.description, func(t *testing.T) {
json, err := os.ReadFile(filepath.Join("testdata", c.testdata))
Ok(t, err)
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.RequestURI {
// The first request should hit this URL.
case "/2.0/repositories/owner/repo/pullrequests/1":
w.Write(json) // nolint: errcheck
return
default:
t.Errorf("got unexpected request at %q", r.RequestURI)
http.Error(w, "not found", http.StatusNotFound)
return
}
}))
defer testServer.Close()
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
client.BaseURL = testServer.URL
repo, err := models.NewRepo(models.BitbucketServer, "owner/repo", "https://bitbucket.org/owner/repo.git", "user", "token")
Ok(t, err)
approvalStatus, err := client.PullIsApproved(repo, models.PullRequest{
Num: 1,
HeadBranch: "branch",
Author: "author",
BaseRepo: repo,
})
Ok(t, err)
Equals(t, c.exp, approvalStatus.IsApproved)
})
}
}
func TestClient_PullIsMergeable(t *testing.T) {
cases := map[string]struct {
DiffStat string
ExpMergeable bool
}{
"mergeable": {
DiffStat: `{
"pagelen": 500,
"values": [
{
"status": "added",
"old": null,
"lines_removed": 0,
"lines_added": 2,
"new": {
"path": "parent/child/file1.txt",
"type": "commit_file",
"links": {
"self": {
"href": "https://api.bitbucket.org/2.0/repositories/lkysow/atlantis-example/src/1ed8205eec00dab4f1c0a8c486a4492c98c51f8e/main.tf"
}
}
},
"type": "diffstat"
}
],
"page": 1,
"size": 1
}`,
ExpMergeable: true,
},
"merge conflict": {
DiffStat: `{
"pagelen": 500,
"values": [
{
"status": "merge conflict",
"old": {
"path": "main.tf",
"type": "commit_file",
"links": {
"self": {
"href": "https://api.bitbucket.org/2.0/repositories/lkysow/atlantis-example/src/6d6a8026a788621b37a9ac422a7d0ebb1500e85f/main.tf"
}
}
},
"lines_removed": 1,
"lines_added": 0,
"new": {
"path": "main.tf",
"type": "commit_file",
"links": {
"self": {
"href": "https://api.bitbucket.org/2.0/repositories/lkysow/atlantis-example/src/742e76108714365788f5681e99e4a64f45dce147/main.tf"
}
}
},
"type": "diffstat"
}
],
"page": 1,
"size": 1
}`,
ExpMergeable: false,
},
"merge conflict due to file deleted": {
DiffStat: `{
"pagelen": 500,
"values": [
{
"status": "local deleted",
"old": null,
"lines_removed": 0,
"lines_added": 3,
"new": {
"path": "main.tf",
"type": "commit_file",
"links": {
"self": {
"href": "https://api.bitbucket.org/2.0/repositories/lkysow/atlantis-example/src/3539b9f51c9f91e8f6280e89c62e2673ddc51144/main.tf"
}
}
},
"type": "diffstat"
}
],
"page": 1,
"size": 1
}`,
ExpMergeable: false,
},
}
for name, c := range cases {
t.Run(name, func(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.RequestURI {
case "/2.0/repositories/owner/repo/pullrequests/1/diffstat":
w.Write([]byte(c.DiffStat)) // nolint: errcheck
return
default:
t.Errorf("got unexpected request at %q", r.RequestURI)
http.Error(w, "not found", http.StatusNotFound)
return
}
}))
defer testServer.Close()
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
client.BaseURL = testServer.URL
actMergeable, err := client.PullIsMergeable(models.Repo{
FullName: "owner/repo",
Owner: "owner",
Name: "repo",
CloneURL: "",
SanitizedCloneURL: "",
VCSHost: models.VCSHost{
Type: models.BitbucketCloud,
Hostname: "bitbucket.org",
},
}, models.PullRequest{
Num: 1,
}, "atlantis-test")
Ok(t, err)
Equals(t, c.ExpMergeable, actMergeable)
})
}
}
func TestClient_MarkdownPullLink(t *testing.T) {
client := bitbucketcloud.NewClient(http.DefaultClient, "user", "pass", "runatlantis.io")
pull := models.PullRequest{Num: 1}
s, _ := client.MarkdownPullLink(pull)
exp := "#1"
Equals(t, exp, s)
}