package adk import ( "context" "encoding/json" "testing" "github.com/orchard9/stemedb-go/steme" ) // mockClient implements EpistemeClient for testing type mockClient struct { queryFunc func(ctx context.Context, params steme.QueryParams) (*steme.QueryResult, error) assertFunc func(ctx context.Context, assertion steme.Assertion) (string, error) traceFunc func(ctx context.Context, params steme.TraceParams) (*steme.TraceResult, error) supersedeFunc func(ctx context.Context, params steme.SupersedeParams) (*steme.SupersedeResult, error) } func (m *mockClient) Query(ctx context.Context, params steme.QueryParams) (*steme.QueryResult, error) { if m.queryFunc != nil { return m.queryFunc(ctx, params) } return &steme.QueryResult{}, nil } func (m *mockClient) Assert(ctx context.Context, assertion steme.Assertion) (string, error) { if m.assertFunc != nil { return m.assertFunc(ctx, assertion) } return "mock_hash", nil } func (m *mockClient) Trace(ctx context.Context, params steme.TraceParams) (*steme.TraceResult, error) { if m.traceFunc != nil { return m.traceFunc(ctx, params) } return &steme.TraceResult{}, nil } func (m *mockClient) Supersede(ctx context.Context, params steme.SupersedeParams) (*steme.SupersedeResult, error) { if m.supersedeFunc != nil { return m.supersedeFunc(ctx, params) } return &steme.SupersedeResult{ Status: "superseded", TargetHash: params.TargetHash, SupersessionType: params.SupersessionType, Timestamp: 1704067200, }, nil } func TestQueryTool(t *testing.T) { // Mock client that returns a test assertion client := &mockClient{ queryFunc: func(ctx context.Context, params steme.QueryParams) (*steme.QueryResult, error) { lifecycle := steme.LifecycleApproved return &steme.QueryResult{ Assertions: []steme.AssertionResponse{ { Hash: "test_hash", Subject: "Tesla_Inc", Predicate: "has_revenue", Object: steme.NewNumberValue(96.7), Confidence: 0.95, SourceHash: "source_hash", Lifecycle: lifecycle, }, }, TotalCount: 1, HasMore: false, }, nil }, } tool := NewQueryTool(client) // Test basic query input := QueryInput{ Subject: "Tesla_Inc", Predicate: "has_revenue", Lens: "consensus", } inputBytes, err := json.Marshal(input) if err != nil { t.Fatalf("failed to marshal input: %v", err) } outputBytes, err := tool.Execute(context.Background(), inputBytes) if err != nil { t.Fatalf("query failed: %v", err) } var output QueryOutput if err := json.Unmarshal(outputBytes, &output); err != nil { t.Fatalf("failed to unmarshal output: %v", err) } // Verify output if output.Confidence != 0.95 { t.Errorf("expected confidence 0.95, got %f", output.Confidence) } if output.Lifecycle != "Approved" { t.Errorf("expected lifecycle Approved, got %s", output.Lifecycle) } if output.QueryID == "" { t.Error("expected non-empty query ID") } if len(output.Sources) == 0 { t.Error("expected at least one source") } } func TestQueryToolConfidenceThreshold(t *testing.T) { // Mock client that returns low confidence client := &mockClient{ queryFunc: func(ctx context.Context, params steme.QueryParams) (*steme.QueryResult, error) { lifecycle := steme.LifecycleApproved return &steme.QueryResult{ Assertions: []steme.AssertionResponse{ { Hash: "test_hash", Subject: "test", Predicate: "test", Object: steme.NewTextValue("test"), Confidence: 0.6, // Low confidence SourceHash: "source_hash", Lifecycle: lifecycle, }, }, TotalCount: 1, }, nil }, } tool := NewQueryTool(client) input := QueryInput{ Subject: "test", Predicate: "test", MinConfidence: 0.8, // Require high confidence } inputBytes, _ := json.Marshal(input) outputBytes, err := tool.Execute(context.Background(), inputBytes) if err != nil { t.Fatalf("query failed: %v", err) } var output QueryOutput if err := json.Unmarshal(outputBytes, &output); err != nil { t.Fatalf("failed to unmarshal output: %v", err) } // Should have error about low confidence if output.Error == "" { t.Error("expected error for low confidence") } } func TestAssertTool(t *testing.T) { // Track what assertion was created var capturedAssertion steme.Assertion client := &mockClient{ assertFunc: func(ctx context.Context, assertion steme.Assertion) (string, error) { capturedAssertion = assertion return "created_hash", nil }, } tool := NewAssertTool(client) input := AssertInput{ Subject: "Tesla_Inc", Predicate: "has_revenue", Object: 96.7, SourceHash: "0000000000000000000000000000000000000000000000000000000000000000", Confidence: 0.95, Lifecycle: "approved", } inputBytes, _ := json.Marshal(input) outputBytes, err := tool.Execute(context.Background(), inputBytes) if err != nil { t.Fatalf("assert failed: %v", err) } var output AssertOutput if err := json.Unmarshal(outputBytes, &output); err != nil { t.Fatalf("failed to unmarshal output: %v", err) } // Verify output if !output.Success { t.Errorf("expected success, got error: %s", output.Error) } if output.Hash != "created_hash" { t.Errorf("expected hash created_hash, got %s", output.Hash) } // Verify captured assertion if capturedAssertion.Subject != "Tesla_Inc" { t.Errorf("expected subject Tesla_Inc, got %s", capturedAssertion.Subject) } // Use approximate comparison for floating point if capturedAssertion.Confidence < 0.94 || capturedAssertion.Confidence > 0.96 { t.Errorf("expected confidence ~0.95, got %f", capturedAssertion.Confidence) } }