package attestotest import ( "context" "crypto/ed25519" "crypto/rand" "encoding/hex" "encoding/json" "testing" attesto "go.attesto.eu/sdk" ) func newClient(t *testing.T, s *Server) *attesto.Client { t.Helper() client, err := attesto.NewClient(s.APIKey, attesto.WithBaseURL(s.URL)) if err != nil { t.Fatal(err) } return client } func toSignedReceipt(t *testing.T, wire attesto.M) attesto.SignedReceipt { t.Helper() raw, _ := json.Marshal(wire["receipt"]) var receipt attesto.SignedReceipt if err := json.Unmarshal(raw, &receipt); err != nil { t.Fatal(err) } return receipt } func TestFullPipelineAgainstTheEmulator(t *testing.T) { server := NewServer() defer server.Close() client := newClient(t, server) ctx := context.Background() stream, err := client.CreateStream(ctx, attesto.StreamCreateInput{UseCase: "ci", PolicyID: "mock-policy"}) if err != nil { t.Fatal(err) } receipt, err := client.LogEvent(ctx, stream.StreamID, attesto.EventInput{ SourceRef: "e1", Payload: attesto.M{"decision": "approve", "score_bp": 8700}, }) if err != nil { t.Fatal(err) } if _, err := client.LogEvents(ctx, stream.StreamID, []attesto.EventInput{ {SourceRef: "e2", Payload: attesto.M{"n": 2}}, {SourceRef: "e3", Payload: attesto.M{"n": 3}}, }); err != nil { t.Fatal(err) } stored, err := client.GetReceipt(ctx, receipt.StreamEventID) if err != nil { t.Fatal(err) } report := attesto.VerifyReceiptOffline(stored.Receipt, server.PublicKeyHex) if !report.OK { t.Fatalf("offline verification failed: %v", report.Problems) } events, err := client.ListTenantStreamEvents(ctx, stream.StreamID, 100, 0) if err != nil { t.Fatal(err) } plain := make([]map[string]any, len(events)) for i, e := range events { plain[i] = e } comp := attesto.VerifyCompleteness(plain, 1, 3) if !comp.OK { t.Fatalf("completeness failed: %v", comp.Problems) } } func TestInclusionProofsFromBuiltWindowVerify(t *testing.T) { server := NewServer() defer server.Close() client := newClient(t, server) ctx := context.Background() stream, _ := client.CreateStream(ctx, attesto.StreamCreateInput{UseCase: "ci", PolicyID: "mock-policy"}) for i := 0; i < 5; i++ { // odd leaf count exercises the promote rule if _, err := client.LogEvent(ctx, stream.StreamID, attesto.EventInput{ SourceRef: "e", Payload: attesto.M{"i": i}, }); err != nil { t.Fatal(err) } } window, err := server.BuildWindow(stream.StreamID) if err != nil { t.Fatal(err) } for _, leaf := range window.Leaves { ok, err := attesto.VerifyInclusionProof(leaf.LeafHash, leaf.Proof, window.RootHash) if err != nil || !ok { t.Fatalf("leaf %d failed inclusion: ok=%v err=%v", leaf.LeafIndex, ok, err) } } } func TestMockReceiptsCannotPassAsReal(t *testing.T) { server := NewServer() defer server.Close() client := newClient(t, server) ctx := context.Background() stream, _ := client.CreateStream(ctx, attesto.StreamCreateInput{UseCase: "ci", PolicyID: "mock-policy"}) receipt, err := client.LogEvent(ctx, stream.StreamID, attesto.EventInput{SourceRef: "e1"}) if err != nil { t.Fatal(err) } stored, err := client.GetReceipt(ctx, receipt.StreamEventID) if err != nil { t.Fatal(err) } // Structurally marked. if stored.Receipt.Payload["mock"] != true { t.Error("mock receipt payload must declare mock: true") } signer, _ := stored.Receipt.Payload["signer"].(map[string]any) if signer["kid"] != MockKid { t.Errorf("kid = %v, want %s", signer["kid"], MockKid) } // Rejected against a different ("real") witness key. realPub, _, _ := ed25519.GenerateKey(rand.Reader) report := attesto.VerifyReceiptOffline(stored.Receipt, hex.EncodeToString(realPub)) if report.OK { t.Fatal("mock receipt verified against a real key — must never happen") } }