Skip to content
quarry Artifact [188d26ada9]
Login

Artifact [188d26ada9]

Artifact 188d26ada99d07791549b240907b50adca259d58f43885e08e701c0eded11323:


package api

import (
	"encoding/json"
	"fmt"
	"strings"
	"testing"
)

// decidedTo is the signoff.decided events held for account.
func (g *setupRig) decidedTo(account string) []AttentionEvent {
	var out []AttentionEvent
	for _, e := range g.attn.to(account) {
		if e.Kind == "signoff.decided" {
			out = append(out, e)
		}
	}
	return out
}

// The asking agent is told, once, on its own attention stream, when its
// request is decided; the id, the op, the repository and the new state
// ride on it, and nobody else is told.
func TestTheAskerIsToldOnceWhenItsRequestIsDecided(t *testing.T) {
	for _, tc := range []struct {
		name    string
		approve bool
		state   string
	}{{"approved", true, "approved"}, {"denied", false, "denied"}} {
		t.Run(tc.name, func(t *testing.T) {
			g := newSetupRig(t)
			id := g.ask("zeitgeist", pushBody, "")
			if n := len(g.decidedTo("zeitgeist")); n != 0 {
				t.Fatalf("FAIL: told %d times before any decision", n)
			}
			if err := g.decide("dmestas", id, tc.approve); err != nil {
				t.Fatal(err)
			}
			got := g.decidedTo("zeitgeist")
			if len(got) != 1 {
				t.Fatalf("FAIL: the asker got %d signoff.decided events", len(got))
			}
			e := got[0]
			if e.Repo != "" || e.Link != "/api/v1/signoffs/"+id || e.Summary != "agent.setup "+tc.state {
				t.Errorf("FAIL: the event: %+v", e)
			}
			for _, other := range []string{"dmestas", "jva", "dmestas-bot", "jva-bot", "suit-ci", ""} {
				if n := len(g.decidedTo(other)); n != 0 {
					t.Errorf("FAIL: %q got %d signoff.decided events", other, n)
				}
			}
			if !t.Failed() {
				t.Log("ok")
			}
		})
	}
}

// A request whose approval ran and failed tells the asker it failed.
func TestTheAskerIsToldWhenAnApprovedCallFailed(t *testing.T) {
	g := newSetupRig(t)
	id := g.ask("zeitgeist", pushBody, "")
	if err := g.db.AddAccount("suit-push", "a-long-enough-password", false); err != nil {
		t.Fatal(err)
	}
	if err := g.decide("dmestas", id, true); err == nil {
		t.Fatalf("FAIL: approving a request whose name was taken succeeded")
	}
	got := g.decidedTo("zeitgeist")
	if len(got) != 1 || got[0].Summary != "agent.setup failed" {
		t.Fatalf("FAIL: the asker's events: %+v", got)
	}
	if !t.Failed() {
		t.Log("ok")
	}
}

// Nothing a pickup or a minted token holds rides the event.
func TestTheDecidedEventCarriesNoSecret(t *testing.T) {
	g := newSetupRig(t)
	id := g.ask("zeitgeist", pushBody, "")
	if err := g.decide("dmestas", id, true); err != nil {
		t.Fatal(err)
	}
	var sec struct{ Value string }
	if err := json.Unmarshal(g.get("zeitgeist", id).Secret, &sec); err != nil || !strings.HasPrefix(sec.Value, "qat_") {
		t.Fatalf("FAIL: the asker's first read lacks the value")
	}
	got := g.decidedTo("zeitgeist")
	if len(got) != 1 {
		t.Fatalf("FAIL: %d events", len(got))
	}
	raw, _ := json.Marshal(got[0])
	if strings.Contains(string(raw), sec.Value) || strings.Contains(string(raw), "qat_") {
		t.Errorf("FAIL: the event carries the credential")
	}

	// A request bound to a pickup code: neither the public code nor the
	// key it hashes from rides the event.
	key, code := newPickupKey(t)
	pid := g.ask("dmestas-bot", `{"name":"e-p","kind":"read","repos":"suit"}`, code)
	if err := g.decide("dmestas", pid, true); err != nil {
		t.Fatal(err)
	}
	pe := g.decidedTo("dmestas-bot")
	if len(pe) != 1 {
		t.Fatalf("FAIL: %d events for the pickup-bound request", len(pe))
	}
	raw, _ = json.Marshal(pe[0])
	if strings.Contains(string(raw), code) || strings.Contains(string(raw), fmt.Sprint(key)) {
		t.Errorf("FAIL: the event carries the pickup code")
	}
	if !t.Failed() {
		t.Log("ok")
	}
}

// A broker that is down changes nothing about the decision.
func TestAnEmitFailureDoesNotChangeTheDecision(t *testing.T) {
	g := newSetupRig(t)
	id := g.ask("zeitgeist", pushBody, "")
	g.attnDown = true
	if err := g.decide("dmestas", id, true); err != nil {
		t.Fatalf("FAIL: the decision failed with the broker down: %v", err)
	}
	got := g.get("zeitgeist", id)
	if got.Request.State != "approved" || got.Setup == nil || !got.Setup.Done {
		t.Errorf("FAIL: the request: %+v", got.Request)
	}
	if _, ok := g.db.AccountByName("suit-push"); !ok {
		t.Errorf("FAIL: the agent was not made")
	}
	if n := len(g.decidedTo("zeitgeist")); n != 0 {
		t.Errorf("FAIL: an event arrived through a down broker")
	}
	if !t.Failed() {
		t.Log("ok")
	}
}