pact.ListExtendRecords fills unstored fields of one list page before its columns are read (WinterCMS listExtendRecords); such columns compile unsortable and refuse sortable/searchable. pact.FormRecordTitle names a record; the show, create and update responses send it as meta.title.
64 lines
2.7 KiB
Go
64 lines
2.7 KiB
Go
package cabana_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestListExtendRecords: the list hook completes each page once, before the
|
|
// columns are read, so an unstored field's column shows the value it set; a
|
|
// hook error fails the list with the generic 500 and no error text.
|
|
func TestListExtendRecords(t *testing.T) {
|
|
env, gdb := newRosterEnv(t)
|
|
ada := rosterInsert(t, gdb, rosterPerson{Tenant: "acme", Name: "Ada"})
|
|
gone := rosterInsert(t, gdb, rosterPerson{Tenant: "acme", Name: "Bob", DeletedAt: rosterDeleted()})
|
|
body, raw := rosterList(t, env, "")
|
|
badges := map[string]any{}
|
|
for _, row := range body.Data {
|
|
badges[fmt.Sprint(row["id"])] = row["badge"]
|
|
}
|
|
if badges[fmt.Sprint(ada)] != fmt.Sprintf("A#%d", ada) || badges[fmt.Sprint(gone)] != fmt.Sprintf("B#%d deleted", gone) {
|
|
t.Fatalf("badges = %v\n%s", badges, raw)
|
|
}
|
|
if got := env.spy.takeExtended(); len(got) != 1 || got[0] != 2 {
|
|
t.Fatalf("ListExtendRecords pages = %v, want one page of 2", got)
|
|
}
|
|
// The unstored column is not sortable.
|
|
env.expect(t, http.StatusUnprocessableEntity, http.MethodGet, rosterPeople+"?sort=badge", "", "bearer")
|
|
|
|
logs := captureLog(t)
|
|
rosterInsert(t, gdb, rosterPerson{Tenant: "acme", Name: rosterExtendErr})
|
|
rec := env.expect(t, http.StatusInternalServerError, http.MethodGet, rosterPeople, "", "bearer")
|
|
if got := rosterError(t, rec); got.Code != "error" || strings.Contains(rec.Body.String(), "hunter2") {
|
|
t.Fatalf("500 body = %s", rec.Body.String())
|
|
}
|
|
if failed := logs.matching("cabana: list extend records failed"); len(failed) != 1 || !strings.Contains(failed[0], "controller=acme.roster.people") {
|
|
t.Fatalf("server log = %q", failed)
|
|
}
|
|
}
|
|
|
|
// TestFormRecordTitle: the show response carries the controller's record
|
|
// title as meta.title; a hook error fails the request without its text.
|
|
func TestFormRecordTitle(t *testing.T) {
|
|
env, gdb := newRosterEnv(t)
|
|
ada := rosterInsert(t, gdb, rosterPerson{Tenant: "acme", Name: "Ada"})
|
|
rec := env.expect(t, http.StatusOK, http.MethodGet, fmt.Sprintf("%s/%d", rosterPeople, ada), "", "bearer")
|
|
var body struct {
|
|
Meta map[string]json.RawMessage `json:"meta"`
|
|
}
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := string(body.Meta["title"]); got != fmt.Sprintf("%q", fmt.Sprintf("Person #%d (Ada)", ada)) {
|
|
t.Fatalf("meta.title = %s\n%s", got, rec.Body.String())
|
|
}
|
|
bad := rosterInsert(t, gdb, rosterPerson{Tenant: "acme", Name: rosterTitleErr})
|
|
rec = env.expect(t, http.StatusInternalServerError, http.MethodGet, fmt.Sprintf("%s/%d", rosterPeople, bad), "", "bearer")
|
|
if strings.Contains(rec.Body.String(), "hunter2") {
|
|
t.Fatalf("500 body = %s", rec.Body.String())
|
|
}
|
|
}
|