sabisan/internal/app/handlers_admin_mutations_test.go

159 lines
6.1 KiB
Go
Raw Permalink Normal View History

2026-05-16 23:03:50 +00:00
package app
import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
)
func TestAdminMutationsRedirectToOwningTabs(t *testing.T) {
srv := newTestServer(t)
handler := srv.Routes()
cookie := loginCookie(t, handler)
for _, test := range []struct {
path string
form url.Values
want string
}{
{
path: "/admin/contact-details",
form: url.Values{"email": {"studio@example.com"}, "phone": {"123"}, "location": {"London"}},
want: "/admin/contact-details?ok=contact+details+saved",
},
{
path: "/admin/content",
form: url.Values{
"hero_title": {"Hero"}, "hero_subtitle": {"Subtitle"}, "intro_title": {"Intro"}, "intro_text": {"Text"},
"about_name": {"Name"}, "about_role": {"Role"}, "about_bio": {"Bio"},
2026-05-17 12:36:50 +00:00
"positioning": {"Residential architect in London"}, "hero_cta_label": {"Enquire"}, "hero_cta_url": {"/contact"},
"secondary_cta_label": {"Projects"}, "secondary_cta_url": {"/projects"},
"service_one_title": {"Homes"}, "service_one_text": {"Home text"},
"service_two_title": {"Interiors"}, "service_two_text": {"Interior text"},
"service_three_title": {"Consulting"}, "service_three_text": {"Consulting text"},
"process_one_title": {"Listen"}, "process_one_text": {"Listen text"},
"process_two_title": {"Shape"}, "process_two_text": {"Shape text"},
"process_three_title": {"Refine"}, "process_three_text": {"Refine text"},
"studio_philosophy": {"Philosophy"}, "studio_approach": {"Approach"}, "studio_credentials": {"Credentials"}, "service_area": {"London"},
2026-05-16 23:03:50 +00:00
"hero_image_current": {"/static/placeholders/hero.svg"}, "about_image_current": {"/static/placeholders/about.svg"},
},
want: "/admin/main?ok=content+saved",
},
} {
req := httptest.NewRequest(http.MethodPost, test.path, strings.NewReader(test.form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
handler.ServeHTTP(rec, req)
if rec.Code != http.StatusSeeOther || rec.Header().Get("Location") != test.want {
t.Fatalf("%s expected redirect %q, got %d %q", test.path, test.want, rec.Code, rec.Header().Get("Location"))
}
}
}
func TestAdminProjectValidation(t *testing.T) {
srv := newTestServer(t)
handler := srv.Routes()
cookie := loginCookie(t, handler)
2026-05-17 12:36:50 +00:00
form := url.Values{"title": {" "}, "location": {"London"}, "year": {"2026"}, "category": {"Residential"}, "summary": {"Summary"}, "scope": {"Scope"}, "status": {"Completed"}, "description": {"Text"}}
2026-05-16 23:03:50 +00:00
req := httptest.NewRequest(http.MethodPost, "/admin/projects", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
handler.ServeHTTP(rec, req)
if rec.Code != http.StatusSeeOther {
t.Fatalf("expected redirect, got %d", rec.Code)
}
if location := rec.Header().Get("Location"); !strings.Contains(location, "/admin/projects?err=") || !strings.Contains(location, "project+title+is+required") {
t.Fatalf("expected validation error redirect, got %q", location)
}
}
2026-05-17 12:36:50 +00:00
func TestAdminProjectCreatePersistsDepthFields(t *testing.T) {
srv := newTestServer(t)
handler := srv.Routes()
cookie := loginCookie(t, handler)
form := url.Values{
"title": {"Garden Studio"},
"location": {"London"},
"year": {"2026"},
"category": {"Residential"},
"summary": {"A compact studio in a rear garden."},
"scope": {"Architecture, interiors"},
"status": {"In progress"},
"position": {"12"},
"description": {"A small project with careful storage and daylight."},
"featured": {"on"},
}
req := httptest.NewRequest(http.MethodPost, "/admin/projects", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
handler.ServeHTTP(rec, req)
if rec.Code != http.StatusSeeOther || rec.Header().Get("Location") != "/admin/projects?ok=project+created" {
t.Fatalf("expected create redirect, got %d %q", rec.Code, rec.Header().Get("Location"))
}
project, err := srv.store.ProjectBySlug(t.Context(), "garden-studio")
if err != nil {
t.Fatal(err)
}
if project.Summary != "A compact studio in a rear garden." || project.Scope != "Architecture, interiors" || project.Status != "In progress" || project.Position != 12 {
t.Fatalf("unexpected project depth fields: %+v", project)
}
}
func TestAdminServiceAndFAQMutations(t *testing.T) {
srv := newTestServer(t)
handler := srv.Routes()
cookie := loginCookie(t, handler)
serviceForm := url.Values{
"title": {"Planning advice"},
"summary": {"Early advice for planning routes."},
"details": {"Detailed planning route guidance."},
"position": {"8"},
"active": {"on"},
}
req := httptest.NewRequest(http.MethodPost, "/admin/services", strings.NewReader(serviceForm.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
handler.ServeHTTP(rec, req)
if rec.Code != http.StatusSeeOther || rec.Header().Get("Location") != "/admin/services?ok=service+created" {
t.Fatalf("expected service redirect, got %d %q", rec.Code, rec.Header().Get("Location"))
}
faqForm := url.Values{
"question": {"Can you help before purchase?"},
"answer": {"Yes, early consultation can clarify feasibility."},
"position": {"9"},
"active": {"on"},
}
req = httptest.NewRequest(http.MethodPost, "/admin/faqs", strings.NewReader(faqForm.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec = httptest.NewRecorder()
handler.ServeHTTP(rec, req)
if rec.Code != http.StatusSeeOther || rec.Header().Get("Location") != "/admin/services?ok=FAQ+created" {
t.Fatalf("expected FAQ redirect, got %d %q", rec.Code, rec.Header().Get("Location"))
}
services, err := srv.store.Services(t.Context(), false)
if err != nil {
t.Fatal(err)
}
faqs, err := srv.store.FAQs(t.Context(), false)
if err != nil {
t.Fatal(err)
}
if len(services) < 5 || len(faqs) < 4 {
t.Fatalf("expected created service and FAQ, got services=%d faqs=%d", len(services), len(faqs))
}
}