Adding approval process

This commit is contained in:
2023-07-03 17:26:43 -04:00
parent a43264189f
commit b1b010deee
15 changed files with 640 additions and 71 deletions

View File

@@ -1,20 +1,155 @@
package registrar
import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.fixergrid.net/servicedemon/pkg/pubsub"
)
func TestHandleRegister(t *testing.T) {
type TestRequest http.Request
func NewTestRequest(t *testing.T, method string, url string, body io.Reader) TestRequest {
req, err := http.NewRequest(method, url, body)
require.NoError(t, err)
return TestRequest(*req)
}
func (tr TestRequest) WithFakeTLSState(dnsName string) TestRequest {
cert := x509.Certificate{
DNSNames: []string{
dnsName,
},
}
tr.TLS = &tls.ConnectionState{
PeerCertificates: []*x509.Certificate{&cert},
}
return tr
}
func (tr TestRequest) Create() *http.Request {
req := http.Request(tr)
return &req
}
type AppState struct {
Name string
State string
}
type TestAppRepo []AppState
func (repo TestAppRepo) IsRegistered(name string) bool {
for _, app := range repo {
if name == app.Name && app.State == "registered" {
return true
}
}
return false
}
func (repo TestAppRepo) PendingApprovalCount() int {
count := 0
for _, app := range repo {
if app.State == "pending_approval" {
count += 1
}
}
return count
}
func (repo *TestAppRepo) StartAppRegistration(name string) uuid.UUID {
*repo = append(*repo, AppState{
Name: name,
State: "pending_approval",
})
return uuid.New()
}
func TestHandleRegisterPendingApproval(t *testing.T) {
resp := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "http://example.com/v1/register", nil)
req := NewTestRequest(t, http.MethodPost, "http://example.com/v1/register", nil).
WithFakeTLSState("dev-app-1.delivery.engineering").
Create()
repo := &TestAppRepo{}
pubsub := pubsub.New()
subscriber := pubsub.Subscribe(REGISTRATION_TOPIC)
NewRegistrar(pubsub, repo).HandleRegistration(resp, req)
assert.Equal(t, http.StatusCreated, resp.Code)
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
HandleRegister(resp, req)
assert.Equal(t, []byte(`{"status": "pending_approval"}`), body)
assert.Equal(t, http.StatusBadRequest, resp.Code)
assert.Equal(t, 1, repo.PendingApprovalCount())
expectedEvent := map[string]string{
"name": "dev-app-1.delivery.engineering",
"type": "ApplicationRegistrationSubmitted",
}
assertMessage(t, expectedEvent, subscriber)
}
func TestHandleRegisterAlreadyRegistered(t *testing.T) {
resp := httptest.NewRecorder()
req := NewTestRequest(t, http.MethodPost, "http://example.com/v1/register", nil).
WithFakeTLSState("dev-app-1.delivery.engineering").
Create()
pubsub := pubsub.New()
repo := &TestAppRepo{
AppState{
Name: "dev-app-1.delivery.engineering",
State: "registered",
},
}
NewRegistrar(pubsub, repo).HandleRegistration(resp, req)
assert.Equal(t, http.StatusOK, resp.Code)
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t, []byte(`{"status": "registered"}`), body)
}
func assertMessage(t *testing.T, expected map[string]string, sender <-chan string) {
timer := time.After(2 * time.Second)
for {
select {
case msg := <-sender:
compareMessage(t, expected, msg)
return
case <-timer:
t.Fatal("failed waiting for message")
}
}
}
func compareMessage(t *testing.T, expected map[string]string, observed string) {
observedEvent := map[string]string{}
require.NoError(t, json.Unmarshal([]byte(observed), &observedEvent))
assert.NotEmpty(t, observedEvent["id"])
for k, v := range expected {
assert.Equal(t, v, observedEvent[k])
}
}