diff --git a/src/edge-agent/didcomm/HandleOfferCredential.ts b/src/edge-agent/didcomm/HandleOfferCredential.ts index 8e7ea3073..fb5c8ff59 100644 --- a/src/edge-agent/didcomm/HandleOfferCredential.ts +++ b/src/edge-agent/didcomm/HandleOfferCredential.ts @@ -50,7 +50,7 @@ export class HandleOfferCredential extends Task { attach_id: response.id, format: `${response.format}`, }], - goalCode: offer.body.goalCode, + goal_code: offer.body.goal_code, comment: offer.body.comment, }, [response], diff --git a/src/edge-agent/helpers/ProtocolHelpers.ts b/src/edge-agent/helpers/ProtocolHelpers.ts index 739d3125d..d4368d4dc 100644 --- a/src/edge-agent/helpers/ProtocolHelpers.ts +++ b/src/edge-agent/helpers/ProtocolHelpers.ts @@ -1,14 +1,9 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { AttachmentDescriptor, Message } from "../../domain"; import { AgentError } from "../../domain/models/Errors"; -import { asArray, isArray, isEmpty, isNil, isObject, isString, notEmptyString, notNil } from "../../utils"; -import { ProtocolType } from "../protocols/ProtocolTypes"; +import { isArray, isEmpty, isNil, isString, notEmptyString, notNil } from "../../utils"; import { CredentialFormat } from "../protocols/issueCredential/CredentialFormat"; import { - ProposeCredentialBody, - OfferCredentialBody, - IssueCredentialBody, - CredentialBody, MediationGrantBody, PresentationBody, RequestPresentationBody, @@ -40,17 +35,6 @@ export const parseCredentialAttachments = (credentials: Map) => { ); }; -const parseCredentialFormat = (value: unknown): CredentialFormat => { - if (!isObject(value) || isNil(value.attach_id) || isNil(value.format)) { - throw new AgentError.InvalidCredentialFormats(); - } - - return { - attach_id: value.attach_id, - format: value.format, - }; -}; - export const parseBasicMessageBody = (msg: Message): BasicMessageBody => { if (notEmptyString(msg.body.content)) { return { @@ -68,82 +52,12 @@ export const parseProblemReportBody = (msg: Message): ProblemReportBody => { isArray(msg.body.args) && isEmpty(msg.body.args) ) { const { code, comment, escalate_to, args } = msg.body; - return { code, comment, escalate_to, args } - } - throw new AgentError.InvalidProblemReportBodyError() -} - -export const parseCredentialBody = (msg: Message): CredentialBody => { - if (Object.keys(msg.body).length === 0) { - throw new AgentError.InvalidCredentialBodyError( - "Invalid CredentialBody Error" - ); - } - - if (notNil(msg.body.formats) && !isArray(msg.body.formats)) { - throw new AgentError.InvalidCredentialFormats(); + return { code, comment, escalate_to, args }; } - - return { - formats: asArray(msg.body.formats).map(x => parseCredentialFormat(x)), - goalCode: msg.body.goalCode, - comment: msg.body.comment, - }; + throw new AgentError.InvalidProblemReportBodyError(); }; -export const parseOfferCredentialMessage = (msg: Message): OfferCredentialBody => { - if (msg.piuri !== ProtocolType.DidcommOfferCredential) { - throw new AgentError.UnknownCredentialBodyError(); - } - - if (isNil(msg.body.credential_preview)) { - throw new AgentError.InvalidOfferCredentialBodyError("Undefined credentialPreview"); - } - const credentialBody = parseCredentialBody(msg); - - return { - ...credentialBody, - credential_preview: msg.body.credential_preview, - replacementId: msg.body.replacementId, - multipleAvailable: msg.body.multipleAvailable, - }; -}; - -export const parseIssueCredentialMessage = (msg: Message): IssueCredentialBody => { - if (msg.piuri !== ProtocolType.DidcommIssueCredential) { - throw new AgentError.UnknownCredentialBodyError(); - } - - if (notNil(msg.body.replacementId) && !isString(msg.body.replacementId)) { - throw new AgentError.InvalidIssueCredentialBodyError( - "Invalid replacementId, should be a string" - ); - } - - const credentialBody = parseCredentialBody(msg); - - return { - ...credentialBody, - replacementId: msg.body.replacementId, - moreAvailable: msg.body.moreAvailable, - }; -}; - -export const parseProposeCredentialMessage = (msg: Message): ProposeCredentialBody => { - if (isNil(msg.body.credential_preview)) { - throw new AgentError.InvalidProposeCredentialBodyError( - "Undefined credentialPreview" - ); - } - - const credentialBody = parseCredentialBody(msg); - - return { - ...credentialBody, - credential_preview: msg.body.credential_preview, - }; -}; export const parseMediationGrantMessage = (msg: Message): MediationGrantBody => { if (isNil(msg.body.routing_did)) { diff --git a/src/edge-agent/protocols/issueCredential/CredentialPreview.ts b/src/edge-agent/protocols/issueCredential/CredentialPreview.ts index adb447aa8..060cd9cd4 100644 --- a/src/edge-agent/protocols/issueCredential/CredentialPreview.ts +++ b/src/edge-agent/protocols/issueCredential/CredentialPreview.ts @@ -1,24 +1,31 @@ -import { ProtocolType } from "../ProtocolTypes"; +import { Nil, isArray, isObject, notEmptyString } from "../../../utils"; + +/** + * Specification: + * https://github.com/decentralized-identity/waci-didcomm/tree/main/issue_credential#preview-credential + */ + +export interface CredentialPreview { + // type: ProtocolType.DidcommCredentialPreview; + type: string; + id?: string; + body: { + attributes: Attribute[]; + }; +} export interface Attribute { name: string; value: string; - mimeType?: string; + media_type?: string | Nil; } -export interface CredentialPreview { - type: ProtocolType.DidcommCredentialPreview; - attributes: Attribute[]; -} +export const validateCredentialPreview = (value: unknown): value is CredentialPreview => isObject(value) + && notEmptyString(value.type) + && isObject(value.body) + && isArray(value.body.attributes) + && value.body.attributes.every(validateAttribute); -export function createCredentialPreviewAttribute( - name: string, - value: string, - mimeType?: string -): Attribute { - return { - name, - value, - mimeType, - }; -} +const validateAttribute = (value: unknown): value is Attribute => isObject(value) + && notEmptyString(value.name) + && notEmptyString(value.value); diff --git a/src/edge-agent/protocols/issueCredential/IssueCredential.ts b/src/edge-agent/protocols/issueCredential/IssueCredential.ts index ac9b02129..75f9b8c7f 100644 --- a/src/edge-agent/protocols/issueCredential/IssueCredential.ts +++ b/src/edge-agent/protocols/issueCredential/IssueCredential.ts @@ -2,12 +2,20 @@ import { uuid } from "@stablelib/uuid"; import { AttachmentDescriptor, DID, Message } from "../../../domain"; import { AgentError } from "../../../domain/models/Errors"; import { ProtocolType } from "../ProtocolTypes"; -import { CredentialFormat } from "./CredentialFormat"; -import { RequestCredential } from "./RequestCredential"; import { base64url } from "multiformats/bases/base64"; -import { IssueCredentialBody } from "../types"; import { isNil } from "../../../utils"; -import { parseCredentialAttachments, parseIssueCredentialMessage } from "../../helpers/ProtocolHelpers"; + +/** + * Specification: + * https://github.com/decentralized-identity/waci-didcomm/tree/main/issue_credential#issue-credential + */ + +export interface IssueCredentialBody { + // optional field that provides human readable information about the issued credential + comment?: string; + // optional field that provides an identifier used to manage credential replacement + replacement_id?: string; +} export class IssueCredential { public static type = ProtocolType.DidcommIssueCredential; @@ -47,75 +55,24 @@ export class IssueCredential { }, initialValue); } - static fromMessage(fromMessage: Message): IssueCredential { + static fromMessage(msg: Message): IssueCredential { if ( - fromMessage.piuri !== ProtocolType.DidcommIssueCredential || - isNil(fromMessage.from) || - isNil(fromMessage.to) + msg.piuri !== ProtocolType.DidcommIssueCredential + || isNil(msg.from) + || isNil(msg.to) ) { throw new AgentError.InvalidIssueCredentialMessageError( "Invalid issue credential message error." ); } - const issueCredentialBody = parseIssueCredentialMessage(fromMessage); - - return new IssueCredential( - issueCredentialBody, - fromMessage.attachments, - fromMessage.from, - fromMessage.to, - fromMessage.thid, - fromMessage.id - ); - } - static makeIssueFromRequestCredential(msg: Message): IssueCredential { - const request = RequestCredential.fromMessage(msg); return new IssueCredential( - createIssueCredentialBody( - request.body.formats, - request.body.goalCode, - request.body.comment - ), - request.attachments, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - request.to!, - request.from, + msg.body, + msg.attachments, + msg.from, + msg.to, + msg.thid, msg.id ); } - - static build( - fromDID: DID, - toDID: DID, - thid?: string, - credentials: Map = new Map() - ): IssueCredential { - const { formats, attachments } = parseCredentialAttachments(credentials); - const issueCredentialBody = createIssueCredentialBody(formats); - - return new IssueCredential( - issueCredentialBody, - attachments, - fromDID, - toDID, - thid - ); - } -} - -export function createIssueCredentialBody( - formats: CredentialFormat[], - goalCode?: string, - comment?: string, - replacementId?: string, - moreAvailable?: string -) { - return { - formats, - goalCode, - comment, - replacementId, - moreAvailable, - }; } diff --git a/src/edge-agent/protocols/issueCredential/OfferCredential.ts b/src/edge-agent/protocols/issueCredential/OfferCredential.ts index 1fa41c4b9..7bc30ab67 100644 --- a/src/edge-agent/protocols/issueCredential/OfferCredential.ts +++ b/src/edge-agent/protocols/issueCredential/OfferCredential.ts @@ -2,11 +2,25 @@ import { uuid } from "@stablelib/uuid"; import { AgentError } from "../../../domain/models/Errors"; import { AttachmentDescriptor, DID, Message } from "../../../domain"; import { ProtocolType } from "../ProtocolTypes"; -import { CredentialFormat } from "./CredentialFormat"; -import { CredentialPreview } from "./CredentialPreview"; +import { CredentialPreview, validateCredentialPreview } from "./CredentialPreview"; import { ProposeCredential } from "./ProposeCredential"; -import { OfferCredentialBody } from "../types"; -import { parseCredentialAttachments, parseOfferCredentialMessage } from "../../helpers/ProtocolHelpers"; +import { isNil, isObject } from "../../../utils"; + +/** + * Specification: + * https://github.com/decentralized-identity/waci-didcomm/tree/main/issue_credential#offer-credential + */ + +export interface OfferCredentialBody { + // optional field that indicates the goal of the message sender + goal_code?: any; + // an optional field to help coordinate credential replacement + replacement_id?: string; + // an optional field that provides human readable information about this Credential Offer + comment?: string; + // a JSON-LD object that represents the credential data that Issuer is willing to issue + credential_preview: CredentialPreview; +} export class OfferCredential { public static type = ProtocolType.DidcommOfferCredential; @@ -19,11 +33,17 @@ export class OfferCredential { public thid?: string, public id: string = uuid() ) { - if (!from || !to) { - new AgentError.InvalidOfferCredentialMessageError( - "Invalid offer credential message error." - ); + this.validate(); + } + + private validate() { + if (validateCredentialPreview(this.body.credential_preview)) { + return; } + + throw new AgentError.InvalidOfferCredentialMessageError( + "Invalid offer credential message error." + ); } makeMessage(): Message { @@ -42,13 +62,14 @@ export class OfferCredential { static makeOfferFromProposedCredential( proposed: ProposeCredential ): OfferCredential { + const body: OfferCredentialBody = { + credential_preview: proposed.body.credential_preview!, + goal_code: proposed.body.goal_code, + comment: proposed.body.comment, + }; + return new OfferCredential( - createOfferCredentialBody( - proposed.body.credential_preview, - proposed.body.formats, - proposed.body.goalCode, - proposed.body.comment - ), + body, proposed.attachments, proposed.to, proposed.from, @@ -56,64 +77,27 @@ export class OfferCredential { ); } - static fromMessage(fromMessage: Message): OfferCredential { + static fromMessage(msg: Message): OfferCredential { if ( - fromMessage.piuri !== ProtocolType.DidcommOfferCredential || - !fromMessage.from + msg.piuri !== ProtocolType.DidcommOfferCredential + || isNil(msg.from) ) { throw new AgentError.InvalidOfferCredentialMessageError( "Invalid offer credential message error." ); } - const offerCredentialBody = parseOfferCredentialMessage(fromMessage); - - return new OfferCredential( - offerCredentialBody, - fromMessage.attachments, - fromMessage.from, - fromMessage.to, - fromMessage.thid, - fromMessage.id - ); - } - static build( - credentialPreview: CredentialPreview, - fromDID: DID, - toDID: DID, - thid?: string, - credentials: Map = new Map() - ) { - const { formats, attachments } = parseCredentialAttachments(credentials); - const offerCredentialBody = createOfferCredentialBody( - credentialPreview, - formats - ); + if (!isObject(msg.body) || !isObject(msg.body.credential_preview)) { + throw new AgentError.InvalidOfferCredentialBodyError("Undefined credentialPreview"); + } return new OfferCredential( - offerCredentialBody, - attachments, - fromDID, - toDID, - thid + msg.body as any, + msg.attachments, + msg.from, + msg.to, + msg.thid, + msg.id ); } } - -export function createOfferCredentialBody( - credentialPreview: CredentialPreview, - formats: CredentialFormat[], - goalCode?: string, - comment?: string, - replacementId?: string, - multipleAvailable?: string -): OfferCredentialBody { - return { - formats, - credential_preview: credentialPreview, - goalCode, - comment, - replacementId, - multipleAvailable, - }; -} diff --git a/src/edge-agent/protocols/issueCredential/ProposeCredential.ts b/src/edge-agent/protocols/issueCredential/ProposeCredential.ts index d444517ef..4c4ed26bf 100644 --- a/src/edge-agent/protocols/issueCredential/ProposeCredential.ts +++ b/src/edge-agent/protocols/issueCredential/ProposeCredential.ts @@ -2,10 +2,22 @@ import { uuid } from "@stablelib/uuid"; import { AttachmentDescriptor, DID, Message } from "../../../domain"; import { AgentError } from "../../../domain/models/Errors"; import { ProtocolType } from "../ProtocolTypes"; -import { CredentialFormat } from "./CredentialFormat"; import { CredentialPreview } from "./CredentialPreview"; -import { ProposeCredentialBody } from "../types"; -import { parseCredentialAttachments, parseProposeCredentialMessage } from "../../helpers/ProtocolHelpers"; +import { isNil } from "../../../utils"; + +/** + * Specification: + * https://github.com/decentralized-identity/waci-didcomm/tree/main/issue_credential#propose-credential + */ + +export interface ProposeCredentialBody { + // optional field that indicates the goal of the message sender + goal_code?: string; + // optional field that provides human readable information about this Credential Proposal + comment?: string; + // optional JSON-LD object that represents the credential data that Prover wants to receive + credential_preview?: CredentialPreview; +} export class ProposeCredential { public static type = ProtocolType.DidcommProposeCredential; @@ -32,61 +44,24 @@ export class ProposeCredential { ); } - static fromMessage(fromMessage: Message): ProposeCredential { + static fromMessage(msg: Message): ProposeCredential { if ( - fromMessage.piuri !== ProtocolType.DidcommProposeCredential || - !fromMessage.from || - !fromMessage.to + msg.piuri !== ProtocolType.DidcommProposeCredential + || isNil(msg.from) + || isNil(msg.to) ) { throw new AgentError.InvalidProposedCredentialMessageError( "Invalid proposed credential message error." ); } - const proposeCredentialBody = parseProposeCredentialMessage(fromMessage); return new ProposeCredential( - proposeCredentialBody, - fromMessage.attachments, - fromMessage.from, - fromMessage.to, - fromMessage.thid, - fromMessage.id + msg.body, + msg.attachments, + msg.from, + msg.to, + msg.thid, + msg.id ); } - - static build( - credentialPreview: CredentialPreview, - fromDID: DID, - toDID: DID, - thid?: string, - credentials: Map = new Map() - ) { - const { formats, attachments } = parseCredentialAttachments(credentials); - const proposeCredentialBody = createProposeCredentialBody( - credentialPreview, - formats - ); - - return new ProposeCredential( - proposeCredentialBody, - attachments, - fromDID, - toDID, - thid - ); - } -} - -export function createProposeCredentialBody( - credentialPreview: CredentialPreview, - formats: CredentialFormat[], - goalCode?: string, - comment?: string -): ProposeCredentialBody { - return { - formats, - credential_preview: credentialPreview, - goalCode, - comment, - }; } diff --git a/src/edge-agent/protocols/issueCredential/RequestCredential.ts b/src/edge-agent/protocols/issueCredential/RequestCredential.ts index 08f1732e8..ee7b0bb62 100644 --- a/src/edge-agent/protocols/issueCredential/RequestCredential.ts +++ b/src/edge-agent/protocols/issueCredential/RequestCredential.ts @@ -1,22 +1,50 @@ import { uuid } from "@stablelib/uuid"; - import { AttachmentDescriptor, DID, Message } from "../../../domain"; import { AgentError } from "../../../domain/models/Errors"; import { ProtocolType } from "../ProtocolTypes"; -import { CredentialBody } from "../types"; -import { parseCredentialAttachments, parseCredentialBody } from "../../helpers/ProtocolHelpers"; +import { CredentialFormat } from "./CredentialFormat"; +import { isArray, isNil, isObject, notNil } from "../../../utils"; + +/** + * Specification: + * https://github.com/decentralized-identity/waci-didcomm/tree/main/issue_credential#request-credential + */ + +interface RequestCredentialBody { + // optional field that indicates the goal of the message sender + goal_code?: string; + // optional field that provides human readable information about this Credential Request + comment?: string; + // contains an entry providing the the value of the attachment @id and the verifiable credential format + formats: CredentialFormat[]; +} export class RequestCredential { public static type = ProtocolType.DidcommRequestCredential; constructor( - public body: CredentialBody, + public body: RequestCredentialBody, public attachments: AttachmentDescriptor[], public from: DID, public to?: DID, public thid?: string, public id: string = uuid() - ) {} + ) { + this.validate(); + } + + private validate() { + if (!isArray(this.body.formats)) { + throw new AgentError.InvalidCredentialFormats(); + } + + const validFormats = this.body.formats.every(x => isObject(x) && notNil(x.attach_id) && notNil(x.format)); + + if (!validFormats) { + throw new AgentError.InvalidCredentialFormats(); + } + // TODO is it a requirement that formats is populated relevant to the attachments? + } makeMessage(): Message { const body = JSON.stringify(this.body); @@ -31,41 +59,20 @@ export class RequestCredential { ); } - static fromMessage(fromMessage: Message): RequestCredential { - if ( - fromMessage.piuri !== ProtocolType.DidcommRequestCredential || - !fromMessage.from - ) { + static fromMessage(msg: Message): RequestCredential { + if (msg.piuri !== ProtocolType.DidcommRequestCredential || isNil(msg.from)) { throw new AgentError.InvalidRequestCredentialMessageError( "Invalid request credential message error." ); } - const credentialBody = parseCredentialBody(fromMessage); - - return new RequestCredential( - credentialBody, - fromMessage.attachments, - fromMessage.from, - fromMessage.to, - fromMessage.thid, - fromMessage.id - ); - } - - static build( - fromDID: DID, - toDID: DID, - thid?: string, - credentials: Map = new Map() - ): RequestCredential { - const { formats, attachments } = parseCredentialAttachments(credentials); return new RequestCredential( - { formats }, - attachments, - fromDID, - toDID, - thid + msg.body as any, + msg.attachments, + msg.from, + msg.to, + msg.thid, + msg.id ); } } diff --git a/src/edge-agent/protocols/types.ts b/src/edge-agent/protocols/types.ts index 39e863068..78b5d7387 100644 --- a/src/edge-agent/protocols/types.ts +++ b/src/edge-agent/protocols/types.ts @@ -1,17 +1,3 @@ -import { CredentialFormat } from "./issueCredential/CredentialFormat"; -import { CredentialPreview } from "./issueCredential/CredentialPreview"; - -export interface CredentialBody { - formats: CredentialFormat[]; - goalCode?: string; - comment?: string; -} - -export interface IssueCredentialBody extends CredentialBody { - moreAvailable?: string; - replacementId?: string; -} - export interface PrismRevocationBody { issueCredentialProtocolThreadId: string; comment?: string; @@ -21,15 +7,6 @@ export interface MediationGrantBody { routing_did: string; } -export interface OfferCredentialBody extends CredentialBody { - credential_preview: CredentialPreview; - replacementId?: string; - multipleAvailable?: string; -} -export interface ProposeCredentialBody extends CredentialBody { - credential_preview: CredentialPreview; -} - export interface MediationKeysUpdateListBody { updates: Array<{ recipient_did: string; diff --git a/tests/agent/Agent.anoncreds.test.ts b/tests/agent/Agent.anoncreds.test.ts index 41177a116..7d48cc0fd 100644 --- a/tests/agent/Agent.anoncreds.test.ts +++ b/tests/agent/Agent.anoncreds.test.ts @@ -97,15 +97,17 @@ describe("Agent Tests", () => { }); describe("prepareRequestCredentialWithIssuer", () => { - const credentialPreview: CredentialPreview = { + const credential_preview: CredentialPreview = { type: ProtocolType.DidcommCredentialPreview, - attributes: [ - { - name: "name", - value: "javi", - mimeType: "text", - }, - ], + body: { + attributes: [ + { + name: "name", + value: "javi", + media_type: "text", + }, + ], + } }; const mypeerDID = new DID( "did", @@ -117,27 +119,21 @@ describe("Agent Tests", () => { ); const createOffer = (credType: CredentialType) => { - const credentialMap = new Map(); + let attach; if (credType === CredentialType.JWT) { - credentialMap.set( - CredentialType.JWT, - Fixtures.Credentials.JWT.credentialPayload - ); + attach = AttachmentDescriptor.build(Fixtures.Credentials.JWT.credentialPayload); } else if (credType === CredentialType.AnonCreds) { - credentialMap.set(credType, Fixtures.Credentials.Anoncreds.credentialOffer); + attach = AttachmentDescriptor.build(Fixtures.Credentials.Anoncreds.credentialOffer); } else if (credType === CredentialType.SDJWT) { - credentialMap.set( - CredentialType.SDJWT, - Fixtures.Credentials.SDJWT.credentialPayloadEncoded - ); + attach = AttachmentDescriptor.build(Fixtures.Credentials.SDJWT.credentialPayloadEncoded); } - return OfferCredential.build( - credentialPreview, + return new OfferCredential( + { credential_preview }, + [attach], mypeerDID, validPeerDID, "threadID123456", - credentialMap ); }; @@ -189,7 +185,7 @@ describe("Agent Tests", () => { it("no attachment - throws", () => { const issueCredential = new IssueCredential( - { formats: [] }, + {}, [], new DID("did", "prism", "from"), new DID("did", "prism", "to") @@ -205,7 +201,7 @@ describe("Agent Tests", () => { vi.spyOn(pluto, "getCredentialMetadata").mockResolvedValue(null); const issueCredential = new IssueCredential( - { formats: [{ attach_id: "attach_id", format: CredentialType.AnonCreds }] }, + {}, [new AttachmentDescriptor({ base64: base64Data }, "attach_1", undefined, undefined, "anoncreds/credential@v1.0")], new DID("did", "prism", "from"), new DID("did", "prism", "to"), @@ -231,7 +227,7 @@ describe("Agent Tests", () => { const base64Data = base64url.baseEncode(encoded); const issueCredential = new IssueCredential( - { formats: [{ attach_id: "attach_id", format: CredentialType.AnonCreds }] }, + {}, [new AttachmentDescriptor({ base64: base64Data }, "attach_1", undefined, undefined, "anoncreds/credential@v1.0")], new DID("did", "prism", "from"), new DID("did", "prism", "to"), diff --git a/tests/agent/Agent.test.ts b/tests/agent/Agent.test.ts index fbc694eb7..2434a3110 100644 --- a/tests/agent/Agent.test.ts +++ b/tests/agent/Agent.test.ts @@ -282,15 +282,17 @@ describe("Agent Tests", () => { }); describe("prepareRequestCredentialWithIssuer", () => { - const credentialPreview: CredentialPreview = { + const credential_preview: CredentialPreview = { type: ProtocolType.DidcommCredentialPreview, - attributes: [ - { - name: "name", - value: "javi", - mimeType: "text", - }, - ], + body: { + attributes: [ + { + name: "name", + value: "javi", + media_type: "text", + }, + ], + } }; const mypeerDID = new DID( "did", @@ -302,27 +304,21 @@ describe("Agent Tests", () => { ); const createOffer = (credType: CredentialType) => { - const credentialMap = new Map(); + let attach; if (credType === CredentialType.JWT) { - credentialMap.set( - CredentialType.JWT, - Fixtures.Credentials.JWT.credentialPayload - ); + attach = AttachmentDescriptor.build(Fixtures.Credentials.JWT.credentialPayload); } else if (credType === CredentialType.AnonCreds) { - credentialMap.set(credType, Fixtures.Credentials.Anoncreds.credentialOffer); + attach = AttachmentDescriptor.build(Fixtures.Credentials.Anoncreds.credentialOffer); } else if (credType === CredentialType.SDJWT) { - credentialMap.set( - CredentialType.SDJWT, - Fixtures.Credentials.SDJWT.credentialPayloadEncoded - ); + attach = AttachmentDescriptor.build(Fixtures.Credentials.SDJWT.credentialPayloadEncoded); } - return OfferCredential.build( - credentialPreview, + return new OfferCredential( + { credential_preview }, + [attach], mypeerDID, validPeerDID, "threadID123456", - credentialMap ); }; @@ -431,7 +427,7 @@ describe("Agent Tests", () => { describe("processIssuedCredentialMessage", () => { it("no attachment - throws", () => { const issueCredential = new IssueCredential( - { formats: [] }, + {}, [], new DID("did", "prism", "from"), new DID("did", "prism", "to") @@ -456,7 +452,7 @@ describe("Agent Tests", () => { CredentialType.JWT ); const issueCredential = new IssueCredential( - { formats: [{ attach_id: "attach_1", format: CredentialType.JWT }] }, + {}, [jwtAttachment], new DID("did", "prism", "from"), new DID("did", "prism", "to"), @@ -474,7 +470,9 @@ describe("Agent Tests", () => { it("Should revoke a JWT Credential", async () => { const revocationIssueMessage = new IssueCredential( - { formats: [{ attach_id: "attach_1", format: CredentialType.JWT }] }, + { + // formats: [{ attach_id: "attach_1", format: CredentialType.JWT }] + }, [new AttachmentDescriptor({ base64: base64Data }, "attach_1", undefined, undefined, CredentialType.JWT)], new DID("did", "prism", "from"), new DID("did", "prism", "to"), @@ -516,7 +514,7 @@ describe("Agent Tests", () => { CredentialType.SDJWT ); const issueCredential = new IssueCredential( - { formats: [{ attach_id: "attach_1", format: CredentialType.SDJWT }] }, + {}, [attachment], new DID("did", "prism", "from"), new DID("did", "prism", "to"), @@ -547,7 +545,7 @@ describe("Agent Tests", () => { const base64Data = base64url.baseEncode(encoded); const issueCredential = new IssueCredential( - { formats: [{ attach_id: "attach_id", format: CredentialType.AnonCreds }] }, + {}, [new AttachmentDescriptor({ base64: base64Data }, "attach_1", undefined, undefined, "anoncreds/credential@v1.0")], new DID("did", "prism", "from"), new DID("did", "prism", "to"), diff --git a/tests/agent/helpers/DID.ts b/tests/agent/helpers/DID.ts deleted file mode 100644 index e2c49eae7..000000000 --- a/tests/agent/helpers/DID.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { DID } from "../../../src/domain"; - -export class DIDTest extends DID { - constructor(testMethod = "test", testMethodId = "testableId") { - super("peer", testMethod, testMethodId); - } - - static fromIndex(index: number): DIDTest { - const testMethod = `test${index}`; - const testMethodId = `testableId${index}`; - return new DIDTest(testMethod, testMethodId); - } -} diff --git a/tests/agent/protocols/connection/HandShakeRequest.test.ts b/tests/agent/protocols/connection/HandShakeRequest.test.ts index a2ce6329b..d67b628e8 100644 --- a/tests/agent/protocols/connection/HandShakeRequest.test.ts +++ b/tests/agent/protocols/connection/HandShakeRequest.test.ts @@ -4,13 +4,12 @@ import { Message } from "../../../../src/domain"; import { HandshakeRequest } from "../../../../src/edge-agent/protocols/connection/HandshakeRequest"; import { ProtocolType } from "../../../../src/edge-agent/protocols/ProtocolTypes"; import { HandshakeRequestBody } from "../../../../src/edge-agent/protocols/types"; -import { DIDTest } from "../../helpers/DID"; +import * as Fixtures from "../../../fixtures"; describe("HandShakeRequest Test", () => { it("Should create a HandshakeRequest from a valid HandShakeRequest Message", () => { - const fromDID = DIDTest.fromIndex(1); - const toDID = DIDTest.fromIndex(2); - + const fromDID = Fixtures.DIDs.peerDID1; + const toDID = Fixtures.DIDs.peerDID2; const request = new HandshakeRequest( { goal: "Test", @@ -35,8 +34,8 @@ describe("HandShakeRequest Test", () => { }); it("Should create HandShakeRequest from a valid InvitationMessage", () => { - const fromDID = DIDTest.fromIndex(1); - const toDID = DIDTest.fromIndex(2); + const fromDID = Fixtures.DIDs.peerDID1; + const toDID = Fixtures.DIDs.peerDID2; const body: HandshakeRequestBody = { goal: "Test", goalCode: "123", @@ -51,7 +50,7 @@ describe("HandShakeRequest Test", () => { toDID ); - const selfDID = DIDTest.fromIndex(2); + const selfDID = Fixtures.DIDs.peerDID3; const request = HandshakeRequest.fromMessage(exampleMessage, selfDID); diff --git a/tests/agent/protocols/issueCredential/IssueCredential.test.ts b/tests/agent/protocols/issueCredential/IssueCredential.test.ts index ff2b67266..31d5fd90a 100644 --- a/tests/agent/protocols/issueCredential/IssueCredential.test.ts +++ b/tests/agent/protocols/issueCredential/IssueCredential.test.ts @@ -1,120 +1,80 @@ -import { vi, assert, describe, it, expect, test, beforeEach, afterEach } from 'vitest'; -import { Message } from "../../../../src/domain"; -import { AgentError } from "../../../../src/domain/models/Errors"; -import { - createIssueCredentialBody, - IssueCredential, -} from "../../../../src/edge-agent/protocols/issueCredential/IssueCredential"; -import { RequestCredential } from "../../../../src/edge-agent/protocols/issueCredential/RequestCredential"; +import { describe, expect, test } from 'vitest'; +import { AttachmentDescriptor, Message } from "../../../../src/domain"; +import { IssueCredential } from "../../../../src/edge-agent/protocols/issueCredential/IssueCredential"; import { ProtocolType } from "../../../../src/edge-agent/protocols/ProtocolTypes"; -import { DIDTest } from "../../helpers/DID"; -import * as Messages from "../../../fixtures/messages"; +import * as Fixtures from "../../../fixtures"; describe("IssueCredential", () => { - it("Should create a valid IssueCredential when valid IssueMessage is provided", () => { - const fromDID = DIDTest.fromIndex(0); - const toDID = DIDTest.fromIndex(1); - const validIssueCredential = new IssueCredential( - createIssueCredentialBody([ - { - attach_id: "test1", - format: "test", - }, - ]), - [], - fromDID, - toDID, - "1" + test("Should create a valid IssueCredential from valid params", () => { + const sut = new IssueCredential({}, [], Fixtures.DIDs.peerDID1, Fixtures.DIDs.peerDID2); + + expect(sut).toBeInstanceOf(IssueCredential); + }); + + test("Should create IssueCredential with attachments", () => { + const json = JSON.stringify({ + options: { + challenge: "fedac0c2-3250-4fb1-bfcb-b5e904058e1f", + domain: "domain" + } + }); + const id = "321905d1-5f01-42b0-b0ba-39b09645eeaa"; + const format = "JWT"; + const attached = new AttachmentDescriptor( + { json }, + undefined, + id, + undefined, + format ); - const issueMessage = validIssueCredential.makeMessage(); - const testIssueCredential = IssueCredential.fromMessage(issueMessage); - expect(validIssueCredential).to.deep.equal(testIssueCredential); + + const sut = new IssueCredential({}, [attached], Fixtures.DIDs.peerDID1, Fixtures.DIDs.peerDID2); + + expect(sut).toBeInstanceOf(IssueCredential); + expect(sut.attachments).toHaveLength(1); + expect(sut.attachments[0].id).toEqual(id); + expect(sut.attachments[0].data).toEqual({ json }); + expect(sut.attachments[0].format).toEqual(format); + }); + + test("Should create IssueCredential with valid optional params", () => { + const body = { comment: "optional-comment", replacement_id: "optional" }; + const from = Fixtures.DIDs.peerDID1; + const to = Fixtures.DIDs.peerDID2; + const thid = "test-thid"; + const id = "test-id"; + const sut = new IssueCredential(body, [], from, to, thid, id); + + expect(sut).toBeInstanceOf(IssueCredential); + expect(sut.attachments).toHaveLength(0); + expect(sut.body).toEqual(body); + expect(sut.from).toBe(from); + expect(sut.to).toBe(to); + expect(sut.thid).toBe(thid); + expect(sut.id).toBe(id); }); test("IssueCredential from an actual PrismAgent Message", () => { - const sut = IssueCredential.fromMessage(Messages.IssueCredential); + const sut = IssueCredential.fromMessage(Fixtures.Messages.IssueCredential); expect(sut).to.be.instanceOf(IssueCredential); - expect(sut.attachments).to.eq(Messages.IssueCredential.attachments); + expect(sut.attachments).to.eq(Fixtures.Messages.IssueCredential.attachments); // expect(sut.body).to.eq(Messages.IssueCredential.body); - expect(sut.from).to.eq(Messages.IssueCredential.from); - expect(sut.id).to.eq(Messages.IssueCredential.id); - expect(sut.thid).to.eq(Messages.IssueCredential.thid); - expect(sut.to).to.eq(Messages.IssueCredential.to); - }); - - it("Should throw an error when initializing an issue credential from an invalid message", () => { - const fromDID = DIDTest.fromIndex(0); - const toDID = DIDTest.fromIndex(1); - const invalidIssueCredential = new Message( - "{}", - "any id", - "invalidType", - fromDID, - toDID - ); - const invalidIssueCredential2 = new Message( - `{ "formats":[{"wrong": true}]}`, - "any id", - ProtocolType.DidcommIssueCredential, - fromDID, - toDID - ); - assert.throws( - () => { - IssueCredential.fromMessage(invalidIssueCredential); - }, - AgentError.InvalidIssueCredentialMessageError, - "Invalid issue credential message error." - ); - assert.throws( - () => { - IssueCredential.fromMessage(invalidIssueCredential2); - }, - Error, - "Invalid credential formats" - ); + expect(sut.from).to.eq(Fixtures.Messages.IssueCredential.from); + expect(sut.id).to.eq(Fixtures.Messages.IssueCredential.id); + expect(sut.thid).to.eq(Fixtures.Messages.IssueCredential.thid); + expect(sut.to).to.eq(Fixtures.Messages.IssueCredential.to); }); - it("Should create an IssueCredential when a valid RequestMessage is provided", () => { - const fromDID = DIDTest.fromIndex(0); - const toDID = DIDTest.fromIndex(1); - const validRequestCredential = new RequestCredential( - createIssueCredentialBody([ - { - attach_id: "test1", - format: "test", - }, - ]), - [], - fromDID, - toDID, - "1" - ); - const requestMessage = validRequestCredential.makeMessage(); - const testIssueCredential = - IssueCredential.makeIssueFromRequestCredential(requestMessage); - expect(validRequestCredential.from.toString()).to.equal( - testIssueCredential.to.toString() - ); - expect(validRequestCredential.to?.toString()).to.equal( - testIssueCredential.from?.toString() - ); - expect(validRequestCredential.attachments).to.deep.equal( - testIssueCredential.attachments - ); + describe("fromMessage", () => { + test("piuri invalid - throws", () => { + const piuri = ProtocolType.DidcommBasicMessage; + const from = Fixtures.DIDs.peerDID1; + const msg = new Message({}, "id", piuri, from); - expect(validRequestCredential.id).to.equal(testIssueCredential.thid); - expect(validRequestCredential.body.goalCode).to.equal( - testIssueCredential.body.goalCode - ); + const sut = () => IssueCredential.fromMessage(msg); - expect(validRequestCredential.body.comment).to.equal( - testIssueCredential.body.comment - ); - - expect(validRequestCredential.body.formats).to.deep.equal( - testIssueCredential.body.formats - ); + expect(sut).toThrow("Invalid issue credential message error."); + }); }); }); diff --git a/tests/agent/protocols/issueCredential/OfferCredential.test.ts b/tests/agent/protocols/issueCredential/OfferCredential.test.ts index 350f4b2d3..e70a90daa 100644 --- a/tests/agent/protocols/issueCredential/OfferCredential.test.ts +++ b/tests/agent/protocols/issueCredential/OfferCredential.test.ts @@ -1,73 +1,110 @@ -import { vi, assert, describe, it, expect, test, beforeEach, afterEach } from 'vitest'; -import { Message } from "../../../../src/domain"; -import { AgentError } from "../../../../src/domain/models/Errors"; -import { - createOfferCredentialBody, - OfferCredential, -} from "../../../../src/edge-agent/protocols/issueCredential/OfferCredential"; +import { describe, expect, test } from 'vitest'; +import { OfferCredential, OfferCredentialBody } from "../../../../src/edge-agent/protocols/issueCredential/OfferCredential"; import { ProtocolType } from "../../../../src/edge-agent/protocols/ProtocolTypes"; -import { DIDTest } from "../../helpers/DID"; +import { AttachmentDescriptor } from '../../../../src/domain'; import * as Messages from "../../../fixtures/messages"; +import * as Fixtures from "../../../fixtures"; describe("OfferCredential", () => { - it("Should create a valid OfferCredential from a correct OfferMessage", () => { - const fromDID = DIDTest.fromIndex(0); - const toDID = DIDTest.fromIndex(1); - const validOfferCredential = new OfferCredential( - createOfferCredentialBody( - { - type: ProtocolType.DidcommCredentialPreview, + test("Should create OfferCredential from valid params", () => { + const body: OfferCredentialBody = { + credential_preview: { + type: ProtocolType.DidcommCredentialPreview, + body: { attributes: [ { name: "test1", value: "test", - mimeType: "test.x", + media_type: "test.x", }, ], }, - [ - { - attach_id: "test1", - format: "test", - }, - ] - ), - [], - fromDID, - toDID, - "1" + }, + }; + const sut = new OfferCredential(body, []); + + expect(sut).toBeInstanceOf(OfferCredential); + expect(sut.attachments).toHaveLength(0); + expect(sut.body).toEqual(body); + expect(sut.from).toBeUndefined(); + expect(sut.to).toBeUndefined(); + expect(sut.thid).toBeUndefined(); + expect(sut.id).toEqual(expect.stringMatching("")); + }); + + test("Should create OfferCredential with attachments", () => { + const body: OfferCredentialBody = { + credential_preview: { + type: ProtocolType.DidcommCredentialPreview, + body: { attributes: [] }, + }, + }; + + const json = JSON.stringify({ + options: { + challenge: "fedac0c2-3250-4fb1-bfcb-b5e904058e1f", + domain: "domain" + } + }); + const id = "321905d1-5f01-42b0-b0ba-39b09645eeaa"; + const format = "JWT"; + const attached = new AttachmentDescriptor( + { json }, + undefined, + id, + undefined, + format ); - const offerMessage = validOfferCredential.makeMessage(); - const testOfferCredential = OfferCredential.fromMessage(offerMessage); + const sut = new OfferCredential(body, [attached]); + + expect(sut).toBeInstanceOf(OfferCredential); + expect(sut.attachments).toHaveLength(1); + expect(sut.attachments[0].id).toEqual(id); + expect(sut.attachments[0].data).toEqual({ json }); + expect(sut.attachments[0].format).toEqual(format); + }); + + test("Should create OfferCredential with valid optional params", () => { + const body: OfferCredentialBody = { + credential_preview: { + type: ProtocolType.DidcommCredentialPreview, + body: { attributes: [] } + }, + }; + const from = Fixtures.DIDs.peerDID1; + const to = Fixtures.DIDs.peerDID2; + const thid = "test-thid"; + const id = "test-id"; + const sut = new OfferCredential(body, [], from, to, thid, id); - expect(validOfferCredential).to.deep.equal(testOfferCredential); + expect(sut).toBeInstanceOf(OfferCredential); + expect(sut.attachments).toHaveLength(0); + expect(sut.body).toEqual(body); + expect(sut.from).toBe(from); + expect(sut.to).toBe(to); + expect(sut.thid).toBe(thid); + expect(sut.id).toBe(id); }); - test("OfferCredential from an actual PrismAgent Message", () => { - const sut = OfferCredential.fromMessage(Messages.OfferCredential); + test("invalid body.credential_preview - throws", () => { + const body: OfferCredentialBody = { credential_preview: {} as any }; + const sut = () => new OfferCredential(body, []); - expect(sut).to.be.instanceOf(OfferCredential); - expect(sut.attachments).to.deep.eq(Messages.OfferCredential.attachments); - // expect(sut.body).to.deep.eq(Messages.OfferCredential.body); - expect(sut.from).to.deep.eq(Messages.OfferCredential.from); - expect(sut.id).to.deep.eq(Messages.OfferCredential.id); - expect(sut.thid).to.deep.eq(Messages.OfferCredential.thid); - expect(sut.to).to.deep.eq(Messages.OfferCredential.to); + expect(sut).toThrow("Invalid offer credential message error."); }); - it("Should test failure when invalid OfferMessage is provided when Creating an OfferCredential", () => { - const invalidOfferCredential = new Message( - '{"body": {}}', - "id", - "InvalidType" - ); - assert.throws( - () => { - OfferCredential.fromMessage(invalidOfferCredential); - }, - AgentError.InvalidOfferCredentialMessageError, - "Invalid offer credential message error." - ); + describe("fromMessage", () => { + test("actual PrismAgent Message - instantiates", () => { + const sut = OfferCredential.fromMessage(Messages.OfferCredential); + + expect(sut).to.be.instanceOf(OfferCredential); + expect(sut.attachments).to.deep.eq(Messages.OfferCredential.attachments); + // expect(sut.body).to.deep.eq(Messages.OfferCredential.body); + expect(sut.from).to.deep.eq(Messages.OfferCredential.from); + expect(sut.id).to.deep.eq(Messages.OfferCredential.id); + expect(sut.thid).to.deep.eq(Messages.OfferCredential.thid); + expect(sut.to).to.deep.eq(Messages.OfferCredential.to); + }); }); }); diff --git a/tests/agent/protocols/issueCredential/ProposeCredential.test.ts b/tests/agent/protocols/issueCredential/ProposeCredential.test.ts index 4b443cc1d..14b3371c2 100644 --- a/tests/agent/protocols/issueCredential/ProposeCredential.test.ts +++ b/tests/agent/protocols/issueCredential/ProposeCredential.test.ts @@ -1,39 +1,114 @@ -import { vi, assert, describe, it, expect, test, beforeEach, afterEach } from 'vitest'; -import { Message } from "../../../../src/domain"; +import { assert, describe, expect, test } from 'vitest'; +import { AttachmentDescriptor, Message } from "../../../../src/domain"; import { AgentError } from "../../../../src/domain/models/Errors"; -import { - createProposeCredentialBody, - ProposeCredential, -} from "../../../../src/edge-agent/protocols/issueCredential/ProposeCredential"; +import { ProposeCredential, ProposeCredentialBody } from "../../../../src/edge-agent/protocols/issueCredential/ProposeCredential"; import { ProtocolType } from "../../../../src/edge-agent/protocols/ProtocolTypes"; -import { DIDTest } from "../../helpers/DID"; +import { CredentialPreview } from '../../../../src/edge-agent/protocols/issueCredential/CredentialPreview'; +import * as Fixtures from "../../../fixtures"; describe("ProposeCredential", () => { - it("Should create a valid ProposeCredential from a correct ProposeMessage", () => { - const fromDID = DIDTest.fromIndex(0); - const toDID = DIDTest.fromIndex(1); - const validProposeCredential = new ProposeCredential( - createProposeCredentialBody( - { - type: ProtocolType.DidcommCredentialPreview, - attributes: [{ name: "test1", value: "test", mimeType: "test.x" }], - }, - [{ attach_id: "test1", format: "test" }] - ), - [], - fromDID, - toDID, - "1" + test("Should create a ProposeCredential from valid params", () => { + const sut = new ProposeCredential({}, []); + + expect(sut).toBeInstanceOf(ProposeCredential); + expect(sut.attachments).toHaveLength(0); + expect(sut.body).toEqual({}); + expect(sut.from).toBeUndefined(); + expect(sut.to).toBeUndefined(); + expect(sut.thid).toBeUndefined(); + expect(sut.id).toEqual(expect.stringMatching("")); + }); + + test("Should create OfferCredential with attachments", () => { + const json = JSON.stringify({ + options: { + challenge: "fedac0c2-3250-4fb1-bfcb-b5e904058e1f", + domain: "domain" + } + }); + const id = "321905d1-5f01-42b0-b0ba-39b09645eeaa"; + const format = "JWT"; + const attached = new AttachmentDescriptor( + { json }, + undefined, + id, + undefined, + format ); - const proposeMessage = validProposeCredential.makeMessage(); - const testProposeCredential = ProposeCredential.fromMessage(proposeMessage); + const sut = new ProposeCredential({}, [attached]); + + expect(sut).toBeInstanceOf(ProposeCredential); + expect(sut.attachments).toHaveLength(1); + expect(sut.attachments[0].id).toEqual(id); + expect(sut.attachments[0].data).toEqual({ json }); + expect(sut.attachments[0].format).toEqual(format); + }); + + test("Should create OfferCredential with valid optional params", () => { + const from = Fixtures.DIDs.peerDID1; + const to = Fixtures.DIDs.peerDID2; + const thid = "test-thid"; + const id = "test-id"; + const sut = new ProposeCredential({}, [], from, to, thid, id); + + expect(sut).toBeInstanceOf(ProposeCredential); + expect(sut.attachments).toHaveLength(0); + expect(sut.body).toEqual({}); + expect(sut.from).toBe(from); + expect(sut.to).toBe(to); + expect(sut.thid).toBe(thid); + expect(sut.id).toBe(id); + }); + + test("ProposeCredential body properties should be correct", () => { + const goal_code = "test-goalcode"; + const comment = "test-comment"; + const credential_preview: CredentialPreview = { type: "1", body: { attributes: [] } }; + const body: ProposeCredentialBody = { goal_code, comment, credential_preview }; + const sut = new ProposeCredential(body, []); + + expect(sut).toBeInstanceOf(ProposeCredential); + expect(sut.body.goal_code).toEqual(goal_code); + expect(sut.body.comment).toEqual(comment); + expect(sut.body.credential_preview).toEqual(credential_preview); + }); + + describe("fromMessage", () => { + test("piuri invalid - throws", () => { + const piuri = ProtocolType.DidcommBasicMessage; + const from = Fixtures.DIDs.peerDID1; + const to = Fixtures.DIDs.peerDID2; + const msg = new Message({}, "id", piuri, from, to); + + const sut = () => ProposeCredential.fromMessage(msg); + + expect(sut).toThrow("Invalid proposed credential message error."); + }); + + test("from missing - throws", () => { + const piuri = ProtocolType.DidcommProposeCredential; + const to = Fixtures.DIDs.peerDID2; + const msg = new Message({}, "id", piuri, null as any, to); + + const sut = () => ProposeCredential.fromMessage(msg); + + expect(sut).toThrow("Invalid proposed credential message error."); + }); + + test("to missing - throws", () => { + const piuri = ProtocolType.DidcommProposeCredential; + const from = Fixtures.DIDs.peerDID1; + const msg = new Message({}, "id", piuri, from); + + const sut = () => ProposeCredential.fromMessage(msg); - expect(validProposeCredential).to.deep.equal(testProposeCredential); + expect(sut).toThrow("Invalid proposed credential message error."); + }); }); - it("Should test failure when invalid ProposeMessage is provided when Creating an ProposeCredential", () => { + test("Should test failure when invalid ProposeMessage is provided when Creating an ProposeCredential", () => { const invalidProposeCredential = new Message( '{"body": {}}', "id", diff --git a/tests/agent/protocols/issueCredential/RequestCredential.test.ts b/tests/agent/protocols/issueCredential/RequestCredential.test.ts new file mode 100644 index 000000000..d233d2ce4 --- /dev/null +++ b/tests/agent/protocols/issueCredential/RequestCredential.test.ts @@ -0,0 +1,122 @@ +import { vi, assert, describe, it, expect, test, beforeEach, afterEach } from 'vitest'; +import { AttachmentDescriptor, Message } from "../../../../src/domain"; +import { AgentError } from "../../../../src/domain/models/Errors"; +import { RequestCredential } from "../../../../src/edge-agent/protocols/issueCredential/RequestCredential"; +import * as Fixtures from "../../../fixtures"; +import { InvalidCredentialFormats } from '../../../../src/domain/models/errors/Agent'; +import { ProtocolType } from '../../../../src'; + +describe("RequestCredential", () => { + it("Should create a valid RequestCredential from valid params", () => { + const validRequestCredential = new RequestCredential({ formats: [] }, [], Fixtures.DIDs.peerDID1); + + expect(validRequestCredential).toBeInstanceOf(RequestCredential); + }); + + test("Should create RequestCredential with attachments", () => { + const json = JSON.stringify({ + options: { + challenge: "fedac0c2-3250-4fb1-bfcb-b5e904058e1f", + domain: "domain" + } + }); + const id = "321905d1-5f01-42b0-b0ba-39b09645eeaa"; + const format = "JWT"; + const attached = new AttachmentDescriptor( + { json }, + undefined, + id, + undefined, + format + ); + + const sut = new RequestCredential({ formats: [] }, [attached], Fixtures.DIDs.peerDID2); + + expect(sut).toBeInstanceOf(RequestCredential); + expect(sut.attachments).toHaveLength(1); + expect(sut.attachments[0].id).toEqual(id); + expect(sut.attachments[0].data).toEqual({ json }); + expect(sut.attachments[0].format).toEqual(format); + }); + + test("Should create RequestCredential with valid optional params", () => { + const formatItem = { attach_id: "123", format: "test-format" }; + const body = { formats: [formatItem] }; + const from = Fixtures.DIDs.peerDID1; + const to = Fixtures.DIDs.peerDID2; + const thid = "test-thid"; + const id = "test-id"; + const sut = new RequestCredential(body, [], from, to, thid, id); + + expect(sut).toBeInstanceOf(RequestCredential); + expect(sut.body.formats).toHaveLength(1); + expect(sut.body.formats[0]).toEqual(formatItem); + + expect(sut.attachments).toHaveLength(0); + expect(sut.body).toEqual(body); + expect(sut.from).toBe(from); + expect(sut.to).toBe(to); + expect(sut.thid).toBe(thid); + expect(sut.id).toBe(id); + }); + + test("invalid body - no formats - throws", () => { + const sut = () => new RequestCredential({} as any, [], Fixtures.DIDs.peerDID1); + + expect(sut).toThrow(InvalidCredentialFormats); + }); + + test("invalid body.formats - not an object - throws", () => { + const sut = () => new RequestCredential( + { formats: ["wrong"] as any }, + [], + Fixtures.DIDs.peerDID1 + ); + + expect(sut).toThrow(InvalidCredentialFormats); + }); + + test("invalid body.formats - missing attach_id - throws", () => { + const formatItem = { format: "test-format" } as any; + const sut = () => new RequestCredential( + { formats: [formatItem] }, + [], + Fixtures.DIDs.peerDID1 + ); + + expect(sut).toThrow(InvalidCredentialFormats); + }); + + test("invalid body.formats - missing format - throws", () => { + const formatItem = { attach_id: "123" } as any; + const sut = () => new RequestCredential( + { formats: [formatItem] }, + [], + Fixtures.DIDs.peerDID1 + ); + + expect(sut).toThrow(InvalidCredentialFormats); + }); + + describe("fromMessage", () => { + test("piuri invalid - throws", () => { + const piuri = ProtocolType.DidcommBasicMessage; + const from = Fixtures.DIDs.peerDID1; + const msg = new Message({}, "id", piuri, from); + + const sut = () => RequestCredential.fromMessage(msg); + + expect(sut).toThrow("Invalid request credential message error."); + }); + + test("from missing - throws", () => { + const piuri = ProtocolType.DidcommProposeCredential; + const to = Fixtures.DIDs.peerDID2; + const msg = new Message({}, "id", piuri, null as any); + + const sut = () => RequestCredential.fromMessage(msg); + + expect(sut).toThrow("Invalid request credential message error."); + }); + }); +}); diff --git a/tests/agent/protocols/proofPresentation/Presentation.test.ts b/tests/agent/protocols/proofPresentation/Presentation.test.ts index 75cd1967e..ecf40ec75 100644 --- a/tests/agent/protocols/proofPresentation/Presentation.test.ts +++ b/tests/agent/protocols/proofPresentation/Presentation.test.ts @@ -4,13 +4,12 @@ import { AgentError } from "../../../../src/domain/models/Errors"; import { parsePresentationMessage } from "../../../../src/edge-agent/helpers/ProtocolHelpers"; import { Presentation } from "../../../../src/edge-agent/protocols/proofPresentation/Presentation"; import { ProtocolType } from "../../../../src/edge-agent/protocols/ProtocolTypes"; -import { PresentationBody } from "../../../../src/edge-agent/protocols/types"; -import { DIDTest } from "../../helpers/DID"; +import * as Fixtures from "../../../fixtures"; describe("ProofPresentation -> Presentation Tests", () => { it("Should create a Presentation from a valid PresentationMessage", async () => { - const fromDID = DIDTest.fromIndex(0); - const toDID = DIDTest.fromIndex(1); + const fromDID = Fixtures.DIDs.peerDID1; + const toDID = Fixtures.DIDs.peerDID2; const msg = new Message("{}", undefined, ProtocolType.DidcommPresentation); const presentationBody = parsePresentationMessage(msg); const validPresentation = new Presentation( diff --git a/tests/agent/protocols/proofPresentation/ProposePresentation.test.ts b/tests/agent/protocols/proofPresentation/ProposePresentation.test.ts index 0820921c8..b18075aee 100644 --- a/tests/agent/protocols/proofPresentation/ProposePresentation.test.ts +++ b/tests/agent/protocols/proofPresentation/ProposePresentation.test.ts @@ -3,12 +3,12 @@ import { Message } from "../../../../src/domain"; import { AgentError } from "../../../../src/domain/models/Errors"; import { ProposePresentation } from "../../../../src/edge-agent/protocols/proofPresentation/ProposePresentation"; import { RequestPresentation } from "../../../../src/edge-agent/protocols/proofPresentation/RequestPresentation"; -import { DIDTest } from "../../helpers/DID"; +import * as Fixtures from "../../../fixtures"; describe("ProofPresentation->ProposePresentation Tests", () => { it("Should create a ProposePresentation from a valid ProposePresentationMessage", async () => { - const fromDID = DIDTest.fromIndex(0); - const toDID = DIDTest.fromIndex(1); + const fromDID = Fixtures.DIDs.peerDID1; + const toDID = Fixtures.DIDs.peerDID2; const validProposePresentation = new ProposePresentation( { @@ -38,8 +38,8 @@ describe("ProofPresentation->ProposePresentation Tests", () => { }).to.throw(AgentError.InvalidProposePresentationMessageError); }); it("Should start a ProposePresentation from a valid RequestMessage", () => { - const fromDID = DIDTest.fromIndex(0); - const toDID = DIDTest.fromIndex(1); + const fromDID = Fixtures.DIDs.peerDID1; + const toDID = Fixtures.DIDs.peerDID2; const validRequestPresentation = new RequestPresentation( { proofTypes: [{ schema: "testSchema" }], diff --git a/tests/agent/protocols/proofPresentation/RequestPresentation.test.ts b/tests/agent/protocols/proofPresentation/RequestPresentation.test.ts index ee6e6fad1..1ecd5090f 100644 --- a/tests/agent/protocols/proofPresentation/RequestPresentation.test.ts +++ b/tests/agent/protocols/proofPresentation/RequestPresentation.test.ts @@ -3,13 +3,13 @@ import { Message } from "../../../../src/domain"; import { AgentError } from "../../../../src/domain/models/Errors"; import { ProposePresentation } from "../../../../src/edge-agent/protocols/proofPresentation/ProposePresentation"; import { RequestPresentation } from "../../../../src/edge-agent/protocols/proofPresentation/RequestPresentation"; -import { DIDTest } from "../../helpers/DID"; import * as Messages from "../../../fixtures/messages"; +import * as Fixtures from "../../../fixtures"; describe("ProofPresentation->RequestPresentation Tests", () => { it("Should create a RequestPresentation from a valid ProposePresentationMessage", async () => { - const fromDID = DIDTest.fromIndex(0); - const toDID = DIDTest.fromIndex(1); + const fromDID = Fixtures.DIDs.peerDID1; + const toDID = Fixtures.DIDs.peerDID2; const validRequestPresentation = new RequestPresentation( { @@ -52,8 +52,8 @@ describe("ProofPresentation->RequestPresentation Tests", () => { }).to.throw(AgentError.InvalidRequestPresentationMessageError); }); it("Should start a RequestPresentation from a valid ProposalMessage", () => { - const fromDID = DIDTest.fromIndex(0); - const toDID = DIDTest.fromIndex(1); + const fromDID = Fixtures.DIDs.peerDID1; + const toDID = Fixtures.DIDs.peerDID2; const validProposalRequest = new ProposePresentation( { proofTypes: [{ schema: "testSchema" }], diff --git a/tests/fixtures/credentials/sdjwt.ts b/tests/fixtures/credentials/sdjwt.ts index 011ab9e5f..030ff9328 100644 --- a/tests/fixtures/credentials/sdjwt.ts +++ b/tests/fixtures/credentials/sdjwt.ts @@ -7,56 +7,56 @@ import { list } from "../dids"; export const credentialPayloadEncoded = "eyJ0eXAiOiJ2YytzZC1qd3QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6cHJpc206NzE2OGEwN2I5NGQxMzAyNjg5MDU2ZTkyN2I0ZGVmOTNjNDIzYjk1NTNmNzcxZTQ4NmM4ZDkxODg4M2UyNTZmMTpDcTBCQ3FvQkVsc0tIMkYxZEdobGJuUnBZMkYwYVc5dVlYVjBhR1Z1ZEdsallYUnBiMjVMWlhrUUJFSTJDZ2RGWkRJMU5URTVFaXRrYlRWbU1rZGtValZDWVVod1VuaENPR0pVUld4MlJWOHdaMGxETW5BME1EUk5jM2c1YzNkS09URTBFa3NLRDIxaGMzUmxjbTFoYzNSbGNrdGxlUkFCUWpZS0IwVmtNalUxTVRrU0syUnROV1l5UjJSU05VSmhTSEJTZUVJNFlsUkZiSFpGWHpCblNVTXljRFF3TkUxemVEbHpkMG81TVRRIiwiaWF0IjoxNzE3Nzc2MTY3NTg5LCJ2Y3QiOiJodHRwOi8vZXhhbXBsZS5jb20iLCJmaXJzdG5hbWUiOiJKb2huIiwibGFzdG5hbWUiOiJEb2UiLCJzc24iOiIxMjMtNDUtNjc4OSIsImlkIjoiMTIzNCIsIl9zZF9hbGciOiJzaGEtMjU2In0.RThFQjlENjJDN0Y5NjlCOEM0NERFNkU3RDg4MDg5RkRBQjg0RTUzNzUyNTZFRUI5NUQyQTUwQ0U1MTdDNzQ2NjU5REExOTM4Njc0RjhFMkQ2QjFCNzNFNEZCRDZBNkQ4NjIzNDFEQkFERjY0MTBERUJCRENDRkVBRjhCMkMwMDU~"; export const credentialOfferMessage = new OfferCredential( - { - "formats": [ - { - attach_id: "321905d1-5f01-42b0-b0ba-39b09645eeaa", - format: CredentialType.SDJWT - } - ], - "credential_preview": { - "body": { - "attributes": [ - { - "media_type": null, - "name": "familyName", - "value": "JWT" - }, - { - "media_type": null, - "name": "emailAddress", - "value": "jwt@wonderland.com" - } - ] - }, - "schema_id": null, - "type": "https://didcomm.org/issue-credential/3.0/credential-credential" - }, - "comment": null - } as any, - [ - new AttachmentDescriptor({ - data: JSON.stringify({ - "options": { - "challenge": "fedac0c2-3250-4fb1-bfcb-b5e904058e1f", - "domain": "domain" - } - }) - }, - undefined, - "321905d1-5f01-42b0-b0ba-39b09645eeaa", - undefined, - CredentialType.SDJWT - ) - ], - list[2], - list[3], - "e0670d7d-933f-4408-9dfb-340cd6230584", - "f8fe3752-710a-4d76-8d9b-87d7d045c85e" + { + // "formats": [ + // { + // attach_id: "321905d1-5f01-42b0-b0ba-39b09645eeaa", + // format: CredentialType.SDJWT + // } + // ], + "credential_preview": { + "body": { + "attributes": [ + { + "media_type": null, + "name": "familyName", + "value": "JWT" + }, + { + "media_type": null, + "name": "emailAddress", + "value": "jwt@wonderland.com" + } + ] + }, + "schema_id": null, + "type": "https://didcomm.org/issue-credential/3.0/credential-credential" + }, + "comment": null + } as any, + [ + new AttachmentDescriptor({ + data: JSON.stringify({ + "options": { + "challenge": "fedac0c2-3250-4fb1-bfcb-b5e904058e1f", + "domain": "domain" + } + }) + }, + undefined, + "321905d1-5f01-42b0-b0ba-39b09645eeaa", + undefined, + CredentialType.SDJWT + ) + ], + list[2], + list[3], + "e0670d7d-933f-4408-9dfb-340cd6230584", + "f8fe3752-710a-4d76-8d9b-87d7d045c85e" ); export const presentationRequest = { - "claims": { - firstname: {} - } -} + "claims": { + firstname: {} + } +};