Files
Agent-System-Core/settings_scope_test.go
weichen 9150e6f90b Add system-managed setting scope contract to SettingDesc
Why: P2 受管设置机制需要 schema 声明写入归属——system 受管项仅管理员可写,user/project 层拒绝写入且生效链忽略存量覆盖。
Evidence: go test ./... 全绿(ManagedPaths/Touches/Strip 含祖先标量覆盖与整棵子树剥离用例)。
Impact: 新增 SettingScope 常量、SettingDesc.Scope 字段与三个纯函数;空 Scope 保持既有行为,向后兼容。
Refs: modules/documents/docs/proposals/2026-10-13-rdm-settings-members-duties-perms-increment.md P2
2026-10-13 03:40:25 +00:00

86 lines
2.9 KiB
Go

package core
import (
"reflect"
"sort"
"testing"
)
func TestManagedPathsFiltersSystemScope(t *testing.T) {
descs := []SettingDesc{
{Key: "models.chat.model", Scope: SettingScopeSystem},
{Key: "ui.theme"},
{Key: "tools.tavily.apiKeys", Scope: SettingScopeSystem},
}
got := ManagedPaths(descs)
sort.Strings(got)
want := []string{"models.chat.model", "tools.tavily.apiKeys"}
if !reflect.DeepEqual(got, want) {
t.Fatalf("ManagedPaths = %v, want %v", got, want)
}
}
func TestTouchesManagedSettings(t *testing.T) {
managed := []string{"models.chat.model", "tools.tavily.apiKeys", "telemetry.otlpEndpoint"}
cases := []struct {
name string
in map[string]any
want []string
}{
{"exact leaf", map[string]any{"models": map[string]any{"chat": map[string]any{"model": "x"}}}, []string{"models.chat.model"}},
{"sibling untouched", map[string]any{"models": map[string]any{"chat": map[string]any{"baseUrl": "x"}}}, nil},
{"ancestor scalar overwrite", map[string]any{"models": "oops"}, []string{"models"}},
{"subtree inside managed", map[string]any{"telemetry": map[string]any{"otlpEndpoint": "http://x"}}, []string{"telemetry.otlpEndpoint"}},
{"other group untouched", map[string]any{"ui": map[string]any{"theme": "light"}}, nil},
{"empty map", map[string]any{}, nil},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got := TouchesManagedSettings(tc.in, managed)
sort.Strings(got)
if tc.want == nil && len(got) != 0 {
t.Fatalf("TouchesManagedSettings = %v, want none", got)
}
if tc.want != nil && !reflect.DeepEqual(got, tc.want) {
t.Fatalf("TouchesManagedSettings = %v, want %v", got, tc.want)
}
})
}
}
func TestStripManagedSettings(t *testing.T) {
managed := []string{"models.chat.model", "models.chat.apiKey"}
in := map[string]any{
"models": map[string]any{
"chat": map[string]any{"model": "x", "baseUrl": "https://b"},
"lightweight": map[string]any{"model": "y"},
},
"ui": map[string]any{"theme": "dark"},
}
got := StripManagedSettings(in, managed)
want := map[string]any{
"models": map[string]any{
"chat": map[string]any{"baseUrl": "https://b"},
"lightweight": map[string]any{"model": "y"},
},
"ui": map[string]any{"theme": "dark"},
}
if !reflect.DeepEqual(got, want) {
t.Fatalf("StripManagedSettings = %v, want %v", got, want)
}
if in["models"].(map[string]any)["chat"].(map[string]any)["model"] != "x" {
t.Fatal("StripManagedSettings 不应修改入参")
}
}
func TestStripManagedSettingsWholeSubtree(t *testing.T) {
managed := []string{"models.chat.model", "models.chat.baseUrl", "models.chat.apiKey", "models.chat.fallbacks"}
in := map[string]any{
"models": map[string]any{"chat": map[string]any{"model": "x", "baseUrl": "b", "apiKey": "k"}},
}
got := StripManagedSettings(in, managed)
if len(got) != 0 {
t.Fatalf("整棵受管子树应被剥除(含空父),got %v", got)
}
}