87 lines
2.5 KiB
Go
87 lines
2.5 KiB
Go
package app
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.warky.dev/wdevs/amcs/internal/config"
|
|
)
|
|
|
|
func TestParseWebhookThoughtRequestRequiresJSON(t *testing.T) {
|
|
req := httptestRequest("text/plain", `{"content":"hello"}`)
|
|
|
|
_, err := parseWebhookThoughtRequest(req)
|
|
if err == nil {
|
|
t.Fatal("expected error for non-json content type")
|
|
}
|
|
}
|
|
|
|
func TestParseWebhookThoughtRequestRequiresContent(t *testing.T) {
|
|
req := httptestRequest("application/json", `{"source":"n8n"}`)
|
|
|
|
_, err := parseWebhookThoughtRequest(req)
|
|
if err == nil || !strings.Contains(err.Error(), "content is required") {
|
|
t.Fatalf("error = %v, want content required", err)
|
|
}
|
|
}
|
|
|
|
func TestBuildWebhookMetadataUsesHeaderIdempotencyAndSanitizesMetadata(t *testing.T) {
|
|
now := time.Date(2026, 7, 15, 4, 0, 0, 0, time.UTC)
|
|
got := buildWebhookMetadata(webhookThoughtRequest{
|
|
ExternalID: " ext-1 ",
|
|
Metadata: map[string]any{
|
|
"service": "n8n",
|
|
"unsafe": struct{}{},
|
|
"nested": map[string]any{"ok": true},
|
|
},
|
|
}, " key-1 ", now)
|
|
|
|
if got.IDempotencyKey != "key-1" {
|
|
t.Fatalf("IDempotencyKey = %q, want key-1", got.IDempotencyKey)
|
|
}
|
|
if got.ExternalID != "ext-1" {
|
|
t.Fatalf("ExternalID = %q, want ext-1", got.ExternalID)
|
|
}
|
|
if got.ReceivedAt != "2026-07-15T04:00:00Z" {
|
|
t.Fatalf("ReceivedAt = %q", got.ReceivedAt)
|
|
}
|
|
if _, ok := got.SourceMetadata["unsafe"]; ok {
|
|
t.Fatal("unsafe metadata value was not removed")
|
|
}
|
|
if got.SourceMetadata["service"] != "n8n" {
|
|
t.Fatalf("service metadata = %#v", got.SourceMetadata["service"])
|
|
}
|
|
}
|
|
|
|
func TestNormalizeWebhookThoughtMetadata(t *testing.T) {
|
|
webhookMeta := buildWebhookMetadata(webhookThoughtRequest{IDempotencyKey: "abc"}, "", time.Date(2026, 7, 15, 4, 0, 0, 0, time.UTC))
|
|
got := normalizeWebhookThoughtMetadata(webhookThoughtRequest{
|
|
Source: "github",
|
|
Type: "task",
|
|
Topics: []string{"ci", "ci", ""},
|
|
People: []string{" Sam "},
|
|
}, webhookMeta, config.CaptureConfig{})
|
|
|
|
if got.Source != "github" {
|
|
t.Fatalf("Source = %q, want github", got.Source)
|
|
}
|
|
if got.Type != "task" {
|
|
t.Fatalf("Type = %q, want task", got.Type)
|
|
}
|
|
if len(got.Topics) != 1 || got.Topics[0] != "ci" {
|
|
t.Fatalf("Topics = %#v, want [ci]", got.Topics)
|
|
}
|
|
if got.Webhook == nil || got.Webhook.IDempotencyKey != "abc" {
|
|
t.Fatalf("Webhook = %#v, want idempotency key abc", got.Webhook)
|
|
}
|
|
}
|
|
|
|
func httptestRequest(contentType, body string) *http.Request {
|
|
req := httptest.NewRequest(http.MethodPost, "/webhooks/thoughts", strings.NewReader(body))
|
|
req.Header.Set("Content-Type", contentType)
|
|
return req
|
|
}
|