6.3 KB
collections_test.go
package controllers
import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"github.com/readysite/readysite/website/models"
)
// Test database setup is handled by testhelper_test.go
func TestCollectionsController_Create(t *testing.T) {
tests := []struct {
name string
formData url.Values
wantStatus int
}{
{
name: "valid collection",
formData: url.Values{
"name": {"Blog Posts"},
"slug": {"blog-posts"},
"description": {"A collection of blog posts"},
"schema": {`[{"name":"title","type":"text","required":true}]`},
},
wantStatus: http.StatusSeeOther,
},
{
name: "missing name",
formData: url.Values{
"slug": {"no_name"},
"description": {"Missing name"},
},
wantStatus: http.StatusOK, // error page
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest("POST", "/admin/collections", strings.NewReader(tt.formData.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
authenticateRequest(req)
w := httptest.NewRecorder()
c := testCollectionsController()
handler := c.Handle(req)
handler.(*CollectionsController).Create(w, req)
if w.Code != tt.wantStatus {
t.Errorf("Create() status = %d, want %d, body: %s", w.Code, tt.wantStatus, w.Body.String())
}
})
}
}
func TestCollectionsController_CreateDocument(t *testing.T) {
// Create a collection first
col := &models.Collection{
Name: "Test Collection",
Schema: `[{"name":"title","type":"text","required":true}]`,
}
col.ID = "test-col"
models.Collections.Insert(col)
tests := []struct {
name string
formData url.Values
wantStatus int
}{
{
name: "valid document",
formData: url.Values{
"title": {"Test Document"},
},
wantStatus: http.StatusSeeOther,
},
{
name: "missing required field",
formData: url.Values{
"other": {"value"},
},
wantStatus: http.StatusOK, // validation error
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest("POST", "/admin/collections/test-col/documents", strings.NewReader(tt.formData.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.SetPathValue("id", "test-col")
authenticateRequest(req)
w := httptest.NewRecorder()
c := testCollectionsController()
handler := c.Handle(req)
handler.(*CollectionsController).CreateDocument(w, req)
if w.Code != tt.wantStatus {
t.Errorf("CreateDocument() status = %d, want %d, body: %s", w.Code, tt.wantStatus, w.Body.String())
}
})
}
}
func TestCollectionsController_UpdateDocument(t *testing.T) {
// Create collection and document with unique IDs
col := &models.Collection{
Name: "Update Test Collection",
Schema: `[{"name":"title","type":"text","required":true}]`,
}
col.ID = "update-col-unique"
models.Collections.Insert(col)
doc := &models.Document{
CollectionID: "update-col-unique",
Data: `{"title":"Original"}`,
}
doc.ID = "update-doc-unique"
models.Documents.Insert(doc)
// Re-fetch to get the correct UpdatedAt timestamp
doc, _ = models.Documents.Get("update-doc-unique")
formData := url.Values{
"title": {"Updated Title"},
"version": {doc.UpdatedAt.Format("2006-01-02T15:04:05")},
}
req := httptest.NewRequest("PUT", "/admin/collections/update-col-unique/documents/update-doc-unique", strings.NewReader(formData.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.SetPathValue("id", "update-col-unique")
req.SetPathValue("doc", "update-doc-unique")
authenticateRequest(req)
w := httptest.NewRecorder()
c := testCollectionsController()
handler := c.Handle(req)
handler.(*CollectionsController).UpdateDocument(w, req)
if w.Code != http.StatusSeeOther {
t.Errorf("UpdateDocument() status = %d, want %d, body: %s", w.Code, http.StatusSeeOther, w.Body.String())
}
// Verify update
updated, _ := models.Documents.Get("update-doc-unique")
if updated.GetString("title") != "Updated Title" {
t.Error("Document not updated correctly")
}
}
func TestCollectionsController_DeleteDocument(t *testing.T) {
// Create collection and document with unique IDs
col := &models.Collection{
Name: "Delete Test Collection",
}
col.ID = "delete-col-unique"
models.Collections.Insert(col)
doc := &models.Document{
CollectionID: "delete-col-unique",
Data: `{"title":"To Delete"}`,
}
doc.ID = "delete-doc-unique"
models.Documents.Insert(doc)
req := httptest.NewRequest("DELETE", "/admin/collections/delete-col-unique/documents/delete-doc-unique", nil)
req.SetPathValue("id", "delete-col-unique")
req.SetPathValue("doc", "delete-doc-unique")
authenticateRequest(req)
w := httptest.NewRecorder()
c := testCollectionsController()
handler := c.Handle(req)
handler.(*CollectionsController).DeleteDocument(w, req)
// Verify deletion
_, err := models.Documents.Get("delete-doc-unique")
if err == nil {
t.Error("Document should be deleted")
}
}
func TestCollectionsController_SchemaValidation(t *testing.T) {
// Create collection with typed schema
col := &models.Collection{
Name: "Typed Collection",
Schema: `[{"name":"count","type":"number","required":true},{"name":"email","type":"email","required":true}]`,
}
col.ID = "typed-col"
models.Collections.Insert(col)
tests := []struct {
name string
formData url.Values
wantStatus int
}{
{
name: "valid typed data",
formData: url.Values{
"count": {"42"},
"email": {"test@example.com"},
},
wantStatus: http.StatusSeeOther,
},
{
name: "invalid email",
formData: url.Values{
"count": {"42"},
"email": {"not-an-email"},
},
wantStatus: http.StatusOK, // validation error
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest("POST", "/admin/collections/typed-col/documents", strings.NewReader(tt.formData.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.SetPathValue("id", "typed-col")
authenticateRequest(req)
w := httptest.NewRecorder()
c := testCollectionsController()
handler := c.Handle(req)
handler.(*CollectionsController).CreateDocument(w, req)
if w.Code != tt.wantStatus {
t.Errorf("CreateDocument() with %s: status = %d, want %d, body: %s", tt.name, w.Code, tt.wantStatus, w.Body.String())
}
})
}
}