Files
summercms/modules/cabana/settings_options_test.go
Jakub Zych 21c5618dd1 feat(18-04): settings forms take method-backed dropdown options from the settings model (task 1)
- the settings schema passes the settings model as the DropdownOptionsProvider
- boot refuses a dropdown method on a settings model without DropdownOptions
- cabana README and docs/backend/settings.md describe it
2026-10-13 14:08:14 +02:00

65 lines
2.4 KiB
Go

package cabana
import (
"context"
"strings"
"testing"
"testing/fstest"
"git.golem15.com/golem15/summercms/modules/pact"
)
// optionSettings is a settings model whose dropdown options come from a
// model method, like a WinterCMS settings model's get*Options.
type optionSettings struct {
ID uint `gorm:"column:id;primaryKey"`
Currency string `gorm:"column:currency"`
}
func (optionSettings) TableName() string { return "cabana_option_settings" }
func (optionSettings) Fillable() []string { return []string{"currency"} }
func (optionSettings) Rules() map[string]string { return map[string]string{} }
func (optionSettings) DropdownOptions(field string) []pact.Option {
if field != "currency" {
return nil
}
return []pact.Option{{Value: "EUR", Label: "EUR — Euro"}, {Value: "PLN", Label: "PLN — Polish zloty"}}
}
// plainSettings has the same column and no DropdownOptions.
type plainSettings struct {
ID uint `gorm:"column:id;primaryKey"`
Currency string `gorm:"column:currency"`
}
func (plainSettings) TableName() string { return "cabana_plain_settings" }
func (plainSettings) Fillable() []string { return []string{"currency"} }
func (plainSettings) Rules() map[string]string { return map[string]string{} }
// TestSettingsDropdownMethod checks that a settings form takes a
// method-backed dropdown's options from its settings model, and that boot
// refuses the method when the model has no DropdownOptions.
func TestSettingsDropdownMethod(t *testing.T) {
fsys := fstest.MapFS{"models/settings/fields.yaml": &fstest.MapFile{Data: []byte("fields:\n currency:\n label: Currency\n type: dropdown\n options: getCurrencyOptions\n")}}
item := pact.SettingsItem{Code: "options", Label: "Options", Form: "models/settings/fields.yaml", NewModel: func() any { return &optionSettings{} }}
setting, err := compileSetting("acme.unit", item, fsys)
if err != nil {
t.Fatal(err)
}
view, err := setting.Form.Localize(context.Background(), nil, settingDropdownProvider(setting))
if err != nil {
t.Fatal(err)
}
opts := view.Fields[0].Options
if len(opts) != 2 || opts[1].Label != "PLN — Polish zloty" {
t.Fatalf("options = %+v", opts)
}
item.NewModel = func() any { return &plainSettings{} }
_, err = compileSetting("acme.unit", item, fsys)
if err == nil || !strings.Contains(err.Error(), "dropdown method getCurrencyOptions requires DropdownOptions on the settings model") {
t.Fatalf("err = %v", err)
}
}