diff --git a/src/controllers/issuer.ts b/src/controllers/issuer.ts index 91596ec9..46d1011b 100644 --- a/src/controllers/issuer.ts +++ b/src/controllers/issuer.ts @@ -740,10 +740,10 @@ export class IssuerController { const did = request.params.did ? await new IdentityServiceStrategySetup(response.locals.customer.customerId).agent.resolveDid( request.params.did - ) + ) : await new IdentityServiceStrategySetup(response.locals.customer.customerId).agent.listDids( response.locals.customer - ); + ); return response.status(StatusCodes.OK).json(did); } catch (error) { diff --git a/src/controllers/presentation.ts b/src/controllers/presentation.ts index b284095e..ce564954 100644 --- a/src/controllers/presentation.ts +++ b/src/controllers/presentation.ts @@ -206,11 +206,11 @@ export class PresentationController { } if (makeFeePayment) { - const setResult = await cheqdPresentation.trySetStatusList2021(identityServiceStrategySetup.agent) + const setResult = await cheqdPresentation.trySetStatusList2021(identityServiceStrategySetup.agent); if (setResult.error) { return response.status(setResult.status).send({ - error: setResult.error - }) + error: setResult.error, + }); } if (cheqdPresentation.isPaymentNeeded()) { const feePaymentResult = await cheqdPresentation.makeFeePayment( diff --git a/src/database/types/types.ts b/src/database/types/types.ts index 4583d8ff..41e10431 100644 --- a/src/database/types/types.ts +++ b/src/database/types/types.ts @@ -68,7 +68,7 @@ export class Postgres implements AbstractDatabase { ssl: config.ssl ? { ca: EXTERNAL_DB_CERT, - } + } : false, migrations: [ ...migrations, diff --git a/src/helpers/helpers.ts b/src/helpers/helpers.ts index c740dc7e..7b8f1635 100644 --- a/src/helpers/helpers.ts +++ b/src/helpers/helpers.ts @@ -103,7 +103,7 @@ export function isValidService(didDocument: DIDDocument): boolean { return didDocument.service ? didDocument?.service?.every((s) => { return s?.serviceEndpoint && s?.id && s?.type; - }) + }) : true; } diff --git a/src/services/connectors/verida.ts b/src/services/connectors/verida.ts index cf39b23c..866de85c 100644 --- a/src/services/connectors/verida.ts +++ b/src/services/connectors/verida.ts @@ -1,15 +1,15 @@ -import type { EnvironmentType } from '@verida/types' -import { Context, Network } from '@verida/client-ts' -import { AutoAccount } from '@verida/account-node' +import type { EnvironmentType } from '@verida/types'; +import { Context, Network } from '@verida/client-ts'; +import { AutoAccount } from '@verida/account-node'; -import type { CredentialDataRecord, DataRecord } from '../../types/verida.js' -import { VERIDA_APP_NAME, VERIDA_CREDENTIAL_RECORD_SCHEMA } from '../../types/constants.js' +import type { CredentialDataRecord, DataRecord } from '../../types/verida.js'; +import { VERIDA_APP_NAME, VERIDA_CREDENTIAL_RECORD_SCHEMA } from '../../types/constants.js'; -import * as dotenv from 'dotenv' -import type { VerifiableCredential } from '@veramo/core' -dotenv.config() +import * as dotenv from 'dotenv'; +import type { VerifiableCredential } from '@veramo/core'; +dotenv.config(); -const { VERIDA_NETWORK, POLYGON_RPC_URL, VERIDA_PRIVATE_KEY, POLYGON_PRIVATE_KEY } = process.env +const { VERIDA_NETWORK, POLYGON_RPC_URL, VERIDA_PRIVATE_KEY, POLYGON_PRIVATE_KEY } = process.env; /** * Helper class for the Verida protocol. @@ -17,120 +17,114 @@ const { VERIDA_NETWORK, POLYGON_RPC_URL, VERIDA_PRIVATE_KEY, POLYGON_PRIVATE_KEY * Run the init method before running any other method. */ export class VeridaService { - private context?: Context - private account?: AutoAccount + private context?: Context; + private account?: AutoAccount; - static instance = new VeridaService() + static instance = new VeridaService(); - /** - * Initialise the Verida account and context. - * - * @param environment The Verida environment. - * @param contextName The Context name of the application. - * @param accountPrivateKey The private key of the account - */ - async init( - environment: EnvironmentType, - contextName: string, - accountPrivateKey: string, - polygonPrivateKey: string - ) { - if(this.context && this.account) { - return - } - this.account = new AutoAccount({ - privateKey: accountPrivateKey, - environment, - didClientConfig: { - callType: 'web3', - web3Config: { - rpcUrl: POLYGON_RPC_URL, - privateKey: polygonPrivateKey, // Polygon private key for creating DID, not needed in our case but required in the current version of the config. - }, - }, - }) - try { - this.context = await Network.connect({ - client: { - environment, - }, - context: { - name: contextName, - }, - account: this.account, - }) - } catch (error) { - throw new Error(`Error: ${error}`) - } - } + /** + * Initialise the Verida account and context. + * + * @param environment The Verida environment. + * @param contextName The Context name of the application. + * @param accountPrivateKey The private key of the account + */ + async init( + environment: EnvironmentType, + contextName: string, + accountPrivateKey: string, + polygonPrivateKey: string + ) { + if (this.context && this.account) { + return; + } + this.account = new AutoAccount({ + privateKey: accountPrivateKey, + environment, + didClientConfig: { + callType: 'web3', + web3Config: { + rpcUrl: POLYGON_RPC_URL, + privateKey: polygonPrivateKey, // Polygon private key for creating DID, not needed in our case but required in the current version of the config. + }, + }, + }); + try { + this.context = await Network.connect({ + client: { + environment, + }, + context: { + name: contextName, + }, + account: this.account, + }); + } catch (error) { + throw new Error(`Error: ${error}`); + } + } - /** - * Send data to a DID via the Verida protocol. - * - * @param recipientDid The DID of the recipient. - * @param subject The subject of the message (similar to an email subject). - * @param data The data to be sent. - */ - async sendData(recipientDid: string, subject: string, data: DataRecord) { - try { - if(!this.context) { - await VeridaService.instance.init( - VERIDA_NETWORK, - VERIDA_APP_NAME, - VERIDA_PRIVATE_KEY, - POLYGON_PRIVATE_KEY - ) - } + /** + * Send data to a DID via the Verida protocol. + * + * @param recipientDid The DID of the recipient. + * @param subject The subject of the message (similar to an email subject). + * @param data The data to be sent. + */ + async sendData(recipientDid: string, subject: string, data: DataRecord) { + try { + if (!this.context) { + await VeridaService.instance.init( + VERIDA_NETWORK, + VERIDA_APP_NAME, + VERIDA_PRIVATE_KEY, + POLYGON_PRIVATE_KEY + ); + } - const messagingClient = await this.context?.getMessaging() + const messagingClient = await this.context?.getMessaging(); - const messageType = 'inbox/type/dataSend' // There are different types of message, here we are sending some data. - const messageData = { - data: [data], - } - const messageConfig = { - recipientContextName: 'Verida: Vault', // The inbox of a DID is on the 'Verida: Vault' context. This context is the private space of this DID. - did: recipientDid, - } + const messageType = 'inbox/type/dataSend'; // There are different types of message, here we are sending some data. + const messageData = { + data: [data], + }; + const messageConfig = { + recipientContextName: 'Verida: Vault', // The inbox of a DID is on the 'Verida: Vault' context. This context is the private space of this DID. + did: recipientDid, + }; - await messagingClient?.send( - recipientDid, - messageType, - messageData, - subject, - messageConfig - ) - } catch (error) { - throw new Error(`Error sending data ${error}`) - } - } + await messagingClient?.send(recipientDid, messageType, messageData, subject, messageConfig); + } catch (error) { + throw new Error(`Error sending data ${error}`); + } + } - /** - * Send a Verifiable Credential to a DID via the Verida protocol. - * - * @param recipientDid The DID of the recipient. - * @param messageSubject The subject of the message in which the Credential will be sent to the recipient (similar to an email subject). - * @param credential The credential itself. - * @param credentialName The name of the credential. For instance, will be displayed in the Verida Wallet UI. - * @param credentialSummary A summary of the credential. For instance, will be displayed in the Verida Wallet UI. - */ - async sendCredential( - recipientDid: string, - messageSubject: string, - credential: VerifiableCredential, - credentialName: string, - credentialSchema: string, - credentialSummary?: string - ) { - // The Credential record is how Verida wrap the credential to store it on the Network. Check the JSdoc of the type and each property. They are following the Verida Credential Record schema. - const credentialRecord: CredentialDataRecord = { - name: credentialName, - summary: credentialSummary, - schema: VERIDA_CREDENTIAL_RECORD_SCHEMA, - didJwtVc: credential.proof.jwt, - credentialSchema, - credentialData: credential, - } - await this.sendData(recipientDid, messageSubject, credentialRecord) - } -} \ No newline at end of file + /** + * Send a Verifiable Credential to a DID via the Verida protocol. + * + * @param recipientDid The DID of the recipient. + * @param messageSubject The subject of the message in which the Credential will be sent to the recipient (similar to an email subject). + * @param credential The credential itself. + * @param credentialName The name of the credential. For instance, will be displayed in the Verida Wallet UI. + * @param credentialSummary A summary of the credential. For instance, will be displayed in the Verida Wallet UI. + */ + async sendCredential( + recipientDid: string, + messageSubject: string, + credential: VerifiableCredential, + credentialName: string, + credentialSchema: string, + credentialSummary?: string + ) { + // The Credential record is how Verida wrap the credential to store it on the Network. Check the JSdoc of the type and each property. They are following the Verida Credential Record schema. + const credentialRecord: CredentialDataRecord = { + name: credentialName, + summary: credentialSummary, + schema: VERIDA_CREDENTIAL_RECORD_SCHEMA, + didJwtVc: credential.proof.jwt, + credentialSchema, + credentialData: credential, + }; + await this.sendData(recipientDid, messageSubject, credentialRecord); + } +} diff --git a/src/services/identity/agent.ts b/src/services/identity/agent.ts index e7a4ba18..3ff82d14 100644 --- a/src/services/identity/agent.ts +++ b/src/services/identity/agent.ts @@ -290,11 +290,11 @@ export class Veramo { ? await agent.cheqdIssueRevocableCredentialWithStatusList2021({ issuanceOptions, statusOptions: statusListOptions as RevocationStatusOptions, - }) + }) : await agent.cheqdIssueSuspendableCredentialWithStatusList2021({ issuanceOptions, statusOptions: statusListOptions as SuspensionStatusOptions, - }); + }); } else { verifiable_credential = await agent.createVerifiableCredential(issuanceOptions); } @@ -468,7 +468,7 @@ export class Veramo { feePaymentAmount: `${toMinimalDenom(condition.feePaymentAmount)}${MINIMAL_DENOM}`, intervalInSeconds: condition.feePaymentWindow * 60, }; - }) + }) : (function () { // validate relevant components - case: feePaymentAddress if (!statusOptions.feePaymentAddress) @@ -490,7 +490,7 @@ export class Veramo { intervalInSeconds: statusOptions.feePaymentWindow * 60, }, ]; - })() + })() ) satisfies PaymentCondition[]; return await agent.cheqdCreateStatusList2021({ @@ -671,7 +671,7 @@ export class Veramo { intervalInSeconds: condition.feePaymentWindow * 60, type: 'timelockPayment', }; - }) + }) : (function () { // validate relevant components if ( @@ -701,7 +701,7 @@ export class Veramo { type: 'timelockPayment', }, ]; - })() + })() ) satisfies PaymentCondition[] | undefined; switch (statusOptions.statusAction) { diff --git a/src/services/w3c_credential.ts b/src/services/w3c_credential.ts index ddb3221d..3097e282 100644 --- a/src/services/w3c_credential.ts +++ b/src/services/w3c_credential.ts @@ -1,4 +1,3 @@ - import { StatusCodes } from 'http-status-codes'; import type { ICommonErrorResponse } from '../types/authentication.js'; import type { @@ -18,7 +17,6 @@ import { CommonReturn, type FeePaymentOptions } from '../types/shared.js'; import { JWT_PROOF_TYPE } from '../types/constants.js'; import type { StatusList2021Revocation, StatusList2021Suspension } from '@cheqd/did-provider-cheqd'; - export interface ICheqdCredential extends UnsignedCredential { proof: { type: string; @@ -135,9 +133,9 @@ export class CheqdW3CVerifiableCredential extends CommonReturn implements ICheqd public isPaymentNeeded(): boolean { if (!this.statusList) { - return false + return false; } - return this.statusList.metadata.encrypted + return this.statusList.metadata.encrypted; } public async makeFeePayment(agent: IIdentityService, customer: CustomerEntity): Promise { diff --git a/src/services/w3c_presentation.ts b/src/services/w3c_presentation.ts index 4e2b9b38..c75efc3f 100644 --- a/src/services/w3c_presentation.ts +++ b/src/services/w3c_presentation.ts @@ -87,29 +87,30 @@ export class CheqdW3CVerifiablePresentation extends CommonReturn implements IChe if (this.verifiableCredential) { return this.verifiableCredential .filter((credential) => credential.credentialStatus) - .some(async (credential) => await credential.isPaymentNeeded()) + .some(async (credential) => await credential.isPaymentNeeded()); } - return false + return false; } - public async trySetStatusList2021(agent: IIdentityService): Promise{ + public async trySetStatusList2021(agent: IIdentityService): Promise { // It returns an error only if there is logical errors inside if (this.verifiableCredential) { const setResults = await Promise.all( this.verifiableCredential .filter((credential) => credential.credentialStatus) - .map(async (credential) => await credential.trySetStatusList2021(agent) satisfies ICommonErrorResponse) + .map( + async (credential) => + (await credential.trySetStatusList2021(agent)) satisfies ICommonErrorResponse + ) ); - if (setResults.some(setResult => setResult.error)) { + if (setResults.some((setResult) => setResult.error)) { return this.returnError( StatusCodes.BAD_REQUEST, - `Errors while setting statusList2021: ${ - setResults.filter((setResult) => setResult.error) - }` - ) + `Errors while setting statusList2021: ${setResults.filter((setResult) => setResult.error)}` + ); } } - return this.returnOk() + return this.returnOk(); } public async makeFeePayment(agent: IIdentityService, customer: CustomerEntity): Promise { @@ -130,10 +131,10 @@ export class CheqdW3CVerifiablePresentation extends CommonReturn implements IChe if (feePaymentResults.some((result) => result.error)) { return this.returnError( StatusCodes.BAD_REQUEST, - `Errors while making payment for the presentation: ${ - feePaymentResults.filter((result) => result.error) - }` - ) + `Errors while making payment for the presentation: ${feePaymentResults.filter( + (result) => result.error + )}` + ); } return this.returnOk(); } diff --git a/src/test/constants.ts b/src/test/constants.ts index 6bcf4c13..dd48ccc9 100644 --- a/src/test/constants.ts +++ b/src/test/constants.ts @@ -1,75 +1,73 @@ -import { JWT_PROOF_TYPE } from "../types/constants"; +import { JWT_PROOF_TYPE } from '../types/constants'; // ------------------ // CREDENTIAL // ------------------ -export const CREDENTIAL_JWT = 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vc2NoZW1hLm9yZy9zY2hlbWEuanNvbmxkIiwiaHR0cHM6Ly92ZXJhbW8uaW8vY29udGV4dHMvcHJvZmlsZS92MSIsImh0dHBzOi8vdzNpZC5vcmcvdmMtc3RhdHVzLWxpc3QtMjAyMS92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiUGVyc29uIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7Im5hbWUiOiJCb2IiLCJnZW5kZXIiOiJtYWxlIn0sImNyZWRlbnRpYWxTdGF0dXMiOnsiaWQiOiJodHRwczovL3Jlc29sdmVyLmNoZXFkLm5ldC8xLjAvaWRlbnRpZmllcnMvZGlkOmNoZXFkOnRlc3RuZXQ6OTBkNWMxNDEtNzI0Zi00N2FkLTlhZTctYTdjMzNhOWU1NjQzP3Jlc291cmNlTmFtZT1zdXNwZW5zaW9uRW4mcmVzb3VyY2VUeXBlPVN0YXR1c0xpc3QyMDIxU3VzcGVuc2lvbiMxMzMzOCIsInR5cGUiOiJTdGF0dXNMaXN0MjAyMUVudHJ5Iiwic3RhdHVzUHVycG9zZSI6InN1c3BlbnNpb24iLCJzdGF0dXNMaXN0SW5kZXgiOiIxMzMzOCJ9fSwic3ViIjoiZGlkOmtleTp6Nk1raGFYZ0JaRHZvdERrTDUyNTdmYWl6dGlHaUMyUXRLTEdwYm5uRUd0YTJkb0siLCJuYmYiOjE3MDA0NzM0MTYsImlzcyI6ImRpZDpjaGVxZDp0ZXN0bmV0OjkwZDVjMTQxLTcyNGYtNDdhZC05YWU3LWE3YzMzYTllNTY0MyJ9.-14Ril1pZEy2HEEo48gTJr2yOtGxBhUGTFmzVdjAtyhFRsW5zZg9onHt6V9JQ8BaiYBlTkP9GzTnJ-O6hdiyCw'; +export const CREDENTIAL_JWT = + 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vc2NoZW1hLm9yZy9zY2hlbWEuanNvbmxkIiwiaHR0cHM6Ly92ZXJhbW8uaW8vY29udGV4dHMvcHJvZmlsZS92MSIsImh0dHBzOi8vdzNpZC5vcmcvdmMtc3RhdHVzLWxpc3QtMjAyMS92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiUGVyc29uIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7Im5hbWUiOiJCb2IiLCJnZW5kZXIiOiJtYWxlIn0sImNyZWRlbnRpYWxTdGF0dXMiOnsiaWQiOiJodHRwczovL3Jlc29sdmVyLmNoZXFkLm5ldC8xLjAvaWRlbnRpZmllcnMvZGlkOmNoZXFkOnRlc3RuZXQ6OTBkNWMxNDEtNzI0Zi00N2FkLTlhZTctYTdjMzNhOWU1NjQzP3Jlc291cmNlTmFtZT1zdXNwZW5zaW9uRW4mcmVzb3VyY2VUeXBlPVN0YXR1c0xpc3QyMDIxU3VzcGVuc2lvbiMxMzMzOCIsInR5cGUiOiJTdGF0dXNMaXN0MjAyMUVudHJ5Iiwic3RhdHVzUHVycG9zZSI6InN1c3BlbnNpb24iLCJzdGF0dXNMaXN0SW5kZXgiOiIxMzMzOCJ9fSwic3ViIjoiZGlkOmtleTp6Nk1raGFYZ0JaRHZvdERrTDUyNTdmYWl6dGlHaUMyUXRLTEdwYm5uRUd0YTJkb0siLCJuYmYiOjE3MDA0NzM0MTYsImlzcyI6ImRpZDpjaGVxZDp0ZXN0bmV0OjkwZDVjMTQxLTcyNGYtNDdhZC05YWU3LWE3YzMzYTllNTY0MyJ9.-14Ril1pZEy2HEEo48gTJr2yOtGxBhUGTFmzVdjAtyhFRsW5zZg9onHt6V9JQ8BaiYBlTkP9GzTnJ-O6hdiyCw'; export const CREDENTIAL_SUBJECT_ID = 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK'; export const ISSUER_DID = 'did:cheqd:testnet:90d5c141-724f-47ad-9ae7-a7c33a9e5643'; -export const CREDENTIAL_STATUS_ID = 'https://resolver.cheqd.net/1.0/identifiers/did:cheqd:testnet:90d5c141-724f-47ad-9ae7-a7c33a9e5643?resourceName=suspensionEn&resourceType=StatusList2021Suspension#13338'; +export const CREDENTIAL_STATUS_ID = + 'https://resolver.cheqd.net/1.0/identifiers/did:cheqd:testnet:90d5c141-724f-47ad-9ae7-a7c33a9e5643?resourceName=suspensionEn&resourceType=StatusList2021Suspension#13338'; export const CREDENTIAL_OBJECT = { - issuer: { - id: ISSUER_DID - }, - credentialSubject: { - gender: "male", - name: "Bob", - id: CREDENTIAL_SUBJECT_ID - }, - credentialStatus: { - id: CREDENTIAL_STATUS_ID, - statusPurpose: "suspension", - statusListIndex: "13338", - type: 'StatusList2021Entry' - }, - type: ["VerifiableCredential", "Person"], - '@context': [ - "https://www.w3.org/2018/credentials/v1", - "https://schema.org", - "https://veramo.io/contexts/profile/v1" - ], - issuanceDate: '2023-06-08T13:49:28.000Z', - proof: { - type: JWT_PROOF_TYPE, - jwt: CREDENTIAL_JWT - } -} - + issuer: { + id: ISSUER_DID, + }, + credentialSubject: { + gender: 'male', + name: 'Bob', + id: CREDENTIAL_SUBJECT_ID, + }, + credentialStatus: { + id: CREDENTIAL_STATUS_ID, + statusPurpose: 'suspension', + statusListIndex: '13338', + type: 'StatusList2021Entry', + }, + type: ['VerifiableCredential', 'Person'], + '@context': [ + 'https://www.w3.org/2018/credentials/v1', + 'https://schema.org', + 'https://veramo.io/contexts/profile/v1', + ], + issuanceDate: '2023-06-08T13:49:28.000Z', + proof: { + type: JWT_PROOF_TYPE, + jwt: CREDENTIAL_JWT, + }, +}; // ------------------ // PRESENTATION // ------------------ -export const PRESENTATION_JWT = 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJ2cCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVQcmVzZW50YXRpb24iXSwidmVyaWZpYWJsZUNyZWRlbnRpYWwiOlsiZXlKaGJHY2lPaUpGWkVSVFFTSXNJblI1Y0NJNklrcFhWQ0o5LmV5SjJZeUk2ZXlKQVkyOXVkR1Y0ZENJNld5Sm9kSFJ3Y3pvdkwzZDNkeTUzTXk1dmNtY3ZNakF4T0M5amNtVmtaVzUwYVdGc2N5OTJNU0lzSW1oMGRIQnpPaTh2YzJOb1pXMWhMbTl5Wnk5elkyaGxiV0V1YW5OdmJteGtJaXdpYUhSMGNITTZMeTkyWlhKaGJXOHVhVzh2WTI5dWRHVjRkSE12Y0hKdlptbHNaUzkyTVNJc0ltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmRtTXRjM1JoZEhWekxXeHBjM1F0TWpBeU1TOTJNU0pkTENKMGVYQmxJanBiSWxabGNtbG1hV0ZpYkdWRGNtVmtaVzUwYVdGc0lpd2lVR1Z5YzI5dUlsMHNJbU55WldSbGJuUnBZV3hUZFdKcVpXTjBJanA3SW01aGJXVWlPaUpDYjJJaUxDSm5aVzVrWlhJaU9pSnRZV3hsSW4wc0ltTnlaV1JsYm5ScFlXeFRkR0YwZFhNaU9uc2lhV1FpT2lKb2RIUndjem92TDNKbGMyOXNkbVZ5TG1Ob1pYRmtMbTVsZEM4eExqQXZhV1JsYm5ScFptbGxjbk12Wkdsa09tTm9aWEZrT25SbGMzUnVaWFE2T1RCa05XTXhOREV0TnpJMFppMDBOMkZrTFRsaFpUY3RZVGRqTXpOaE9XVTFOalF6UDNKbGMyOTFjbU5sVG1GdFpUMXpkWE53Wlc1emFXOXVSVzRtY21WemIzVnlZMlZVZVhCbFBWTjBZWFIxYzB4cGMzUXlNREl4VTNWemNHVnVjMmx2YmlNeE16TXpPQ0lzSW5SNWNHVWlPaUpUZEdGMGRYTk1hWE4wTWpBeU1VVnVkSEo1SWl3aWMzUmhkSFZ6VUhWeWNHOXpaU0k2SW5OMWMzQmxibk5wYjI0aUxDSnpkR0YwZFhOTWFYTjBTVzVrWlhnaU9pSXhNek16T0NKOWZTd2ljM1ZpSWpvaVpHbGtPbXRsZVRwNk5rMXJhR0ZZWjBKYVJIWnZkRVJyVERVeU5UZG1ZV2w2ZEdsSGFVTXlVWFJMVEVkd1ltNXVSVWQwWVRKa2Iwc2lMQ0p1WW1ZaU9qRTNNREEwTnpNME1UWXNJbWx6Y3lJNkltUnBaRHBqYUdWeFpEcDBaWE4wYm1WME9qa3daRFZqTVRReExUY3lOR1l0TkRkaFpDMDVZV1UzTFdFM1l6TXpZVGxsTlRZME15SjkuLTE0UmlsMXBaRXkySEVFbzQ4Z1RKcjJ5T3RHeEJoVUdURm16VmRqQXR5aEZSc1c1elpnOW9uSHQ2VjlKUThCYWlZQmxUa1A5R3pUbkotTzZoZGl5Q3ciXX0sIm5iZiI6MTcwMTE3NDQyMiwiaXNzIjoiZGlkOmNoZXFkOnRlc3RuZXQ6OGM3MWU5YjYtYzVhMy00MjUwLThjNTgtZmE1OTE1MzNjZDIyIiwiYXVkIjpbImRpZDpjaGVxZDp0ZXN0bmV0OjRiODQ2ZDBmLTJmNmMtNGFiNi05ZmUyLTViOGRiMzAxYzgzYyJdfQ.C3lgGtU5jKwCv1Zz50T1-hjjJbQaq2Z8yxon_KhEciyUig4cb-Whh92htolA62a1qVewySfOSR5q2OBmTGEOAQ'; +export const PRESENTATION_JWT = + 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJ2cCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVQcmVzZW50YXRpb24iXSwidmVyaWZpYWJsZUNyZWRlbnRpYWwiOlsiZXlKaGJHY2lPaUpGWkVSVFFTSXNJblI1Y0NJNklrcFhWQ0o5LmV5SjJZeUk2ZXlKQVkyOXVkR1Y0ZENJNld5Sm9kSFJ3Y3pvdkwzZDNkeTUzTXk1dmNtY3ZNakF4T0M5amNtVmtaVzUwYVdGc2N5OTJNU0lzSW1oMGRIQnpPaTh2YzJOb1pXMWhMbTl5Wnk5elkyaGxiV0V1YW5OdmJteGtJaXdpYUhSMGNITTZMeTkyWlhKaGJXOHVhVzh2WTI5dWRHVjRkSE12Y0hKdlptbHNaUzkyTVNJc0ltaDBkSEJ6T2k4dmR6TnBaQzV2Y21jdmRtTXRjM1JoZEhWekxXeHBjM1F0TWpBeU1TOTJNU0pkTENKMGVYQmxJanBiSWxabGNtbG1hV0ZpYkdWRGNtVmtaVzUwYVdGc0lpd2lVR1Z5YzI5dUlsMHNJbU55WldSbGJuUnBZV3hUZFdKcVpXTjBJanA3SW01aGJXVWlPaUpDYjJJaUxDSm5aVzVrWlhJaU9pSnRZV3hsSW4wc0ltTnlaV1JsYm5ScFlXeFRkR0YwZFhNaU9uc2lhV1FpT2lKb2RIUndjem92TDNKbGMyOXNkbVZ5TG1Ob1pYRmtMbTVsZEM4eExqQXZhV1JsYm5ScFptbGxjbk12Wkdsa09tTm9aWEZrT25SbGMzUnVaWFE2T1RCa05XTXhOREV0TnpJMFppMDBOMkZrTFRsaFpUY3RZVGRqTXpOaE9XVTFOalF6UDNKbGMyOTFjbU5sVG1GdFpUMXpkWE53Wlc1emFXOXVSVzRtY21WemIzVnlZMlZVZVhCbFBWTjBZWFIxYzB4cGMzUXlNREl4VTNWemNHVnVjMmx2YmlNeE16TXpPQ0lzSW5SNWNHVWlPaUpUZEdGMGRYTk1hWE4wTWpBeU1VVnVkSEo1SWl3aWMzUmhkSFZ6VUhWeWNHOXpaU0k2SW5OMWMzQmxibk5wYjI0aUxDSnpkR0YwZFhOTWFYTjBTVzVrWlhnaU9pSXhNek16T0NKOWZTd2ljM1ZpSWpvaVpHbGtPbXRsZVRwNk5rMXJhR0ZZWjBKYVJIWnZkRVJyVERVeU5UZG1ZV2w2ZEdsSGFVTXlVWFJMVEVkd1ltNXVSVWQwWVRKa2Iwc2lMQ0p1WW1ZaU9qRTNNREEwTnpNME1UWXNJbWx6Y3lJNkltUnBaRHBqYUdWeFpEcDBaWE4wYm1WME9qa3daRFZqTVRReExUY3lOR1l0TkRkaFpDMDVZV1UzTFdFM1l6TXpZVGxsTlRZME15SjkuLTE0UmlsMXBaRXkySEVFbzQ4Z1RKcjJ5T3RHeEJoVUdURm16VmRqQXR5aEZSc1c1elpnOW9uSHQ2VjlKUThCYWlZQmxUa1A5R3pUbkotTzZoZGl5Q3ciXX0sIm5iZiI6MTcwMTE3NDQyMiwiaXNzIjoiZGlkOmNoZXFkOnRlc3RuZXQ6OGM3MWU5YjYtYzVhMy00MjUwLThjNTgtZmE1OTE1MzNjZDIyIiwiYXVkIjpbImRpZDpjaGVxZDp0ZXN0bmV0OjRiODQ2ZDBmLTJmNmMtNGFiNi05ZmUyLTViOGRiMzAxYzgzYyJdfQ.C3lgGtU5jKwCv1Zz50T1-hjjJbQaq2Z8yxon_KhEciyUig4cb-Whh92htolA62a1qVewySfOSR5q2OBmTGEOAQ'; export const HOLDER_DID = 'did:cheqd:testnet:8c71e9b6-c5a3-4250-8c58-fa591533cd22'; export const VERIFIER_DID = 'did:cheqd:testnet:4b846d0f-2f6c-4ab6-9fe2-5b8db301c83c'; export const PRESENTATION_OBJECT_CREDENTIAL_JWT = { - '@context': [ - "https://www.w3.org/2018/credentials/v1" - ], - type: ["VerifiablePresentation"], - verifiableCredential: [CREDENTIAL_JWT], - holder: HOLDER_DID, - verifier: [ VERIFIER_DID] , - proof: { - type: JWT_PROOF_TYPE, - jwt: PRESENTATION_JWT - } -} + '@context': ['https://www.w3.org/2018/credentials/v1'], + type: ['VerifiablePresentation'], + verifiableCredential: [CREDENTIAL_JWT], + holder: HOLDER_DID, + verifier: [VERIFIER_DID], + proof: { + type: JWT_PROOF_TYPE, + jwt: PRESENTATION_JWT, + }, +}; export const PRESENTATION_OBJECT_CREDENTIAL_OBJECT = { - '@context': [ - "https://www.w3.org/2018/credentials/v1" - ], - type: ["VerifiablePresentation"], - verifiableCredential: [CREDENTIAL_OBJECT], - holder: HOLDER_DID, - verifier: [ VERIFIER_DID] , - proof: { - type: JWT_PROOF_TYPE, - jwt: PRESENTATION_JWT - } -} \ No newline at end of file + '@context': ['https://www.w3.org/2018/credentials/v1'], + type: ['VerifiablePresentation'], + verifiableCredential: [CREDENTIAL_OBJECT], + holder: HOLDER_DID, + verifier: [VERIFIER_DID], + proof: { + type: JWT_PROOF_TYPE, + jwt: PRESENTATION_JWT, + }, +}; diff --git a/src/test/credential/credential.cheqd.test.ts b/src/test/credential/credential.cheqd.test.ts index 082a1bcd..9c07e5ad 100644 --- a/src/test/credential/credential.cheqd.test.ts +++ b/src/test/credential/credential.cheqd.test.ts @@ -1,97 +1,99 @@ -import { describe, it } from "@jest/globals"; -import { CheqdW3CVerifiableCredential } from "../../services/w3c_credential.js"; -import { expect } from "@playwright/test"; -import { JWT_PROOF_TYPE } from "../../types/constants.js"; -import { CREDENTIAL_JWT, CREDENTIAL_OBJECT, CREDENTIAL_STATUS_ID, CREDENTIAL_SUBJECT_ID, ISSUER_DID } from "../constants.js"; +import { describe, it } from '@jest/globals'; +import { CheqdW3CVerifiableCredential } from '../../services/w3c_credential.js'; +import { expect } from '@playwright/test'; +import { JWT_PROOF_TYPE } from '../../types/constants.js'; +import { + CREDENTIAL_JWT, + CREDENTIAL_OBJECT, + CREDENTIAL_STATUS_ID, + CREDENTIAL_SUBJECT_ID, + ISSUER_DID, +} from '../constants.js'; describe('Credential from JWT to object', () => { - const credential = new CheqdW3CVerifiableCredential(CREDENTIAL_JWT); + const credential = new CheqdW3CVerifiableCredential(CREDENTIAL_JWT); - it('should have a proof', () => { - expect(credential.proof).toBeDefined(); - expect(credential.proof.jwt).toEqual(CREDENTIAL_JWT); - expect(credential.proof.type).toEqual(JWT_PROOF_TYPE); - }) + it('should have a proof', () => { + expect(credential.proof).toBeDefined(); + expect(credential.proof.jwt).toEqual(CREDENTIAL_JWT); + expect(credential.proof.type).toEqual(JWT_PROOF_TYPE); + }); - it('should have a type', () => { - expect(credential.type).toBeDefined(); - expect(credential.type).toContain('VerifiableCredential'); - }) - it('should have a context', () => { - expect(credential['@context']).toBeDefined(); - expect(credential['@context']).toContain('https://www.w3.org/2018/credentials/v1'); - }) - it('should have a credentialSubject', () => { - expect(credential.credentialSubject).toBeDefined(); - expect(credential.credentialSubject).toEqual({ - gender: "male", - name: "Bob", - id: CREDENTIAL_SUBJECT_ID - }); - }) - it('should have a credentialStatus', () => { - expect(credential.credentialStatus).toBeDefined(); - expect(credential.credentialStatus).toEqual( - { - id: CREDENTIAL_STATUS_ID, - statusPurpose: "suspension", - statusListIndex: "13338", - type: 'StatusList2021Entry' - } - ); - }) - it('should have an issuer', () => { - expect(credential.issuer).toBeDefined(); - expect(credential.issuer).toEqual(ISSUER_DID); - }) - it('should have an issuanceDate', () => { - expect(credential.issuanceDate).toBeDefined(); - expect(credential.issuanceDate).toEqual('2023-11-20T09:43:36.000Z'); - }) -}) + it('should have a type', () => { + expect(credential.type).toBeDefined(); + expect(credential.type).toContain('VerifiableCredential'); + }); + it('should have a context', () => { + expect(credential['@context']).toBeDefined(); + expect(credential['@context']).toContain('https://www.w3.org/2018/credentials/v1'); + }); + it('should have a credentialSubject', () => { + expect(credential.credentialSubject).toBeDefined(); + expect(credential.credentialSubject).toEqual({ + gender: 'male', + name: 'Bob', + id: CREDENTIAL_SUBJECT_ID, + }); + }); + it('should have a credentialStatus', () => { + expect(credential.credentialStatus).toBeDefined(); + expect(credential.credentialStatus).toEqual({ + id: CREDENTIAL_STATUS_ID, + statusPurpose: 'suspension', + statusListIndex: '13338', + type: 'StatusList2021Entry', + }); + }); + it('should have an issuer', () => { + expect(credential.issuer).toBeDefined(); + expect(credential.issuer).toEqual(ISSUER_DID); + }); + it('should have an issuanceDate', () => { + expect(credential.issuanceDate).toBeDefined(); + expect(credential.issuanceDate).toEqual('2023-11-20T09:43:36.000Z'); + }); +}); describe('Credential from object ', () => { - const credential = new CheqdW3CVerifiableCredential(CREDENTIAL_OBJECT); - - it('should have a proof', () => { - expect(credential.proof).toBeDefined(); - expect(credential.proof.jwt).toEqual(CREDENTIAL_JWT); - expect(credential.proof.type).toEqual(JWT_PROOF_TYPE); - }) + const credential = new CheqdW3CVerifiableCredential(CREDENTIAL_OBJECT); - it('should have a type', () => { - expect(credential.type).toBeDefined(); - expect(credential.type).toContain('VerifiableCredential'); - }) - it('should have a context', () => { - expect(credential['@context']).toBeDefined(); - expect(credential['@context']).toContain('https://www.w3.org/2018/credentials/v1'); - }) - it('should have a credentialSubject', () => { - expect(credential.credentialSubject).toBeDefined(); - expect(credential.credentialSubject).toEqual({ - gender: "male", - name: "Bob", - id: CREDENTIAL_SUBJECT_ID - }); - }) - it('should have a credentialStatus', () => { - expect(credential.credentialStatus).toBeDefined(); - expect(credential.credentialStatus).toEqual( - { - id: CREDENTIAL_STATUS_ID, - statusPurpose: "suspension", - statusListIndex: "13338", - type: 'StatusList2021Entry' - } - ); - }) - it('should have an issuer', () => { - expect(credential.issuer).toBeDefined(); - expect(credential.issuer).toEqual(ISSUER_DID); - }) - it('should have an issuanceDate', () => { - expect(credential.issuanceDate).toBeDefined(); - expect(credential.issuanceDate).toEqual('2023-06-08T13:49:28.000Z'); - }) -}) \ No newline at end of file + it('should have a proof', () => { + expect(credential.proof).toBeDefined(); + expect(credential.proof.jwt).toEqual(CREDENTIAL_JWT); + expect(credential.proof.type).toEqual(JWT_PROOF_TYPE); + }); + + it('should have a type', () => { + expect(credential.type).toBeDefined(); + expect(credential.type).toContain('VerifiableCredential'); + }); + it('should have a context', () => { + expect(credential['@context']).toBeDefined(); + expect(credential['@context']).toContain('https://www.w3.org/2018/credentials/v1'); + }); + it('should have a credentialSubject', () => { + expect(credential.credentialSubject).toBeDefined(); + expect(credential.credentialSubject).toEqual({ + gender: 'male', + name: 'Bob', + id: CREDENTIAL_SUBJECT_ID, + }); + }); + it('should have a credentialStatus', () => { + expect(credential.credentialStatus).toBeDefined(); + expect(credential.credentialStatus).toEqual({ + id: CREDENTIAL_STATUS_ID, + statusPurpose: 'suspension', + statusListIndex: '13338', + type: 'StatusList2021Entry', + }); + }); + it('should have an issuer', () => { + expect(credential.issuer).toBeDefined(); + expect(credential.issuer).toEqual(ISSUER_DID); + }); + it('should have an issuanceDate', () => { + expect(credential.issuanceDate).toBeDefined(); + expect(credential.issuanceDate).toEqual('2023-06-08T13:49:28.000Z'); + }); +}); diff --git a/src/test/presentation/presentation.cheqd.test.ts b/src/test/presentation/presentation.cheqd.test.ts index 498509b3..dcd2cf4c 100644 --- a/src/test/presentation/presentation.cheqd.test.ts +++ b/src/test/presentation/presentation.cheqd.test.ts @@ -1,106 +1,117 @@ -import { describe, it } from "@jest/globals"; -import { CheqdW3CVerifiableCredential } from "../../services/w3c_credential.js"; -import { expect } from "@playwright/test"; -import { JWT_PROOF_TYPE } from "../../types/constants.js"; -import { CheqdW3CVerifiablePresentation } from "../../services/w3c_presentation.js"; -import type { W3CVerifiablePresentation } from "@veramo/core"; -import { CREDENTIAL_JWT, HOLDER_DID, PRESENTATION_JWT, PRESENTATION_OBJECT_CREDENTIAL_JWT, VERIFIER_DID, PRESENTATION_OBJECT_CREDENTIAL_OBJECT, CREDENTIAL_OBJECT } from "../constants.js"; +import { describe, it } from '@jest/globals'; +import { CheqdW3CVerifiableCredential } from '../../services/w3c_credential.js'; +import { expect } from '@playwright/test'; +import { JWT_PROOF_TYPE } from '../../types/constants.js'; +import { CheqdW3CVerifiablePresentation } from '../../services/w3c_presentation.js'; +import type { W3CVerifiablePresentation } from '@veramo/core'; +import { + CREDENTIAL_JWT, + HOLDER_DID, + PRESENTATION_JWT, + PRESENTATION_OBJECT_CREDENTIAL_JWT, + VERIFIER_DID, + PRESENTATION_OBJECT_CREDENTIAL_OBJECT, + CREDENTIAL_OBJECT, +} from '../constants.js'; describe('Presentation from JWT to object', () => { - const presentation = new CheqdW3CVerifiablePresentation(PRESENTATION_JWT); - - it('should have a proof', () => { - expect(presentation.proof).toBeDefined(); - expect(presentation.proof.jwt).toEqual(PRESENTATION_JWT); - expect(presentation.proof.type).toEqual(JWT_PROOF_TYPE); - }) + const presentation = new CheqdW3CVerifiablePresentation(PRESENTATION_JWT); - it('should have a type', () => { - expect(presentation.type).toBeDefined(); - expect(presentation.type).toContain('VerifiablePresentation'); - }) + it('should have a proof', () => { + expect(presentation.proof).toBeDefined(); + expect(presentation.proof.jwt).toEqual(PRESENTATION_JWT); + expect(presentation.proof.type).toEqual(JWT_PROOF_TYPE); + }); - it('should have holder', () => { - expect(presentation.holder).toBeDefined(); - expect(presentation.holder).toEqual(HOLDER_DID); - }) + it('should have a type', () => { + expect(presentation.type).toBeDefined(); + expect(presentation.type).toContain('VerifiablePresentation'); + }); - it('should have verifier', () => { - expect(presentation.verifier).toBeDefined(); - expect(presentation.verifier).toEqual([VERIFIER_DID]); - }) - it('should have issuanceDate', () => { - expect(presentation.issuanceDate).toBeDefined(); - expect(presentation.issuanceDate).toEqual('2023-11-28T12:27:02.000Z'); - }) - it('should have verifiableCredential', () => { - expect(presentation.verifiableCredential).toBeDefined(); - expect(presentation.verifiableCredential).toHaveLength(1); - if (presentation.verifiableCredential) { - expect(presentation.verifiableCredential[0]).toEqual(new CheqdW3CVerifiableCredential(CREDENTIAL_JWT)); - } - }) + it('should have holder', () => { + expect(presentation.holder).toBeDefined(); + expect(presentation.holder).toEqual(HOLDER_DID); + }); + it('should have verifier', () => { + expect(presentation.verifier).toBeDefined(); + expect(presentation.verifier).toEqual([VERIFIER_DID]); + }); + it('should have issuanceDate', () => { + expect(presentation.issuanceDate).toBeDefined(); + expect(presentation.issuanceDate).toEqual('2023-11-28T12:27:02.000Z'); + }); + it('should have verifiableCredential', () => { + expect(presentation.verifiableCredential).toBeDefined(); + expect(presentation.verifiableCredential).toHaveLength(1); + if (presentation.verifiableCredential) { + expect(presentation.verifiableCredential[0]).toEqual(new CheqdW3CVerifiableCredential(CREDENTIAL_JWT)); + } + }); }); describe('Presentation from object with credential as JWT', () => { - const presentation = new CheqdW3CVerifiablePresentation(PRESENTATION_OBJECT_CREDENTIAL_JWT as W3CVerifiablePresentation); - it('should have a proof', () => { - expect(presentation.proof).toBeDefined(); - expect(presentation.proof.jwt).toEqual(PRESENTATION_JWT); - expect(presentation.proof.type).toEqual(JWT_PROOF_TYPE); - }); + const presentation = new CheqdW3CVerifiablePresentation( + PRESENTATION_OBJECT_CREDENTIAL_JWT as W3CVerifiablePresentation + ); + it('should have a proof', () => { + expect(presentation.proof).toBeDefined(); + expect(presentation.proof.jwt).toEqual(PRESENTATION_JWT); + expect(presentation.proof.type).toEqual(JWT_PROOF_TYPE); + }); - it('should have a type', () => { - expect(presentation.type).toBeDefined(); - expect(presentation.type).toContain('VerifiablePresentation'); - }) + it('should have a type', () => { + expect(presentation.type).toBeDefined(); + expect(presentation.type).toContain('VerifiablePresentation'); + }); - it('should have holder', () => { - expect(presentation.holder).toBeDefined(); - expect(presentation.holder).toEqual(HOLDER_DID); - }) + it('should have holder', () => { + expect(presentation.holder).toBeDefined(); + expect(presentation.holder).toEqual(HOLDER_DID); + }); - it('should have verifier', () => { - expect(presentation.verifier).toBeDefined(); - expect(presentation.verifier).toEqual([VERIFIER_DID]); - }) - it('should have verifiableCredential', () => { - expect(presentation.verifiableCredential).toBeDefined(); - expect(presentation.verifiableCredential).toHaveLength(1); - if (presentation.verifiableCredential) { - expect(presentation.verifiableCredential[0]).toEqual(new CheqdW3CVerifiableCredential(CREDENTIAL_JWT)); - } - }) + it('should have verifier', () => { + expect(presentation.verifier).toBeDefined(); + expect(presentation.verifier).toEqual([VERIFIER_DID]); + }); + it('should have verifiableCredential', () => { + expect(presentation.verifiableCredential).toBeDefined(); + expect(presentation.verifiableCredential).toHaveLength(1); + if (presentation.verifiableCredential) { + expect(presentation.verifiableCredential[0]).toEqual(new CheqdW3CVerifiableCredential(CREDENTIAL_JWT)); + } + }); }); describe('Presentation from object with credential as object', () => { - const presentation = new CheqdW3CVerifiablePresentation(PRESENTATION_OBJECT_CREDENTIAL_OBJECT as W3CVerifiablePresentation); - it('should have a proof', () => { - expect(presentation.proof).toBeDefined(); - expect(presentation.proof.jwt).toEqual(PRESENTATION_JWT); - expect(presentation.proof.type).toEqual(JWT_PROOF_TYPE); - }); + const presentation = new CheqdW3CVerifiablePresentation( + PRESENTATION_OBJECT_CREDENTIAL_OBJECT as W3CVerifiablePresentation + ); + it('should have a proof', () => { + expect(presentation.proof).toBeDefined(); + expect(presentation.proof.jwt).toEqual(PRESENTATION_JWT); + expect(presentation.proof.type).toEqual(JWT_PROOF_TYPE); + }); - it('should have a type', () => { - expect(presentation.type).toBeDefined(); - expect(presentation.type).toContain('VerifiablePresentation'); - }) + it('should have a type', () => { + expect(presentation.type).toBeDefined(); + expect(presentation.type).toContain('VerifiablePresentation'); + }); - it('should have holder', () => { - expect(presentation.holder).toBeDefined(); - expect(presentation.holder).toEqual(HOLDER_DID); - }) + it('should have holder', () => { + expect(presentation.holder).toBeDefined(); + expect(presentation.holder).toEqual(HOLDER_DID); + }); - it('should have verifier', () => { - expect(presentation.verifier).toBeDefined(); - expect(presentation.verifier).toEqual([VERIFIER_DID]); - }) - it('should have verifiableCredential', () => { - expect(presentation.verifiableCredential).toBeDefined(); - expect(presentation.verifiableCredential).toHaveLength(1); - if (presentation.verifiableCredential) { - expect(presentation.verifiableCredential[0]).toEqual(new CheqdW3CVerifiableCredential(CREDENTIAL_OBJECT)); - } - }) -}) \ No newline at end of file + it('should have verifier', () => { + expect(presentation.verifier).toBeDefined(); + expect(presentation.verifier).toEqual([VERIFIER_DID]); + }); + it('should have verifiableCredential', () => { + expect(presentation.verifiableCredential).toBeDefined(); + expect(presentation.verifiableCredential).toHaveLength(1); + if (presentation.verifiableCredential) { + expect(presentation.verifiableCredential[0]).toEqual(new CheqdW3CVerifiableCredential(CREDENTIAL_OBJECT)); + } + }); +}); diff --git a/src/types/shared.ts b/src/types/shared.ts index cfd36232..5111f6cc 100644 --- a/src/types/shared.ts +++ b/src/types/shared.ts @@ -201,7 +201,7 @@ export type CheckStatusListUnsuccessfulResponseBody = { export type VerifyPresentationResponseBody = { verified: false; error: string; -} +}; export type SearchStatusListQuery = { did: string; diff --git a/src/types/verida.ts b/src/types/verida.ts index 028f39c4..1fa5cc84 100644 --- a/src/types/verida.ts +++ b/src/types/verida.ts @@ -1,23 +1,23 @@ /** Structure of the record stored on the Verida Network */ export interface DataRecord { - /** Name/Title of the record, for instance used while browsing the UI. Optional. */ - name?: string; - /** A summary of the data, could be displayed in the UI. Optional. */ - summary?: string; - /** The schema of the record, For Credential data, it will be the Credential schema. Required. */ - schema: string; - /** Any specific attributes of the record. These are following the schema mentioned above. */ - [key: string]: unknown; + /** Name/Title of the record, for instance used while browsing the UI. Optional. */ + name?: string; + /** A summary of the data, could be displayed in the UI. Optional. */ + summary?: string; + /** The schema of the record, For Credential data, it will be the Credential schema. Required. */ + schema: string; + /** Any specific attributes of the record. These are following the schema mentioned above. */ + [key: string]: unknown; } /** Structure of a Credential record stored on the Verida Network. */ export interface CredentialDataRecord extends DataRecord { - /** Name is mandatory */ - name: string; - /** DID JWT of this credential */ - didJwtVc: string; - /** Schema of the DID-JWT Verifiable Credential */ - credentialSchema: string; - /** Data included in the DID-JWT Verifiable Credential */ - credentialData: object; + /** Name is mandatory */ + name: string; + /** DID JWT of this credential */ + didJwtVc: string; + /** Schema of the DID-JWT Verifiable Credential */ + credentialSchema: string; + /** Data included in the DID-JWT Verifiable Credential */ + credentialData: object; } diff --git a/tests/constants.ts b/tests/constants.ts index 8c43d54a..861275bf 100644 --- a/tests/constants.ts +++ b/tests/constants.ts @@ -1,53 +1,52 @@ -export const STORAGE_STATE_AUTHENTICATED = "playwright/.auth/user.json"; -export const STORAGE_STATE_UNAUTHENTICATED = "playwright/.auth/stranger.json"; +export const STORAGE_STATE_AUTHENTICATED = 'playwright/.auth/user.json'; +export const STORAGE_STATE_UNAUTHENTICATED = 'playwright/.auth/stranger.json'; -const PAYLOAD_BASE_PATH = "./tests/payloads"; +const PAYLOAD_BASE_PATH = './tests/payloads'; export enum PAYLOADS_PATH { DID = `${PAYLOAD_BASE_PATH}/did`, RESOURCE = `${PAYLOAD_BASE_PATH}/resource`, CREDENTIAL = `${PAYLOAD_BASE_PATH}/credential`, - CREDENTIAL_STATUS = `${PAYLOAD_BASE_PATH}/credential-status` -}; + CREDENTIAL_STATUS = `${PAYLOAD_BASE_PATH}/credential-status`, +} -const GENERATED_BASE_PATH = "./tests/generated"; +const GENERATED_BASE_PATH = './tests/generated'; export enum GENERATED_PATH { CREDENTIAL = `${GENERATED_BASE_PATH}/credential`, } export enum CONTENT_TYPE { - APPLICATION_JSON = "application/json", - APPLICATION_DID_LD_JSON = "application/did+ld+json" -}; + APPLICATION_JSON = 'application/json', + APPLICATION_DID_LD_JSON = 'application/did+ld+json', +} -export const DID_METHOD = "cheqd"; -export const DID_NOT_FOUND_ERROR = "notFound"; +export const DID_METHOD = 'cheqd'; +export const DID_NOT_FOUND_ERROR = 'notFound'; export const DEFAULT_MAINNET_DID = 'did:cheqd:mainnet:7c950b5d-dbbb-4a12-9d79-6b553ca0c271'; export const DEFAULT_TESTNET_DID = 'did:cheqd:testnet:0c3581f0-011f-4263-b1ca-15ad70d54ede'; -export const DEFAULT_TESTNET_DID_IDENTIFIER = "0c3581f0-011f-4263-b1ca-15ad70d54ede"; -export const DEFAULT_TESTNET_DID_RESOURCE_ID = "1a79a313-8fc3-421c-af3d-34730fa046d1"; +export const DEFAULT_TESTNET_DID_IDENTIFIER = '0c3581f0-011f-4263-b1ca-15ad70d54ede'; +export const DEFAULT_TESTNET_DID_RESOURCE_ID = '1a79a313-8fc3-421c-af3d-34730fa046d1'; -export const TESTNET_DID_WITH_JSON_RESOURCE = "did:cheqd:testnet:c69d7867-be90-4dea-8bbf-f4419d3599d8"; -export const TESTNET_DID_WITH_JSON_RESOURCE_ID = "3194b5a6-1b73-44a0-8ccf-27dc01509eb2"; +export const TESTNET_DID_WITH_JSON_RESOURCE = 'did:cheqd:testnet:c69d7867-be90-4dea-8bbf-f4419d3599d8'; +export const TESTNET_DID_WITH_JSON_RESOURCE_ID = '3194b5a6-1b73-44a0-8ccf-27dc01509eb2'; -export const TESTNET_DID_WITH_IMAGE_RESOURCE = "did:cheqd:testnet:55dbc8bf-fba3-4117-855c-1e0dc1d3bb47"; -export const TESTNET_DID_WITH_IMAGE_RESOURCE_ID = "3a84b9fc-2c2b-4065-86d6-58bc462284d8"; +export const TESTNET_DID_WITH_IMAGE_RESOURCE = 'did:cheqd:testnet:55dbc8bf-fba3-4117-855c-1e0dc1d3bb47'; +export const TESTNET_DID_WITH_IMAGE_RESOURCE_ID = '3a84b9fc-2c2b-4065-86d6-58bc462284d8'; -export const TESTNET_DID_FRAGMENT = "key-1"; +export const TESTNET_DID_FRAGMENT = 'key-1'; export const TESTNET_RESOURCE_JSON = '{"data": "Hello World"}'; -export const NOT_EXISTENT_TESTNET_DID = "did:cheqd:testnet:d4a13003-0bc5-4608-b23a-54ea90fe9f91"; -export const NOT_EXISTENT_RESOURCE_ID = "ff0a6502-03bf-422d-9a91-ad0a3755f3ff"; -export const NOT_EXISTENT_STATUS_LIST_NAME = "not-exist-status-list-name"; -export const NOT_EXISTENT_TESTNET_DID_IDENTIFIER = "d4a13003-0bc5-4608-b23a-54ea90fe9f91"; - +export const NOT_EXISTENT_TESTNET_DID = 'did:cheqd:testnet:d4a13003-0bc5-4608-b23a-54ea90fe9f91'; +export const NOT_EXISTENT_RESOURCE_ID = 'ff0a6502-03bf-422d-9a91-ad0a3755f3ff'; +export const NOT_EXISTENT_STATUS_LIST_NAME = 'not-exist-status-list-name'; +export const NOT_EXISTENT_TESTNET_DID_IDENTIFIER = 'd4a13003-0bc5-4608-b23a-54ea90fe9f91'; // Credential status list names export const DEFAULT_STATUS_LIST_ENCRYPTED_NAME = 'cheqd-employee-credentials-encrypted'; export const DEFAULT_STATUS_LIST_UNENCRYPTED_NAME = 'cheqd-employee-credentials-unencrypted'; export const DEFAULT_STATUS_LIST_PAYMENT_ADDRESS = 'cheqd1qs0nhyk868c246defezhz5eymlt0dmajna2csg'; export const DEFAULT_STATUS_LIST_INDICES = [10, 3199, 12109, 130999]; -export const DEFAULT_STATUS_LIST_NAME = "cheqd-employee-credentials" +export const DEFAULT_STATUS_LIST_NAME = 'cheqd-employee-credentials'; // Credential names export const DEFAULT_SUBJECT_DID = 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK'; @@ -56,7 +55,7 @@ export const DEFAULT_SUBJECT_DID = 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLG export const DEFAULT_DOES_NOT_HAVE_PERMISSIONS = 'Unauthorized error: Your account is not authorized to carry out this action.'; -export const INVALID_JWT_TOKEN = "invalid_jwt_token"; +export const INVALID_JWT_TOKEN = 'invalid_jwt_token'; export const DEFAULT_CONTEXT = 'https://www.w3.org/ns/did/v1'; export const NOT_EXISTENT_KEY = '88888888888895e01f3d98fcec8ccc7861a030b317d4326b0e48a88888888888'; diff --git a/tests/credential-status/check.spec.ts b/tests/credential-status/check.spec.ts index 4c0af8f0..c1967456 100644 --- a/tests/credential-status/check.spec.ts +++ b/tests/credential-status/check.spec.ts @@ -1,79 +1,84 @@ import { - DEFAULT_TESTNET_DID, - CONTENT_TYPE, - NOT_EXISTENT_TESTNET_DID, - NOT_EXISTENT_STATUS_LIST_NAME, - DEFAULT_STATUS_LIST_UNENCRYPTED_NAME, - STORAGE_STATE_AUTHENTICATED + DEFAULT_TESTNET_DID, + CONTENT_TYPE, + NOT_EXISTENT_TESTNET_DID, + NOT_EXISTENT_STATUS_LIST_NAME, + DEFAULT_STATUS_LIST_UNENCRYPTED_NAME, + STORAGE_STATE_AUTHENTICATED, } from '../constants'; import { test, expect } from '@playwright/test'; import { StatusCodes } from 'http-status-codes'; - test.use({ storageState: STORAGE_STATE_AUTHENTICATED }); -test('[Positive] It can check an unencrypted status-list with an existent body and statusPurpose=revocation parameter', async ({ request }) => { - const response = await request.post('/credential-status/check?statusPurpose=revocation', { - data: { - did: DEFAULT_TESTNET_DID, - index: 10, - statusListName: DEFAULT_STATUS_LIST_UNENCRYPTED_NAME, - }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); +test('[Positive] It can check an unencrypted status-list with an existent body and statusPurpose=revocation parameter', async ({ + request, +}) => { + const response = await request.post('/credential-status/check?statusPurpose=revocation', { + data: { + did: DEFAULT_TESTNET_DID, + index: 10, + statusListName: DEFAULT_STATUS_LIST_UNENCRYPTED_NAME, + }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); + + expect(response).toBeOK(); - expect(response).toBeOK(); - - const body = await response.json(); - expect(body.revoked).toBe(false); + const body = await response.json(); + expect(body.revoked).toBe(false); }); -test('[Positive] It can check an unencrypted status-list with an existent body and statusPurpose=suspension parameter', async ({ request }) => { - const response = await request.post('/credential-status/check?statusPurpose=suspension', { - data: { - did: DEFAULT_TESTNET_DID, - index: 10, - statusListName: DEFAULT_STATUS_LIST_UNENCRYPTED_NAME, - }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); +test('[Positive] It can check an unencrypted status-list with an existent body and statusPurpose=suspension parameter', async ({ + request, +}) => { + const response = await request.post('/credential-status/check?statusPurpose=suspension', { + data: { + did: DEFAULT_TESTNET_DID, + index: 10, + statusListName: DEFAULT_STATUS_LIST_UNENCRYPTED_NAME, + }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); + + expect(response).toBeOK(); - expect(response).toBeOK(); - - const body = await response.json(); - expect(body.suspended).toBe(false); + const body = await response.json(); + expect(body.suspended).toBe(false); }); test('[Negative] It cannot check credential-status with not existent DID', async ({ request }) => { - const response = await request.post('/credential-status/check?statusPurpose=revocation', { - data: { - did: NOT_EXISTENT_TESTNET_DID, - index: 10, - statusListName: DEFAULT_STATUS_LIST_UNENCRYPTED_NAME, - }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); + const response = await request.post('/credential-status/check?statusPurpose=revocation', { + data: { + did: NOT_EXISTENT_TESTNET_DID, + index: 10, + statusListName: DEFAULT_STATUS_LIST_UNENCRYPTED_NAME, + }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); - expect(response).not.toBeOK(); - expect(response.status()).toBe(StatusCodes.NOT_FOUND); + expect(response).not.toBeOK(); + expect(response.status()).toBe(StatusCodes.NOT_FOUND); - const body = await response.json(); - expect(body.error).toBe(`check: error: status list '${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}' not found`); + const body = await response.json(); + expect(body.error).toBe(`check: error: status list '${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}' not found`); }); -test('[Negative] It cannot check credential-status with an existent DID and not existent statusListName', async ({ request }) => { - const response = await request.post('/credential-status/check?statusPurpose=revocation', { - data: { - did: DEFAULT_TESTNET_DID, - index: 10, - statusListName: NOT_EXISTENT_STATUS_LIST_NAME, - }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); +test('[Negative] It cannot check credential-status with an existent DID and not existent statusListName', async ({ + request, +}) => { + const response = await request.post('/credential-status/check?statusPurpose=revocation', { + data: { + did: DEFAULT_TESTNET_DID, + index: 10, + statusListName: NOT_EXISTENT_STATUS_LIST_NAME, + }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); - expect(response).not.toBeOK(); - expect(response.status()).toBe(StatusCodes.NOT_FOUND); + expect(response).not.toBeOK(); + expect(response.status()).toBe(StatusCodes.NOT_FOUND); - const body = await response.json(); - expect(body.error).toBe(`check: error: status list '${NOT_EXISTENT_STATUS_LIST_NAME}' not found`); + const body = await response.json(); + expect(body.error).toBe(`check: error: status list '${NOT_EXISTENT_STATUS_LIST_NAME}' not found`); }); diff --git a/tests/credential-status/create-encrypted.spec.ts b/tests/credential-status/create-encrypted.spec.ts index 565e55fa..030e24e3 100644 --- a/tests/credential-status/create-encrypted.spec.ts +++ b/tests/credential-status/create-encrypted.spec.ts @@ -2,7 +2,7 @@ import { CONTENT_TYPE, PAYLOADS_PATH, STORAGE_STATE_AUTHENTICATED, - DEFAULT_DOES_NOT_HAVE_PERMISSIONS + DEFAULT_DOES_NOT_HAVE_PERMISSIONS, } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; @@ -10,12 +10,14 @@ import { StatusCodes } from 'http-status-codes'; test.use({ storageState: STORAGE_STATE_AUTHENTICATED }); -test('[Negative] It cannot create an encrypted statusList2021 in mainnet network for user with testnet role', async ({ request }) => { +test('[Negative] It cannot create an encrypted statusList2021 in mainnet network for user with testnet role', async ({ + request, +}) => { const response = await request.post(`/credential-status/create/encrypted`, { data: JSON.parse( fs.readFileSync(`${PAYLOADS_PATH.CREDENTIAL_STATUS}/create-encrypted-without-permissions.json`, 'utf-8') ), - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, }); expect(response).not.toBeOK(); expect(response.status()).toBe(StatusCodes.FORBIDDEN); diff --git a/tests/credential-status/create-unencrypted.spec.ts b/tests/credential-status/create-unencrypted.spec.ts index 116eeeec..7a1de0c9 100644 --- a/tests/credential-status/create-unencrypted.spec.ts +++ b/tests/credential-status/create-unencrypted.spec.ts @@ -2,7 +2,7 @@ import { CONTENT_TYPE, PAYLOADS_PATH, STORAGE_STATE_AUTHENTICATED, - DEFAULT_DOES_NOT_HAVE_PERMISSIONS + DEFAULT_DOES_NOT_HAVE_PERMISSIONS, } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; @@ -10,7 +10,9 @@ import { StatusCodes } from 'http-status-codes'; test.use({ storageState: STORAGE_STATE_AUTHENTICATED }); -test('[Negative] It cannot create an unencrypted statusList2021 in mainnet network for user with testnet role', async ({ request }) => { +test('[Negative] It cannot create an unencrypted statusList2021 in mainnet network for user with testnet role', async ({ + request, +}) => { const response = await request.post(`/credential-status/create/unencrypted`, { data: JSON.parse( fs.readFileSync(`${PAYLOADS_PATH.CREDENTIAL_STATUS}/create-unencrypted-without-permissions.json`, 'utf-8') diff --git a/tests/credential-status/search.no-auth.spec.ts b/tests/credential-status/search.no-auth.spec.ts index 827a91c6..e5794e2a 100644 --- a/tests/credential-status/search.no-auth.spec.ts +++ b/tests/credential-status/search.no-auth.spec.ts @@ -1,91 +1,96 @@ import { - DEFAULT_TESTNET_DID, - INVALID_DID, - NOT_EXISTENT_TESTNET_DID, - NOT_EXISTENT_STATUS_LIST_NAME, - STORAGE_STATE_UNAUTHENTICATED, - DEFAULT_STATUS_LIST_UNENCRYPTED_NAME, - DEFAULT_TESTNET_DID_IDENTIFIER + DEFAULT_TESTNET_DID, + INVALID_DID, + NOT_EXISTENT_TESTNET_DID, + NOT_EXISTENT_STATUS_LIST_NAME, + STORAGE_STATE_UNAUTHENTICATED, + DEFAULT_STATUS_LIST_UNENCRYPTED_NAME, + DEFAULT_TESTNET_DID_IDENTIFIER, } from '../constants'; import { test, expect } from '@playwright/test'; import { StatusCodes } from 'http-status-codes'; - test.use({ storageState: STORAGE_STATE_UNAUTHENTICATED }); -test('[Positive] It can search credential-status with existent DID, statusListName, and statusPurpose=revocation', async ({ request }) => { - const response = await request.get( - '/credential-status/search?' + - `did=${DEFAULT_TESTNET_DID}&` + - 'statusPurpose=revocation&' + - `statusListName=${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}` - ); - expect(response).toBeOK(); - const body = await response.json(); +test('[Positive] It can search credential-status with existent DID, statusListName, and statusPurpose=revocation', async ({ + request, +}) => { + const response = await request.get( + '/credential-status/search?' + + `did=${DEFAULT_TESTNET_DID}&` + + 'statusPurpose=revocation&' + + `statusListName=${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}` + ); + expect(response).toBeOK(); + const body = await response.json(); - expect(body.found).toBe(true); - expect(body.resource).not.toBeNull(); - expect(body.resourceMetadata).not.toBeNull(); - expect(body.resource.StatusList2021.statusPurpose).toBe("revocation"); - expect(body.resource.metadata.encrypted).toBe(false); - expect(body.resourceMetadata.resourceCollectionId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); - expect(body.resourceMetadata.resourceName).toBe(DEFAULT_STATUS_LIST_UNENCRYPTED_NAME); + expect(body.found).toBe(true); + expect(body.resource).not.toBeNull(); + expect(body.resourceMetadata).not.toBeNull(); + expect(body.resource.StatusList2021.statusPurpose).toBe('revocation'); + expect(body.resource.metadata.encrypted).toBe(false); + expect(body.resourceMetadata.resourceCollectionId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); + expect(body.resourceMetadata.resourceName).toBe(DEFAULT_STATUS_LIST_UNENCRYPTED_NAME); }); -test('[Positive] It can search credential-status with existent DID, statusListName, and statusPurpose=suspension', async ({ request }) => { - const response = await request.get( - '/credential-status/search?' + - `did=${DEFAULT_TESTNET_DID}&` + - 'statusPurpose=suspension&' + - `statusListName=${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}`, - ); - expect(response).toBeOK(); - const body = await response.json(); - - expect(body.found).toBe(true); - expect(body.resource).not.toBeNull(); - expect(body.resourceMetadata).not.toBeNull(); - expect(body.resource.StatusList2021.statusPurpose).toBe("suspension"); - expect(body.resource.metadata.encrypted).toBe(false); - expect(body.resourceMetadata.resourceCollectionId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); - expect(body.resourceMetadata.resourceName).toBe(DEFAULT_STATUS_LIST_UNENCRYPTED_NAME); +test('[Positive] It can search credential-status with existent DID, statusListName, and statusPurpose=suspension', async ({ + request, +}) => { + const response = await request.get( + '/credential-status/search?' + + `did=${DEFAULT_TESTNET_DID}&` + + 'statusPurpose=suspension&' + + `statusListName=${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}` + ); + expect(response).toBeOK(); + const body = await response.json(); + + expect(body.found).toBe(true); + expect(body.resource).not.toBeNull(); + expect(body.resourceMetadata).not.toBeNull(); + expect(body.resource.StatusList2021.statusPurpose).toBe('suspension'); + expect(body.resource.metadata.encrypted).toBe(false); + expect(body.resourceMetadata.resourceCollectionId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); + expect(body.resourceMetadata.resourceName).toBe(DEFAULT_STATUS_LIST_UNENCRYPTED_NAME); }); test('[Negative] It cannot search credential-status with not existent DID', async ({ request }) => { - const response = await request.get( - '/credential-status/search?' + - `did=${NOT_EXISTENT_TESTNET_DID}&` + - 'statusPurpose=revocation&' + - `statusListName=${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}` - ); - expect(response.status()).toBe(StatusCodes.NOT_FOUND); - const body = await response.json(); + const response = await request.get( + '/credential-status/search?' + + `did=${NOT_EXISTENT_TESTNET_DID}&` + + 'statusPurpose=revocation&' + + `statusListName=${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}` + ); + expect(response.status()).toBe(StatusCodes.NOT_FOUND); + const body = await response.json(); - expect(body.error).toBe(`search: error: status list '${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}' not found`); + expect(body.error).toBe(`search: error: status list '${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}' not found`); }); test('[Negative] It cannot search credential-status with an invalid DID', async ({ request }) => { - const response = await request.get( - '/credential-status/search?' + - `did=${INVALID_DID}&` + - 'statusPurpose=revocation&' + - `statusListName=${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}` - ); - expect(response.status()).toBe(StatusCodes.BAD_REQUEST); - const body = await response.json(); + const response = await request.get( + '/credential-status/search?' + + `did=${INVALID_DID}&` + + 'statusPurpose=revocation&' + + `statusListName=${DEFAULT_STATUS_LIST_UNENCRYPTED_NAME}` + ); + expect(response.status()).toBe(StatusCodes.BAD_REQUEST); + const body = await response.json(); - expect(body.error).toBe("did: invalid format, should be did:cheqd::"); + expect(body.error).toBe('did: invalid format, should be did:cheqd::'); }); -test('[Negative] It cannot search credential-status with an existent DID an not existed statusListName', async ({ request }) => { - const response = await request.get( - '/credential-status/search?' + - `did=${DEFAULT_TESTNET_DID}&` + - 'statusPurpose=revocation&' + - `statusListName=${NOT_EXISTENT_STATUS_LIST_NAME}` - ); - expect(response.status()).toBe(StatusCodes.NOT_FOUND); - const body = await response.json(); +test('[Negative] It cannot search credential-status with an existent DID an not existed statusListName', async ({ + request, +}) => { + const response = await request.get( + '/credential-status/search?' + + `did=${DEFAULT_TESTNET_DID}&` + + 'statusPurpose=revocation&' + + `statusListName=${NOT_EXISTENT_STATUS_LIST_NAME}` + ); + expect(response.status()).toBe(StatusCodes.NOT_FOUND); + const body = await response.json(); - expect(body.error).toBe(`search: error: status list '${NOT_EXISTENT_STATUS_LIST_NAME}' not found`); + expect(body.error).toBe(`search: error: status list '${NOT_EXISTENT_STATUS_LIST_NAME}' not found`); }); diff --git a/tests/credential-status/update-encrypted.spec.ts b/tests/credential-status/update-encrypted.spec.ts index 6818f25b..d74fb299 100644 --- a/tests/credential-status/update-encrypted.spec.ts +++ b/tests/credential-status/update-encrypted.spec.ts @@ -2,7 +2,7 @@ import { CONTENT_TYPE, PAYLOADS_PATH, STORAGE_STATE_AUTHENTICATED, - DEFAULT_DOES_NOT_HAVE_PERMISSIONS + DEFAULT_DOES_NOT_HAVE_PERMISSIONS, } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; @@ -10,9 +10,13 @@ import { StatusCodes } from 'http-status-codes'; test.use({ storageState: STORAGE_STATE_AUTHENTICATED }); -test('[Negative] It cannot update an encrypted statusList2021 in mainnet network for user with testnet role', async ({ request }) => { +test('[Negative] It cannot update an encrypted statusList2021 in mainnet network for user with testnet role', async ({ + request, +}) => { const response = await request.post(`/credential-status/update/encrypted`, { - data: JSON.parse(fs.readFileSync(`${PAYLOADS_PATH.CREDENTIAL_STATUS}/update-encrypted-without-permissions.json`, 'utf-8')), + data: JSON.parse( + fs.readFileSync(`${PAYLOADS_PATH.CREDENTIAL_STATUS}/update-encrypted-without-permissions.json`, 'utf-8') + ), headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, }); expect(response).not.toBeOK(); diff --git a/tests/credential-status/update-unencrypted.spec.ts b/tests/credential-status/update-unencrypted.spec.ts index de53e940..f1df1e2e 100644 --- a/tests/credential-status/update-unencrypted.spec.ts +++ b/tests/credential-status/update-unencrypted.spec.ts @@ -2,7 +2,7 @@ import { CONTENT_TYPE, PAYLOADS_PATH, STORAGE_STATE_AUTHENTICATED, - DEFAULT_DOES_NOT_HAVE_PERMISSIONS + DEFAULT_DOES_NOT_HAVE_PERMISSIONS, } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; @@ -10,9 +10,13 @@ import { StatusCodes } from 'http-status-codes'; test.use({ storageState: STORAGE_STATE_AUTHENTICATED }); -test('[Negative] It cannot update an unencrypted statusList2021 in mainnet network for user with testnet role', async ({ request }) => { +test('[Negative] It cannot update an unencrypted statusList2021 in mainnet network for user with testnet role', async ({ + request, +}) => { const response = await request.post(`/credential-status/update/unencrypted`, { - data: JSON.parse(fs.readFileSync(`${PAYLOADS_PATH.CREDENTIAL_STATUS}/update-unencrypted-without-permissions.json`, 'utf-8')), + data: JSON.parse( + fs.readFileSync(`${PAYLOADS_PATH.CREDENTIAL_STATUS}/update-unencrypted-without-permissions.json`, 'utf-8') + ), headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, }); expect(response).not.toBeOK(); diff --git a/tests/credential/issue.spec.ts b/tests/credential/issue.spec.ts index 491895b2..13f94d15 100644 --- a/tests/credential/issue.spec.ts +++ b/tests/credential/issue.spec.ts @@ -2,7 +2,7 @@ import { CONTENT_TYPE, PAYLOADS_PATH, STORAGE_STATE_AUTHENTICATED, - DEFAULT_DOES_NOT_HAVE_PERMISSIONS + DEFAULT_DOES_NOT_HAVE_PERMISSIONS, } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; @@ -15,7 +15,7 @@ test('[Negative] It cannot issue credential in mainnet network for user with tes data: JSON.parse( fs.readFileSync(`${PAYLOADS_PATH.CREDENTIAL}/issue-credential-without-permissions.json`, 'utf-8') ), - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, }); expect(response).not.toBeOK(); expect(response.status()).toBe(StatusCodes.FORBIDDEN); diff --git a/tests/credential/reinstate.spec.ts b/tests/credential/reinstate.spec.ts index f5f5d167..21b93367 100644 --- a/tests/credential/reinstate.spec.ts +++ b/tests/credential/reinstate.spec.ts @@ -2,7 +2,7 @@ import { CONTENT_TYPE, PAYLOADS_PATH, STORAGE_STATE_AUTHENTICATED, - DEFAULT_DOES_NOT_HAVE_PERMISSIONS + DEFAULT_DOES_NOT_HAVE_PERMISSIONS, } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; @@ -15,7 +15,7 @@ test('[Negative] It cannot reinstate credential in mainnet network for user with data: JSON.parse( fs.readFileSync(`${PAYLOADS_PATH.CREDENTIAL}/reinstate-credential-without-permissions.json`, 'utf-8') ), - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, }); expect(response).not.toBeOK(); expect(response.status()).toBe(StatusCodes.FORBIDDEN); diff --git a/tests/credential/revoke.spec.ts b/tests/credential/revoke.spec.ts index 8aedfa85..435261c1 100644 --- a/tests/credential/revoke.spec.ts +++ b/tests/credential/revoke.spec.ts @@ -15,7 +15,7 @@ test('[Negative] It cannot revoke credential in mainnet network for user with te data: JSON.parse( fs.readFileSync(`${PAYLOADS_PATH.CREDENTIAL}/revoke-credential-without-permissions.json`, 'utf-8') ), - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, }); expect(response).not.toBeOK(); expect(response.status()).toBe(StatusCodes.FORBIDDEN); diff --git a/tests/credential/suspend.spec.ts b/tests/credential/suspend.spec.ts index c127198a..7014288e 100644 --- a/tests/credential/suspend.spec.ts +++ b/tests/credential/suspend.spec.ts @@ -2,7 +2,7 @@ import { CONTENT_TYPE, PAYLOADS_PATH, STORAGE_STATE_AUTHENTICATED, - DEFAULT_DOES_NOT_HAVE_PERMISSIONS + DEFAULT_DOES_NOT_HAVE_PERMISSIONS, } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; @@ -15,7 +15,7 @@ test('[Negative] It cannot suspend credential in mainnet network for user with t data: JSON.parse( fs.readFileSync(`${PAYLOADS_PATH.CREDENTIAL}/suspend-credential-without-permissions.json`, 'utf-8') ), - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, }); expect(response).not.toBeOK(); expect(response.status()).toBe(StatusCodes.FORBIDDEN); diff --git a/tests/credential/verify.no-auth.spec.ts b/tests/credential/verify.no-auth.spec.ts index dc6e29f3..8a4ca2eb 100644 --- a/tests/credential/verify.no-auth.spec.ts +++ b/tests/credential/verify.no-auth.spec.ts @@ -1,128 +1,134 @@ -import { - CONTENT_TYPE, - INVALID_JWT_TOKEN, - GENERATED_PATH, - STORAGE_STATE_UNAUTHENTICATED -} from '../constants'; +import { CONTENT_TYPE, INVALID_JWT_TOKEN, GENERATED_PATH, STORAGE_STATE_UNAUTHENTICATED } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; import { StatusCodes } from 'http-status-codes'; async function check_verify_response(response: any, issuer: string) { - expect(response).toBeOK(); + expect(response).toBeOK(); - const body = await response.json(); - expect(body.verified).toBe(true); - expect(body.issuer).toBe(issuer); - expect(body.credentialStatus).not.toBeNull(); - expect(body.credentialSubject).not.toBeNull(); + const body = await response.json(); + expect(body.verified).toBe(true); + expect(body.issuer).toBe(issuer); + expect(body.credentialStatus).not.toBeNull(); + expect(body.credentialSubject).not.toBeNull(); } test.use({ storageState: STORAGE_STATE_UNAUTHENTICATED }); test('[Positive] It can verify credential with a valid JWT body', async ({ request }) => { - const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); - const response = await request.post('/credential/verify', { - data: { credential: json.proof.jwt }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); + const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); + const response = await request.post('/credential/verify', { + data: { credential: json.proof.jwt }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); - check_verify_response(response, json.issuer.id); + check_verify_response(response, json.issuer.id); }); test('[Positive] It can verify credential with a valid credential body', async ({ request }) => { - const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); - const response = await request.post('/credential/verify', { - data: { credential: json }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); - - check_verify_response(response, json.issuer.id); + const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); + const response = await request.post('/credential/verify', { + data: { credential: json }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); + + check_verify_response(response, json.issuer.id); }); +test('[Positive] It can verify credential with a valid JWT body and verifyStatus=true query parameter', async ({ + request, +}) => { + const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); + const response = await request.post('/credential/verify?verifyStatus=true', { + data: { credential: json.proof.jwt }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); -test('[Positive] It can verify credential with a valid JWT body and verifyStatus=true query parameter', async ({ request }) => { - const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); - const response = await request.post('/credential/verify?verifyStatus=true', { - data: { credential: json.proof.jwt }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); - - check_verify_response(response, json.issuer.id); + check_verify_response(response, json.issuer.id); }); -test('[Positive] It can verify credential with a valid credential body and verifyStatus=true query parameter', async ({ request }) => { - const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); - const response = await request.post('/credential/verify?verifyStatus=true', { - data: { credential: json.proof.jwt }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); - - check_verify_response(response, json.issuer.id); -}); +test('[Positive] It can verify credential with a valid credential body and verifyStatus=true query parameter', async ({ + request, +}) => { + const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); + const response = await request.post('/credential/verify?verifyStatus=true', { + data: { credential: json.proof.jwt }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); + check_verify_response(response, json.issuer.id); +}); -test('[Positive] It can verify credential with a valid JWT body and fetchRemoteContexts=true query parameter', async ({ request }) => { - const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); - const response = await request.post('/credential/verify?fetchRemoteContexts=true', { - data: { credential: json.proof.jwt }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); +test('[Positive] It can verify credential with a valid JWT body and fetchRemoteContexts=true query parameter', async ({ + request, +}) => { + const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); + const response = await request.post('/credential/verify?fetchRemoteContexts=true', { + data: { credential: json.proof.jwt }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); - check_verify_response(response, json.issuer.id); + check_verify_response(response, json.issuer.id); }); -test('[Positive] It can verify credential with a valid credential body and fetchRemoteContexts=true query parameter', async ({ request }) => { - const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); - const response = await request.post('/credential/verify?fetchRemoteContexts=true', { - data: { credential: json }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); - - check_verify_response(response, json.issuer.id); +test('[Positive] It can verify credential with a valid credential body and fetchRemoteContexts=true query parameter', async ({ + request, +}) => { + const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); + const response = await request.post('/credential/verify?fetchRemoteContexts=true', { + data: { credential: json }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); + + check_verify_response(response, json.issuer.id); }); -test('[Positive] It can verify credential with a valid JWT body, verifyStatus=true, and fetchRemoteContexts=true query parameter', async ({ request }) => { - const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); - const response = await request.post('/credential/verify?verifyStatus=true&fetchRemoteContexts=true', { - data: { credential: json.proof.jwt }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); +test('[Positive] It can verify credential with a valid JWT body, verifyStatus=true, and fetchRemoteContexts=true query parameter', async ({ + request, +}) => { + const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); + const response = await request.post('/credential/verify?verifyStatus=true&fetchRemoteContexts=true', { + data: { credential: json.proof.jwt }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); - check_verify_response(response, json.issuer.id); + check_verify_response(response, json.issuer.id); }); +test('[Positive] It can verify credential with a valid credential body, verifyStatus=true, and fetchRemoteContexts=true query parameter', async ({ + request, +}) => { + const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); + const response = await request.post('/credential/verify?verifyStatus=true&fetchRemoteContexts=true', { + data: { credential: json }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); -test('[Positive] It can verify credential with a valid credential body, verifyStatus=true, and fetchRemoteContexts=true query parameter', async ({ request }) => { - const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/valid_credential.json`, 'utf-8')); - const response = await request.post('/credential/verify?verifyStatus=true&fetchRemoteContexts=true', { - data: { credential: json }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); - - check_verify_response(response, json.issuer.id); + check_verify_response(response, json.issuer.id); }); -test('[Negative] It cannot verify credential with an invalid credential body where credential and JWT are different', async ({ request }) => { - const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/not_valid_credential.json`, 'utf-8')); - const response = await request.post('/credential/verify', { - data: { credential: json }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); - expect(response.status()).toBe(StatusCodes.BAD_REQUEST); - - const body = await response.json(); - expect(body.verified).toBe(false); +test('[Negative] It cannot verify credential with an invalid credential body where credential and JWT are different', async ({ + request, +}) => { + const json = JSON.parse(fs.readFileSync(`${GENERATED_PATH.CREDENTIAL}/not_valid_credential.json`, 'utf-8')); + const response = await request.post('/credential/verify', { + data: { credential: json }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); + expect(response.status()).toBe(StatusCodes.BAD_REQUEST); + + const body = await response.json(); + expect(body.verified).toBe(false); }); test('[Negative] It cannot verify credential with an invalid JWT body', async ({ request }) => { - const response = await request.post('/credential/verify', { - data: { credential: INVALID_JWT_TOKEN }, - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } - }); + const response = await request.post('/credential/verify', { + data: { credential: INVALID_JWT_TOKEN }, + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, + }); - expect(response.status()).toBe(StatusCodes.BAD_REQUEST); + expect(response.status()).toBe(StatusCodes.BAD_REQUEST); - const body = await response.json(); - expect(body.error).toBe("An invalid JWT string"); + const body = await response.json(); + expect(body.error).toBe('An invalid JWT string'); }); diff --git a/tests/did/create.spec.ts b/tests/did/create.spec.ts index b459bd10..c2bfd4ab 100644 --- a/tests/did/create.spec.ts +++ b/tests/did/create.spec.ts @@ -2,7 +2,7 @@ import { CONTENT_TYPE, PAYLOADS_PATH, STORAGE_STATE_AUTHENTICATED, - DEFAULT_DOES_NOT_HAVE_PERMISSIONS + DEFAULT_DOES_NOT_HAVE_PERMISSIONS, } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; @@ -13,7 +13,7 @@ test.use({ storageState: STORAGE_STATE_AUTHENTICATED }); test('[Negative] It cannot create DID in mainnet network for user with testnet role', async ({ request }) => { const response = await request.post(`/did/create`, { data: JSON.parse(fs.readFileSync(`${PAYLOADS_PATH.DID}/did-create-without-permissions.json`, 'utf-8')), - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, }); expect(response).not.toBeOK(); expect(response.status()).toBe(StatusCodes.FORBIDDEN); diff --git a/tests/did/search.no-auth.spec.ts b/tests/did/search.no-auth.spec.ts index 80e6dc7a..5b8fe710 100644 --- a/tests/did/search.no-auth.spec.ts +++ b/tests/did/search.no-auth.spec.ts @@ -1,12 +1,12 @@ import { - DID_METHOD, - DEFAULT_TESTNET_DID, - CONTENT_TYPE, - TESTNET_DID_FRAGMENT, - DEFAULT_TESTNET_DID_IDENTIFIER, - NOT_EXISTENT_TESTNET_DID, - STORAGE_STATE_UNAUTHENTICATED, - DID_NOT_FOUND_ERROR + DID_METHOD, + DEFAULT_TESTNET_DID, + CONTENT_TYPE, + TESTNET_DID_FRAGMENT, + DEFAULT_TESTNET_DID_IDENTIFIER, + NOT_EXISTENT_TESTNET_DID, + STORAGE_STATE_UNAUTHENTICATED, + DID_NOT_FOUND_ERROR, } from '../constants'; import { test, expect } from '@playwright/test'; import { StatusCodes } from 'http-status-codes'; @@ -14,54 +14,54 @@ import { StatusCodes } from 'http-status-codes'; test.use({ storageState: STORAGE_STATE_UNAUTHENTICATED }); test('[Positive] It can search with an existent DID', async ({ request }) => { - const response = await request.get(`/did/search/${DEFAULT_TESTNET_DID}`); + const response = await request.get(`/did/search/${DEFAULT_TESTNET_DID}`); - expect(response).toBeOK(); + expect(response).toBeOK(); - const body = await response.json(); + const body = await response.json(); - expect(body.didResolutionMetadata.contentType).toBe(CONTENT_TYPE.APPLICATION_DID_LD_JSON); - expect(body.didResolutionMetadata.did.didString).toStrictEqual(DEFAULT_TESTNET_DID); - expect(body.didResolutionMetadata.did.methodSpecificId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); - expect(body.didResolutionMetadata.did.method).toBe(DID_METHOD); + expect(body.didResolutionMetadata.contentType).toBe(CONTENT_TYPE.APPLICATION_DID_LD_JSON); + expect(body.didResolutionMetadata.did.didString).toStrictEqual(DEFAULT_TESTNET_DID); + expect(body.didResolutionMetadata.did.methodSpecificId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); + expect(body.didResolutionMetadata.did.method).toBe(DID_METHOD); }); test('[Positive] It can search with an existent DID and metadata=true query parameter', async ({ request }) => { - const response = await request.get(`/did/search/${DEFAULT_TESTNET_DID}?metadata=true`); - expect(response).toBeOK(); + const response = await request.get(`/did/search/${DEFAULT_TESTNET_DID}?metadata=true`); + expect(response).toBeOK(); - const body = await response.json(); + const body = await response.json(); - expect(body.dereferencingMetadata.contentType).toBe(CONTENT_TYPE.APPLICATION_DID_LD_JSON); - expect(body.dereferencingMetadata.did.didString).toStrictEqual(DEFAULT_TESTNET_DID); - expect(body.dereferencingMetadata.did.methodSpecificId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); - expect(body.dereferencingMetadata.did.method).toBe(DID_METHOD); - expect(body.contentMetadata).not.toBeNull(); - expect(body.contentStream).not.toBeNull(); + expect(body.dereferencingMetadata.contentType).toBe(CONTENT_TYPE.APPLICATION_DID_LD_JSON); + expect(body.dereferencingMetadata.did.didString).toStrictEqual(DEFAULT_TESTNET_DID); + expect(body.dereferencingMetadata.did.methodSpecificId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); + expect(body.dereferencingMetadata.did.method).toBe(DID_METHOD); + expect(body.contentMetadata).not.toBeNull(); + expect(body.contentStream).not.toBeNull(); }); test('[Positive] It can search with an existent DID and fragment', async ({ request }) => { - const hashTag = '%23'; - const url = `/did/search/${DEFAULT_TESTNET_DID}${encodeURI(hashTag)}${TESTNET_DID_FRAGMENT}`; - const response = await request.get(url); + const hashTag = '%23'; + const url = `/did/search/${DEFAULT_TESTNET_DID}${encodeURI(hashTag)}${TESTNET_DID_FRAGMENT}`; + const response = await request.get(url); - expect(response).toBeOK(); + expect(response).toBeOK(); - const body = await response.json(); + const body = await response.json(); - expect(body.dereferencingMetadata.contentType).toBe(CONTENT_TYPE.APPLICATION_DID_LD_JSON); - expect(body.dereferencingMetadata.did.didString).toStrictEqual(DEFAULT_TESTNET_DID); - expect(body.dereferencingMetadata.did.methodSpecificId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); - expect(body.dereferencingMetadata.did.method).toBe(DID_METHOD); - expect(body.contentMetadata).not.toBeNull(); - expect(body.contentStream).not.toBeNull(); - expect(body.contentStream.id).toBe(`${DEFAULT_TESTNET_DID}#${TESTNET_DID_FRAGMENT}`); + expect(body.dereferencingMetadata.contentType).toBe(CONTENT_TYPE.APPLICATION_DID_LD_JSON); + expect(body.dereferencingMetadata.did.didString).toStrictEqual(DEFAULT_TESTNET_DID); + expect(body.dereferencingMetadata.did.methodSpecificId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); + expect(body.dereferencingMetadata.did.method).toBe(DID_METHOD); + expect(body.contentMetadata).not.toBeNull(); + expect(body.contentStream).not.toBeNull(); + expect(body.contentStream.id).toBe(`${DEFAULT_TESTNET_DID}#${TESTNET_DID_FRAGMENT}`); }); test('[Negative] It cannot search not existent DID', async ({ request }) => { - const response = await request.get(`/did/search/${NOT_EXISTENT_TESTNET_DID}`); - expect(response.status()).toBe(StatusCodes.NOT_FOUND); + const response = await request.get(`/did/search/${NOT_EXISTENT_TESTNET_DID}`); + expect(response.status()).toBe(StatusCodes.NOT_FOUND); - const body = await response.json(); - expect(body.didResolutionMetadata.error).toBe(DID_NOT_FOUND_ERROR); + const body = await response.json(); + expect(body.didResolutionMetadata.error).toBe(DID_NOT_FOUND_ERROR); }); diff --git a/tests/did/update.spec.ts b/tests/did/update.spec.ts index aa33776b..e5684c79 100644 --- a/tests/did/update.spec.ts +++ b/tests/did/update.spec.ts @@ -2,7 +2,7 @@ import { CONTENT_TYPE, PAYLOADS_PATH, STORAGE_STATE_AUTHENTICATED, - DEFAULT_DOES_NOT_HAVE_PERMISSIONS + DEFAULT_DOES_NOT_HAVE_PERMISSIONS, } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; @@ -13,7 +13,7 @@ test.use({ storageState: STORAGE_STATE_AUTHENTICATED }); test('[Negative] It cannot update DID in mainnet network for user with testnet role', async ({ request }) => { const response = await request.post(`/did/update`, { data: JSON.parse(fs.readFileSync(`${PAYLOADS_PATH.DID}/did-update-without-permissions.json`, 'utf-8')), - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, }); expect(response).not.toBeOK(); expect(response.status()).toBe(StatusCodes.FORBIDDEN); diff --git a/tests/helpers.ts b/tests/helpers.ts index 97af2076..defa4be6 100644 --- a/tests/helpers.ts +++ b/tests/helpers.ts @@ -152,8 +152,7 @@ export const buildSimpleService = ( }; }; - -export async function createDID( request: APIRequestContext, payload): Promise { +export async function createDID(request: APIRequestContext, payload): Promise { const response = await request.post('/did/create', { data: payload, headers: { 'Content-Type': 'application/json' }, @@ -162,4 +161,4 @@ export async function createDID( request: APIRequestContext, payload): Promise { - // Check that current user is really unauthenticated + // Check that current user is really unauthenticated await page.goto(`${process.env.APPLICATION_BASE_URL}/swagger`); await expect(page.getByRole('button', { name: 'Log in' })).toBeVisible(); const response = await page.goto(`${process.env.APPLICATION_BASE_URL}/account`); expect(response.ok()).not.toBe(true); - expect(response.status()).toBe(StatusCodes.UNAUTHORIZED); + expect(response.status()).toBe(StatusCodes.UNAUTHORIZED); // End of authentication steps. await page.context().storageState({ path: STORAGE_STATE_UNAUTHENTICATED }); -}); \ No newline at end of file +}); diff --git a/tests/presentation/verify.negative.spec.ts b/tests/presentation/verify.negative.spec.ts index fb088a62..ff5735f6 100644 --- a/tests/presentation/verify.negative.spec.ts +++ b/tests/presentation/verify.negative.spec.ts @@ -6,48 +6,57 @@ const PAYLOADS_BASE_PATH = './tests/payloads/presentation'; test.use({ storageState: 'playwright/.auth/user.json' }); for (const presentationType of ['jwt', 'object']) { - for (const verifyStatus of [true]) { - test(`[Negative] It should return verify: False. + for (const verifyStatus of [true]) { + test(`[Negative] It should return verify: False. Presenation format is ${presentationType}. Encrypted statusList2021. VerifyStatus: ${verifyStatus}, - makeFeePayments: false`, async ({ - request - }) => { - const verifyRequest = JSON.parse(fs.readFileSync(`${PAYLOADS_BASE_PATH}/verify-negative-${presentationType}-encrypted.json`, 'utf-8')); - verifyRequest.makeFeePayment = false; - const response = await request.post(`/presentation/verify?verifyStatus=${verifyStatus}&fetchRemoteContexts=false&allowDeactivatedDid=false`, { - data: verifyRequest, - headers: { 'Content-Type': 'application/json' }, - }); - expect(response).not.toBeOK(); - expect(response.status()).toBe(StatusCodes.UNAUTHORIZED); - const body = await response.json(); - expect(body.error).toContain("check: error: unauthorised: decryption conditions are not met"); - }); - } + makeFeePayments: false`, async ({ request }) => { + const verifyRequest = JSON.parse( + fs.readFileSync(`${PAYLOADS_BASE_PATH}/verify-negative-${presentationType}-encrypted.json`, 'utf-8') + ); + verifyRequest.makeFeePayment = false; + const response = await request.post( + `/presentation/verify?verifyStatus=${verifyStatus}&fetchRemoteContexts=false&allowDeactivatedDid=false`, + { + data: verifyRequest, + headers: { 'Content-Type': 'application/json' }, + } + ); + expect(response).not.toBeOK(); + expect(response.status()).toBe(StatusCodes.UNAUTHORIZED); + const body = await response.json(); + expect(body.error).toContain('check: error: unauthorised: decryption conditions are not met'); + }); + } } for (const presentationType of ['jwt', 'object']) { - for (const verifyStatus of [true]) { - test(`[Negative] Presentation with 2 credentials. One has encrypted statusList another one - no + for (const verifyStatus of [true]) { + test(`[Negative] Presentation with 2 credentials. One has encrypted statusList another one - no It should return verify: False. Presenation format is ${presentationType}. Encrypted and unencrypted statusList2021. VerifyStatus: ${verifyStatus}, - makeFeePayments: false`, async ({ - request - }) => { - const verifyRequest = JSON.parse(fs.readFileSync(`${PAYLOADS_BASE_PATH}/verify-negative-${presentationType}-un-and-encrypted.json`, 'utf-8')); - verifyRequest.makeFeePayment = false; - const response = await request.post(`/presentation/verify?verifyStatus=${verifyStatus}&fetchRemoteContexts=false&allowDeactivatedDid=false`, { - data: verifyRequest, - headers: { 'Content-Type': 'application/json' }, - }); - expect(response).not.toBeOK(); - expect(response.status()).toBe(StatusCodes.UNAUTHORIZED); - const body = await response.json(); - expect(body.error).toContain("check: error: unauthorised: decryption conditions are not met"); - }); - } + makeFeePayments: false`, async ({ request }) => { + const verifyRequest = JSON.parse( + fs.readFileSync( + `${PAYLOADS_BASE_PATH}/verify-negative-${presentationType}-un-and-encrypted.json`, + 'utf-8' + ) + ); + verifyRequest.makeFeePayment = false; + const response = await request.post( + `/presentation/verify?verifyStatus=${verifyStatus}&fetchRemoteContexts=false&allowDeactivatedDid=false`, + { + data: verifyRequest, + headers: { 'Content-Type': 'application/json' }, + } + ); + expect(response).not.toBeOK(); + expect(response.status()).toBe(StatusCodes.UNAUTHORIZED); + const body = await response.json(); + expect(body.error).toContain('check: error: unauthorised: decryption conditions are not met'); + }); + } } diff --git a/tests/presentation/verify.positive.spec.ts b/tests/presentation/verify.positive.spec.ts index 5ac12c2d..9b5a44ac 100644 --- a/tests/presentation/verify.positive.spec.ts +++ b/tests/presentation/verify.positive.spec.ts @@ -4,78 +4,92 @@ import { test, expect } from '@playwright/test'; const PAYLOADS_BASE_PATH = './tests/payloads/presentation'; test.use({ storageState: 'playwright/.auth/user.json' }); - for (const presentationType of ['jwt', 'object']) { - for (const verifyStatus of [true, false]) { - test(`[Positive] It should return verify: True. + for (const verifyStatus of [true, false]) { + test(`[Positive] It should return verify: True. Presentation format is ${presentationType}. Encrypted statusList2021. VerifyStatus: ${verifyStatus}, - makeFeePayments: true`, async ({ - request - }) => { - const verifyRequest = JSON.parse(fs.readFileSync(`${PAYLOADS_BASE_PATH}/verify-positive-${presentationType}-encrypted.json`, 'utf-8')); - verifyRequest.makeFeePayment = true; - const response = await request.post(`/presentation/verify?verifyStatus=${verifyStatus}&fetchRemoteContexts=false&allowDeactivatedDid=false`, { - data: verifyRequest, - headers: { 'Content-Type': 'application/json' }, - }); - expect(response).toBeOK(); - expect(await response.json()).toEqual( - expect.objectContaining({ - verified: true, - }) - ); - }); - } + makeFeePayments: true`, async ({ request }) => { + const verifyRequest = JSON.parse( + fs.readFileSync(`${PAYLOADS_BASE_PATH}/verify-positive-${presentationType}-encrypted.json`, 'utf-8') + ); + verifyRequest.makeFeePayment = true; + const response = await request.post( + `/presentation/verify?verifyStatus=${verifyStatus}&fetchRemoteContexts=false&allowDeactivatedDid=false`, + { + data: verifyRequest, + headers: { 'Content-Type': 'application/json' }, + } + ); + expect(response).toBeOK(); + expect(await response.json()).toEqual( + expect.objectContaining({ + verified: true, + }) + ); + }); + } } for (const presentationType of ['jwt', 'object']) { - for (const verifyStatus of [true, false]) { - for (const makeFeePayments of [true, false]) { - test(`[Positive] It should return verify: True. + for (const verifyStatus of [true, false]) { + for (const makeFeePayments of [true, false]) { + test(`[Positive] It should return verify: True. Presenation format is ${presentationType}. Uncrypted statusList2021. VerifyStatus: ${verifyStatus}, - makeFeePayments: ${makeFeePayments}`, async ({ - request - }) => { - const verifyRequest = JSON.parse(fs.readFileSync(`${PAYLOADS_BASE_PATH}/verify-positive-${presentationType}-unencrypted.json`, 'utf-8')); - verifyRequest.makeFeePayments = makeFeePayments; - const response = await request.post(`/presentation/verify?verifyStatus=${verifyStatus}&fetchRemoteContexts=false&allowDeactivatedDid=false`, { - data: verifyRequest, - headers: { 'Content-Type': 'application/json' }, - }); - expect(response).toBeOK(); - expect(await response.json()).toEqual( - expect.objectContaining({ - verified: true, - }) - ); - }); - } - } + makeFeePayments: ${makeFeePayments}`, async ({ request }) => { + const verifyRequest = JSON.parse( + fs.readFileSync( + `${PAYLOADS_BASE_PATH}/verify-positive-${presentationType}-unencrypted.json`, + 'utf-8' + ) + ); + verifyRequest.makeFeePayments = makeFeePayments; + const response = await request.post( + `/presentation/verify?verifyStatus=${verifyStatus}&fetchRemoteContexts=false&allowDeactivatedDid=false`, + { + data: verifyRequest, + headers: { 'Content-Type': 'application/json' }, + } + ); + expect(response).toBeOK(); + expect(await response.json()).toEqual( + expect.objectContaining({ + verified: true, + }) + ); + }); + } + } } for (const presentationType of ['jwt', 'object']) { - for (const verifyStatus of [true, false]) { - test(`[Positive] It should return verify: True. + for (const verifyStatus of [true, false]) { + test(`[Positive] It should return verify: True. Presenation format is ${presentationType}. Encrypted and Unencrypted statusList2021. - VerifyStatus: ${verifyStatus}}`, async ({ - request - }) => { - const verifyRequest = JSON.parse(fs.readFileSync(`${PAYLOADS_BASE_PATH}/verify-positive-${presentationType}-un-and-encrypted.json`, 'utf-8')); - const response = await request.post(`/presentation/verify?verifyStatus=${verifyStatus}&fetchRemoteContexts=false&allowDeactivatedDid=false`, { - data: verifyRequest, - headers: { 'Content-Type': 'application/json' }, - }); - expect(response).toBeOK(); - expect(await response.json()).toEqual( - expect.objectContaining({ - verified: true, - }) - ); - }); - } -} \ No newline at end of file + VerifyStatus: ${verifyStatus}}`, async ({ request }) => { + const verifyRequest = JSON.parse( + fs.readFileSync( + `${PAYLOADS_BASE_PATH}/verify-positive-${presentationType}-un-and-encrypted.json`, + 'utf-8' + ) + ); + const response = await request.post( + `/presentation/verify?verifyStatus=${verifyStatus}&fetchRemoteContexts=false&allowDeactivatedDid=false`, + { + data: verifyRequest, + headers: { 'Content-Type': 'application/json' }, + } + ); + expect(response).toBeOK(); + expect(await response.json()).toEqual( + expect.objectContaining({ + verified: true, + }) + ); + }); + } +} diff --git a/tests/resource/create.spec.ts b/tests/resource/create.spec.ts index 193d15d1..73aacec7 100644 --- a/tests/resource/create.spec.ts +++ b/tests/resource/create.spec.ts @@ -3,7 +3,7 @@ import { PAYLOADS_PATH, DEFAULT_MAINNET_DID, STORAGE_STATE_AUTHENTICATED, - DEFAULT_DOES_NOT_HAVE_PERMISSIONS + DEFAULT_DOES_NOT_HAVE_PERMISSIONS, } from '../constants'; import * as fs from 'fs'; import { test, expect } from '@playwright/test'; @@ -14,7 +14,7 @@ test.use({ storageState: STORAGE_STATE_AUTHENTICATED }); test('[Negative] It cannot create resource in mainnet network for user with testnet role', async ({ request }) => { const response = await request.post(`/resource/create/${DEFAULT_MAINNET_DID}`, { data: JSON.parse(fs.readFileSync(`${PAYLOADS_PATH.RESOURCE}/create-without-permissions.json`, 'utf-8')), - headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON } + headers: { 'Content-Type': CONTENT_TYPE.APPLICATION_JSON }, }); expect(response).not.toBeOK(); expect(response.status()).toBe(StatusCodes.FORBIDDEN); diff --git a/tests/resource/search.no-auth.spec.ts b/tests/resource/search.no-auth.spec.ts index 9b3e6128..c7bf3f69 100644 --- a/tests/resource/search.no-auth.spec.ts +++ b/tests/resource/search.no-auth.spec.ts @@ -1,68 +1,76 @@ import { - CONTENT_TYPE, - TESTNET_RESOURCE_JSON, - DEFAULT_TESTNET_DID_IDENTIFIER, - DID_METHOD, DEFAULT_TESTNET_DID, - NOT_EXISTENT_TESTNET_DID, - NOT_EXISTENT_RESOURCE_ID, - NOT_EXISTENT_TESTNET_DID_IDENTIFIER, - DID_NOT_FOUND_ERROR, - TESTNET_DID_WITH_IMAGE_RESOURCE, - TESTNET_DID_WITH_IMAGE_RESOURCE_ID, - TESTNET_DID_WITH_JSON_RESOURCE_ID, - TESTNET_DID_WITH_JSON_RESOURCE + CONTENT_TYPE, + TESTNET_RESOURCE_JSON, + DEFAULT_TESTNET_DID_IDENTIFIER, + DID_METHOD, + DEFAULT_TESTNET_DID, + NOT_EXISTENT_TESTNET_DID, + NOT_EXISTENT_RESOURCE_ID, + NOT_EXISTENT_TESTNET_DID_IDENTIFIER, + DID_NOT_FOUND_ERROR, + TESTNET_DID_WITH_IMAGE_RESOURCE, + TESTNET_DID_WITH_IMAGE_RESOURCE_ID, + TESTNET_DID_WITH_JSON_RESOURCE_ID, + TESTNET_DID_WITH_JSON_RESOURCE, } from '../constants'; import { test, expect } from '@playwright/test'; import { StatusCodes } from 'http-status-codes'; test('[Positive] It can search resource with an existent DID and resourceId. Resource: JSON', async ({ request }) => { - const response = await request.get(`/resource/search/${TESTNET_DID_WITH_JSON_RESOURCE}?resourceId=${TESTNET_DID_WITH_JSON_RESOURCE_ID}`); - expect(response.status()).toBe(StatusCodes.OK); + const response = await request.get( + `/resource/search/${TESTNET_DID_WITH_JSON_RESOURCE}?resourceId=${TESTNET_DID_WITH_JSON_RESOURCE_ID}` + ); + expect(response.status()).toBe(StatusCodes.OK); - const body = (await response.body()).toString(); + const body = (await response.body()).toString(); - expect(body).toEqual(TESTNET_RESOURCE_JSON); - const headers = response.headers(); - expect(headers['content-type']).toBe('application/json; charset=utf-8'); + expect(body).toEqual(TESTNET_RESOURCE_JSON); + const headers = response.headers(); + expect(headers['content-type']).toBe('application/json; charset=utf-8'); }); -test('[Positive] It can search resource with an existent DID and resourceId.Resource is image and MIME type image', async ({ request }) => { - const response = await request.get(`/resource/search/${TESTNET_DID_WITH_IMAGE_RESOURCE}?resourceId=${TESTNET_DID_WITH_IMAGE_RESOURCE_ID}`); - expect(response.status()).toBe(StatusCodes.OK); +test('[Positive] It can search resource with an existent DID and resourceId.Resource is image and MIME type image', async ({ + request, +}) => { + const response = await request.get( + `/resource/search/${TESTNET_DID_WITH_IMAGE_RESOURCE}?resourceId=${TESTNET_DID_WITH_IMAGE_RESOURCE_ID}` + ); + expect(response.status()).toBe(StatusCodes.OK); - const headers = response.headers(); + const headers = response.headers(); - expect(headers['content-type']).toBe('image/png; charset=utf-8'); + expect(headers['content-type']).toBe('image/png; charset=utf-8'); }); -test('[Positive] It can search resource with an existent DID and resourceMetadata=true query parameter', async ({ request }) => { - const response = await request.get(`/resource/search/${DEFAULT_TESTNET_DID}?resourceMetadata=true`); - expect(response.status()).toBe(StatusCodes.OK); +test('[Positive] It can search resource with an existent DID and resourceMetadata=true query parameter', async ({ + request, +}) => { + const response = await request.get(`/resource/search/${DEFAULT_TESTNET_DID}?resourceMetadata=true`); + expect(response.status()).toBe(StatusCodes.OK); - const body = await response.json(); + const body = await response.json(); - expect(body.dereferencingMetadata.contentType).toBe(CONTENT_TYPE.APPLICATION_DID_LD_JSON); - expect(body.dereferencingMetadata.did.didString).toStrictEqual(DEFAULT_TESTNET_DID); - expect(body.dereferencingMetadata.did.methodSpecificId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); - expect(body.dereferencingMetadata.did.method).toBe(DID_METHOD); - expect(body.contentStream).not.toBeNull(); - expect(body.contentMetadata).not.toBeNull(); -}) + expect(body.dereferencingMetadata.contentType).toBe(CONTENT_TYPE.APPLICATION_DID_LD_JSON); + expect(body.dereferencingMetadata.did.didString).toStrictEqual(DEFAULT_TESTNET_DID); + expect(body.dereferencingMetadata.did.methodSpecificId).toBe(DEFAULT_TESTNET_DID_IDENTIFIER); + expect(body.dereferencingMetadata.did.method).toBe(DID_METHOD); + expect(body.contentStream).not.toBeNull(); + expect(body.contentMetadata).not.toBeNull(); +}); test('[Negative] It cannot search not existent {did} and {resourceId}', async ({ request }) => { - const response = await request.get( - `/did/search/${NOT_EXISTENT_TESTNET_DID}?` + - `resourceId=${NOT_EXISTENT_RESOURCE_ID}` - ); - expect(response.status()).toBe(StatusCodes.NOT_FOUND); + const response = await request.get( + `/did/search/${NOT_EXISTENT_TESTNET_DID}?` + `resourceId=${NOT_EXISTENT_RESOURCE_ID}` + ); + expect(response.status()).toBe(StatusCodes.NOT_FOUND); - const body = await response.json(); + const body = await response.json(); - expect(body.dereferencingMetadata.contentType).toBe(CONTENT_TYPE.APPLICATION_DID_LD_JSON); - expect(body.dereferencingMetadata.did.didString).toStrictEqual(NOT_EXISTENT_TESTNET_DID); - expect(body.dereferencingMetadata.did.methodSpecificId).toBe(NOT_EXISTENT_TESTNET_DID_IDENTIFIER); - expect(body.dereferencingMetadata.did.method).toBe(DID_METHOD); - expect(body.dereferencingMetadata.error).toBe(DID_NOT_FOUND_ERROR); - expect(body.contentStream).toBeNull(); - expect(body.contentMetadata).not.toBeNull(); + expect(body.dereferencingMetadata.contentType).toBe(CONTENT_TYPE.APPLICATION_DID_LD_JSON); + expect(body.dereferencingMetadata.did.didString).toStrictEqual(NOT_EXISTENT_TESTNET_DID); + expect(body.dereferencingMetadata.did.methodSpecificId).toBe(NOT_EXISTENT_TESTNET_DID_IDENTIFIER); + expect(body.dereferencingMetadata.did.method).toBe(DID_METHOD); + expect(body.dereferencingMetadata.error).toBe(DID_NOT_FOUND_ERROR); + expect(body.contentStream).toBeNull(); + expect(body.contentMetadata).not.toBeNull(); });