validate_test.go
package content_test
import (
"testing"
"github.com/readysite/readysite/website/internal/content"
"github.com/readysite/readysite/website/models"
)
func TestValidateDocumentNoSchema(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: "", // No schema
}
// Should accept any data when no schema
data := map[string]any{
"foo": "bar",
"number": 42,
}
err := content.ValidateDocument(col, data)
if err != nil {
t.Errorf("expected no error for schemaless collection, got %v", err)
}
}
func TestValidateDocumentRequiredField(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"title","type":"text","required":true}]`,
}
// Missing required field
data := map[string]any{}
err := content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for missing required field")
}
// With required field
data = map[string]any{"title": "Hello"}
err = content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Empty string for required field
data = map[string]any{"title": ""}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for empty required field")
}
}
func TestValidateDocumentTextField(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"title","type":"text","options":{"maxLength":10}}]`,
}
// Valid text
data := map[string]any{"title": "Hello"}
err := content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Text too long
data = map[string]any{"title": "This is way too long"}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for text exceeding maxLength")
}
// Wrong type
data = map[string]any{"title": 123}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for wrong type")
}
}
func TestValidateDocumentNumberField(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"count","type":"number","options":{"min":0,"max":100}}]`,
}
// Valid number
data := map[string]any{"count": 50.0}
err := content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Below minimum
data = map[string]any{"count": -5.0}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for number below min")
}
// Above maximum
data = map[string]any{"count": 150.0}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for number above max")
}
// Wrong type
data = map[string]any{"count": "fifty"}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for wrong type")
}
}
func TestValidateDocumentBoolField(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"active","type":"bool"}]`,
}
// Valid bool
data := map[string]any{"active": true}
err := content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
data = map[string]any{"active": false}
err = content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Wrong type
data = map[string]any{"active": "true"}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for wrong type")
}
}
func TestValidateDocumentDateField(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"created","type":"date"}]`,
}
// RFC3339 format
data := map[string]any{"created": "2024-01-15T10:30:00Z"}
err := content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error for RFC3339: %v", err)
}
// Date only format
data = map[string]any{"created": "2024-01-15"}
err = content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error for date-only: %v", err)
}
// Invalid date
data = map[string]any{"created": "not-a-date"}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for invalid date")
}
}
func TestValidateDocumentEmailField(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"email","type":"email"}]`,
}
// Valid email
data := map[string]any{"email": "test@example.com"}
err := content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Invalid email
data = map[string]any{"email": "not-an-email"}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for invalid email")
}
}
func TestValidateDocumentURLField(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"website","type":"url"}]`,
}
// Valid URL
data := map[string]any{"website": "https://example.com"}
err := content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// URL without scheme
data = map[string]any{"website": "example.com"}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for URL without scheme")
}
}
func TestValidateDocumentSelectField(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"status","type":"select","options":{"values":["draft","published","archived"]}}]`,
}
// Valid option
data := map[string]any{"status": "draft"}
err := content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Invalid option
data = map[string]any{"status": "invalid"}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for invalid select option")
}
}
func TestValidateDocumentMultipleSelect(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"tags","type":"select","options":{"values":["tech","news","sports"],"multiple":true}}]`,
}
// Valid multiple selection
data := map[string]any{"tags": []any{"tech", "news"}}
err := content.ValidateDocument(col, data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Invalid option in array
data = map[string]any{"tags": []any{"tech", "invalid"}}
err = content.ValidateDocument(col, data)
if err == nil {
t.Error("expected error for invalid option in array")
}
}
func TestValidateDocumentMultipleErrors(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"title","type":"text","required":true},{"name":"count","type":"number","required":true}]`,
}
// Both fields missing
data := map[string]any{}
err := content.ValidateDocument(col, data)
if err == nil {
t.Error("expected validation errors")
}
// Check it's a ValidationErrors
if errors, ok := err.(content.ValidationErrors); ok {
if len(errors) != 2 {
t.Errorf("expected 2 errors, got %d", len(errors))
}
} else {
t.Errorf("expected ValidationErrors, got %T", err)
}
}
func TestValidateDocumentJSON(t *testing.T) {
col := &models.Collection{
Name: "Test",
Schema: `[{"name":"title","type":"text","required":true}]`,
}
// Valid JSON
err := content.ValidateDocumentJSON(col, `{"title":"Hello"}`)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Invalid JSON
err = content.ValidateDocumentJSON(col, `{invalid json}`)
if err == nil {
t.Error("expected error for invalid JSON")
}
// Empty JSON string
err = content.ValidateDocumentJSON(col, "")
if err == nil {
t.Error("expected error for empty JSON with required field")
}
}