From 898b465d4d819ace37a1c69c303b4a8387effeca Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Thu, 22 Feb 2024 15:45:10 -0800 Subject: [PATCH] Send problem report on reject cred Signed-off-by: Lucas ONeil --- .../src/components/holder/Credentials.vue | 9 +++- .../frontend/src/helpers/constants.ts | 4 +- .../frontend/src/store/holderStore.ts | 47 +++++-------------- .../test/__mocks__/api/routes/holder.ts | 12 +++++ .../tenant-ui/frontend/test/commonTests.ts | 10 ++-- .../frontend/test/store/holderStore.test.ts | 16 +++++-- 6 files changed, 55 insertions(+), 43 deletions(-) diff --git a/services/tenant-ui/frontend/src/components/holder/Credentials.vue b/services/tenant-ui/frontend/src/components/holder/Credentials.vue index 21a7eb2a3..18f4402e6 100644 --- a/services/tenant-ui/frontend/src/components/holder/Credentials.vue +++ b/services/tenant-ui/frontend/src/components/holder/Credentials.vue @@ -81,8 +81,15 @@ const rejectOffer = (event: any, data: V10CredentialExchange) => { message: 'Are you sure you want to reject this credential offer?', header: 'Confirmation', icon: 'pi pi-exclamation-triangle', - accept: () => { + accept: async () => { if (data.credential_exchange_id) { + // Send a problem report then delete the cred exchange record + await holderStore + .sendProblemReport(data.credential_exchange_id) + .catch((err: any) => { + console.error(`Problem report failed: ${err}`); + toast.error('Failure sending Problem Report'); + }); holderStore .deleteCredentialExchange(data.credential_exchange_id) .then(() => { diff --git a/services/tenant-ui/frontend/src/helpers/constants.ts b/services/tenant-ui/frontend/src/helpers/constants.ts index 5d28563ef..adc278361 100644 --- a/services/tenant-ui/frontend/src/helpers/constants.ts +++ b/services/tenant-ui/frontend/src/helpers/constants.ts @@ -80,6 +80,8 @@ export const API_PATH = { ISSUE_CREDENTIALS_SEND_OFFER: '/issue-credential/send-offer', ISSUE_CREDENTIAL_RECORDS_SEND_REQUEST: (id: string) => `/issue-credential/records/${id}/send-request`, + ISSUE_CREDENTIAL_RECORDS_PROBLEM_REPORT: (id: string) => + `/issue-credential/records/${id}/problem-report`, LEDGER_TAA: '/ledger/taa', LEDGER_TAA_ACCEPT: '/ledger/taa/accept', @@ -159,8 +161,6 @@ export const API_PATH = { HOLDER_CREDENTIALS: '/tenant/v1/holder/credentials/', HOLDER_CREDENTIALS_ACCEPT_OFFER: (id: string) => `/tenant/v1/holder/credentials/${id}/accept-offer`, - HOLDER_CREDENTIALS_REJECT_OFFER: (id: string) => - `/tenant/v1/holder/credentials/${id}/reject-offer`, HOLDER_CREDENTIAL: (id: string) => `/tenant/v1/holder/credentials/${id}`, HOLDER_PRESENTATIONS: '/tenant/v1/holder/presentations/', HOLDER_PRESENTATION: (id: string) => `/tenant/v1/holder/presentations/${id}`, diff --git a/services/tenant-ui/frontend/src/store/holderStore.ts b/services/tenant-ui/frontend/src/store/holderStore.ts index 85570a67a..6e0c811a8 100644 --- a/services/tenant-ui/frontend/src/store/holderStore.ts +++ b/services/tenant-ui/frontend/src/store/holderStore.ts @@ -114,39 +114,6 @@ export const useHolderStore = defineStore('holder', () => { return result; } - async function rejectCredentialOffer(credId: string) { - console.log('> holderStore.rejectCredentialOffer'); - - error.value = null; - loading.value = true; - - const result = null; - - // await acapyApi - // .postHttp(API_PATH.HOLDER_CREDENTIALS_REJECT_OFFER(credId), { - // holder_credential_id: credId, - // }) - // .then((res) => { - // result = res.data.item; - // }) - // .then(() => { - // console.log('credential offer rejected.'); - // listCredentials(); // Refresh table - // }) - // .catch((err) => { - // error.value = err; - // }) - // .finally(() => { - // loading.value = false; - // }); - // if (error.value != null) { - // // throw error so $onAction.onError listeners can add their own handler - // throw error.value; - // } - // return data so $onAction.after listeners can add their own handler - return result; - } - async function deleteCredentialExchange(credExId: string) { console.log('> holderStore.deleteCredentialExchange'); @@ -178,6 +145,18 @@ export const useHolderStore = defineStore('holder', () => { return result; } + async function sendProblemReport(credExId: string) { + console.log('> holderStore.sendProblemReport'); + + await acapyApi + .postHttp(API_PATH.ISSUE_CREDENTIAL_RECORDS_PROBLEM_REPORT(credExId), { + description: 'Tenant rejected credential offer through Tenant UI.', + }) + .then(() => { + console.log('Problem report sent.'); + }); + } + return { credentialExchanges, credentials, @@ -197,7 +176,7 @@ export const useHolderStore = defineStore('holder', () => { listHolderCredentialExchanges, listOcas, listPresentations, - rejectCredentialOffer, + sendProblemReport, }; }); diff --git a/services/tenant-ui/frontend/test/__mocks__/api/routes/holder.ts b/services/tenant-ui/frontend/test/__mocks__/api/routes/holder.ts index 13fb97060..1ba08b061 100644 --- a/services/tenant-ui/frontend/test/__mocks__/api/routes/holder.ts +++ b/services/tenant-ui/frontend/test/__mocks__/api/routes/holder.ts @@ -18,6 +18,12 @@ export const successHandlers = [ fullPathWithProxyTenant(API_PATH.ISSUE_CREDENTIAL_RECORD('test-id')), () => HttpResponse.json({}) ), + http.post( + fullPathWithProxyTenant( + API_PATH.ISSUE_CREDENTIAL_RECORDS_PROBLEM_REPORT('test-id') + ), + () => HttpResponse.json({}) + ), ]; export const unknownErrorHandlers = [ @@ -34,4 +40,10 @@ export const unknownErrorHandlers = [ fullPathWithProxyTenant(API_PATH.ISSUE_CREDENTIAL_RECORD('test-id')), () => HttpResponse.json({}, { status: 500 }) ), + http.post( + fullPathWithProxyTenant( + API_PATH.ISSUE_CREDENTIAL_RECORDS_PROBLEM_REPORT('test-id') + ), + () => HttpResponse.json({}, { status: 500 }) + ), ]; diff --git a/services/tenant-ui/frontend/test/commonTests.ts b/services/tenant-ui/frontend/test/commonTests.ts index 059e34fb3..881f6543a 100644 --- a/services/tenant-ui/frontend/test/commonTests.ts +++ b/services/tenant-ui/frontend/test/commonTests.ts @@ -8,13 +8,17 @@ import { expect } from 'vitest'; const testSuccessResponse = async ( store: any, func: () => void, - loadingKey: string + loadingKey: string | undefined ) => { - expect(store[loadingKey]).toEqual(true); + if (loadingKey) { + expect(store[loadingKey]).toEqual(true); + } const response = await func; expect(response).not.toBeNull(); - expect(store[loadingKey]).toEqual(false); + if (loadingKey) { + expect(store[loadingKey]).toEqual(false); + } expect(store.error).toBeNull(); }; diff --git a/services/tenant-ui/frontend/test/store/holderStore.test.ts b/services/tenant-ui/frontend/test/store/holderStore.test.ts index 1d66b7faf..ce7c4cd66 100644 --- a/services/tenant-ui/frontend/test/store/holderStore.test.ts +++ b/services/tenant-ui/frontend/test/store/holderStore.test.ts @@ -7,7 +7,7 @@ import { restHandlersUnknownError, server } from '../setupApi'; let store: any; -describe('connectionStore', () => { +describe('holderStore', () => { beforeEach(async () => { setActivePinia(createPinia()); store = useHolderStore(); @@ -42,6 +42,14 @@ describe('connectionStore', () => { ); }); + test('sendProblemReport does not throw exception', async () => { + await testSuccessResponse( + store, + store.sendProblemReport('test-id'), + undefined + ); + }); + // TODO: This doesn't seem to be used anywhere test.todo('getCredential'); // TODO: This doesn't seem to be used anywhere @@ -57,7 +65,6 @@ describe('connectionStore', () => { test.todo('listHolderCredentialExchanges'); test.todo('listOcas'); test.todo('listPresentations'); - test.todo('rejectCredentialOffer'); }); describe('Unsuccessful API calls', async () => { @@ -85,9 +92,12 @@ describe('connectionStore', () => { await expect(store.listCredentials()).rejects.toThrow(); }); + test('sendProblemReport throws an error', async () => { + await expect(store.sendProblemReport('test-id')).rejects.toThrow(); + }); + test.todo('listHolderCredentialExchanges'); test.todo('listOcas'); test.todo('listPresentations'); - test.todo('rejectCredentialOffer'); }); });