stemedb/sdk/go/steme/canonical_test.go
jordan b3e8a9a058 feat: Multi-application expansion with chaos testing and community UI
Major additions:
- Community Next.js app (port 18187) for browsing claims with API docs
- stemedb-chaos crate: Fault injection, chaos testing, CRDT properties
- Latent ingestion system: Reddit/FDA ingesters with ADK-Go agents
- Disputed claims handling: Manual review workflows and validation
- Aphoria security scanner: New extractors (SQL injection, command
  injection, weak crypto, TLS version), policy-based ignores, UAT reports
- Docker infrastructure: Dockerfile, docker-compose.yml for full stack
- VulnBank demo: Intentionally vulnerable multi-language test corpus

SDK & API enhancements:
- Source registry handlers for tracking data provenance
- Metrics endpoint
- Skeptic filtering improvements

Code quality:
- Split 14 large files (>500 lines) into focused modules
- All files now under 500-line limit per project guidelines

Documentation:
- Chaos testing guide, circuit breakers, observability docs
- Phase 7 UAT documentation updates
- Martin Kleppmann technical writer agent

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:24:14 -07:00

158 lines
4.3 KiB
Go

package steme
import (
"testing"
)
// TestCanonicalMessage tests the canonical message generation for signing.
func TestCanonicalMessage(t *testing.T) {
assertion := NewAssertion("Tesla_Inc", "has_revenue").
WithNumber(96.7).
WithConfidence(0.95).
WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
Build()
msg1, err := canonicalAssertionMessage(&assertion)
if err != nil {
t.Fatalf("canonicalAssertionMessage() failed: %v", err)
}
// Verify format matches server expectation: "{subject}:{predicate}"
expected := "Tesla_Inc:has_revenue"
if string(msg1) != expected {
t.Errorf("canonicalAssertionMessage() = %q, want %q", string(msg1), expected)
}
// Same assertion should produce same message
msg2, err := canonicalAssertionMessage(&assertion)
if err != nil {
t.Fatalf("canonicalAssertionMessage() failed: %v", err)
}
if string(msg1) != string(msg2) {
t.Errorf("Canonical message not deterministic")
}
// Different subject/predicate should produce different message
assertion2 := NewAssertion("Tesla_Inc", "has_employees"). // Different predicate
WithNumber(97.0).
WithConfidence(0.95).
WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
Build()
msg3, err := canonicalAssertionMessage(&assertion2)
if err != nil {
t.Fatalf("canonicalAssertionMessage() failed: %v", err)
}
if string(msg1) == string(msg3) {
t.Errorf("Different assertions produced same canonical message")
}
}
// TestCanonicalMessageAllObjectTypes tests canonical message with all object types.
// The canonical message is just "{subject}:{predicate}" - object type doesn't affect it.
func TestCanonicalMessageAllObjectTypes(t *testing.T) {
types := []struct {
name string
obj ObjectValue
}{
{"text", NewTextValue("hello")},
{"number", NewNumberValue(42.5)},
{"boolean", NewBooleanValue(true)},
{"reference", NewReferenceValue("Entity_123")},
}
for _, tt := range types {
t.Run(tt.name, func(t *testing.T) {
a := NewAssertion("Subject", "Predicate").
WithConfidence(0.5).
WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
Build()
a.Object = tt.obj
msg, err := canonicalAssertionMessage(&a)
if err != nil {
t.Errorf("canonicalAssertionMessage() failed for %s: %v", tt.name, err)
}
// Canonical message is "{subject}:{predicate}" regardless of object type
expected := "Subject:Predicate"
if string(msg) != expected {
t.Errorf("Expected %q, got %q", expected, string(msg))
}
})
}
}
// TestCanonicalMessageEdgeCases tests edge cases in canonical message generation.
func TestCanonicalMessageEdgeCases(t *testing.T) {
tests := []struct {
name string
build func() Assertion
wantErr bool
expected string
}{
{
name: "zero confidence",
build: func() Assertion {
return NewAssertion("S", "P").
WithText("v").
WithConfidence(0.0).
WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
Build()
},
wantErr: false,
expected: "S:P",
},
{
name: "max confidence",
build: func() Assertion {
return NewAssertion("S", "P").
WithText("v").
WithConfidence(1.0).
WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
Build()
},
wantErr: false,
expected: "S:P",
},
{
name: "empty strings",
build: func() Assertion {
return NewAssertion("", "").
WithText("v").
WithConfidence(0.5).
WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
Build()
},
wantErr: false,
expected: ":",
},
{
name: "special characters",
build: func() Assertion {
return NewAssertion("Subject:With:Colons", "Predicate").
WithText("v").
WithConfidence(0.5).
WithSourceHash("0000000000000000000000000000000000000000000000000000000000000000").
Build()
},
wantErr: false,
expected: "Subject:With:Colons:Predicate",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := tt.build()
msg, err := canonicalAssertionMessage(&a)
if (err != nil) != tt.wantErr {
t.Errorf("error = %v, wantErr %v", err, tt.wantErr)
}
if !tt.wantErr && string(msg) != tt.expected {
t.Errorf("got %q, want %q", string(msg), tt.expected)
}
})
}
}