package elderagent import ( "context" "encoding/json" "fmt" "net/http" "net/http/httptest" "strings" "testing" ) func TestProviderCreateAndRecover(t *testing.T) { var created, updated int server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" || r.URL.Query().Get("Version") != "2025-08-01" || r.Header.Get("Authorization") == "" { t.Error("incorrect signed API request") } var body map[string]any json.NewDecoder(r.Body).Decode(&body) switch r.URL.Query().Get("Action") { case "AibotQuery": if body["AccessType"] != "public" { t.Error("name lookup requires public AccessType") } if created == 0 { fmt.Fprint(w, `{"Result":{"Bots":[]}}`) } else { fmt.Fprint(w, `{"Result":{"Bots":[{"Id":"bot-elder","Name":"elder-1"}]}}`) } case "AibotCreate": created++ if body["AccessType"] != "public" || body["Config"] == nil || body["Name"] != "elder-1" { t.Error("missing creation fields") } fmt.Fprint(w, `{"Result":{"Id":"bot-elder"}}`) case "AibotUpdate": updated++ fmt.Fprint(w, `{"Result":{}}`) default: t.Error("unexpected action") } })) defer server.Close() c := NewClient("test-ak", "test-sk", "", server.URL, "") for n := 0; n < 2; n++ { b, err := c.Ensure(context.Background(), "elder-1", map[string]any{"S2SConfig": map[string]any{}}, map[string]any{}) if err != nil || b.ID != "bot-elder" { t.Fatal(b, err) } } if created != 1 || updated != 1 { t.Fatal(created, updated) } } func TestConfigurationIsPerElderAndKeepsS2SOnServer(t *testing.T) { s := Service{Template: []byte(`{"templates":{"s2s_hybrid":{"Config":{"S2SConfig":{"Provider":"volcano","OutputMode":1,"ProviderParams":{"app":{"appid":"test-app","token":"test-token"},"dialog":{"system_role":"温暖陪伴","dialog_id":"shared"}}},"MemoryConfig":{"Enable":true}}}}}`), CallbackURL: "https://example.com/callback", CallbackSecret: []byte(strings.Repeat("k", 32))} a, aa, err := s.Configuration("elder-1", "张奶奶") if err != nil { t.Fatal(err) } b, ba, err := s.Configuration("elder-2", "李爷爷") if err != nil { t.Fatal(err) } rawA, _ := json.Marshal(a) rawB, _ := json.Marshal(b) if !strings.Contains(string(rawA), "张奶奶") || strings.Contains(string(rawB), "张奶奶") || strings.Contains(string(rawA), "dialog_id") { t.Fatal("elder config isolation failed") } if a["S2SConfig"].(map[string]any)["OutputMode"] != 0 || aa["ServerMessageURLForRTS"] == ba["ServerMessageURLForRTS"] { t.Fatal("incorrect S2S/callback config") } if a["MemoryConfig"].(map[string]any)["Enable"] != false { t.Fatal("inherited shared memory") } } func TestProviderErrorDoesNotExposeConfiguration(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, `{"ResponseMetadata":{"Error":{"Code":"InvalidParameter","Message":"secret-token"}}}`) })) defer server.Close() _, err := NewClient("ak", "sk", "", server.URL, "").Ensure(context.Background(), "elder", nil, nil) if err == nil || strings.Contains(err.Error(), "secret-token") { t.Fatal(err) } } func TestPersonaReadbackChecksManagedFieldsAndMasksErrors(t *testing.T) { config := map[string]any{"S2SConfig": map[string]any{"ProviderParams": map[string]any{"app": map[string]any{"token": "SECRET_TOKEN"}, "dialog": map[string]any{"system_role": "新角色"}}}, "MemoryConfig": map[string]any{"Enable": false}} agent := map[string]any{"WelcomeMessage": "开场", "ServerMessageURLForRTS": "https://example.com/callback", "ServerMessageSignatureForRTS": "signature"} stale := false server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Query().Get("Action") != "AibotQuery" { t.Error("wrong verification action") } role := "新角色" if stale { role = "SECRET_STALE_ROLE" } actual := map[string]any{"S2SConfig": map[string]any{"ProviderParams": map[string]any{"dialog": map[string]any{"system_role": role}}}, "MemoryConfig": map[string]any{"Enable": false}} json.NewEncoder(w).Encode(map[string]any{"Result": map[string]any{"Bots": []Bot{{ID: "bot", Config: actual, AgentConfig: agent}}}}) })) defer server.Close() c := NewClient("ak", "sk", "", server.URL, "") if err := c.VerifyConfiguration(context.Background(), "bot", config, agent); err != nil { t.Fatal("masked credentials failed verification", err) } stale = true if err := c.VerifyConfiguration(context.Background(), "bot", config, agent); err == nil || strings.Contains(err.Error(), "SECRET") { t.Fatal("unverified or exposed provider config", err) } }