612 lines
13 KiB
Go
612 lines
13 KiB
Go
package http
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/keel-hq/keel/approvals"
|
|
"github.com/keel-hq/keel/pkg/auth"
|
|
"github.com/keel-hq/keel/provider"
|
|
"github.com/keel-hq/keel/types"
|
|
)
|
|
|
|
func TestListApprovals(t *testing.T) {
|
|
|
|
fp := &fakeProvider{}
|
|
store, teardown := NewTestingUtils()
|
|
defer teardown()
|
|
|
|
am := approvals.New(&approvals.Opts{
|
|
Store: store,
|
|
})
|
|
|
|
authenticator := auth.New(&auth.Opts{
|
|
Username: "admin",
|
|
Password: "pass",
|
|
})
|
|
|
|
providers := provider.New([]provider.Provider{fp}, am)
|
|
srv := NewTriggerServer(&Opts{
|
|
Providers: providers,
|
|
ApprovalManager: am,
|
|
Authenticator: authenticator,
|
|
Store: store,
|
|
})
|
|
srv.registerRoutes(srv.router)
|
|
|
|
err := am.Create(&types.Approval{
|
|
Identifier: "123",
|
|
VotesRequired: 5,
|
|
NewVersion: "2.0.0",
|
|
CurrentVersion: "1.0.0",
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatalf("failed to create approval: %s", err)
|
|
}
|
|
|
|
// listing
|
|
req, err := http.NewRequest("GET", "/v1/approvals", nil)
|
|
if err != nil {
|
|
t.Fatalf("failed to create req: %s", err)
|
|
}
|
|
|
|
req.SetBasicAuth("admin", "pass")
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
srv.router.ServeHTTP(rec, req)
|
|
if rec.Code != 200 {
|
|
t.Errorf("unexpected status code: %d", rec.Code)
|
|
|
|
t.Log(rec.Body.String())
|
|
}
|
|
|
|
var approvals []*types.Approval
|
|
|
|
err = json.Unmarshal(rec.Body.Bytes(), &approvals)
|
|
if err != nil {
|
|
t.Fatalf("failed to unmarshal response into approvals: %s", err)
|
|
}
|
|
|
|
if len(approvals) != 1 {
|
|
t.Fatalf("expected to find 1 approval but found: %d", len(approvals))
|
|
}
|
|
|
|
if approvals[0].VotesRequired != 5 {
|
|
t.Errorf("unexpected votes required")
|
|
}
|
|
if approvals[0].NewVersion != "2.0.0" {
|
|
t.Errorf("unexpected new version: %s", approvals[0].NewVersion)
|
|
}
|
|
if approvals[0].CurrentVersion != "1.0.0" {
|
|
t.Errorf("unexpected current version: %s", approvals[0].CurrentVersion)
|
|
}
|
|
}
|
|
|
|
func TestDeleteApproval(t *testing.T) {
|
|
fp := &fakeProvider{}
|
|
store, teardown := NewTestingUtils()
|
|
defer teardown()
|
|
|
|
am := approvals.New(&approvals.Opts{
|
|
Store: store,
|
|
})
|
|
|
|
authenticator := auth.New(&auth.Opts{
|
|
Username: "admin",
|
|
Password: "pass",
|
|
})
|
|
|
|
providers := provider.New([]provider.Provider{fp}, am)
|
|
srv := NewTriggerServer(&Opts{
|
|
Providers: providers,
|
|
ApprovalManager: am,
|
|
Authenticator: authenticator,
|
|
Store: store,
|
|
})
|
|
srv.registerRoutes(srv.router)
|
|
|
|
err := am.Create(&types.Approval{
|
|
Identifier: "dev/whd-dev:0.0.15",
|
|
VotesRequired: 5,
|
|
NewVersion: "2.0.0",
|
|
CurrentVersion: "1.0.0",
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatalf("failed to create approval: %s", err)
|
|
}
|
|
|
|
// listing
|
|
req, err := http.NewRequest("POST", "/v1/approvals", bytes.NewBufferString(`{"action": "delete","identifier": "dev/whd-dev:0.0.15"}`))
|
|
if err != nil {
|
|
t.Fatalf("failed to create req: %s", err)
|
|
}
|
|
|
|
req.SetBasicAuth("admin", "pass")
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
srv.router.ServeHTTP(rec, req)
|
|
if rec.Code != 200 {
|
|
t.Errorf("unexpected status code: %d", rec.Code)
|
|
|
|
t.Log(rec.Body.String())
|
|
}
|
|
|
|
deleted, err := am.Get("dev/whd-dev:0.0.15")
|
|
if err == nil {
|
|
t.Errorf("expected approval to be deleted, got ident: %s", deleted.Identifier)
|
|
}
|
|
}
|
|
|
|
func TestApprove(t *testing.T) {
|
|
fp := &fakeProvider{}
|
|
store, teardown := NewTestingUtils()
|
|
defer teardown()
|
|
|
|
am := approvals.New(&approvals.Opts{
|
|
Store: store,
|
|
})
|
|
authenticator := auth.New(&auth.Opts{
|
|
Username: "admin",
|
|
Password: "pass",
|
|
})
|
|
|
|
providers := provider.New([]provider.Provider{fp}, am)
|
|
srv := NewTriggerServer(&Opts{
|
|
Providers: providers,
|
|
ApprovalManager: am,
|
|
Authenticator: authenticator,
|
|
Store: store,
|
|
})
|
|
srv.registerRoutes(srv.router)
|
|
|
|
err := am.Create(&types.Approval{
|
|
Identifier: "dev/whd-dev:0.0.15",
|
|
VotesRequired: 5,
|
|
NewVersion: "2.0.0",
|
|
CurrentVersion: "1.0.0",
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatalf("failed to create approval: %s", err)
|
|
}
|
|
|
|
// listing
|
|
req, err := http.NewRequest("POST", "/v1/approvals", bytes.NewBufferString(`{"voter": "foo","identifier": "dev/whd-dev:0.0.15"}`))
|
|
if err != nil {
|
|
t.Fatalf("failed to create req: %s", err)
|
|
}
|
|
req.SetBasicAuth("admin", "pass")
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
srv.router.ServeHTTP(rec, req)
|
|
if rec.Code != 200 {
|
|
t.Errorf("unexpected status code: %d", rec.Code)
|
|
|
|
t.Log(rec.Body.String())
|
|
}
|
|
|
|
approved, err := am.Get("dev/whd-dev:0.0.15")
|
|
if err != nil {
|
|
t.Fatalf("failed to get approval: %s", err)
|
|
}
|
|
|
|
if approved.VotesReceived != 1 {
|
|
t.Errorf("expected to find one voter")
|
|
}
|
|
|
|
voters := approved.GetVoters()
|
|
if voters[0] != "foo" {
|
|
t.Errorf("unexpected voter: %s", voters[0])
|
|
}
|
|
}
|
|
|
|
func TestApproveNotFound(t *testing.T) {
|
|
fp := &fakeProvider{}
|
|
store, teardown := NewTestingUtils()
|
|
defer teardown()
|
|
|
|
am := approvals.New(&approvals.Opts{
|
|
Store: store,
|
|
})
|
|
authenticator := auth.New(&auth.Opts{
|
|
Username: "admin",
|
|
Password: "pass",
|
|
})
|
|
|
|
providers := provider.New([]provider.Provider{fp}, am)
|
|
srv := NewTriggerServer(&Opts{
|
|
Providers: providers,
|
|
ApprovalManager: am,
|
|
Authenticator: authenticator,
|
|
Store: store,
|
|
})
|
|
srv.registerRoutes(srv.router)
|
|
|
|
// listing
|
|
req, err := http.NewRequest("POST", "/v1/approvals", bytes.NewBufferString(`{"voter": "foo","identifier": "dev/whd-dev:0.0.15"}`))
|
|
if err != nil {
|
|
t.Fatalf("failed to create req: %s", err)
|
|
}
|
|
req.SetBasicAuth("admin", "pass")
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
srv.router.ServeHTTP(rec, req)
|
|
if rec.Code != 404 {
|
|
t.Errorf("unexpected status code: %d", rec.Code)
|
|
|
|
t.Log(rec.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestApproveGarbageRequest(t *testing.T) {
|
|
fp := &fakeProvider{}
|
|
store, teardown := NewTestingUtils()
|
|
defer teardown()
|
|
|
|
am := approvals.New(&approvals.Opts{
|
|
Store: store,
|
|
})
|
|
authenticator := auth.New(&auth.Opts{
|
|
Username: "admin",
|
|
Password: "pass",
|
|
})
|
|
|
|
providers := provider.New([]provider.Provider{fp}, am)
|
|
srv := NewTriggerServer(&Opts{
|
|
Providers: providers,
|
|
ApprovalManager: am,
|
|
Authenticator: authenticator,
|
|
Store: store,
|
|
})
|
|
srv.registerRoutes(srv.router)
|
|
|
|
// listing
|
|
req, err := http.NewRequest("POST", "/v1/approvals", bytes.NewBufferString(`<>`))
|
|
if err != nil {
|
|
t.Fatalf("failed to create req: %s", err)
|
|
}
|
|
|
|
req.SetBasicAuth("admin", "pass")
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
srv.router.ServeHTTP(rec, req)
|
|
if rec.Code != 400 {
|
|
t.Errorf("unexpected status code: %d", rec.Code)
|
|
|
|
t.Log(rec.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestSameVoter(t *testing.T) {
|
|
fp := &fakeProvider{}
|
|
store, teardown := NewTestingUtils()
|
|
defer teardown()
|
|
|
|
am := approvals.New(&approvals.Opts{
|
|
Store: store,
|
|
})
|
|
authenticator := auth.New(&auth.Opts{
|
|
Username: "admin",
|
|
Password: "pass",
|
|
})
|
|
|
|
providers := provider.New([]provider.Provider{fp}, am)
|
|
srv := NewTriggerServer(&Opts{
|
|
Providers: providers,
|
|
ApprovalManager: am,
|
|
Authenticator: authenticator,
|
|
Store: store,
|
|
})
|
|
srv.registerRoutes(srv.router)
|
|
|
|
err := am.Create(&types.Approval{
|
|
Identifier: "dev/12345",
|
|
VotesRequired: 5,
|
|
NewVersion: "2.0.0",
|
|
CurrentVersion: "1.0.0",
|
|
VotesReceived: 1,
|
|
Voters: map[string]interface{}{"foo": time.Now()},
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatalf("failed to create approval: %s", err)
|
|
}
|
|
|
|
// listing
|
|
req, err := http.NewRequest("POST", "/v1/approvals", bytes.NewBufferString(`{"voter": "foo", "identifier": "dev/12345"}`))
|
|
if err != nil {
|
|
t.Fatalf("failed to create req: %s", err)
|
|
}
|
|
req.SetBasicAuth("admin", "pass")
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
srv.router.ServeHTTP(rec, req)
|
|
if rec.Code != 200 {
|
|
t.Errorf("unexpected status code: %d", rec.Code)
|
|
|
|
t.Log(rec.Body.String())
|
|
}
|
|
|
|
approved, err := am.Get("dev/12345")
|
|
if err != nil {
|
|
t.Fatalf("failed to get approval: %s", err)
|
|
}
|
|
|
|
if approved.VotesReceived != 1 {
|
|
t.Errorf("expected to find one voter")
|
|
}
|
|
|
|
voters := approved.GetVoters()
|
|
|
|
if voters[0] != "foo" {
|
|
t.Errorf("unexpected voter: %s", voters[0])
|
|
}
|
|
}
|
|
|
|
func TestDifferentVoter(t *testing.T) {
|
|
fp := &fakeProvider{}
|
|
store, teardown := NewTestingUtils()
|
|
defer teardown()
|
|
|
|
am := approvals.New(&approvals.Opts{
|
|
Store: store,
|
|
})
|
|
authenticator := auth.New(&auth.Opts{
|
|
Username: "admin",
|
|
Password: "pass",
|
|
})
|
|
|
|
providers := provider.New([]provider.Provider{fp}, am)
|
|
srv := NewTriggerServer(&Opts{
|
|
Providers: providers,
|
|
ApprovalManager: am,
|
|
Authenticator: authenticator,
|
|
Store: store,
|
|
})
|
|
srv.registerRoutes(srv.router)
|
|
|
|
err := am.Create(&types.Approval{
|
|
Identifier: "dev/12345",
|
|
VotesRequired: 5,
|
|
NewVersion: "2.0.0",
|
|
CurrentVersion: "1.0.0",
|
|
VotesReceived: 1,
|
|
Voters: map[string]interface{}{"bar": time.Now()},
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatalf("failed to create approval: %s", err)
|
|
}
|
|
|
|
// listing
|
|
req, err := http.NewRequest("POST", "/v1/approvals", bytes.NewBufferString(`{"voter": "foo", "identifier": "dev/12345"}`))
|
|
if err != nil {
|
|
t.Fatalf("failed to create req: %s", err)
|
|
}
|
|
req.SetBasicAuth("admin", "pass")
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
srv.router.ServeHTTP(rec, req)
|
|
if rec.Code != 200 {
|
|
t.Errorf("unexpected status code: %d", rec.Code)
|
|
|
|
t.Log(rec.Body.String())
|
|
}
|
|
|
|
approved, err := am.Get("dev/12345")
|
|
if err != nil {
|
|
t.Fatalf("failed to get approval: %s", err)
|
|
}
|
|
|
|
if approved.VotesReceived != 2 {
|
|
t.Errorf("expected to find 2 voters")
|
|
}
|
|
|
|
_, fooFound := approved.Voters["foo"]
|
|
if !fooFound {
|
|
t.Errorf("expected to find 'foo' voter")
|
|
}
|
|
_, barFound := approved.Voters["bar"]
|
|
if !barFound {
|
|
t.Errorf("expected to find 'bar' voter")
|
|
}
|
|
}
|
|
|
|
func TestReject(t *testing.T) {
|
|
fp := &fakeProvider{}
|
|
store, teardown := NewTestingUtils()
|
|
defer teardown()
|
|
|
|
am := approvals.New(&approvals.Opts{
|
|
Store: store,
|
|
})
|
|
authenticator := auth.New(&auth.Opts{
|
|
Username: "admin",
|
|
Password: "pass",
|
|
})
|
|
|
|
providers := provider.New([]provider.Provider{fp}, am)
|
|
srv := NewTriggerServer(&Opts{
|
|
Providers: providers,
|
|
ApprovalManager: am,
|
|
Authenticator: authenticator,
|
|
Store: store,
|
|
})
|
|
srv.registerRoutes(srv.router)
|
|
|
|
err := am.Create(&types.Approval{
|
|
Identifier: "dev/12345",
|
|
VotesRequired: 5,
|
|
NewVersion: "2.0.0",
|
|
CurrentVersion: "1.0.0",
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatalf("failed to create approval: %s", err)
|
|
}
|
|
|
|
// listing
|
|
req, err := http.NewRequest("POST", "/v1/approvals", bytes.NewBufferString(`{"voter": "foo", "action": "reject", "identifier":"dev/12345"}`))
|
|
if err != nil {
|
|
t.Fatalf("failed to create req: %s", err)
|
|
}
|
|
|
|
req.SetBasicAuth("admin", "pass")
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
srv.router.ServeHTTP(rec, req)
|
|
if rec.Code != 200 {
|
|
t.Errorf("unexpected status code: %d", rec.Code)
|
|
|
|
t.Log(rec.Body.String())
|
|
}
|
|
|
|
approved, err := am.Get("dev/12345")
|
|
if err != nil {
|
|
t.Fatalf("failed to get approval: %s", err)
|
|
}
|
|
|
|
if approved.Rejected != true {
|
|
t.Errorf("expected to find approval rejected")
|
|
}
|
|
|
|
}
|
|
|
|
func TestAuthListApprovalsA(t *testing.T) {
|
|
|
|
fp := &fakeProvider{}
|
|
store, teardown := NewTestingUtils()
|
|
defer teardown()
|
|
|
|
am := approvals.New(&approvals.Opts{
|
|
Store: store,
|
|
})
|
|
|
|
authenticator := auth.New(&auth.Opts{
|
|
Username: "user-1",
|
|
Password: " secret",
|
|
})
|
|
|
|
providers := provider.New([]provider.Provider{fp}, am)
|
|
srv := NewTriggerServer(&Opts{
|
|
Providers: providers,
|
|
ApprovalManager: am,
|
|
Authenticator: authenticator,
|
|
})
|
|
srv.registerRoutes(srv.router)
|
|
|
|
err := am.Create(&types.Approval{
|
|
Identifier: "123",
|
|
VotesRequired: 5,
|
|
NewVersion: "2.0.0",
|
|
CurrentVersion: "1.0.0",
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatalf("failed to create approval: %s", err)
|
|
}
|
|
|
|
// listing
|
|
req, err := http.NewRequest("GET", "/v1/approvals", nil)
|
|
if err != nil {
|
|
t.Fatalf("failed to create req: %s", err)
|
|
}
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
srv.router.ServeHTTP(rec, req)
|
|
if rec.Code != 401 {
|
|
t.Errorf("expected 401 status code, got: %d", rec.Code)
|
|
|
|
t.Log(rec.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestAuthListApprovalsB(t *testing.T) {
|
|
|
|
fp := &fakeProvider{}
|
|
store, teardown := NewTestingUtils()
|
|
defer teardown()
|
|
|
|
am := approvals.New(&approvals.Opts{
|
|
Store: store,
|
|
})
|
|
|
|
authenticator := auth.New(&auth.Opts{
|
|
Username: "user-1",
|
|
Password: "secret",
|
|
})
|
|
|
|
providers := provider.New([]provider.Provider{fp}, am)
|
|
srv := NewTriggerServer(&Opts{
|
|
Providers: providers,
|
|
ApprovalManager: am,
|
|
Authenticator: authenticator,
|
|
Store: store,
|
|
})
|
|
srv.registerRoutes(srv.router)
|
|
|
|
err := am.Create(&types.Approval{
|
|
Identifier: "123",
|
|
VotesRequired: 5,
|
|
NewVersion: "2.0.0",
|
|
CurrentVersion: "1.0.0",
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatalf("failed to create approval: %s", err)
|
|
}
|
|
|
|
// listing
|
|
req, err := http.NewRequest("GET", "/v1/approvals", nil)
|
|
if err != nil {
|
|
t.Fatalf("failed to create req: %s", err)
|
|
}
|
|
|
|
req.SetBasicAuth("user-1", "secret")
|
|
|
|
rec := httptest.NewRecorder()
|
|
|
|
srv.router.ServeHTTP(rec, req)
|
|
if rec.Code != 200 {
|
|
t.Errorf("expected 200 status code, got: %d", rec.Code)
|
|
|
|
t.Log(rec.Body.String())
|
|
}
|
|
|
|
var approvals []*types.Approval
|
|
|
|
err = json.Unmarshal(rec.Body.Bytes(), &approvals)
|
|
if err != nil {
|
|
t.Fatalf("failed to unmarshal response into approvals: %s", err)
|
|
}
|
|
|
|
if len(approvals) != 1 {
|
|
t.Fatalf("expected to find 1 approval but found: %d", len(approvals))
|
|
}
|
|
|
|
if approvals[0].VotesRequired != 5 {
|
|
t.Errorf("unexpected votes required")
|
|
}
|
|
if approvals[0].NewVersion != "2.0.0" {
|
|
t.Errorf("unexpected new version: %s", approvals[0].NewVersion)
|
|
}
|
|
if approvals[0].CurrentVersion != "1.0.0" {
|
|
t.Errorf("unexpected current version: %s", approvals[0].CurrentVersion)
|
|
}
|
|
}
|