diff --git a/internal/service/compilation_template_service.go b/internal/service/compilation_template_service.go index ecd02c66f3..b647dce249 100644 --- a/internal/service/compilation_template_service.go +++ b/internal/service/compilation_template_service.go @@ -96,7 +96,7 @@ type WikiPreset struct { ID string `json:"id"` Topic string `json:"topic"` Instruction string `json:"instruction"` - PageExample string `json:"page_example"` + Example string `json:"example"` } // CompilationTemplateService implements the read-side compilation template @@ -175,7 +175,7 @@ func (s *CompilationTemplateService) LoadWikiPresets() ([]*WikiPreset, error) { ID: strings.TrimSuffix(entry.Name(), filepath.Ext(entry.Name())), Topic: strings.TrimSpace(yamlStr(doc["topic"])), Instruction: yamlStr(doc["instruction"]), - PageExample: yamlStr(doc["page_example"]), + Example: yamlStr(doc["example"]), }) } return presets, nil diff --git a/internal/service/compilation_template_service_test.go b/internal/service/compilation_template_service_test.go index fb9392d810..7f714fee5c 100644 --- a/internal/service/compilation_template_service_test.go +++ b/internal/service/compilation_template_service_test.go @@ -1,6 +1,8 @@ package service import ( + "encoding/json" + "os" "testing" "ragflow/internal/entity" @@ -67,3 +69,54 @@ func TestValidateTemplatePayload_AcceptsJSONMapConfig(t *testing.T) { t.Fatal("non-map config should be rejected") } } + +// TestLoadWikiPresets_FrontendContract pins the Python API contract of +// /v1/compilation-templates/wiki-presets: every preset must expose the +// "example" JSON key filled from the yaml "example" key. The Go port once +// emitted "page_example" while reading a yaml key that does not exist, so +// the frontend received undefined for preset.example and the "Add template" +// page crashed with "TypeError: Cannot read properties of undefined +// (reading 'trim')" as soon as the Wiki kind was selected. +func TestLoadWikiPresets_FrontendContract(t *testing.T) { + // LoadWikiPresets resolves the preset directory from the working + // directory, so run from the repo root where the data files live. + origWd, err := os.Getwd() + if err != nil { + t.Fatalf("getwd: %v", err) + } + if err = os.Chdir("../.."); err != nil { + t.Fatalf("chdir to repo root: %v", err) + } + t.Cleanup(func() { _ = os.Chdir(origWd) }) + + svc := NewCompilationTemplateService() + presets, err := svc.LoadWikiPresets() + if err != nil { + t.Fatalf("LoadWikiPresets: %v", err) + } + if len(presets) == 0 { + t.Fatal("expected wiki presets to load from api/db/init_data") + } + for _, preset := range presets { + if preset.Instruction == "" { + t.Errorf("preset %q: empty instruction", preset.ID) + } + if preset.Example == "" { + t.Errorf("preset %q: empty example (yaml key mismatch?)", preset.ID) + } + blob, merr := json.Marshal(preset) + if merr != nil { + t.Fatalf("marshal preset %q: %v", preset.ID, merr) + } + var decoded map[string]interface{} + if uerr := json.Unmarshal(blob, &decoded); uerr != nil { + t.Fatalf("unmarshal preset %q: %v", preset.ID, uerr) + } + if _, ok := decoded["example"]; !ok { + t.Errorf("preset %q: JSON payload missing \"example\" key: %s", preset.ID, blob) + } + if _, ok := decoded["page_example"]; ok { + t.Errorf("preset %q: stale \"page_example\" key in JSON payload: %s", preset.ID, blob) + } + } +}