4.8 KB
pages_test.go
package controllers
import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"github.com/readysite/readysite/website/internal/content"
"github.com/readysite/readysite/website/models"
)
// Test database setup is handled by testhelper_test.go
func TestPagesController_Create(t *testing.T) {
// Create controller
_, c := Pages()
c.Setup(nil)
tests := []struct {
name string
formData url.Values
wantStatus int
}{
{
name: "valid page creation",
formData: url.Values{
"title": {"Test Page"},
"slug": {"test-page"},
"html": {"<h1>Hello</h1>"},
},
wantStatus: http.StatusSeeOther, // redirect on success
},
{
name: "missing title",
formData: url.Values{
"slug": {"no-title"},
"html": {"<p>Content</p>"},
},
wantStatus: http.StatusOK, // error rendered as HTML
},
{
name: "invalid slug with spaces",
formData: url.Values{
"title": {"Bad Slug"},
"slug": {"bad slug"},
"html": {"<p>Content</p>"},
},
wantStatus: http.StatusOK, // validation error
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest("POST", "/admin/pages", strings.NewReader(tt.formData.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
w := httptest.NewRecorder()
handler := c.Handle(req)
handler.(*PagesController).Create(w, req)
if w.Code != tt.wantStatus {
t.Errorf("Create() status = %d, want %d", w.Code, tt.wantStatus)
}
})
}
}
func TestPagesController_SlugValidation(t *testing.T) {
tests := []struct {
slug string
valid bool
}{
{"valid-slug", true},
{"another123", true},
{"has space", false},
{"has/slash", false},
{"UPPERCASE", false},
{"special!char", false},
{"admin", false}, // reserved
{"api", false}, // reserved
}
for _, tt := range tests {
t.Run(tt.slug, func(t *testing.T) {
// Test validation through form submission
formData := url.Values{
"title": {"Test"},
"slug": {tt.slug},
"html": {"<p>Test</p>"},
}
req := httptest.NewRequest("POST", "/admin/pages", strings.NewReader(formData.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
w := httptest.NewRecorder()
_, c := Pages()
handler := c.Handle(req)
handler.(*PagesController).Create(w, req)
isRedirect := w.Code == http.StatusSeeOther
if isRedirect != tt.valid {
t.Errorf("slug %q: got redirect=%v, want valid=%v (status=%d)", tt.slug, isRedirect, tt.valid, w.Code)
}
})
}
}
func TestPagesController_Update(t *testing.T) {
// Create a test page first
page := &models.Page{
ParentID: "",
}
page.ID = "update-test"
models.Pages.Insert(page)
content.SavePageContent(page, "Original Title", "Original desc", "<h1>Original</h1>", "", models.StatusDraft)
// Update the page
formData := url.Values{
"title": {"Updated Title"},
"description": {"Updated description"},
}
req := httptest.NewRequest("PUT", "/admin/pages/update-test", strings.NewReader(formData.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.SetPathValue("id", "update-test")
w := httptest.NewRecorder()
_, c := Pages()
handler := c.Handle(req)
handler.(*PagesController).Update(w, req)
if w.Code != http.StatusSeeOther {
t.Errorf("Update() status = %d, want %d", w.Code, http.StatusSeeOther)
}
// Verify update
updated, _ := models.Pages.Get("update-test")
content := updated.LatestContent()
if content == nil || content.Title != "Updated Title" {
t.Errorf("Page not updated correctly")
}
}
func TestPagesController_Delete(t *testing.T) {
// Create a test page
page := &models.Page{}
page.ID = "delete-test"
models.Pages.Insert(page)
req := httptest.NewRequest("DELETE", "/admin/pages/delete-test", nil)
req.SetPathValue("id", "delete-test")
w := httptest.NewRecorder()
_, c := Pages()
handler := c.Handle(req)
handler.(*PagesController).Delete(w, req)
if w.Code != http.StatusSeeOther {
t.Errorf("Delete() status = %d, want %d", w.Code, http.StatusSeeOther)
}
// Verify deletion
_, err := models.Pages.Get("delete-test")
if err == nil {
t.Error("Page should be deleted")
}
}
func TestPagesController_TogglePublish(t *testing.T) {
// Create an unpublished page with draft content
page := &models.Page{}
page.ID = "publish-test"
models.Pages.Insert(page)
content.SavePageContent(page, "Test Page", "Description", "<h1>Test</h1>", "", models.StatusDraft)
req := httptest.NewRequest("POST", "/admin/pages/publish-test/publish", nil)
req.SetPathValue("id", "publish-test")
w := httptest.NewRecorder()
_, c := Pages()
handler := c.Handle(req)
handler.(*PagesController).TogglePublish(w, req)
// Verify toggle - page should now have published content
toggled, _ := models.Pages.Get("publish-test")
if !toggled.IsPublished() {
t.Error("Page should be published after toggle")
}
}