From cbdff28d566e3eaabcb806d9158c62476379b5dd Mon Sep 17 00:00:00 2001 From: NB-MikeRichardson <93971245+NB-MikeRichardson@users.noreply.github.com> Date: Wed, 11 May 2022 15:53:11 +0300 Subject: [PATCH] fix: delete credentials (#766) Signed-off-by: Mike Richardson --- .../modules/credentials/CredentialsModule.ts | 12 ++++-- .../v2credentials.propose-offer.test.ts | 39 +++++++++++++++++-- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/packages/core/src/modules/credentials/CredentialsModule.ts b/packages/core/src/modules/credentials/CredentialsModule.ts index 45c97a12e4..7b1c1d6d53 100644 --- a/packages/core/src/modules/credentials/CredentialsModule.ts +++ b/packages/core/src/modules/credentials/CredentialsModule.ts @@ -1,5 +1,6 @@ import type { AgentMessage } from '../../agent/AgentMessage' import type { Logger } from '../../logger' +import type { DeleteCredentialOptions } from './CredentialServiceOptions' import type { AcceptOfferOptions, AcceptProposalOptions, @@ -62,7 +63,7 @@ export interface CredentialsModule { getAll(): Promise getById(credentialRecordId: string): Promise findById(credentialRecordId: string): Promise - deleteById(credentialRecordId: string): Promise + deleteById(credentialRecordId: string, options?: DeleteCredentialOptions): Promise } @scoped(Lifecycle.ContainerScoped) @@ -501,14 +502,17 @@ export class CredentialsModule implements CredentialsModule { public findById(credentialRecordId: string): Promise { return this.credentialRepository.findById(credentialRecordId) } + /** - * Delete a credential record by id + * Delete a credential record by id, also calls service to delete from wallet * * @param credentialId the credential record id + * @param options the delete credential options for the delete operation */ - public async deleteById(credentialId: string) { + public async deleteById(credentialId: string, options?: DeleteCredentialOptions) { const credentialRecord = await this.getById(credentialId) - return this.credentialRepository.delete(credentialRecord) + const service = this.getService(credentialRecord.protocolVersion) + return service.deleteById(credentialId, options) } /** diff --git a/packages/core/src/modules/credentials/protocol/v2/__tests__/v2credentials.propose-offer.test.ts b/packages/core/src/modules/credentials/protocol/v2/__tests__/v2credentials.propose-offer.test.ts index c93f0e5a40..9cb9bbebcd 100644 --- a/packages/core/src/modules/credentials/protocol/v2/__tests__/v2credentials.propose-offer.test.ts +++ b/packages/core/src/modules/credentials/protocol/v2/__tests__/v2credentials.propose-offer.test.ts @@ -12,10 +12,11 @@ import type { } from '../../../CredentialsModuleOptions' import type { CredPropose } from '../../../formats/models/CredPropose' -import { AriesFrameworkError } from '../../../../../../src/error/AriesFrameworkError' -import { DidCommMessageRepository } from '../../../../../../src/storage' -import { setupCredentialTests, waitForCredentialRecord } from '../../../../../../tests/helpers' +import { issueCredential, setupCredentialTests, waitForCredentialRecord } from '../../../../../../tests/helpers' import testLogger from '../../../../../../tests/logger' +import { AriesFrameworkError } from '../../../../../error/AriesFrameworkError' +import { IndyHolderService } from '../../../../../modules/indy/services/IndyHolderService' +import { DidCommMessageRepository } from '../../../../../storage' import { JsonTransformer } from '../../../../../utils' import { CredentialProtocolVersion } from '../../../CredentialProtocolVersion' import { CredentialState } from '../../../CredentialState' @@ -381,6 +382,38 @@ describe('credentials', () => { } }) + test('Faber Issues Credential which is then deleted from Alice`s wallet', async () => { + const credentialPreview = V2CredentialPreview.fromRecord({ + name: 'John', + age: '99', + 'x-ray': 'some x-ray', + profile_picture: 'profile picture', + }) + + const { holderCredential } = await issueCredential({ + issuerAgent: faberAgent, + issuerConnectionId: faberConnection.id, + holderAgent: aliceAgent, + credentialTemplate: { + credentialDefinitionId: credDefId, + comment: 'some comment about credential', + preview: credentialPreview, + }, + }) + // test that delete credential removes from both repository and wallet + // latter is tested by spying on holder service (Indy) to + // see if deleteCredential is called + const holderService = aliceAgent.injectionContainer.resolve(IndyHolderService) + + const deleteCredentialSpy = jest.spyOn(holderService, 'deleteCredential') + await aliceAgent.credentials.deleteById(holderCredential.id, { deleteAssociatedCredentials: true }) + expect(deleteCredentialSpy).toHaveBeenCalledTimes(1) + + return expect(aliceAgent.credentials.getById(holderCredential.id)).rejects.toThrowError( + `CredentialRecord: record with id ${holderCredential.id} not found.` + ) + }) + test('Alice starts with propose - Faber counter offer - Alice second proposal- Faber sends second offer', async () => { // proposeCredential -> negotiateProposal -> negotiateOffer -> negotiateProposal -> acceptOffer -> acceptRequest -> DONE (credential issued) const credentialPreview = V2CredentialPreview.fromRecord({