- 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
93 lines
4.0 KiB
Go
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")
|
|
}
|
|
}
|