108 lines
3.8 KiB
Go
108 lines
3.8 KiB
Go
package attesto
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
const testAPIKey = "atto_test_0123456789abcdef0123456789abcdef"
|
|
|
|
func TestClientCallsProductionV2Endpoints(t *testing.T) {
|
|
var seen []string
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
seen = append(seen, r.Method+" "+r.URL.String())
|
|
if r.Header.Get("Authorization") != "Bearer "+testAPIKey {
|
|
t.Fatalf("authorization header missing")
|
|
}
|
|
if !strings.HasPrefix(r.Header.Get("X-Attesto-SDK"), "attesto-go/") {
|
|
t.Fatalf("sdk header missing: %s", r.Header.Get("X-Attesto-SDK"))
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
switch {
|
|
case r.Method == http.MethodPost && r.URL.Path == "/v2/streams":
|
|
json.NewEncoder(w).Encode(Stream{
|
|
StreamID: "str_123", SystemID: "sys_123", UseCase: "ai-governance", PolicyID: "policy-main", Status: "active", Created: true,
|
|
})
|
|
case r.Method == http.MethodPost && r.URL.Path == "/v2/streams/str_123/events":
|
|
if r.Header.Get("Idempotency-Key") == "" {
|
|
t.Fatalf("idempotency key missing")
|
|
}
|
|
var payload map[string]any
|
|
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
|
|
t.Fatalf("decode event body: %v", err)
|
|
}
|
|
if payload["occurredAt"] == "" {
|
|
t.Fatalf("occurredAt missing from event body")
|
|
}
|
|
json.NewEncoder(w).Encode(EventReceipt{
|
|
StreamID: "str_123", StreamEventID: "evt_123", SeqNo: 1, EventHash: strings.Repeat("a", 64), StreamHeadHash: strings.Repeat("b", 64),
|
|
Receipt: SignedReceipt{Payload: M{}, ReceiptHash: strings.Repeat("c", 64), Signature: ReceiptSignature{Alg: "ed25519"}},
|
|
})
|
|
case r.Method == http.MethodPost && r.URL.Path == "/v2/verify":
|
|
json.NewEncoder(w).Encode(VerifyReport{Kind: VerifyReceipt, OK: true, Problems: []string{}, Result: "accepted"})
|
|
default:
|
|
t.Fatalf("unexpected request: %s %s", r.Method, r.URL.String())
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
|
|
client, err := NewClient(testAPIKey, WithBaseURL(server.URL), WithMaxRetries(1))
|
|
if err != nil {
|
|
t.Fatalf("client: %v", err)
|
|
}
|
|
ctx := context.Background()
|
|
stream, err := client.CreateStream(ctx, StreamCreateInput{UseCase: "ai-governance", PolicyID: "policy-main"})
|
|
if err != nil {
|
|
t.Fatalf("create stream: %v", err)
|
|
}
|
|
if stream.StreamID != "str_123" {
|
|
t.Fatalf("stream id mismatch: %s", stream.StreamID)
|
|
}
|
|
receipt, err := client.LogEvent(ctx, "str_123", EventInput{SourceRef: "go-test"})
|
|
if err != nil {
|
|
t.Fatalf("log event: %v", err)
|
|
}
|
|
if receipt.StreamEventID != "evt_123" {
|
|
t.Fatalf("receipt id mismatch: %s", receipt.StreamEventID)
|
|
}
|
|
report, err := client.VerifyObjectRemote(ctx, OfflineVerifyInput{Kind: VerifyReceipt, Object: M{"receipt": "object"}})
|
|
if err != nil {
|
|
t.Fatalf("verify object: %v", err)
|
|
}
|
|
if !report.OK {
|
|
t.Fatalf("verify report failed: %#v", report)
|
|
}
|
|
if len(seen) != 3 {
|
|
t.Fatalf("request count mismatch: %v", seen)
|
|
}
|
|
}
|
|
|
|
func TestBearerClientCanCallTenantEndpoints(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Header.Get("Authorization") != "Bearer tenant-token" {
|
|
t.Fatalf("tenant bearer header missing")
|
|
}
|
|
if r.URL.Path != "/v2/tenant/streams" {
|
|
t.Fatalf("unexpected path: %s", r.URL.Path)
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode([]TenantStream{{StreamID: "str_tenant", SystemID: "sys_123", UseCase: "audit", PolicyID: "policy", Status: "active"}})
|
|
}))
|
|
defer server.Close()
|
|
client, err := NewBearerClient("tenant-token", WithBaseURL(server.URL), WithMaxRetries(1))
|
|
if err != nil {
|
|
t.Fatalf("client: %v", err)
|
|
}
|
|
streams, err := client.ListTenantStreams(context.Background(), "", 100, 0)
|
|
if err != nil {
|
|
t.Fatalf("list streams: %v", err)
|
|
}
|
|
if len(streams) != 1 || streams[0].StreamID != "str_tenant" {
|
|
t.Fatalf("unexpected streams: %#v", streams)
|
|
}
|
|
}
|