Files
atlantis/server/events/vcs/gitlab_client_test.go
2020-08-06 15:30:20 -07:00

253 lines
7.3 KiB
Go

package vcs
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
version "github.com/hashicorp/go-version"
"github.com/runatlantis/atlantis/server/events/models"
gitlab "github.com/xanzy/go-gitlab"
. "github.com/runatlantis/atlantis/testing"
)
// Test that the base url gets set properly.
func TestNewGitlabClient_BaseURL(t *testing.T) {
gitlabClientUnderTest = true
defer func() { gitlabClientUnderTest = false }()
cases := []struct {
Hostname string
ExpBaseURL string
}{
{
"gitlab.com",
"https://gitlab.com/api/v4/",
},
{
"custom.domain",
"https://custom.domain/api/v4/",
},
{
"http://custom.domain",
"http://custom.domain/api/v4/",
},
{
"http://custom.domain:8080",
"http://custom.domain:8080/api/v4/",
},
{
"https://custom.domain",
"https://custom.domain/api/v4/",
},
{
"https://custom.domain/",
"https://custom.domain/api/v4/",
},
{
"https://custom.domain/basepath/",
"https://custom.domain/basepath/api/v4/",
},
}
for _, c := range cases {
t.Run(c.Hostname, func(t *testing.T) {
client, err := NewGitlabClient(c.Hostname, "token", nil)
Ok(t, err)
Equals(t, c.ExpBaseURL, client.Client.BaseURL().String())
})
}
}
// This function gets called even if GitlabClient is nil
// so we need to test that.
func TestGitlabClient_SupportsCommonMarkNil(t *testing.T) {
var gl *GitlabClient
Equals(t, false, gl.SupportsCommonMark())
}
func TestGitlabClient_SupportsCommonMark(t *testing.T) {
cases := []struct {
version string
exp bool
}{
{
"11.0",
false,
},
{
"11.1",
true,
},
{
"11.2",
true,
},
{
"12.0",
true,
},
}
for _, c := range cases {
t.Run(c.version, func(t *testing.T) {
vers, err := version.NewVersion(c.version)
Ok(t, err)
gl := GitlabClient{
Version: vers,
}
Equals(t, c.exp, gl.SupportsCommonMark())
})
}
}
func TestGitlabClient_MergePull(t *testing.T) {
cases := []struct {
description string
glResponse string
code int
expErr string
}{
{
"success",
mergeSuccess,
200,
"",
},
{
"405",
`{"message":"405 Method Not Allowed"}`,
405,
"405 {message: 405 Method Not Allowed}",
},
{
"406",
`{"message":"406 Branch cannot be merged"}`,
406,
"406 {message: 406 Branch cannot be merged}",
},
}
for _, c := range cases {
t.Run(c.description, func(t *testing.T) {
testServer := httptest.NewServer(
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.RequestURI {
// The first request should hit this URL.
case "/api/v4/projects/runatlantis%2Fatlantis/merge_requests/1/merge":
w.WriteHeader(c.code)
w.Write([]byte(c.glResponse)) // nolint: errcheck
case "/api/v4/":
// Rate limiter requests.
w.WriteHeader(http.StatusOK)
default:
t.Errorf("got unexpected request at %q", r.RequestURI)
http.Error(w, "not found", http.StatusNotFound)
}
}))
internalClient, err := gitlab.NewClient("token", gitlab.WithBaseURL(testServer.URL))
Ok(t, err)
client := &GitlabClient{
Client: internalClient,
Version: nil,
}
err = client.MergePull(models.PullRequest{
Num: 1,
BaseRepo: models.Repo{
FullName: "runatlantis/atlantis",
Owner: "runatlantis",
Name: "atlantis",
},
})
if c.expErr == "" {
Ok(t, err)
} else {
ErrContains(t, c.expErr, err)
ErrContains(t, "unable to merge merge request, it may not be in a mergeable state", err)
}
})
}
}
func TestGitlabClient_UpdateStatus(t *testing.T) {
cases := []struct {
status models.CommitStatus
expState string
}{
{
models.PendingCommitStatus,
"pending",
},
{
models.SuccessCommitStatus,
"success",
},
{
models.FailedCommitStatus,
"failed",
},
}
for _, c := range cases {
t.Run(c.expState, func(t *testing.T) {
gotRequest := false
testServer := httptest.NewServer(
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.RequestURI {
case "/api/v4/projects/runatlantis%2Fatlantis/statuses/sha":
gotRequest = true
body, err := ioutil.ReadAll(r.Body)
Ok(t, err)
exp := fmt.Sprintf(`{"state":"%s","context":"src","target_url":"https://google.com","description":"description"}`, c.expState)
Equals(t, exp, string(body))
defer r.Body.Close() // nolint: errcheck
w.Write([]byte("{}")) // nolint: errcheck
case "/api/v4/":
// Rate limiter requests.
w.WriteHeader(http.StatusOK)
default:
t.Errorf("got unexpected request at %q", r.RequestURI)
http.Error(w, "not found", http.StatusNotFound)
}
}))
internalClient, err := gitlab.NewClient("token", gitlab.WithBaseURL(testServer.URL))
Ok(t, err)
client := &GitlabClient{
Client: internalClient,
Version: nil,
}
repo := models.Repo{
FullName: "runatlantis/atlantis",
Owner: "runatlantis",
Name: "atlantis",
}
err = client.UpdateStatus(repo, models.PullRequest{
Num: 1,
BaseRepo: repo,
HeadCommit: "sha",
}, c.status, "src", "description", "https://google.com")
Ok(t, err)
Assert(t, gotRequest, "expected to get the request")
})
}
}
func TestGitlabClient_MarkdownPullLink(t *testing.T) {
gitlabClientUnderTest = true
defer func() { gitlabClientUnderTest = false }()
client, err := NewGitlabClient("gitlab.com", "token", nil)
Ok(t, err)
pull := models.PullRequest{Num: 1}
s, _ := client.MarkdownPullLink(pull)
exp := "!1"
Equals(t, exp, s)
}
var mergeSuccess = `{"id":22461274,"iid":13,"project_id":4580910,"title":"Update main.tf","description":"","state":"merged","created_at":"2019-01-15T18:27:29.375Z","updated_at":"2019-01-25T17:28:01.437Z","merged_by":{"id":1755902,"name":"Luke Kysow","username":"lkysow","state":"active","avatar_url":"https://secure.gravatar.com/avatar/25fd57e71590fe28736624ff24d41c5f?s=80\u0026d=identicon","web_url":"https://gitlab.com/lkysow"},"merged_at":"2019-01-25T17:28:01.459Z","closed_by":null,"closed_at":null,"target_branch":"patch-1","source_branch":"patch-1-merger","upvotes":0,"downvotes":0,"author":{"id":1755902,"name":"Luke Kysow","username":"lkysow","state":"active","avatar_url":"https://secure.gravatar.com/avatar/25fd57e71590fe28736624ff24d41c5f?s=80\u0026d=identicon","web_url":"https://gitlab.com/lkysow"},"assignee":null,"source_project_id":4580910,"target_project_id":4580910,"labels":[],"work_in_progress":false,"milestone":null,"merge_when_pipeline_succeeds":false,"merge_status":"can_be_merged","sha":"cb86d70f464632bdfbe1bb9bc0f2f9d847a774a0","merge_commit_sha":"c9b336f1c71d3e64810b8cfa2abcfab232d6bff6","user_notes_count":0,"discussion_locked":null,"should_remove_source_branch":null,"force_remove_source_branch":false,"web_url":"https://gitlab.com/lkysow/atlantis-example/merge_requests/13","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"squash":false,"subscribed":true,"changes_count":"1","latest_build_started_at":null,"latest_build_finished_at":null,"first_deployed_to_production_at":null,"pipeline":null,"diff_refs":{"base_sha":"67cb91d3f6198189f433c045154a885784ba6977","head_sha":"cb86d70f464632bdfbe1bb9bc0f2f9d847a774a0","start_sha":"67cb91d3f6198189f433c045154a885784ba6977"},"merge_error":null,"approvals_before_merge":null}`