Why: Allow consumers to download an immutable module revision without nested source checkouts or local path replacements. Evidence: SELF package tests and the prior canonical-path rejection are recorded in the Dev dependency-workspace task card; remote consumption is replayed against the committed candidate. Impact: Change the module identity and its Go imports while preserving API behavior. Existing historical submodule revisions remain buildable. Refs: Versioned dependencies U1/U3; feature/dependency-workspace
87 lines
3.8 KiB
Go
87 lines
3.8 KiB
Go
package settings
|
|
|
|
import (
|
|
core "git-ssh.u1680832.nyat.app/weichen/Agent-System-Core.git"
|
|
"bytes"
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
func TestMaskedProjectMetadataCopiesSecretViews(t *testing.T) {
|
|
s := NewService(nil)
|
|
s.SetExtraSchema([]core.SettingDesc{{Key: "plugins.private.credential", Secret: true}})
|
|
raw := map[string]any{"models.chat.apiKey": "fixture-known", "legacy.token": "fixture-flat", "plugins.private": map[string]any{"credential": "fixture-schema"}, "nested": []any{map[string]any{"api_key": "fixture-array"}}, "opaque.secret": map[string]any{"value": "fixture-opaque"}, "custom.token": []any{"fixture-list"}, "custom.caption": "Allowed", "rdm.projectId": "canonical", "rdm.state": "ready"}
|
|
before, _ := json.Marshal(raw)
|
|
view := s.MaskedProjectMetadata(raw)
|
|
after, _ := json.Marshal(raw)
|
|
if string(before) != string(after) {
|
|
t.Fatal("read-only metadata view mutated its source")
|
|
}
|
|
encoded, _ := json.Marshal(view)
|
|
for _, secret := range []string{"fixture-known", "fixture-flat", "fixture-schema", "fixture-array", "fixture-opaque", "fixture-list"} {
|
|
if bytes.Contains(encoded, []byte(secret)) {
|
|
t.Fatal("metadata view exposed a fixture secret")
|
|
}
|
|
}
|
|
if view["custom.caption"] != "Allowed" || view["rdm.projectId"] != "canonical" || view["rdm.state"] != "ready" {
|
|
t.Fatal("nonsecret metadata shape/value changed")
|
|
}
|
|
if view["legacy.token"] != MaskPlaceholder || view["opaque.secret"] != MaskPlaceholder || view["custom.token"] != MaskPlaceholder {
|
|
t.Fatal("secret fallback did not mask complete dotted values")
|
|
}
|
|
}
|
|
|
|
func TestPrepareProjectMetadataWriteUsesManagedGuard(t *testing.T) {
|
|
s := NewService(nil)
|
|
s.SetExtraSchema([]core.SettingDesc{{Key: "plugins.private.managed", Scope: core.SettingScopeSystem}})
|
|
for _, raw := range []map[string]any{{"models.chat.apiKey": "fixture"}, {"models": map[string]any{"chat": map[string]any{"apiKey": "fixture"}}}, {"models": "smash"}, {"plugins.private.managed": "override"}} {
|
|
if _, err := s.PrepareProjectMetadataWrite(raw); err == nil {
|
|
t.Fatal("managed metadata write accepted")
|
|
}
|
|
}
|
|
raw := map[string]any{"custom.caption": "Allowed", "custom.token": MaskPlaceholder, "models.chat.apiKey": MaskPlaceholder}
|
|
view, err := s.PrepareProjectMetadataWrite(raw)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(view) != 1 || view["custom.caption"] != "Allowed" {
|
|
t.Fatal("metadata writes must preserve allowed dotted keys and ignore mask placeholders")
|
|
}
|
|
if raw["custom.token"] != MaskPlaceholder {
|
|
t.Fatal("write preparation mutated its input")
|
|
}
|
|
}
|
|
|
|
func TestPrepareProjectMetadataWritePrunesOnlyMaskedParents(t *testing.T) {
|
|
s := NewService(nil)
|
|
for _, raw := range []map[string]any{
|
|
{"models": map[string]any{"chat": map[string]any{"apiKey": MaskPlaceholder}}, "display": map[string]any{"caption": "Updated"}},
|
|
{"models.chat": map[string]any{"apiKey": MaskPlaceholder}, "display.caption": "Updated"},
|
|
{"models": map[string]any{"chat.apiKey": MaskPlaceholder}, "display.caption": "Updated"},
|
|
} {
|
|
before, _ := json.Marshal(raw)
|
|
got, err := s.PrepareProjectMetadataWrite(raw)
|
|
if err != nil {
|
|
t.Fatalf("unchanged masked credential rejected legal metadata edit: %v", err)
|
|
}
|
|
if len(got) != 1 {
|
|
t.Fatal("mask-only parent remained in prepared metadata")
|
|
}
|
|
after, _ := json.Marshal(raw)
|
|
if !bytes.Equal(before, after) {
|
|
t.Fatal("mask preparation changed its input")
|
|
}
|
|
}
|
|
for _, raw := range []map[string]any{
|
|
{"models": map[string]any{}},
|
|
{"models": map[string]any{"chat": map[string]any{}}},
|
|
{"models.chat": map[string]any{}},
|
|
{"models": map[string]any{"chat": map[string]any{"apiKey": MaskPlaceholder, "model": "Real overwrite"}}},
|
|
{"models.chat": map[string]any{"apiKey": MaskPlaceholder}, "models": map[string]any{"chat": map[string]any{}}},
|
|
} {
|
|
if _, err := s.PrepareProjectMetadataWrite(raw); err == nil {
|
|
t.Fatal("explicit empty or real managed overwrite accepted")
|
|
}
|
|
}
|
|
}
|