/* Unit tests for identity sign covering identityCredentialBytes; signIdentityCredential / verifyIdentityCredential. Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only. RFC-0558: initial identity-sign tests. */ import { describe, it, expect } from "vitest"; import { generateKeypair } from "./sign.ts"; import { identityCredentialBytes, signIdentityCredential, verifyIdentityCredential, } from "./identity-sign.ts"; import type { SiteOwnershipCredentialSubject, ActorDelegationCredentialSubject } from "./schema.ts"; describe("identityCredentialBytes", () => { it("produces deterministic bytes for SiteOwnershipCredentialSubject", () => { const subject: SiteOwnershipCredentialSubject = { id: "did:web:warpgogol.com#operator-v1", siteId: "warpgogol-com", role: "owner", }; const bytes1 = identityCredentialBytes(subject); const bytes2 = identityCredentialBytes(subject); expect(bytes1).toEqual(bytes2); }); it("produces deterministic bytes for ActorDelegationCredentialSubject", () => { const subject: ActorDelegationCredentialSubject = { id: "did:web:warpgogol.com#agent-v1", siteId: "warpgogol-com", delegatedBy: "did:web:warpgogol.com#operator-v1", expiresAt: "2027-01-01T00:00:00.000Z", scopes: ["*"], }; const bytes1 = identityCredentialBytes(subject); const bytes2 = identityCredentialBytes(subject); expect(bytes1).toEqual(bytes2); }); it("produces different bytes for different subjects", () => { const subject1: SiteOwnershipCredentialSubject = { id: "did:web:warpgogol.com#operator-v1", siteId: "warpgogol-com", role: "owner", }; const subject2: SiteOwnershipCredentialSubject = { id: "did:web:warpgogol.com#operator-v2", siteId: "warpgogol-com", role: "owner", }; expect(identityCredentialBytes(subject1)).not.toEqual(identityCredentialBytes(subject2)); }); }); describe("signIdentityCredential / verifyIdentityCredential", () => { it("round-trips for SiteOwnershipCredentialSubject", async () => { const keypair = await generateKeypair(); const subject: SiteOwnershipCredentialSubject = { id: "did:web:warpgogol.com#operator-v1", siteId: "warpgogol-com", role: "owner", }; const proof = await signIdentityCredential( subject, keypair.privateKeyHex, "did:web:warpgogol.com#v1", "2026-07-27T00:00:00.000Z", ); const valid = await verifyIdentityCredential(subject, proof, keypair.publicKeyMultibase); expect(valid).toBe(true); }); it("round-trips for ActorDelegationCredentialSubject", async () => { const keypair = await generateKeypair(); const subject: ActorDelegationCredentialSubject = { id: "did:web:warpgogol.com#agent-v1", siteId: "warpgogol-com", delegatedBy: "did:web:warpgogol.com#operator-v1", expiresAt: "2027-01-01T00:00:00.000Z", scopes: ["mission.open", "workpiece.write"], }; const proof = await signIdentityCredential( subject, keypair.privateKeyHex, "did:web:warpgogol.com#v1", "2026-07-27T00:00:00.000Z", ); const valid = await verifyIdentityCredential(subject, proof, keypair.publicKeyMultibase); expect(valid).toBe(true); }); it("fails verification for tampered subject", async () => { const keypair = await generateKeypair(); const subject: SiteOwnershipCredentialSubject = { id: "did:web:warpgogol.com#operator-v1", siteId: "warpgogol-com", role: "owner", }; const proof = await signIdentityCredential( subject, keypair.privateKeyHex, "did:web:warpgogol.com#v1", "2026-07-27T00:00:00.000Z", ); const tampered: SiteOwnershipCredentialSubject = { ...subject, siteId: "other-site", }; const valid = await verifyIdentityCredential(tampered, proof, keypair.publicKeyMultibase); expect(valid).toBe(false); }); it("fails verification with wrong public key", async () => { const keypair1 = await generateKeypair(); const keypair2 = await generateKeypair(); const subject: SiteOwnershipCredentialSubject = { id: "did:web:warpgogol.com#operator-v1", siteId: "warpgogol-com", role: "owner", }; const proof = await signIdentityCredential( subject, keypair1.privateKeyHex, "did:web:warpgogol.com#v1", "2026-07-27T00:00:00.000Z", ); const valid = await verifyIdentityCredential(subject, proof, keypair2.publicKeyMultibase); expect(valid).toBe(false); }); });