package briefing import ( "strings" "testing" "gitea.maximumdirect.net/eric/weatherreporter/internal/module" "gitea.maximumdirect.net/eric/weatherreporter/internal/report" ) func TestDefaultModuleRegistryValidatesReportDefaults(t *testing.T) { registry := MustDefaultModuleRegistry() for _, definition := range report.DefaultRegistry().All() { if err := registry.ValidateComposition(definition.ID, definition.Modules); err != nil { t.Fatalf("ValidateComposition(%s) error = %v", definition.ID, err) } } } func TestModuleRegistryRejectsUnknownModule(t *testing.T) { registry := MustDefaultModuleRegistry() err := registry.ValidateComposition(report.DailyToday, []module.ConfigItem{{ID: module.ID("unknown")}}) if err == nil || !strings.Contains(err.Error(), `unknown module "unknown"`) { t.Fatalf("error = %v, want unknown module", err) } } func TestModuleRegistryRejectsDuplicateModuleIDs(t *testing.T) { registry := MustDefaultModuleRegistry() err := registry.ValidateComposition(report.DailyToday, []module.ConfigItem{ {ID: module.Metadata}, {ID: module.Metadata}, }) if err == nil || !strings.Contains(err.Error(), `duplicate module "metadata"`) { t.Fatalf("error = %v, want duplicate module", err) } } func TestModuleRegistryRejectsDuplicateStanzaNames(t *testing.T) { _, err := NewModuleRegistry([]ModuleDefinition{ {ID: module.Metadata, StanzaName: "metadata", DefaultOptions: module.MetadataOptions{}}, {ID: module.CurrentConditions, StanzaName: "metadata", DefaultOptions: module.CurrentConditionsOptions{}}, }) if err == nil || !strings.Contains(err.Error(), `duplicate stanza name "metadata"`) { t.Fatalf("error = %v, want duplicate stanza name", err) } } func TestModuleRegistryRejectsIncompatibleReports(t *testing.T) { registry := MustDefaultModuleRegistry() err := registry.ValidateComposition(report.DailyToday, []module.ConfigItem{{ID: module.StormWindowSummary}}) if err == nil || !strings.Contains(err.Error(), `module "storm_window_summary" is not compatible with report "daily_today"`) { t.Fatalf("error = %v, want incompatible report", err) } } func TestModuleRegistryRejectsInvalidOptionShapes(t *testing.T) { registry := MustDefaultModuleRegistry() err := registry.ValidateComposition(report.DailyToday, []module.ConfigItem{ {ID: module.Metadata, Options: module.CurrentConditionsOptions{}}, }) if err == nil || !strings.Contains(err.Error(), `module "metadata" options have type module.CurrentConditionsOptions, want module.MetadataOptions`) { t.Fatalf("error = %v, want invalid option shape", err) } } func TestModuleRegistryAcceptsTypedOptions(t *testing.T) { registry := MustDefaultModuleRegistry() err := registry.ValidateComposition(report.DailyToday, []module.ConfigItem{ {ID: module.Metadata, Options: module.MetadataOptions{}}, {ID: module.CurrentConditions, Options: &module.CurrentConditionsOptions{}}, }) if err != nil { t.Fatalf("ValidateComposition() error = %v", err) } }