package web import ( "net/http" "net/http/httptest" "net/url" "strconv" "strings" "testing" ) func postForm(t *testing.T, s *Server, path string, form url.Values) *httptest.ResponseRecorder { t.Helper() req := httptest.NewRequest(http.MethodPost, path, strings.NewReader(form.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.AddCookie(authCookie(t, s)) rec := httptest.NewRecorder() s.Routes().ServeHTTP(rec, req) return rec } func TestManage_AddAndRenamePerson(t *testing.T) { s := testServerWithStore(t) // Add "johnn" (with the typo). rec := postForm(t, s, "/manage/people", url.Values{"label": {"johnn"}}) if rec.Code != http.StatusSeeOther { t.Fatalf("add person status = %d, want 303", rec.Code) } people, _ := s.store.ListPeople() if len(people) != 1 || people[0].Label != "johnn" { t.Fatalf("after add: %+v", people) } id := people[0].ID // Rename to fix the typo — same id. rec = postForm(t, s, "/manage/people/rename", url.Values{"id": {strconv.FormatInt(id, 10)}, "label": {"John"}}) if rec.Code != http.StatusSeeOther { t.Fatalf("rename status = %d, want 303", rec.Code) } people, _ = s.store.ListPeople() if len(people) != 1 || people[0].ID != id || people[0].Label != "John" { t.Errorf("after rename: %+v (id should be unchanged)", people) } } func TestManage_AddCategory(t *testing.T) { s := testServerWithStore(t) postForm(t, s, "/manage/categories", url.Values{"label": {"Chiropractic"}}) cats, _ := s.store.ListCategories() if len(cats) != 6 { // 5 seeded + 1 t.Errorf("categories = %d, want 6", len(cats)) } } func TestManage_EmptyLabelRejected(t *testing.T) { s := testServerWithStore(t) rec := postForm(t, s, "/manage/people", url.Values{"label": {" "}}) loc := rec.Header().Get("Location") if !strings.Contains(loc, "error=") { t.Errorf("expected error redirect, got %q", loc) } people, _ := s.store.ListPeople() if len(people) != 0 { t.Errorf("empty label should not create a person, got %d", len(people)) } } func TestManage_PageListsCategories(t *testing.T) { s := testServerWithStore(t) req := httptest.NewRequest(http.MethodGet, "/manage", nil) req.AddCookie(authCookie(t, s)) rec := httptest.NewRecorder() s.Routes().ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("status = %d, want 200", rec.Code) } body := rec.Body.String() for _, want := range []string{"Medical", "Categories", "Who"} { if !strings.Contains(body, want) { t.Errorf("manage page missing %q", want) } } } func TestUpload_WithWho_StoresPersonID(t *testing.T) { s := testServerWithStore(t) pid, err := s.store.AddPerson("John") if err != nil { t.Fatal(err) } body, ct := multipartUpload(t, map[string]string{ "amount": "20.00", "receipt_date": "2026-06-01", "category_id": aCategoryID(t, s), "person_id": strconv.FormatInt(pid, 10), }, "receipt", "r.png", fakePNG()) req := httptest.NewRequest(http.MethodPost, "/upload", body) req.Header.Set("Content-Type", ct) req.AddCookie(authCookie(t, s)) rec := httptest.NewRecorder() s.Routes().ServeHTTP(rec, req) if rec.Code != http.StatusOK || !strings.Contains(rec.Body.String(), "John") { t.Errorf("expected confirmation mentioning John; status=%d body=%s", rec.Code, rec.Body.String()) } }