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()) } }