Add per-report distributor path overrides
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"gitea.maximumdirect.net/eric/weatherreporter/internal/module"
|
||||
"gitea.maximumdirect.net/eric/weatherreporter/internal/report"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func TestDefaults(t *testing.T) {
|
||||
@@ -313,6 +314,102 @@ reports:
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadReportDistributorPathOverrides(t *testing.T) {
|
||||
path := writeConfig(t, `
|
||||
reports:
|
||||
daily:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "daily/{valid_start_date}/{run_id}.md"
|
||||
- "daily/{valid_start_date}/index.md"
|
||||
today:
|
||||
deterministic_modules:
|
||||
- metadata
|
||||
`)
|
||||
|
||||
cfg, err := LoadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadFile() error = %v", err)
|
||||
}
|
||||
daily := cfg.Reports["daily"].Distributor
|
||||
if !daily.PathTemplatesSet() {
|
||||
t.Fatal("daily distributor path_templates set = false, want true")
|
||||
}
|
||||
want := []string{
|
||||
"daily/{valid_start_date}/{run_id}.md",
|
||||
"daily/{valid_start_date}/index.md",
|
||||
}
|
||||
if !reflect.DeepEqual(daily.PathTemplates, want) {
|
||||
t.Fatalf("daily path templates = %#v, want %#v", daily.PathTemplates, want)
|
||||
}
|
||||
if cfg.Reports["today"].Distributor.PathTemplatesSet() {
|
||||
t.Fatal("today distributor path_templates set = true, want false")
|
||||
}
|
||||
|
||||
overrides, err := cfg.ReportDistributorPathOverrides()
|
||||
if err != nil {
|
||||
t.Fatalf("ReportDistributorPathOverrides() error = %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(overrides[report.Daily], want) {
|
||||
t.Fatalf("daily distributor override = %#v, want %#v", overrides[report.Daily], want)
|
||||
}
|
||||
if _, ok := overrides[report.Today]; ok {
|
||||
t.Fatalf("today distributor override = %#v, want omitted override absent", overrides[report.Today])
|
||||
}
|
||||
}
|
||||
|
||||
func TestReportDistributorPathTemplatesSetTracksExplicitEmptyList(t *testing.T) {
|
||||
var cfg Config
|
||||
if err := yaml.Unmarshal([]byte(`
|
||||
reports:
|
||||
daily:
|
||||
distributor:
|
||||
path_templates: []
|
||||
today:
|
||||
distributor: {}
|
||||
`), &cfg); err != nil {
|
||||
t.Fatalf("yaml.Unmarshal() error = %v", err)
|
||||
}
|
||||
if !cfg.Reports["daily"].Distributor.PathTemplatesSet() {
|
||||
t.Fatal("daily distributor path_templates set = false, want true")
|
||||
}
|
||||
if len(cfg.Reports["daily"].Distributor.PathTemplates) != 0 {
|
||||
t.Fatalf("daily path templates = %#v, want empty explicit list", cfg.Reports["daily"].Distributor.PathTemplates)
|
||||
}
|
||||
if cfg.Reports["today"].Distributor.PathTemplatesSet() {
|
||||
t.Fatal("today distributor path_templates set = true, want false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadReportDistributorPathOverrideAliases(t *testing.T) {
|
||||
path := writeConfig(t, `
|
||||
reports:
|
||||
three-day-outlook:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "three-day/{valid_start_date}/index.md"
|
||||
weekend_outlook:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "weekend/{valid_start_date}/index.md"
|
||||
`)
|
||||
|
||||
cfg, err := LoadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadFile() error = %v", err)
|
||||
}
|
||||
overrides, err := cfg.ReportDistributorPathOverrides()
|
||||
if err != nil {
|
||||
t.Fatalf("ReportDistributorPathOverrides() error = %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(overrides[report.ThreeDay], []string{"three-day/{valid_start_date}/index.md"}) {
|
||||
t.Fatalf("three-day distributor override = %#v, want alias override", overrides[report.ThreeDay])
|
||||
}
|
||||
if !reflect.DeepEqual(overrides[report.Weekend], []string{"weekend/{valid_start_date}/index.md"}) {
|
||||
t.Fatalf("weekend distributor override = %#v, want alias override", overrides[report.Weekend])
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateReportModuleKeysWithoutMutatingOptions(t *testing.T) {
|
||||
cfg := Defaults()
|
||||
rawOptions := map[string]any{
|
||||
@@ -565,6 +662,168 @@ reports:
|
||||
}
|
||||
}
|
||||
|
||||
func TestReportDistributorPathOverrideValidation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
yaml string
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "UnknownReportField",
|
||||
yaml: `
|
||||
reports:
|
||||
daily:
|
||||
distributor_paths:
|
||||
- latest.md
|
||||
`,
|
||||
wantErr: `unknown report entry field "distributor_paths"`,
|
||||
},
|
||||
{
|
||||
name: "UnknownDistributorField",
|
||||
yaml: `
|
||||
reports:
|
||||
daily:
|
||||
distributor:
|
||||
paths:
|
||||
- latest.md
|
||||
`,
|
||||
wantErr: `unknown report distributor field "paths"`,
|
||||
},
|
||||
{
|
||||
name: "DuplicateReportAlias",
|
||||
yaml: `
|
||||
reports:
|
||||
three-day:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "three-day/{valid_start_date}/index.md"
|
||||
three_day:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "three-day/latest.md"
|
||||
`,
|
||||
wantErr: "duplicates report override",
|
||||
},
|
||||
{
|
||||
name: "UnknownTemplateVariable",
|
||||
yaml: `
|
||||
reports:
|
||||
daily:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "{unknown}.md"
|
||||
`,
|
||||
wantErr: `reports.daily.distributor.path_templates[0] contains unknown template variable "unknown"`,
|
||||
},
|
||||
{
|
||||
name: "AbsolutePath",
|
||||
yaml: `
|
||||
reports:
|
||||
daily:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "/daily.md"
|
||||
`,
|
||||
wantErr: "reports.daily.distributor.path_templates[0] must render a relative path",
|
||||
},
|
||||
{
|
||||
name: "ParentSegment",
|
||||
yaml: `
|
||||
reports:
|
||||
daily:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "daily/../index.md"
|
||||
`,
|
||||
wantErr: "reports.daily.distributor.path_templates[0] must not render . or .. path segments",
|
||||
},
|
||||
{
|
||||
name: "Manifest",
|
||||
yaml: `
|
||||
reports:
|
||||
daily:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "daily/manifest.json"
|
||||
`,
|
||||
wantErr: `reports.daily.distributor.path_templates[0] must not render reserved path segment "manifest.json"`,
|
||||
},
|
||||
{
|
||||
name: "DuplicateRenderedPath",
|
||||
yaml: `
|
||||
reports:
|
||||
daily:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "daily/index.md"
|
||||
- "daily/index.md"
|
||||
`,
|
||||
wantErr: `reports.daily.distributor.path_templates renders duplicate path "daily/index.md"`,
|
||||
},
|
||||
{
|
||||
name: "EmptyOverrideList",
|
||||
yaml: `
|
||||
reports:
|
||||
daily:
|
||||
distributor:
|
||||
path_templates: []
|
||||
`,
|
||||
wantErr: "reports.daily.distributor.path_templates must contain at least one entry",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := LoadFile(writeConfig(t, tt.yaml))
|
||||
if err == nil {
|
||||
t.Fatal("LoadFile() error = nil, want validation error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), tt.wantErr) {
|
||||
t.Fatalf("error = %q, want %q", err.Error(), tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReportDistributorPathOverridesConsistentForLoadedAndConstructedConfig(t *testing.T) {
|
||||
yaml := `
|
||||
reports:
|
||||
daily:
|
||||
distributor:
|
||||
path_templates:
|
||||
- "daily/{valid_start_date}/index.md"
|
||||
`
|
||||
reports := map[string]ReportConfig{
|
||||
"daily": {
|
||||
Distributor: ReportDistributorConfig{
|
||||
PathTemplates: []string{"daily/{valid_start_date}/index.md"},
|
||||
pathTemplatesSet: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cfg, err := LoadFile(writeConfig(t, yaml))
|
||||
if err != nil {
|
||||
t.Fatalf("LoadFile() error = %v", err)
|
||||
}
|
||||
loaded, err := cfg.ReportDistributorPathOverrides()
|
||||
if err != nil {
|
||||
t.Fatalf("loaded ReportDistributorPathOverrides() error = %v", err)
|
||||
}
|
||||
cfg = Defaults()
|
||||
cfg.Reports = reports
|
||||
if err := Validate(cfg); err != nil {
|
||||
t.Fatalf("Validate() error = %v", err)
|
||||
}
|
||||
constructed, err := cfg.ReportDistributorPathOverrides()
|
||||
if err != nil {
|
||||
t.Fatalf("constructed ReportDistributorPathOverrides() error = %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(loaded, constructed) {
|
||||
t.Fatalf("loaded overrides = %#v, constructed = %#v", loaded, constructed)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReportModuleValidationConsistentForLoadedAndConstructedConfig(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user