- Prompt, Payload and AIResponse value objects ported from Golem15.Golem - OpenAIAdapter: chat completions mapping with PHP's response_format, max_completion_tokens and reasoning_effort rules - AIService.Send through fetchguard (TrustedMode for operator models, PublicOnlyMode otherwise) with PHP's failure messages - config defaults for the SSRF allowlist and the AI timeout, lang, README
66 lines
2.1 KiB
Go
66 lines
2.1 KiB
Go
package golem
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/backpack"
|
|
"git.golem15.com/golem15/summercms/modules/compass"
|
|
"git.golem15.com/golem15/summercms/modules/party"
|
|
"git.golem15.com/golem15/summercms/modules/phrasebook"
|
|
)
|
|
|
|
func testConfig(t testing.TB) *compass.Config {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
if err := os.WriteFile(filepath.Join(dir, "app.yaml"), []byte("name: golem-test\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg, err := compass.Open(compass.Options{Dir: dir, Environ: []string{"SUMMER_ENV=development"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
// TestGolemPluginBoot activates the plugin alone (no golem15.user: it
|
|
// requires no other plugin) and checks its ID, its config defaults and its
|
|
// lang namespace.
|
|
func TestGolemPluginBoot(t *testing.T) {
|
|
cfg := testConfig(t)
|
|
app := backpack.New(cfg)
|
|
plugins, err := party.Activate(app, []string{"golem15.golem"})
|
|
if err != nil {
|
|
t.Fatalf("activate golem15.golem alone: %v", err)
|
|
}
|
|
if len(plugins) != 1 || plugins[0].ID() != "golem15.golem" {
|
|
t.Fatalf("activated plugins = %v", plugins)
|
|
}
|
|
if got := (&Plugin{}).Requires(); len(got) != 0 {
|
|
t.Fatalf("Requires() = %v, want none", got)
|
|
}
|
|
if got := cfg.Int("golem15.golem.ai.timeout_seconds"); got != 120 {
|
|
t.Fatalf("golem15.golem.ai.timeout_seconds = %d, want 120", got)
|
|
}
|
|
hosts, ok := cfg.Lookup("golem15.golem.ssrf.allowed_hosts")
|
|
if !ok {
|
|
t.Fatal("golem15.golem.ssrf.allowed_hosts is not set")
|
|
}
|
|
list, _ := hosts.([]any)
|
|
if len(list) != 2 || list[0] != "oaidalleapiprodscus.blob.core.windows.net" || list[1] != ".openai.com" {
|
|
t.Fatalf("allowed_hosts = %#v", hosts)
|
|
}
|
|
tr, ok := app.Lookup[*phrasebook.Translator]()
|
|
if !ok {
|
|
t.Fatal("no translator published")
|
|
}
|
|
if got := tr.Get(context.Background(), "golem15.golem::lang.plugin.name", nil); got != "Golem" {
|
|
t.Fatalf("golem15.golem::lang.plugin.name = %q", got)
|
|
}
|
|
if got := tr.Get(context.Background(), "golem15.golem::lang.permissions.access_settings", nil); got != "Manage AI settings" {
|
|
t.Fatalf("access_settings label = %q", got)
|
|
}
|
|
}
|