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) } }