157 lines
5.7 KiB
Go
157 lines
5.7 KiB
Go
package view
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/asks"
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
)
|
|
|
|
const askHeadA = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
// askEntry is a key of the gate's asks as the gate writes it (mesh-sdk go/delivery EncodeAsk, MergeAskKey): the router's ask
|
|
// whole, under the id its key gives.
|
|
func askEntry(t *testing.T, group, headline, words string) Entry {
|
|
t.Helper()
|
|
heads := []delivery.Head{{Repository: "novox/mesh-delivery", Number: 12, Head: askHeadA}}
|
|
key, err := delivery.MergeAskKey(group, heads)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
a := asks.Ask{ID: delivery.AskID(key), Headline: headline, Explanation: words, Who: asks.Operator, Expires: t0.Add(23 * time.Hour), OnExpiry: "the merge stays held",
|
|
Options: []asks.Option{{ID: "approve", Label: "Approve", Does: "merges", Level: asks.Approve, Binds: "sha256:00"}}}
|
|
v, err := delivery.EncodeAsk(delivery.Ask{Group: group, Heads: heads, Ask: a})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return Entry{Bucket: delivery.AsksBucket, Key: key, Value: v, At: t0}
|
|
}
|
|
|
|
func answerEntry(t *testing.T, key string) Entry {
|
|
t.Helper()
|
|
v, err := delivery.EncodeAnswer(delivery.Answer{Option: "approve", Warrant: "w1", Words: "the operator, via telegram, chose Approve"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return Entry{Bucket: delivery.AnswersBucket, Key: key, Value: v, At: t0}
|
|
}
|
|
|
|
func TestAnAskWithNoAnswerIsListedAndAnAnsweredOneIsNot(t *testing.T) { // 1345/AC1
|
|
m := New()
|
|
e := askEntry(t, "feat/x", "Merge into main: mesh-delivery#12", "Merges one pull request.\nReview: approved.")
|
|
fill(m, e)
|
|
s := m.Snapshot()
|
|
if len(s.Asks) != 1 {
|
|
t.Fatalf("asks = %+v, want the one open ask", s.Asks)
|
|
}
|
|
a := s.Asks[0]
|
|
if a.Key != e.Key || a.Group != "feat/x" || a.Headline != "Merge into main: mesh-delivery#12" || !strings.Contains(a.Words, "Merges one pull request.") ||
|
|
a.How != "answer on the phone" || len(a.Pulls) != 1 || !strings.Contains(a.Pulls[0], "novox/mesh-delivery#12") || !strings.Contains(a.Pulls[0], askHeadA[:12]) {
|
|
t.Errorf("ask = %+v", a)
|
|
}
|
|
fill(m, answerEntry(t, e.Key))
|
|
if got := m.Snapshot().Asks; len(got) != 0 {
|
|
t.Errorf("an answered ask is listed: %+v", got)
|
|
}
|
|
// An answer taken away leaves the ask open again; an ask taken away leaves the list.
|
|
fill(m, Entry{Bucket: delivery.AnswersBucket, Key: e.Key, Deleted: true})
|
|
if got := m.Snapshot().Asks; len(got) != 1 {
|
|
t.Errorf("asks after the answer was taken away = %+v", got)
|
|
}
|
|
fill(m, Entry{Bucket: delivery.AsksBucket, Key: e.Key, Deleted: true})
|
|
if got := m.Snapshot().Asks; len(got) != 0 {
|
|
t.Errorf("a withdrawn ask is listed: %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestAnAnswerHeardBeforeItsAskStillHidesTheAsk(t *testing.T) {
|
|
m := New()
|
|
e := askEntry(t, "feat/x", "Merge", "Merges.")
|
|
fill(m, answerEntry(t, e.Key), e)
|
|
if got := m.Snapshot().Asks; len(got) != 0 {
|
|
t.Errorf("asks = %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestAnUnreadableAskIsNamedAndNotListed(t *testing.T) { // never dropped silently
|
|
m := New()
|
|
fill(m, Entry{Bucket: delivery.AsksBucket, Key: "merge.g.0123456789ab", Value: []byte("{"), At: t0})
|
|
s := m.Snapshot()
|
|
if len(s.Asks) != 0 || len(s.Unreadable) != 1 || s.Unreadable[0].Bucket != delivery.AsksBucket {
|
|
t.Errorf("snapshot = %+v", s)
|
|
}
|
|
}
|
|
|
|
func TestTableAndPageShowTheAsks(t *testing.T) { // 1345/AC2
|
|
m := New()
|
|
fill(m, askEntry(t, "feat/x", "Merge into main: mesh-delivery#12", "Merges one pull request."))
|
|
var out bytes.Buffer
|
|
Table(&out, m.Snapshot())
|
|
for _, want := range []string{"ASKS", "Merge into main: mesh-delivery#12", "Merges one pull request.", "answer on the phone", "novox/mesh-delivery#12"} {
|
|
if !strings.Contains(out.String(), want) {
|
|
t.Errorf("the table lacks %q:\n%s", want, out.String())
|
|
}
|
|
}
|
|
rec := httptest.NewRecorder()
|
|
Web(m).ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/", nil))
|
|
for _, want := range []string{"ASKS", "Merge into main: mesh-delivery#12", "Merges one pull request.", "answer on the phone"} {
|
|
if !strings.Contains(rec.Body.String(), want) {
|
|
t.Errorf("the page lacks %q:\n%s", want, rec.Body.String())
|
|
}
|
|
}
|
|
// No ask, no section.
|
|
out.Reset()
|
|
Table(&out, New().Snapshot())
|
|
if strings.Contains(out.String(), "ASKS") {
|
|
t.Errorf("the table shows an ASKS section with no ask:\n%s", out.String())
|
|
}
|
|
}
|
|
|
|
func TestTheSnapshotsJSONCarriesTheAsks(t *testing.T) { // 1345/AC2
|
|
m := New()
|
|
fill(m, askEntry(t, "feat/x", "Merge into main: mesh-delivery#12", "Merges one pull request."))
|
|
raw, err := json.Marshal(m.Snapshot())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var back struct {
|
|
Asks []struct {
|
|
Headline string `json:"headline"`
|
|
How string `json:"how"`
|
|
} `json:"asks"`
|
|
}
|
|
if err := json.Unmarshal(raw, &back); err != nil || len(back.Asks) != 1 || back.Asks[0].How != "answer on the phone" {
|
|
t.Errorf("json %s: %+v %v", raw, back, err)
|
|
}
|
|
}
|
|
|
|
func TestAHaveOfARemovedModuleIsShownRemovedNotLeftBehind(t *testing.T) { // 1370: the node-engine writes phase removed
|
|
m := New()
|
|
fill(m, haveE(t, "novox", "mesh-delivery", have(t, "b1", delivery.PhaseRemoved, delivery.HealthOK, ""), t0),
|
|
haveE(t, "novox", "stray", have(t, "b2", delivery.PhaseRunning, delivery.HealthOK, ""), t0))
|
|
s := m.Snapshot()
|
|
if r := find(t, s, "novox", "mesh-delivery"); r.Status != StatusRemoved {
|
|
t.Errorf("row = %+v, want status %q", r, StatusRemoved)
|
|
}
|
|
if r := find(t, s, "novox", "stray"); r.Status != StatusLeftBehind {
|
|
t.Errorf("row = %+v, want left behind", r)
|
|
}
|
|
var out bytes.Buffer
|
|
Table(&out, s)
|
|
line := ""
|
|
for _, l := range strings.Split(out.String(), "\n") {
|
|
if strings.Contains(l, "mesh-delivery") {
|
|
line = l
|
|
}
|
|
}
|
|
if !strings.Contains(line, "removed") || strings.Contains(line, "left behind") {
|
|
t.Errorf("table line %q", line)
|
|
}
|
|
}
|