mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-28 21:28:20 +00:00
Operating on forked pull requests is dangerous if it's a public repo because anyone can make a pull request to a public repo. We default to false like CircleCI and TravisCI who don't allow credentials to be available on fork PRs.
231 lines
7.0 KiB
Go
231 lines
7.0 KiB
Go
package server_test
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gorilla/mux"
|
|
. "github.com/petergtz/pegomock"
|
|
"github.com/runatlantis/atlantis/server"
|
|
"github.com/runatlantis/atlantis/server/events/locking/mocks"
|
|
"github.com/runatlantis/atlantis/server/events/models"
|
|
"github.com/runatlantis/atlantis/server/logging"
|
|
sMocks "github.com/runatlantis/atlantis/server/mocks"
|
|
. "github.com/runatlantis/atlantis/testing"
|
|
)
|
|
|
|
func TestNewServer(t *testing.T) {
|
|
t.Log("Run through NewServer constructor")
|
|
tmpDir, err := ioutil.TempDir("", "")
|
|
Ok(t, err)
|
|
_, err = server.NewServer(server.Config{
|
|
DataDir: tmpDir,
|
|
}, server.FlagNames{})
|
|
Ok(t, err)
|
|
}
|
|
|
|
func TestIndex_LockErr(t *testing.T) {
|
|
t.Log("index should return a 503 if unable to list locks")
|
|
RegisterMockTestingT(t)
|
|
l := mocks.NewMockLocker()
|
|
When(l.List()).ThenReturn(nil, errors.New("err"))
|
|
s := server.Server{
|
|
Locker: l,
|
|
}
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s.Index(w, eventsReq)
|
|
responseContains(t, w, 503, "Could not retrieve locks: err")
|
|
}
|
|
|
|
func TestIndex_Success(t *testing.T) {
|
|
t.Log("Index should render the index template successfully.")
|
|
RegisterMockTestingT(t)
|
|
l := mocks.NewMockLocker()
|
|
// These are the locks that we expect to be rendered.
|
|
now := time.Now()
|
|
locks := map[string]models.ProjectLock{
|
|
"id1": {
|
|
Pull: models.PullRequest{
|
|
Num: 9,
|
|
},
|
|
Project: models.Project{
|
|
RepoFullName: "owner/repo",
|
|
},
|
|
Time: now,
|
|
},
|
|
}
|
|
When(l.List()).ThenReturn(locks, nil)
|
|
it := sMocks.NewMockTemplateWriter()
|
|
r := mux.NewRouter()
|
|
// Need to create a lock route since the server expects this route to exist.
|
|
r.NewRoute().Path("").Name(server.LockRouteName)
|
|
s := server.Server{
|
|
Locker: l,
|
|
IndexTemplate: it,
|
|
Router: r,
|
|
}
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s.Index(w, eventsReq)
|
|
it.VerifyWasCalledOnce().Execute(w, []server.LockIndexData{
|
|
{
|
|
LockURL: "",
|
|
RepoFullName: "owner/repo",
|
|
PullNum: 9,
|
|
Time: now,
|
|
},
|
|
})
|
|
responseContains(t, w, http.StatusOK, "")
|
|
}
|
|
|
|
func TestGetLockRoute_NoLockID(t *testing.T) {
|
|
t.Log("If there is no lock ID in the request then we should get a 400")
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s := server.Server{}
|
|
s.GetLockRoute(w, eventsReq)
|
|
responseContains(t, w, http.StatusBadRequest, "No lock id in request")
|
|
}
|
|
|
|
func TestGetLock_InvalidLockID(t *testing.T) {
|
|
t.Log("If the lock ID is invalid then we should get a 400")
|
|
s := server.Server{}
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s.GetLock(w, eventsReq, "%A@")
|
|
responseContains(t, w, http.StatusBadRequest, "Invalid lock id")
|
|
}
|
|
|
|
func TestGetLock_LockerErr(t *testing.T) {
|
|
t.Log("If there is an error retrieving the lock, a 500 is returned")
|
|
RegisterMockTestingT(t)
|
|
l := mocks.NewMockLocker()
|
|
When(l.GetLock("id")).ThenReturn(nil, errors.New("err"))
|
|
s := server.Server{
|
|
Locker: l,
|
|
}
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s.GetLock(w, eventsReq, "id")
|
|
responseContains(t, w, http.StatusInternalServerError, "err")
|
|
}
|
|
|
|
func TestGetLock_None(t *testing.T) {
|
|
t.Log("If there is no lock at that ID we get a 404")
|
|
RegisterMockTestingT(t)
|
|
l := mocks.NewMockLocker()
|
|
When(l.GetLock("id")).ThenReturn(nil, nil)
|
|
s := server.Server{
|
|
Locker: l,
|
|
}
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s.GetLock(w, eventsReq, "id")
|
|
responseContains(t, w, http.StatusNotFound, "No lock found at that id")
|
|
}
|
|
|
|
func TestGetLock_Success(t *testing.T) {
|
|
t.Log("Should be able to render a lock successfully")
|
|
RegisterMockTestingT(t)
|
|
l := mocks.NewMockLocker()
|
|
When(l.GetLock("id")).ThenReturn(&models.ProjectLock{
|
|
Project: models.Project{RepoFullName: "owner/repo", Path: "path"},
|
|
Pull: models.PullRequest{URL: "url", Author: "lkysow"},
|
|
Workspace: "workspace",
|
|
}, nil)
|
|
tmpl := sMocks.NewMockTemplateWriter()
|
|
s := server.Server{
|
|
Locker: l,
|
|
LockDetailTemplate: tmpl,
|
|
}
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s.GetLock(w, eventsReq, "id")
|
|
tmpl.VerifyWasCalledOnce().Execute(w, server.LockDetailData{
|
|
LockKeyEncoded: "id",
|
|
LockKey: "id",
|
|
RepoOwner: "owner",
|
|
RepoName: "repo",
|
|
PullRequestLink: "url",
|
|
LockedBy: "lkysow",
|
|
Workspace: "workspace",
|
|
})
|
|
responseContains(t, w, http.StatusOK, "")
|
|
}
|
|
|
|
func TestDeleteLockRoute_NoLockID(t *testing.T) {
|
|
t.Log("If there is no lock ID in the request then we should get a 400")
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s := server.Server{Logger: logging.NewNoopLogger()}
|
|
s.DeleteLockRoute(w, eventsReq)
|
|
responseContains(t, w, http.StatusBadRequest, "No lock id in request")
|
|
}
|
|
|
|
func TestDeleteLock_InvalidLockID(t *testing.T) {
|
|
t.Log("If the lock ID is invalid then we should get a 400")
|
|
s := server.Server{Logger: logging.NewNoopLogger()}
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s.DeleteLock(w, eventsReq, "%A@")
|
|
responseContains(t, w, http.StatusBadRequest, "Invalid lock id")
|
|
}
|
|
|
|
func TestDeleteLock_LockerErr(t *testing.T) {
|
|
t.Log("If there is an error retrieving the lock, a 500 is returned")
|
|
RegisterMockTestingT(t)
|
|
l := mocks.NewMockLocker()
|
|
When(l.Unlock("id")).ThenReturn(nil, errors.New("err"))
|
|
s := server.Server{
|
|
Locker: l,
|
|
Logger: logging.NewNoopLogger(),
|
|
}
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s.DeleteLock(w, eventsReq, "id")
|
|
responseContains(t, w, http.StatusInternalServerError, "err")
|
|
}
|
|
|
|
func TestDeleteLock_None(t *testing.T) {
|
|
t.Log("If there is no lock at that ID we get a 404")
|
|
RegisterMockTestingT(t)
|
|
l := mocks.NewMockLocker()
|
|
When(l.Unlock("id")).ThenReturn(nil, nil)
|
|
s := server.Server{
|
|
Locker: l,
|
|
Logger: logging.NewNoopLogger(),
|
|
}
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s.DeleteLock(w, eventsReq, "id")
|
|
responseContains(t, w, http.StatusNotFound, "No lock found at that id")
|
|
}
|
|
|
|
func TestDeleteLock_Success(t *testing.T) {
|
|
t.Log("If the lock is deleted successfully we get a 200")
|
|
RegisterMockTestingT(t)
|
|
l := mocks.NewMockLocker()
|
|
When(l.Unlock("id")).ThenReturn(&models.ProjectLock{}, nil)
|
|
s := server.Server{
|
|
Locker: l,
|
|
Logger: logging.NewNoopLogger(),
|
|
}
|
|
eventsReq, _ = http.NewRequest("GET", "", bytes.NewBuffer(nil))
|
|
w := httptest.NewRecorder()
|
|
s.DeleteLock(w, eventsReq, "id")
|
|
responseContains(t, w, http.StatusOK, "Deleted lock id id")
|
|
}
|
|
|
|
func responseContains(t *testing.T, r *httptest.ResponseRecorder, status int, bodySubstr string) {
|
|
Equals(t, status, r.Result().StatusCode)
|
|
body, _ := ioutil.ReadAll(r.Result().Body)
|
|
Assert(t, strings.Contains(string(body), bodySubstr), "exp %q to be contained in %q", bodySubstr, string(body))
|
|
}
|