132 lines
4.8 KiB
Go
132 lines
4.8 KiB
Go
package web
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/local/glpi-neural-brain/internal/activity"
|
|
"github.com/local/glpi-neural-brain/internal/config"
|
|
"github.com/local/glpi-neural-brain/internal/engine"
|
|
"github.com/local/glpi-neural-brain/internal/graph"
|
|
"github.com/local/glpi-neural-brain/internal/model"
|
|
"github.com/local/glpi-neural-brain/internal/research"
|
|
)
|
|
|
|
func TestRuntimeSettingsAndSourcesAPI(t *testing.T) {
|
|
data := t.TempDir()
|
|
g, err := graph.Open(data)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
g.UpsertNode(model.Node{ID: "n1", Kind: "knowledge", Label: "GLPI", Origin: "test", Categories: []string{"GLPI"}, Metadata: map[string]any{"source": "GLPI Knowledge Base"}})
|
|
g.UpsertNode(model.Node{ID: "n2", Kind: "knowledge", Label: "Ollama", Origin: "test", Categories: []string{"Ollama"}, Metadata: map[string]any{"source": "internal-kb"}})
|
|
g.UpsertNode(model.Node{ID: "n3", Kind: "knowledge", Label: "Ohne Kategorie", Origin: "test"})
|
|
|
|
broker := activity.New(20)
|
|
eng := engine.New(config.Config{
|
|
DataDir: data,
|
|
PersistInterval: time.Minute,
|
|
RuntimeDefaultsConfigured: true,
|
|
LearningEnabled: true,
|
|
ThinkingEnabled: true,
|
|
DefaultView: "neural",
|
|
GLPIKBSource: "Configured GLPI Source",
|
|
}, g, broker)
|
|
h := (&Server{Engine: eng, Graph: g, Broker: broker}).Handler()
|
|
|
|
body := `{"learning_enabled":false,"thinking_enabled":false,"learning_sources":["GLPI Knowledge Base"],"display_sources":["internal-kb"],"thinking_sources":["GLPI Knowledge Base"],"view_mode":"constellation","max_display_nodes":1500,"low_power_mode":true}`
|
|
req := httptest.NewRequest(http.MethodPut, "/api/runtime-settings", strings.NewReader(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
res := httptest.NewRecorder()
|
|
h.ServeHTTP(res, req)
|
|
if res.Code != http.StatusOK {
|
|
t.Fatalf("PUT runtime settings returned %d: %s", res.Code, res.Body.String())
|
|
}
|
|
var settings engine.RuntimeSettings
|
|
if err := json.NewDecoder(res.Body).Decode(&settings); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if settings.LearningEnabled || settings.ThinkingEnabled || settings.ViewMode != "constellation" || settings.MaxDisplayNodes != 1500 || !settings.LowPowerMode {
|
|
t.Fatalf("unexpected settings: %+v", settings)
|
|
}
|
|
|
|
res = httptest.NewRecorder()
|
|
h.ServeHTTP(res, httptest.NewRequest(http.MethodGet, "/api/sources", nil))
|
|
if res.Code != http.StatusOK {
|
|
t.Fatalf("GET sources returned %d", res.Code)
|
|
}
|
|
var sources struct {
|
|
Sources []engine.SourceInfo `json:"sources"`
|
|
}
|
|
if err := json.NewDecoder(res.Body).Decode(&sources); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
foundConfiguredGLPI := false
|
|
foundInternal := false
|
|
for _, source := range sources.Sources {
|
|
if source.Name == "Configured GLPI Source" && source.Count == 0 {
|
|
foundConfiguredGLPI = true
|
|
}
|
|
if source.Name == "internal-kb" && source.Count == 1 {
|
|
foundInternal = true
|
|
}
|
|
}
|
|
if !foundConfiguredGLPI || !foundInternal {
|
|
t.Fatalf("exact source options or configured GLPI source missing: %+v", sources.Sources)
|
|
}
|
|
|
|
res = httptest.NewRecorder()
|
|
h.ServeHTTP(res, httptest.NewRequest(http.MethodPost, "/api/enrich?async=1", strings.NewReader(`{}`)))
|
|
if res.Code != http.StatusConflict {
|
|
t.Fatalf("disabled thinking should return 409, got %d: %s", res.Code, res.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestResearchDiagnosticAPI(t *testing.T) {
|
|
searx := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`{"results":[{"title":"Btrfs documentation","url":"https://example.test/btrfs","content":"Snapshot evidence"}]}`))
|
|
}))
|
|
defer searx.Close()
|
|
|
|
broker := activity.New(20)
|
|
eng := &engine.Engine{
|
|
Cfg: config.Config{ResearchEnabled: true},
|
|
Research: research.New(searx.URL),
|
|
Broker: broker,
|
|
}
|
|
h := (&Server{Engine: eng, Broker: broker}).Handler()
|
|
|
|
res := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodPost, "/api/research/test", strings.NewReader(`{"query":"btrfs snapshots","limit":4}`))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
h.ServeHTTP(res, req)
|
|
if res.Code != http.StatusOK {
|
|
t.Fatalf("research test returned %d: %s", res.Code, res.Body.String())
|
|
}
|
|
var result engine.ResearchTestResult
|
|
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !result.OK || !result.Diagnostic.OK || len(result.Results) != 1 {
|
|
t.Fatalf("unexpected result: %+v", result)
|
|
}
|
|
|
|
res = httptest.NewRecorder()
|
|
h.ServeHTTP(res, httptest.NewRequest(http.MethodGet, "/api/research/status", nil))
|
|
if res.Code != http.StatusOK {
|
|
t.Fatalf("research status returned %d: %s", res.Code, res.Body.String())
|
|
}
|
|
var status map[string]any
|
|
if err := json.NewDecoder(res.Body).Decode(&status); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if status["ok"] != true {
|
|
t.Fatalf("unexpected status: %#v", status)
|
|
}
|
|
}
|