Files
summercms/modules/cabana/field_request_options_test.go
Jakub Zych eb8a0280ca test: unit tests for content facts, field type request options, variant keys and WebP
- pact: the content kinds and tools, zero facts, the value types
- cabana: mergeRequestOptions precedence, one call per type, fail-open,
  no shared maps
- attach: VariantKey on thumbnail names
- attach/webp: every image kind, the stored content type, the
  broken-image thumbnail and a refused mode
2026-11-04 19:54:54 +01:00

93 lines
4.0 KiB
Go

package cabana
import (
"context"
"errors"
"reflect"
"testing"
"git.golem15.com/golem15/summercms/modules/pact"
"gorm.io/gorm"
)
// TestMergeRequestOptions pins mergeRequestOptions without a database: a
// key set in fields.yaml wins over the request's answer, the other answer
// keys join; each type is asked once however many fields use it; a field of
// a built-in type, a type without RequestOptions and an empty answer keep
// their options; an error fails open (the field keeps its fields.yaml
// options); the compiled options are never changed and fields never share
// a map.
func TestMergeRequestOptions(t *testing.T) {
calls := 0
shared := map[string]any{"sources": []any{"a", "b"}, "mode": "request"}
withOptions := &compiledFieldType{owner: "acme.blog", def: pact.FormFieldType{Name: "picker", RequestOptions: func(context.Context, *gorm.DB) (map[string]any, error) {
calls++
return shared, nil
}}}
failing := &compiledFieldType{owner: "acme.blog", def: pact.FormFieldType{Name: "broken", RequestOptions: func(context.Context, *gorm.DB) (map[string]any, error) {
return nil, errors.New("database is down")
}}}
empty := &compiledFieldType{owner: "acme.blog", def: pact.FormFieldType{Name: "empty", RequestOptions: func(context.Context, *gorm.DB) (map[string]any, error) {
return map[string]any{}, nil
}}}
plain := &compiledFieldType{owner: "acme.blog", def: pact.FormFieldType{Name: "plain"}}
compiled := map[string]any{"mode": "yaml", "size": 3}
fields := []FormField{
{Name: "one", fieldType: withOptions, TypeOptions: compiled},
{Name: "two", fieldType: withOptions},
{Name: "three", fieldType: failing, TypeOptions: map[string]any{"mode": "yaml"}},
{Name: "four", fieldType: empty, TypeOptions: map[string]any{"size": 1}},
{Name: "five", fieldType: plain, TypeOptions: map[string]any{"size": 2}},
{Name: "six", TypeOptions: nil},
}
mergeRequestOptions(context.Background(), nil, fields)
if calls != 1 {
t.Fatalf("RequestOptions asked %d times, want once per type", calls)
}
if want := map[string]any{"sources": []any{"a", "b"}, "mode": "yaml", "size": 3}; !reflect.DeepEqual(fields[0].TypeOptions, want) {
t.Fatalf("field one = %v, want %v (fields.yaml wins)", fields[0].TypeOptions, want)
}
if want := map[string]any{"sources": []any{"a", "b"}, "mode": "request"}; !reflect.DeepEqual(fields[1].TypeOptions, want) {
t.Fatalf("field two = %v, want the answer", fields[1].TypeOptions)
}
if want := map[string]any{"mode": "yaml"}; !reflect.DeepEqual(fields[2].TypeOptions, want) {
t.Fatalf("field three = %v, want its fields.yaml options after the error", fields[2].TypeOptions)
}
if want := map[string]any{"size": 1}; !reflect.DeepEqual(fields[3].TypeOptions, want) {
t.Fatalf("field four = %v", fields[3].TypeOptions)
}
if want := map[string]any{"size": 2}; !reflect.DeepEqual(fields[4].TypeOptions, want) {
t.Fatalf("field five = %v", fields[4].TypeOptions)
}
if fields[5].TypeOptions != nil {
t.Fatalf("a built-in field got options %v", fields[5].TypeOptions)
}
if want := map[string]any{"mode": "yaml", "size": 3}; !reflect.DeepEqual(compiled, want) {
t.Fatalf("the compiled options changed: %v", compiled)
}
// The two fields of one type hold their own maps and copies of the
// answer's values.
fields[1].TypeOptions["mode"] = "changed"
fields[1].TypeOptions["sources"].([]any)[0] = "z"
if fields[0].TypeOptions["mode"] != "yaml" || shared["mode"] != "request" || shared["sources"].([]any)[0] != "a" {
t.Fatalf("fields share state: one=%v answer=%v", fields[0].TypeOptions, shared)
}
}
// TestMergeRequestOptionsNoFields pins the empty request: nothing is asked.
func TestMergeRequestOptionsNoFields(t *testing.T) {
asked := false
ft := &compiledFieldType{def: pact.FormFieldType{Name: "picker", RequestOptions: func(context.Context, *gorm.DB) (map[string]any, error) {
asked = true
return nil, nil
}}}
_ = ft
mergeRequestOptions(context.Background(), nil, nil)
mergeRequestOptions(context.Background(), nil, []FormField{})
if asked {
t.Fatal("RequestOptions was asked without a field")
}
}