Files
addrkit/internal/config/config_test.go
T
Maksim Totmin 50f180ea10 fix(outages): parse portal address at the boundary; strip district suffix
The outages portal appends the district in parentheses, e.g.
"Медкадры улица, 1 (Заельцовский район)". That suffix hid the house number
from the parser, so every portal address failed house matching and /v1/outages
always returned empty.

- address: NormalizeText drops a trailing "(...)" group (root fix, benefits
  every source)
- outages: introduce HouseUnit; the ArcGIS adapter parses the (cleaned) address
  at the boundary and stores the structured unit; MatchingHouse matches on the
  unit (with a parse fallback for sources that only provide text)
- config: portal.url is now optional (core runs without the events module)
- httpapi: always return "outages": [] (no more omitempty); report
  "detail" when the events module is not configured
- tests: regression coverage for the portal district format
2026-10-09 22:05:18 +07:00

71 lines
1.9 KiB
Go

package config
import (
"os"
"path/filepath"
"testing"
)
func writeFile(t *testing.T, dir, name, content string) string {
t.Helper()
path := filepath.Join(dir, name)
if err := os.WriteFile(path, []byte(content), 0o600); err != nil {
t.Fatalf("write %s: %v", name, err)
}
return path
}
func baseConfig(promptFields string) string {
return `{
"addr": ":6171",
"data_path": "registry.db",
"portal": { "url": "http://portal" },
"llm": { "enabled": true, "url": "http://llm"` + promptFields + ` }
}`
}
func TestLoadInlineSystemPrompt(t *testing.T) {
dir := t.TempDir()
path := writeFile(t, dir, "config.json", baseConfig(`, "system_prompt": "INLINE PROMPT"`))
cfg, err := Load(path)
if err != nil {
t.Fatalf("Load: %v", err)
}
if cfg.LLM.SystemPrompt != "INLINE PROMPT" {
t.Errorf("SystemPrompt = %q", cfg.LLM.SystemPrompt)
}
}
func TestLoadSystemPromptFromFile(t *testing.T) {
dir := t.TempDir()
promptFile := writeFile(t, dir, "prompt.txt", "PROMPT FROM FILE\n")
path := writeFile(t, dir, "config.json", baseConfig(`, "system_prompt_file": "`+promptFile+`"`))
cfg, err := Load(path)
if err != nil {
t.Fatalf("Load: %v", err)
}
if cfg.LLM.SystemPrompt != "PROMPT FROM FILE\n" {
t.Errorf("SystemPrompt = %q", cfg.LLM.SystemPrompt)
}
}
func TestLoadMissingSystemPromptFileFailsClosed(t *testing.T) {
dir := t.TempDir()
path := writeFile(t, dir, "config.json", baseConfig(`, "system_prompt_file": "`+filepath.Join(dir, "nope.txt")+`"`))
if _, err := Load(path); err == nil {
t.Fatal("expected error for missing system_prompt_file")
}
}
func TestPortalURLOptional(t *testing.T) {
dir := t.TempDir()
// No portal.url: the events module is disabled, the core still loads.
path := writeFile(t, dir, "config.json", `{"addr": ":6171", "data_path": "x.db"}`)
if _, err := Load(path); err != nil {
t.Fatalf("portal.url must be optional: %v", err)
}
}