package view import ( "net/http" "net/http/httptest" "strings" "testing" "git.novox.be/novox/mesh-sdk/go/delivery" ) const ( fpOld = "src2:1111111111111111111111111111111111111111111111111111111111111111" fpNew = "src2:2222222222222222222222222222222222222222222222222222222222222222" ) // diffEntry is a key of the assigner's differences as the assigner writes it (mesh-sdk go/delivery EncodeDifference). func differenceE(t *testing.T, node, module string, d delivery.Difference) Entry { t.Helper() key, err := delivery.DifferenceKey(node, module) if err != nil { t.Fatal(err) } v, err := delivery.EncodeDifference(d) if err != nil { t.Fatal(err) } return Entry{Bucket: delivery.AssignerDifferencesBucket, Key: key, Value: v, At: t0} } func TestEveryDifferenceIsListedWithItsRule(t *testing.T) { // 1297/B8 AC m := New() fill(m, differenceE(t, "ace", "plex", delivery.Difference{Want: fpOld, Sent: fpNew, Rule: delivery.RuleCanary, Words: "ace is not the canary"}), differenceE(t, "g14", "plex", delivery.Difference{Want: fpOld, Sent: fpNew, Unexplained: true}), differenceE(t, "ace", "old", delivery.Difference{WantRemoved: true, Sent: fpOld, Rule: delivery.RuleNotHeld}), ) got := m.Snapshot().Differences if len(got) != 3 { t.Fatalf("differences = %+v, want all three", got) } // ordered by node then module if got[0].Node != "ace" || got[0].Module != "old" || got[1].Module != "plex" || got[2].Node != "g14" { t.Errorf("order = %+v", got) } if r := got[1]; r.Want != fpOld || r.Sent != fpNew || r.Rule != delivery.RuleCanary || r.Unexplained || r.Words != "ace is not the canary" { t.Errorf("row = %+v", r) } if !got[0].WantRemoved || got[0].Rule != delivery.RuleNotHeld { t.Errorf("removed row = %+v", got[0]) } if !got[2].Unexplained || got[2].Rule != 0 { t.Errorf("unexplained row = %+v", got[2]) } // a difference taken away (the want and the send agree again) leaves the list fill(m, Entry{Bucket: delivery.AssignerDifferencesBucket, Key: "g14.plex", Deleted: true}) if got := m.Snapshot().Differences; len(got) != 2 { t.Errorf("after the delete = %+v", got) } } func TestAnUnreadableDifferenceIsNamedAndNotDropped(t *testing.T) { // never dropped silently m := New() fill(m, Entry{Bucket: delivery.AssignerDifferencesBucket, Key: "ace.plex", Value: []byte(`{"v":99}`), At: t0}) s := m.Snapshot() if len(s.Differences) != 0 || len(s.Unreadable) != 1 || s.Unreadable[0].Bucket != delivery.AssignerDifferencesBucket || s.Unreadable[0].Key != "ace.plex" { t.Errorf("snapshot = %+v", s) } } func TestTableAndPageShowTheWantsAgainstTheSends(t *testing.T) { // 1297/B8 AC m := New() fill(m, differenceE(t, "ace", "plex", delivery.Difference{Want: fpOld, Sent: fpNew, Rule: delivery.RuleCanary, Words: "ace is not the canary"}), differenceE(t, "g14", "plex", delivery.Difference{Want: fpOld, Sent: fpNew, Unexplained: true}), ) var out strings.Builder Table(&out, m.Snapshot()) for _, w := range []string{"WANTS AGAINST SENDS", "ace", "plex", fpOld, fpNew, "rule 3", "ace is not the canary", "unexplained"} { if !strings.Contains(out.String(), w) { t.Errorf("table lacks %q:\n%s", w, out.String()) } } for _, path := range []string{"/", "/wants"} { rec := httptest.NewRecorder() Web(m).ServeHTTP(rec, httptest.NewRequest(http.MethodGet, path, nil)) body := rec.Body.String() if rec.Code != 200 { t.Fatalf("%s = %d", path, rec.Code) } for _, w := range []string{"WANTS AGAINST SENDS", "rule 3", "unexplained", "ace is not the canary"} { if !strings.Contains(body, w) { t.Errorf("%s lacks %q:\n%s", path, w, body) } } } // With none, the page says so and does not hide the heading. rec := httptest.NewRecorder() Web(New()).ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/wants", nil)) if !strings.Contains(rec.Body.String(), "no difference") { t.Errorf("empty page = %q", rec.Body.String()) } }