// SPDX-License-Identifier: EUPL-1.2 package agentic import ( "context" "net/http" "net/http/httptest" "testing" core "dappco.re/go/core" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestContent_HandleContentGenerate_Good(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "/v1/content/generate", r.URL.Path) require.Equal(t, http.MethodPost, r.Method) require.Equal(t, "Bearer secret-token", r.Header.Get("Authorization")) bodyResult := core.ReadAll(r.Body) require.True(t, bodyResult.OK) var payload map[string]any parseResult := core.JSONUnmarshalString(bodyResult.Value.(string), &payload) require.True(t, parseResult.OK) require.Equal(t, "Draft a release note", payload["prompt"]) require.Equal(t, "claude", payload["provider"]) config, ok := payload["config"].(map[string]any) require.True(t, ok) require.Equal(t, float64(4000), config["max_tokens"]) _, _ = w.Write([]byte(`{"data":{"id":"gen_1","provider":"claude","model":"claude-3.7-sonnet","content":"Release notes draft","input_tokens":12,"output_tokens":48,"duration_ms":321}}`)) })) defer server.Close() subsystem := testPrepWithPlatformServer(t, server, "secret-token") result := subsystem.handleContentGenerate(context.Background(), core.NewOptions( core.Option{Key: "prompt", Value: "Draft a release note"}, core.Option{Key: "provider", Value: "claude"}, core.Option{Key: "config", Value: `{"max_tokens":4000}`}, )) require.True(t, result.OK) output, ok := result.Value.(ContentGenerateOutput) require.True(t, ok) assert.Equal(t, "gen_1", output.Result.ID) assert.Equal(t, "claude", output.Result.Provider) assert.Equal(t, "claude-3.7-sonnet", output.Result.Model) assert.Equal(t, "Release notes draft", output.Result.Content) assert.Equal(t, 48, output.Result.OutputTokens) } func TestContent_HandleContentGenerate_Good_BriefTemplate(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "/v1/content/generate", r.URL.Path) require.Equal(t, http.MethodPost, r.Method) bodyResult := core.ReadAll(r.Body) require.True(t, bodyResult.OK) var payload map[string]any parseResult := core.JSONUnmarshalString(bodyResult.Value.(string), &payload) require.True(t, parseResult.OK) require.Equal(t, "brief_1", payload["brief_id"]) require.Equal(t, "help-article", payload["template"]) require.NotContains(t, payload, "prompt") _, _ = w.Write([]byte(`{"data":{"result":{"id":"gen_2","provider":"claude","model":"claude-3.7-sonnet","content":"Template draft","status":"completed"}}}`)) })) defer server.Close() subsystem := testPrepWithPlatformServer(t, server, "secret-token") result := subsystem.handleContentGenerate(context.Background(), core.NewOptions( core.Option{Key: "brief_id", Value: "brief_1"}, core.Option{Key: "template", Value: "help-article"}, core.Option{Key: "provider", Value: "claude"}, )) require.True(t, result.OK) output, ok := result.Value.(ContentGenerateOutput) require.True(t, ok) assert.Equal(t, "gen_2", output.Result.ID) assert.Equal(t, "Template draft", output.Result.Content) } func TestContent_HandleContentGenerate_Bad(t *testing.T) { subsystem := testPrepWithPlatformServer(t, nil, "secret-token") result := subsystem.handleContentGenerate(context.Background(), core.NewOptions()) assert.False(t, result.OK) } func TestContent_HandleContentGenerate_Ugly(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(`{"data":`)) })) defer server.Close() subsystem := testPrepWithPlatformServer(t, server, "secret-token") result := subsystem.handleContentGenerate(context.Background(), core.NewOptions( core.Option{Key: "prompt", Value: "Draft a release note"}, )) assert.False(t, result.OK) } func TestContent_HandleContentBriefCreate_Good(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "/v1/content/briefs", r.URL.Path) require.Equal(t, http.MethodPost, r.Method) bodyResult := core.ReadAll(r.Body) require.True(t, bodyResult.OK) var payload map[string]any parseResult := core.JSONUnmarshalString(bodyResult.Value.(string), &payload) require.True(t, parseResult.OK) require.Equal(t, "LinkHost brief", payload["title"]) require.Equal(t, "LinkHost", payload["product"]) _, _ = w.Write([]byte(`{"data":{"brief":{"id":"brief_1","slug":"host-link","title":"LinkHost brief","product":"LinkHost","category":"product","brief":"Core context"}}}`)) })) defer server.Close() subsystem := testPrepWithPlatformServer(t, server, "secret-token") result := subsystem.handleContentBriefCreate(context.Background(), core.NewOptions( core.Option{Key: "title", Value: "LinkHost brief"}, core.Option{Key: "product", Value: "LinkHost"}, core.Option{Key: "category", Value: "product"}, core.Option{Key: "brief", Value: "Core context"}, )) require.True(t, result.OK) output, ok := result.Value.(ContentBriefOutput) require.True(t, ok) assert.Equal(t, "brief_1", output.Brief.ID) assert.Equal(t, "host-link", output.Brief.Slug) assert.Equal(t, "LinkHost", output.Brief.Product) } func TestContent_HandleContentBriefList_Good(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "/v1/content/briefs", r.URL.Path) require.Equal(t, "product", r.URL.Query().Get("category")) require.Equal(t, "5", r.URL.Query().Get("limit")) _, _ = w.Write([]byte(`{"data":{"briefs":[{"id":"brief_1","slug":"host-link","title":"LinkHost brief","category":"product"}],"total":1}}`)) })) defer server.Close() subsystem := testPrepWithPlatformServer(t, server, "secret-token") result := subsystem.handleContentBriefList(context.Background(), core.NewOptions( core.Option{Key: "category", Value: "product"}, core.Option{Key: "limit", Value: 5}, )) require.True(t, result.OK) output, ok := result.Value.(ContentBriefListOutput) require.True(t, ok) assert.Equal(t, 1, output.Total) require.Len(t, output.Briefs, 1) assert.Equal(t, "host-link", output.Briefs[0].Slug) } func TestContent_HandleContentStatus_Good(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "/v1/content/status/batch_123", r.URL.Path) _, _ = w.Write([]byte(`{"data":{"status":"running","batch_id":"batch_123","queued":2}}`)) })) defer server.Close() subsystem := testPrepWithPlatformServer(t, server, "secret-token") result := subsystem.handleContentStatus(context.Background(), core.NewOptions( core.Option{Key: "batch_id", Value: "batch_123"}, )) require.True(t, result.OK) output, ok := result.Value.(ContentStatusOutput) require.True(t, ok) assert.Equal(t, "running", stringValue(output.Status["status"])) assert.Equal(t, "batch_123", stringValue(output.Status["batch_id"])) } func TestContent_HandleContentUsageStats_Good(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "/v1/content/usage/stats", r.URL.Path) require.Equal(t, "claude", r.URL.Query().Get("provider")) require.Equal(t, "week", r.URL.Query().Get("period")) _, _ = w.Write([]byte(`{"data":{"calls":4,"tokens":1200}}`)) })) defer server.Close() subsystem := testPrepWithPlatformServer(t, server, "secret-token") result := subsystem.handleContentUsageStats(context.Background(), core.NewOptions( core.Option{Key: "provider", Value: "claude"}, core.Option{Key: "period", Value: "week"}, )) require.True(t, result.OK) output, ok := result.Value.(ContentUsageStatsOutput) require.True(t, ok) assert.Equal(t, 4, intValue(output.Usage["calls"])) assert.Equal(t, 1200, intValue(output.Usage["tokens"])) } func TestContent_HandleContentFromPlan_Good(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "/v1/content/from-plan", r.URL.Path) require.Equal(t, http.MethodPost, r.Method) bodyResult := core.ReadAll(r.Body) require.True(t, bodyResult.OK) var payload map[string]any parseResult := core.JSONUnmarshalString(bodyResult.Value.(string), &payload) require.True(t, parseResult.OK) require.Equal(t, "release-notes", payload["plan_slug"]) require.Equal(t, "openai", payload["provider"]) _, _ = w.Write([]byte(`{"data":{"result":{"batch_id":"batch_123","provider":"openai","model":"gpt-5.4","content":"Plan-driven draft","status":"completed"}}}`)) })) defer server.Close() subsystem := testPrepWithPlatformServer(t, server, "secret-token") result := subsystem.handleContentFromPlan(context.Background(), core.NewOptions( core.Option{Key: "plan_slug", Value: "release-notes"}, core.Option{Key: "provider", Value: "openai"}, )) require.True(t, result.OK) output, ok := result.Value.(ContentFromPlanOutput) require.True(t, ok) assert.Equal(t, "batch_123", output.Result.BatchID) assert.Equal(t, "completed", output.Result.Status) assert.Equal(t, "Plan-driven draft", output.Result.Content) } func TestContent_HandleContentSchemaGenerate_Good_Article(t *testing.T) { subsystem := testPrepWithPlatformServer(t, nil, "secret-token") result := subsystem.handleContentSchemaGenerate(context.Background(), core.NewOptions( core.Option{Key: "type", Value: "article"}, core.Option{Key: "title", Value: "Release notes"}, core.Option{Key: "description", Value: "What changed in this release"}, core.Option{Key: "url", Value: "https://example.test/releases/1"}, core.Option{Key: "author", Value: "Virgil"}, core.Option{Key: "language", Value: "en-GB"}, )) require.True(t, result.OK) output, ok := result.Value.(ContentSchemaOutput) require.True(t, ok) assert.Equal(t, "BlogPosting", output.SchemaType) assert.Equal(t, "Release notes", output.Schema["headline"]) assert.Equal(t, "What changed in this release", output.Schema["description"]) assert.Equal(t, "https://example.test/releases/1", output.Schema["url"]) assert.Equal(t, "en-GB", output.Schema["inLanguage"]) author, ok := output.Schema["author"].(map[string]any) require.True(t, ok) assert.Equal(t, "Virgil", author["name"]) assert.Contains(t, output.SchemaJSON, `"@type":"BlogPosting"`) } func TestContent_HandleContentSchemaGenerate_Good_FAQ(t *testing.T) { subsystem := testPrepWithPlatformServer(t, nil, "secret-token") result := subsystem.handleContentSchemaGenerate(context.Background(), core.NewOptions( core.Option{Key: "kind", Value: "faq"}, core.Option{Key: "title", Value: "Release notes FAQ"}, core.Option{Key: "questions", Value: `[{"question":"What changed?","answer":"We added schema generation."}]`}, )) require.True(t, result.OK) output, ok := result.Value.(ContentSchemaOutput) require.True(t, ok) assert.Equal(t, "FAQPage", output.SchemaType) entries, ok := output.Schema["mainEntity"].([]map[string]any) require.True(t, ok) require.Len(t, entries, 1) assert.Equal(t, "Question", entries[0]["@type"]) assert.Equal(t, "What changed?", entries[0]["name"]) answer, ok := entries[0]["acceptedAnswer"].(map[string]any) require.True(t, ok) assert.Equal(t, "Answer", answer["@type"]) assert.Equal(t, "We added schema generation.", answer["text"]) } func TestContent_HandleContentSchemaGenerate_Good_HowTo(t *testing.T) { subsystem := testPrepWithPlatformServer(t, nil, "secret-token") result := subsystem.handleContentSchemaGenerate(context.Background(), core.NewOptions( core.Option{Key: "kind", Value: "howto"}, core.Option{Key: "title", Value: "Set up the workspace"}, core.Option{Key: "steps", Value: `[{"name":"Prepare","text":"Clone the repo"},{"name":"Run","text":"Start the agent"}]`}, )) require.True(t, result.OK) output, ok := result.Value.(ContentSchemaOutput) require.True(t, ok) assert.Equal(t, "HowTo", output.SchemaType) steps, ok := output.Schema["step"].([]map[string]any) require.True(t, ok) require.Len(t, steps, 2) assert.Equal(t, "HowToStep", steps[0]["@type"]) assert.Equal(t, "Prepare", steps[0]["name"]) assert.Equal(t, "Clone the repo", steps[0]["text"]) } func TestContent_HandleContentSchemaGenerate_Bad(t *testing.T) { subsystem := testPrepWithPlatformServer(t, nil, "secret-token") result := subsystem.handleContentSchemaGenerate(context.Background(), core.NewOptions( core.Option{Key: "type", Value: "article"}, )) assert.False(t, result.OK) } func TestContent_HandleContentSchemaGenerate_Ugly(t *testing.T) { subsystem := testPrepWithPlatformServer(t, nil, "secret-token") result := subsystem.handleContentSchemaGenerate(context.Background(), core.NewOptions( core.Option{Key: "kind", Value: "faq"}, core.Option{Key: "title", Value: "FAQ"}, core.Option{Key: "questions", Value: `[{"question":"What changed?"`}, )) assert.False(t, result.OK) }