From 96265d6f8314ca90133b3fccdd93c0ca699ed17d Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Mon, 20 Jun 2022 19:04:48 +0200 Subject: [PATCH 1/6] test(credentials): fix flaky tests with events Signed-off-by: Timo Glastra --- .../v2/__tests__/v2-credentials.e2e.test.ts | 135 +++++++++++------- 1 file changed, 82 insertions(+), 53 deletions(-) diff --git a/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials.e2e.test.ts b/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials.e2e.test.ts index 3a2cb288ca..159cdb9b3b 100644 --- a/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials.e2e.test.ts +++ b/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials.e2e.test.ts @@ -1,8 +1,15 @@ import type { Agent } from '../../../../../agent/Agent' import type { ConnectionRecord } from '../../../../connections' +import type { CredentialStateChangedEvent } from '../../../CredentialEvents' import type { IndyCredPropose } from '../../../formats/indy/models/IndyCredPropose' - -import { issueCredential, setupCredentialTests, waitForCredentialRecord } from '../../../../../../tests/helpers' +import type { ReplaySubject } from 'rxjs' + +import { + issueCredential, + setupCredentialTests, + waitForCredentialRecord, + waitForCredentialRecordSubject, +} from '../../../../../../tests/helpers' import testLogger from '../../../../../../tests/logger' import { DidCommMessageRepository } from '../../../../../storage' import { JsonTransformer } from '../../../../../utils' @@ -27,6 +34,9 @@ describe('v2 credentials', () => { let aliceConnection: ConnectionRecord let aliceCredentialRecord: CredentialExchangeRecord let faberCredentialRecord: CredentialExchangeRecord + let faberReplay: ReplaySubject + let aliceReplay: ReplaySubject + let credPropose: IndyCredPropose const newCredentialPreview = V2CredentialPreview.fromRecord({ @@ -37,10 +47,9 @@ describe('v2 credentials', () => { }) beforeAll(async () => { - ;({ faberAgent, aliceAgent, credDefId, faberConnection, aliceConnection } = await setupCredentialTests( - 'Faber Agent Credentials v2', - 'Alice Agent Credentials v2' - )) + ;({ faberAgent, aliceAgent, credDefId, faberConnection, aliceConnection, faberReplay, aliceReplay } = + await setupCredentialTests('Faber Agent Credentials v2', 'Alice Agent Credentials v2')) + credPropose = { credentialDefinitionId: credDefId, schemaIssuerDid: 'GMm4vMw8LLrLJjp81kRRLp', @@ -86,7 +95,7 @@ describe('v2 credentials', () => { }) testLogger.test('Faber waits for credential proposal from Alice') - faberCredentialRecord = await waitForCredentialRecord(faberAgent, { + faberCredentialRecord = await waitForCredentialRecordSubject(faberReplay, { threadId: credentialExchangeRecord.threadId, state: CredentialState.ProposalReceived, }) @@ -104,7 +113,7 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential offer from Faber') - aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { + aliceCredentialRecord = await waitForCredentialRecordSubject(aliceReplay, { threadId: faberCredentialRecord.threadId, state: CredentialState.OfferReceived, }) @@ -173,7 +182,7 @@ describe('v2 credentials', () => { }) testLogger.test('Faber waits for credential request from Alice') - faberCredentialRecord = await waitForCredentialRecord(faberAgent, { + faberCredentialRecord = await waitForCredentialRecordSubject(faberReplay, { threadId: aliceCredentialRecord.threadId, state: CredentialState.RequestReceived, }) @@ -185,7 +194,7 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential from Faber') - aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { + aliceCredentialRecord = await waitForCredentialRecordSubject(aliceReplay, { threadId: faberCredentialRecord.threadId, state: CredentialState.CredentialReceived, }) @@ -195,7 +204,7 @@ describe('v2 credentials', () => { }) testLogger.test('Faber waits for state done') - await waitForCredentialRecord(faberAgent, { + await waitForCredentialRecordSubject(faberReplay, { threadId: faberCredentialRecord.threadId, state: CredentialState.Done, }) @@ -232,6 +241,10 @@ describe('v2 credentials', () => { test('Alice starts with proposal, faber sends a counter offer, alice sends second proposal, faber sends second offer', async () => { // proposeCredential -> negotiateProposal -> negotiateOffer -> negotiateProposal -> acceptOffer -> acceptRequest -> DONE (credential issued) + let faberCredentialRecordPromise = waitForCredentialRecord(faberAgent, { + state: CredentialState.ProposalReceived, + }) + testLogger.test('Alice sends credential proposal to Faber') let aliceCredentialExchangeRecord = await aliceAgent.credentials.proposeCredential({ connectionId: aliceConnection.id, @@ -247,9 +260,11 @@ describe('v2 credentials', () => { expect(aliceCredentialExchangeRecord.state).toBe(CredentialState.ProposalSent) testLogger.test('Faber waits for credential proposal from Alice') - let faberCredentialRecord = await waitForCredentialRecord(faberAgent, { - threadId: aliceCredentialExchangeRecord.threadId, - state: CredentialState.ProposalReceived, + let faberCredentialRecord = await faberCredentialRecordPromise + + let aliceCredentialRecordPromise = waitForCredentialRecord(aliceAgent, { + threadId: faberCredentialRecord.threadId, + state: CredentialState.OfferReceived, }) faberCredentialRecord = await faberAgent.credentials.negotiateProposal({ @@ -263,10 +278,7 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential offer from Faber') - let aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialRecord.threadId, - state: CredentialState.OfferReceived, - }) + let aliceCredentialRecord = await aliceCredentialRecordPromise // Check if the state of the credential records did not change faberCredentialRecord = await faberAgent.credentials.getById(faberCredentialRecord.id) @@ -275,6 +287,11 @@ describe('v2 credentials', () => { aliceCredentialRecord = await aliceAgent.credentials.getById(aliceCredentialRecord.id) aliceCredentialRecord.assertState(CredentialState.OfferReceived) + faberCredentialRecordPromise = waitForCredentialRecord(faberAgent, { + threadId: aliceCredentialExchangeRecord.threadId, + state: CredentialState.ProposalReceived, + }) + // second proposal aliceCredentialExchangeRecord = await aliceAgent.credentials.negotiateOffer({ credentialRecordId: aliceCredentialRecord.id, @@ -289,9 +306,11 @@ describe('v2 credentials', () => { expect(aliceCredentialExchangeRecord.state).toBe(CredentialState.ProposalSent) testLogger.test('Faber waits for credential proposal from Alice') - faberCredentialRecord = await waitForCredentialRecord(faberAgent, { - threadId: aliceCredentialExchangeRecord.threadId, - state: CredentialState.ProposalReceived, + faberCredentialRecord = await faberCredentialRecordPromise + + aliceCredentialRecordPromise = waitForCredentialRecord(aliceAgent, { + threadId: faberCredentialRecord.threadId, + state: CredentialState.OfferReceived, }) faberCredentialRecord = await faberAgent.credentials.negotiateProposal({ @@ -306,10 +325,7 @@ describe('v2 credentials', () => { testLogger.test('Alice waits for credential offer from Faber') - aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialRecord.threadId, - state: CredentialState.OfferReceived, - }) + aliceCredentialRecord = await aliceCredentialRecordPromise const offerCredentialExchangeRecord = await aliceAgent.credentials.acceptOffer({ credentialRecordId: aliceCredentialExchangeRecord.id, @@ -323,7 +339,7 @@ describe('v2 credentials', () => { }) testLogger.test('Faber waits for credential request from Alice') - faberCredentialRecord = await waitForCredentialRecord(faberAgent, { + faberCredentialRecord = await waitForCredentialRecordSubject(faberReplay, { threadId: aliceCredentialExchangeRecord.threadId, state: CredentialState.RequestReceived, }) @@ -335,16 +351,15 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential from Faber') - aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { + aliceCredentialRecord = await waitForCredentialRecordSubject(aliceReplay, { threadId: faberCredentialRecord.threadId, state: CredentialState.CredentialReceived, }) - // testLogger.test('Alice sends credential ack to Faber') await aliceAgent.credentials.acceptCredential({ credentialRecordId: aliceCredentialRecord.id }) testLogger.test('Faber waits for credential ack from Alice') - faberCredentialRecord = await waitForCredentialRecord(faberAgent, { + faberCredentialRecord = await waitForCredentialRecordSubject(faberReplay, { threadId: faberCredentialRecord.threadId, state: CredentialState.Done, }) @@ -359,8 +374,12 @@ describe('v2 credentials', () => { }) test('Faber starts with offer, alice sends counter proposal, faber sends second offer, alice sends second proposal', async () => { + let aliceCredentialRecordPromise = waitForCredentialRecord(aliceAgent, { + state: CredentialState.OfferReceived, + }) + testLogger.test('Faber sends credential offer to Alice') - const faberCredentialExchangeRecord = await faberAgent.credentials.offerCredential({ + let faberCredentialRecord = await faberAgent.credentials.offerCredential({ comment: 'some comment about credential', connectionId: faberConnection.id, credentialFormats: { @@ -373,9 +392,11 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential offer from Faber') - aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialExchangeRecord.threadId, - state: CredentialState.OfferReceived, + aliceCredentialRecord = await aliceCredentialRecordPromise + + let faberCredentialRecordPromise = waitForCredentialRecord(faberAgent, { + threadId: aliceCredentialRecord.threadId, + state: CredentialState.ProposalReceived, }) aliceCredentialRecord = await aliceAgent.credentials.negotiateOffer({ @@ -391,10 +412,13 @@ describe('v2 credentials', () => { expect(aliceCredentialRecord.state).toBe(CredentialState.ProposalSent) testLogger.test('Faber waits for credential proposal from Alice') - faberCredentialRecord = await waitForCredentialRecord(faberAgent, { - threadId: aliceCredentialRecord.threadId, - state: CredentialState.ProposalReceived, + faberCredentialRecord = await faberCredentialRecordPromise + + aliceCredentialRecordPromise = waitForCredentialRecord(aliceAgent, { + threadId: faberCredentialRecord.threadId, + state: CredentialState.OfferReceived, }) + faberCredentialRecord = await faberAgent.credentials.negotiateProposal({ credentialRecordId: faberCredentialRecord.id, credentialFormats: { @@ -407,9 +431,11 @@ describe('v2 credentials', () => { testLogger.test('Alice waits for credential offer from Faber') - aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialRecord.threadId, - state: CredentialState.OfferReceived, + aliceCredentialRecord = await aliceCredentialRecordPromise + + faberCredentialRecordPromise = waitForCredentialRecord(faberAgent, { + threadId: aliceCredentialRecord.threadId, + state: CredentialState.ProposalReceived, }) aliceCredentialRecord = await aliceAgent.credentials.negotiateOffer({ @@ -425,9 +451,11 @@ describe('v2 credentials', () => { expect(aliceCredentialRecord.state).toBe(CredentialState.ProposalSent) testLogger.test('Faber waits for credential proposal from Alice') - faberCredentialRecord = await waitForCredentialRecord(faberAgent, { - threadId: aliceCredentialRecord.threadId, - state: CredentialState.ProposalReceived, + faberCredentialRecord = await faberCredentialRecordPromise + + aliceCredentialRecordPromise = waitForCredentialRecord(aliceAgent, { + threadId: faberCredentialRecord.threadId, + state: CredentialState.OfferReceived, }) testLogger.test('Faber sends credential offer to Alice') @@ -443,9 +471,11 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential offer from Faber') - aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialRecord.threadId, - state: CredentialState.OfferReceived, + aliceCredentialRecord = await aliceCredentialRecordPromise + + faberCredentialRecordPromise = waitForCredentialRecord(faberAgent, { + threadId: aliceCredentialRecord.threadId, + state: CredentialState.RequestReceived, }) const offerCredentialExchangeRecord = await aliceAgent.credentials.acceptOffer({ @@ -459,9 +489,11 @@ describe('v2 credentials', () => { }) testLogger.test('Faber waits for credential request from Alice') - faberCredentialRecord = await waitForCredentialRecord(faberAgent, { - threadId: aliceCredentialRecord.threadId, - state: CredentialState.RequestReceived, + faberCredentialRecord = await faberCredentialRecordPromise + + aliceCredentialRecordPromise = waitForCredentialRecord(aliceAgent, { + threadId: faberCredentialRecord.threadId, + state: CredentialState.CredentialReceived, }) testLogger.test('Faber sends credential to Alice') @@ -471,10 +503,7 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential from Faber') - aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialRecord.threadId, - state: CredentialState.CredentialReceived, - }) + aliceCredentialRecord = await aliceCredentialRecordPromise const formatData = await aliceAgent.credentials.getFormatData(aliceCredentialRecord.id) @@ -594,7 +623,7 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential offer from Faber') - aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { + aliceCredentialRecord = await waitForCredentialRecordSubject(aliceReplay, { threadId: faberCredentialExchangeRecord.threadId, state: CredentialState.OfferReceived, }) From 491dfdf995558ab4a4b43b78aa8293adb209ce7b Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Mon, 20 Jun 2022 19:11:43 +0200 Subject: [PATCH 2/6] fix(updating): incorrect snippet in handler Signed-off-by: Timo Glastra --- packages/core/tests/helpers.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/core/tests/helpers.ts b/packages/core/tests/helpers.ts index 5bc264c681..e8f4fb7b09 100644 --- a/packages/core/tests/helpers.ts +++ b/packages/core/tests/helpers.ts @@ -631,7 +631,17 @@ export async function setupCredentialTests( const [faberConnection, aliceConnection] = await makeConnection(faberAgent, aliceAgent) - return { faberAgent, aliceAgent, credDefId, schema, faberConnection, aliceConnection } + const faberReplay = new ReplaySubject() + const aliceReplay = new ReplaySubject() + + faberAgent.events + .observable(CredentialEventTypes.CredentialStateChanged) + .subscribe(faberReplay) + aliceAgent.events + .observable(CredentialEventTypes.CredentialStateChanged) + .subscribe(aliceReplay) + + return { faberAgent, aliceAgent, credDefId, schema, faberConnection, aliceConnection, faberReplay, aliceReplay } } export async function setupProofsTest(faberName: string, aliceName: string, autoAcceptProofs?: AutoAcceptProof) { From 9d85d18d2cb9ba83a503cb3ea39c443f6f62ef08 Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Thu, 23 Jun 2022 17:10:53 +0200 Subject: [PATCH 3/6] test: fix test name Signed-off-by: Timo Glastra --- .../src/modules/ledger/__tests__/IndyPoolService.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/core/src/modules/ledger/__tests__/IndyPoolService.test.ts b/packages/core/src/modules/ledger/__tests__/IndyPoolService.test.ts index fabd75140a..cf72f71cf7 100644 --- a/packages/core/src/modules/ledger/__tests__/IndyPoolService.test.ts +++ b/packages/core/src/modules/ledger/__tests__/IndyPoolService.test.ts @@ -49,8 +49,8 @@ const pools: IndyPoolConfig[] = [ }, ] -describe('IndyLedgerService', () => { - const config = getAgentConfig('IndyLedgerServiceTest', { +describe('IndyPoolService', () => { + const config = getAgentConfig('IndyPoolServiceTest', { indyLedgers: pools, }) let wallet: IndyWallet @@ -80,7 +80,7 @@ describe('IndyLedgerService', () => { }) it('should throw a LedgerNotConfiguredError error if no pools are configured on the agent', async () => { - const config = getAgentConfig('IndyLedgerServiceTest', { indyLedgers: [] }) + const config = getAgentConfig('IndyPoolServiceTest', { indyLedgers: [] }) poolService = new IndyPoolService(config, cacheRepository) expect(() => poolService.ledgerWritePool).toThrow(LedgerNotConfiguredError) @@ -89,7 +89,7 @@ describe('IndyLedgerService', () => { describe('getPoolForDid', () => { it('should throw a LedgerNotConfiguredError error if no pools are configured on the agent', async () => { - const config = getAgentConfig('IndyLedgerServiceTest', { indyLedgers: [] }) + const config = getAgentConfig('IndyPoolServiceTest', { indyLedgers: [] }) poolService = new IndyPoolService(config, cacheRepository) expect(poolService.getPoolForDid('some-did')).rejects.toThrow(LedgerNotConfiguredError) From 898e683548a443d053f8f279cddf15870e8c1ce8 Mon Sep 17 00:00:00 2001 From: 2byrds <2byrds@gmail.com> Date: Tue, 26 Jul 2022 10:55:26 -0400 Subject: [PATCH 4/6] waiting for record prior to the operation to avoid flaky tests Signed-off-by: 2byrds <2byrds@gmail.com> --- .../v2-credentials-auto-accept.e2e.test.ts | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts b/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts index 09612c9877..627a2e7c12 100644 --- a/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts +++ b/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts @@ -171,6 +171,10 @@ describe('v2 credentials', () => { let faberCredentialExchangeRecord: CredentialExchangeRecord let aliceCredentialExchangeRecord: CredentialExchangeRecord + const faberCredentialExchangeRecordPromise = waitForCredentialRecord(faberAgent, { + state: CredentialState.ProposalReceived, + }) + aliceCredentialExchangeRecord = await aliceAgent.credentials.proposeCredential({ connectionId: aliceConnection.id, protocolVersion: 'v2', @@ -183,10 +187,7 @@ describe('v2 credentials', () => { }) testLogger.test('Faber waits for credential proposal from Alice') - faberCredentialExchangeRecord = await waitForCredentialRecord(faberAgent, { - threadId: aliceCredentialExchangeRecord.threadId, - state: CredentialState.ProposalReceived, - }) + faberCredentialExchangeRecord = await faberCredentialExchangeRecordPromise const options: AcceptProposalOptions = { credentialRecordId: faberCredentialExchangeRecord.id, @@ -342,6 +343,10 @@ describe('v2 credentials', () => { }) test('Alice starts with V2 credential proposal to Faber, both have autoAcceptCredential on `contentApproved` and attributes did change', async () => { + const faberCredentialExchangeRecordPromise = waitForCredentialRecord(faberAgent, { + state: CredentialState.ProposalReceived, + }) + testLogger.test('Alice sends credential proposal to Faber') const aliceCredentialExchangeRecord = await aliceAgent.credentials.proposeCredential({ connectionId: aliceConnection.id, @@ -354,14 +359,17 @@ describe('v2 credentials', () => { }, comment: 'v2 propose credential test', }) + expect(aliceCredentialExchangeRecord.state).toBe(CredentialState.ProposalSent) testLogger.test('Faber waits for credential proposal from Alice') - let faberCredentialExchangeRecord = await waitForCredentialRecord(faberAgent, { - threadId: aliceCredentialExchangeRecord.threadId, - state: CredentialState.ProposalReceived, + let faberCredentialExchangeRecord = await faberCredentialExchangeRecordPromise + + const aliceCredentialExchangeRecordPromise = waitForCredentialRecord(aliceAgent, { + threadId: faberCredentialExchangeRecord.threadId, + state: CredentialState.OfferReceived, }) - await faberAgent.credentials.negotiateProposal({ + faberCredentialExchangeRecord = await faberAgent.credentials.negotiateProposal({ credentialRecordId: faberCredentialExchangeRecord.id, credentialFormats: { indy: { @@ -372,11 +380,7 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential offer from Faber') - - const record = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialExchangeRecord.threadId, - state: CredentialState.OfferReceived, - }) + const record = await aliceCredentialExchangeRecordPromise // below values are not in json object expect(record.id).not.toBeNull() @@ -396,6 +400,10 @@ describe('v2 credentials', () => { }) test('Faber starts with V2 credential offer to Alice, both have autoAcceptCredential on `contentApproved` and attributes did change', async () => { + const aliceCredentialExchangeRecordPromise = waitForCredentialRecord(aliceAgent, { + state: CredentialState.OfferReceived, + }) + testLogger.test('Faber sends credential offer to Alice') let faberCredentialExchangeRecord = await faberAgent.credentials.offerCredential({ comment: 'some comment about credential', @@ -410,10 +418,7 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential offer from Faber') - let aliceCredentialExchangeRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialExchangeRecord.threadId, - state: CredentialState.OfferReceived, - }) + let aliceCredentialExchangeRecord = await aliceCredentialExchangeRecordPromise // below values are not in json object expect(aliceCredentialExchangeRecord.id).not.toBeNull() @@ -424,6 +429,10 @@ describe('v2 credentials', () => { credentialIds: [], }) + const faberCredentialExchangeRecordPromise = waitForCredentialRecord(faberAgent, { + state: CredentialState.ProposalReceived, + }) + testLogger.test('Alice sends credential request to Faber') const aliceExchangeCredentialRecord = await aliceAgent.credentials.negotiateOffer({ credentialRecordId: aliceCredentialExchangeRecord.id, @@ -437,10 +446,7 @@ describe('v2 credentials', () => { }) testLogger.test('Faber waits for credential proposal from Alice') - faberCredentialExchangeRecord = await waitForCredentialRecord(faberAgent, { - threadId: aliceExchangeCredentialRecord.threadId, - state: CredentialState.ProposalReceived, - }) + faberCredentialExchangeRecord = await faberCredentialExchangeRecordPromise await sleep(5000) From 0158d5bfb742c9c2a34185cde475b30ad8ef8c65 Mon Sep 17 00:00:00 2001 From: 2byrds <2byrds@gmail.com> Date: Thu, 28 Jul 2022 11:42:50 -0400 Subject: [PATCH 5/6] auto accept test changes to fix flaky tests Signed-off-by: 2byrds <2byrds@gmail.com> --- .../v2-credentials-auto-accept.e2e.test.ts | 271 +++++++++--------- 1 file changed, 141 insertions(+), 130 deletions(-) diff --git a/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts b/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts index 627a2e7c12..b63f1fa07d 100644 --- a/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts +++ b/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts @@ -50,8 +50,17 @@ describe('v2 credentials', () => { }) test('Alice starts with V2 credential proposal to Faber, both with autoAcceptCredential on `always`', async () => { - testLogger.test('Alice sends credential proposal to Faber') + testLogger.test('Alice begins listening for credential') + const aliceCredReceivedPromise = waitForCredentialRecord(aliceAgent, { + state: CredentialState.CredentialReceived, + }) + + testLogger.test('Faber begins listening for credential ack') + const faberCredAckPromise = waitForCredentialRecord(faberAgent, { + state: CredentialState.Done, + }) + testLogger.test('Alice sends credential proposal to Faber') const aliceCredentialExchangeRecord = await aliceAgent.credentials.proposeCredential({ connectionId: aliceConnection.id, protocolVersion: 'v2', @@ -65,16 +74,10 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential from Faber') - let aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { - threadId: aliceCredentialExchangeRecord.threadId, - state: CredentialState.CredentialReceived, - }) + let aliceCredentialRecord = await aliceCredReceivedPromise testLogger.test('Faber waits for credential ack from Alice') - aliceCredentialRecord = await waitForCredentialRecord(faberAgent, { - threadId: aliceCredentialRecord.threadId, - state: CredentialState.Done, - }) + aliceCredentialRecord = await faberCredAckPromise expect(aliceCredentialRecord).toMatchObject({ type: CredentialExchangeRecord.type, @@ -93,6 +96,16 @@ describe('v2 credentials', () => { }) test('Faber starts with V2 credential offer to Alice, both with autoAcceptCredential on `always`', async () => { + testLogger.test('Alice begins listening for credential') + const aliceCredReceivedPromise = waitForCredentialRecord(aliceAgent, { + state: CredentialState.CredentialReceived, + }) + + testLogger.test('Faber begins listening for credential ack') + const faberCredAckPromise = waitForCredentialRecord(faberAgent, { + state: CredentialState.Done, + }) + testLogger.test('Faber sends credential offer to Alice') const schemaId = schema.id const faberCredentialExchangeRecord = await faberAgent.credentials.offerCredential({ @@ -107,15 +120,7 @@ describe('v2 credentials', () => { protocolVersion: 'v2', }) testLogger.test('Alice waits for credential from Faber') - const aliceCredentialRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialExchangeRecord.threadId, - state: CredentialState.CredentialReceived, - }) - testLogger.test('Faber waits for credential ack from Alice') - const faberCredentialRecord: CredentialExchangeRecord = await waitForCredentialRecord(faberAgent, { - threadId: faberCredentialExchangeRecord.threadId, - state: CredentialState.Done, - }) + const aliceCredentialRecord = await aliceCredReceivedPromise expect(aliceCredentialRecord).toMatchObject({ type: CredentialExchangeRecord.type, id: expect.any(String), @@ -137,6 +142,9 @@ describe('v2 credentials', () => { ], state: CredentialState.CredentialReceived, }) + + testLogger.test('Faber waits for credential ack from Alice') + const faberCredentialRecord: CredentialExchangeRecord = await faberCredAckPromise expect(faberCredentialRecord).toMatchObject({ type: CredentialExchangeRecord.type, id: expect.any(String), @@ -168,14 +176,13 @@ describe('v2 credentials', () => { test('Alice starts with V2 credential proposal to Faber, both with autoAcceptCredential on `contentApproved`', async () => { testLogger.test('Alice sends credential proposal to Faber') const schemaId = schema.id - let faberCredentialExchangeRecord: CredentialExchangeRecord - let aliceCredentialExchangeRecord: CredentialExchangeRecord - const faberCredentialExchangeRecordPromise = waitForCredentialRecord(faberAgent, { + testLogger.test('Faber starts listening for credential proposal from Alice') + const faberPropReceivedPromise = waitForCredentialRecord(faberAgent, { state: CredentialState.ProposalReceived, }) - aliceCredentialExchangeRecord = await aliceAgent.credentials.proposeCredential({ + await aliceAgent.credentials.proposeCredential({ connectionId: aliceConnection.id, protocolVersion: 'v2', credentialFormats: { @@ -187,10 +194,20 @@ describe('v2 credentials', () => { }) testLogger.test('Faber waits for credential proposal from Alice') - faberCredentialExchangeRecord = await faberCredentialExchangeRecordPromise + const faberPropReceivedRecord = await faberPropReceivedPromise + + const aliceCredReceivedPromise = waitForCredentialRecord(aliceAgent, { + threadId: faberPropReceivedRecord.threadId, + state: CredentialState.CredentialReceived, + }) + + const faberCredAckPromise = waitForCredentialRecord(faberAgent, { + threadId: faberPropReceivedRecord.threadId, + state: CredentialState.Done, + }) const options: AcceptProposalOptions = { - credentialRecordId: faberCredentialExchangeRecord.id, + credentialRecordId: faberPropReceivedRecord.id, comment: 'V2 Indy Offer', credentialFormats: { indy: { @@ -200,22 +217,13 @@ describe('v2 credentials', () => { }, } testLogger.test('Faber sends credential offer to Alice') - options.credentialRecordId = faberCredentialExchangeRecord.id - faberCredentialExchangeRecord = await faberAgent.credentials.acceptProposal(options) + options.credentialRecordId = faberPropReceivedRecord.id + const faberAcceptPropRecord = await faberAgent.credentials.acceptProposal(options) testLogger.test('Alice waits for credential from Faber') - aliceCredentialExchangeRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialExchangeRecord.threadId, - state: CredentialState.CredentialReceived, - }) + const aliceCredReceivedRecord = await aliceCredReceivedPromise - testLogger.test('Faber waits for credential ack from Alice') - faberCredentialExchangeRecord = await waitForCredentialRecord(faberAgent, { - threadId: faberCredentialExchangeRecord.threadId, - state: CredentialState.Done, - }) - - expect(aliceCredentialExchangeRecord).toMatchObject({ + expect(aliceCredReceivedRecord).toMatchObject({ type: CredentialExchangeRecord.type, id: expect.any(String), createdAt: expect.any(Date), @@ -237,7 +245,10 @@ describe('v2 credentials', () => { state: CredentialState.CredentialReceived, }) - expect(faberCredentialExchangeRecord).toMatchObject({ + testLogger.test('Faber waits for credential ack from Alice') + const faberCredAckRecord = await faberCredAckPromise + + expect(faberCredAckRecord).toMatchObject({ type: CredentialExchangeRecord.type, id: expect.any(String), createdAt: expect.any(Date), @@ -254,12 +265,14 @@ describe('v2 credentials', () => { }) test('Faber starts with V2 credential offer to Alice, both with autoAcceptCredential on `contentApproved`', async () => { + testLogger.test('Alice starts listening for credential offer from Faber') + const aliceOfferReceivedPromise = waitForCredentialRecord(aliceAgent, { + state: CredentialState.OfferReceived, + }) + testLogger.test('Faber sends credential offer to Alice') const schemaId = schema.id - let aliceCredentialExchangeRecord: CredentialExchangeRecord - let faberCredentialExchangeRecord: CredentialExchangeRecord - - faberCredentialExchangeRecord = await faberAgent.credentials.offerCredential({ + const faberOfferCredRecord = await faberAgent.credentials.offerCredential({ comment: 'some comment about credential', connectionId: faberConnection.id, credentialFormats: { @@ -272,83 +285,80 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential offer from Faber') - aliceCredentialExchangeRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialExchangeRecord.threadId, - state: CredentialState.OfferReceived, - }) + const aliceOfferReceivedRecord = await aliceOfferReceivedPromise - expect(JsonTransformer.toJSON(aliceCredentialExchangeRecord)).toMatchObject({ + expect(JsonTransformer.toJSON(aliceOfferReceivedRecord)).toMatchObject({ state: CredentialState.OfferReceived, }) // below values are not in json object - expect(aliceCredentialExchangeRecord.id).not.toBeNull() - expect(aliceCredentialExchangeRecord.getTags()).toEqual({ - threadId: aliceCredentialExchangeRecord.threadId, - state: aliceCredentialExchangeRecord.state, + expect(aliceOfferReceivedRecord.id).not.toBeNull() + expect(aliceOfferReceivedRecord.getTags()).toEqual({ + threadId: aliceOfferReceivedRecord.threadId, + state: aliceOfferReceivedRecord.state, connectionId: aliceConnection.id, credentialIds: [], }) + testLogger.test('Alice received credential offer from Faber') + + testLogger.test('Alice starts listening for credential from Faber') + const aliceCredReceivedPromise = waitForCredentialRecord(aliceAgent, { + state: CredentialState.CredentialReceived, + }) - if (aliceCredentialExchangeRecord.connectionId) { - const acceptOfferOptions: AcceptOfferOptions = { - credentialRecordId: aliceCredentialExchangeRecord.id, - } - testLogger.test('alice sends credential request to faber') - faberCredentialExchangeRecord = await aliceAgent.credentials.acceptOffer(acceptOfferOptions) - - testLogger.test('Alice waits for credential from Faber') - aliceCredentialExchangeRecord = await waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialExchangeRecord.threadId, - state: CredentialState.CredentialReceived, - }) - - testLogger.test('Faber waits for credential ack from Alice') - faberCredentialExchangeRecord = await waitForCredentialRecord(faberAgent, { - threadId: faberCredentialExchangeRecord.threadId, - state: CredentialState.Done, - }) - - expect(aliceCredentialExchangeRecord).toMatchObject({ - type: CredentialExchangeRecord.type, - id: expect.any(String), - createdAt: expect.any(Date), - metadata: { - data: { - '_internal/indyRequest': expect.any(Object), - '_internal/indyCredential': { - schemaId, - credentialDefinitionId: credDefId, - }, + const faberCredAckPromise = waitForCredentialRecord(faberAgent, { + state: CredentialState.Done, + }) + + const acceptOfferOptions: AcceptOfferOptions = { + credentialRecordId: aliceOfferReceivedRecord.id, + } + testLogger.test('alice sends credential request to faber') + const faberOfferedCredRecord = await aliceAgent.credentials.acceptOffer(acceptOfferOptions) + + testLogger.test('Alice waits for credential from Faber') + const aliceCredReceivedRecord = await aliceCredReceivedPromise + expect(aliceCredReceivedRecord).toMatchObject({ + type: CredentialExchangeRecord.type, + id: expect.any(String), + createdAt: expect.any(Date), + metadata: { + data: { + '_internal/indyRequest': expect.any(Object), + '_internal/indyCredential': { + schemaId, + credentialDefinitionId: credDefId, }, }, - credentials: [ - { - credentialRecordType: 'indy', - credentialRecordId: expect.any(String), - }, - ], - state: CredentialState.CredentialReceived, - }) - - expect(faberCredentialExchangeRecord).toMatchObject({ - type: CredentialExchangeRecord.type, - id: expect.any(String), - createdAt: expect.any(Date), - state: CredentialState.Done, - }) - } else { - throw new AriesFrameworkError('missing alice connection id') - } + }, + credentials: [ + { + credentialRecordType: 'indy', + credentialRecordId: expect.any(String), + }, + ], + state: CredentialState.CredentialReceived, + }) + + testLogger.test('Faber waits for credential ack from Alice') + const faberCredAckRecord = await faberCredAckPromise + + expect(faberCredAckRecord).toMatchObject({ + type: CredentialExchangeRecord.type, + id: expect.any(String), + createdAt: expect.any(Date), + state: CredentialState.Done, + }) }) test('Alice starts with V2 credential proposal to Faber, both have autoAcceptCredential on `contentApproved` and attributes did change', async () => { - const faberCredentialExchangeRecordPromise = waitForCredentialRecord(faberAgent, { + testLogger.test('Faber starts listening for proposal from Alice') + const faberPropReceivedPromise = waitForCredentialRecord(faberAgent, { state: CredentialState.ProposalReceived, }) testLogger.test('Alice sends credential proposal to Faber') - const aliceCredentialExchangeRecord = await aliceAgent.credentials.proposeCredential({ + const aliceCredProposal = await aliceAgent.credentials.proposeCredential({ connectionId: aliceConnection.id, protocolVersion: 'v2', credentialFormats: { @@ -359,18 +369,19 @@ describe('v2 credentials', () => { }, comment: 'v2 propose credential test', }) - expect(aliceCredentialExchangeRecord.state).toBe(CredentialState.ProposalSent) + expect(aliceCredProposal.state).toBe(CredentialState.ProposalSent) testLogger.test('Faber waits for credential proposal from Alice') - let faberCredentialExchangeRecord = await faberCredentialExchangeRecordPromise + const faberPropReceivedRecord = await faberPropReceivedPromise - const aliceCredentialExchangeRecordPromise = waitForCredentialRecord(aliceAgent, { - threadId: faberCredentialExchangeRecord.threadId, + testLogger.test('Alice starts listening for credential offer from Faber') + const aliceOfferReceivedPromise = waitForCredentialRecord(aliceAgent, { state: CredentialState.OfferReceived, }) - faberCredentialExchangeRecord = await faberAgent.credentials.negotiateProposal({ - credentialRecordId: faberCredentialExchangeRecord.id, + testLogger.test('Faber negotiated proposal, sending credential offer to Alice') + const faberOfferSentRecord = await faberAgent.credentials.negotiateProposal({ + credentialRecordId: faberPropReceivedRecord.id, credentialFormats: { indy: { credentialDefinitionId: credDefId, @@ -380,32 +391,33 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential offer from Faber') - const record = await aliceCredentialExchangeRecordPromise + const aliceOfferReceivedRecord = await aliceOfferReceivedPromise // below values are not in json object - expect(record.id).not.toBeNull() - expect(record.getTags()).toEqual({ - threadId: record.threadId, - state: record.state, + expect(aliceOfferReceivedRecord.id).not.toBeNull() + expect(aliceOfferReceivedRecord.getTags()).toEqual({ + threadId: aliceOfferReceivedRecord.threadId, + state: aliceOfferReceivedRecord.state, connectionId: aliceConnection.id, credentialIds: [], }) // Check if the state of the credential records did not change - faberCredentialExchangeRecord = await faberAgent.credentials.getById(faberCredentialExchangeRecord.id) - faberCredentialExchangeRecord.assertState(CredentialState.OfferSent) + const faberRecord = await faberAgent.credentials.getById(faberOfferSentRecord.id) + faberRecord.assertState(CredentialState.OfferSent) - const aliceRecord = await aliceAgent.credentials.getById(record.id) + const aliceRecord = await aliceAgent.credentials.getById(aliceOfferReceivedRecord.id) aliceRecord.assertState(CredentialState.OfferReceived) }) test('Faber starts with V2 credential offer to Alice, both have autoAcceptCredential on `contentApproved` and attributes did change', async () => { + testLogger.test('Alice starts listening for offer from Faber') const aliceCredentialExchangeRecordPromise = waitForCredentialRecord(aliceAgent, { state: CredentialState.OfferReceived, }) testLogger.test('Faber sends credential offer to Alice') - let faberCredentialExchangeRecord = await faberAgent.credentials.offerCredential({ + const faberOfferCredentialRecord = await faberAgent.credentials.offerCredential({ comment: 'some comment about credential', connectionId: faberConnection.id, credentialFormats: { @@ -418,24 +430,25 @@ describe('v2 credentials', () => { }) testLogger.test('Alice waits for credential offer from Faber') - let aliceCredentialExchangeRecord = await aliceCredentialExchangeRecordPromise + const aliceOfferReceivedRecord = await aliceCredentialExchangeRecordPromise // below values are not in json object - expect(aliceCredentialExchangeRecord.id).not.toBeNull() - expect(aliceCredentialExchangeRecord.getTags()).toEqual({ - threadId: aliceCredentialExchangeRecord.threadId, - state: aliceCredentialExchangeRecord.state, + expect(aliceOfferReceivedRecord.id).not.toBeNull() + expect(aliceOfferReceivedRecord.getTags()).toEqual({ + threadId: aliceOfferReceivedRecord.threadId, + state: aliceOfferReceivedRecord.state, connectionId: aliceConnection.id, credentialIds: [], }) - const faberCredentialExchangeRecordPromise = waitForCredentialRecord(faberAgent, { + testLogger.test('Faber starts listening for proposal received') + const faberProposalReceivedPromise = waitForCredentialRecord(faberAgent, { state: CredentialState.ProposalReceived, }) testLogger.test('Alice sends credential request to Faber') - const aliceExchangeCredentialRecord = await aliceAgent.credentials.negotiateOffer({ - credentialRecordId: aliceCredentialExchangeRecord.id, + const aliceCredRequestRecord = await aliceAgent.credentials.negotiateOffer({ + credentialRecordId: aliceOfferReceivedRecord.id, credentialFormats: { indy: { attributes: newCredentialPreview.attributes, @@ -446,16 +459,14 @@ describe('v2 credentials', () => { }) testLogger.test('Faber waits for credential proposal from Alice') - faberCredentialExchangeRecord = await faberCredentialExchangeRecordPromise - - await sleep(5000) + const faberCredProposalRecord = await faberProposalReceivedPromise // Check if the state of fabers credential record did not change - const faberRecord = await faberAgent.credentials.getById(faberCredentialExchangeRecord.id) + const faberRecord = await faberAgent.credentials.getById(faberCredProposalRecord.id) faberRecord.assertState(CredentialState.ProposalReceived) - aliceCredentialExchangeRecord = await aliceAgent.credentials.getById(aliceCredentialExchangeRecord.id) - aliceCredentialExchangeRecord.assertState(CredentialState.ProposalSent) + const aliceRecord = await aliceAgent.credentials.getById(aliceCredRequestRecord.id) + aliceRecord.assertState(CredentialState.ProposalSent) }) }) }) From 7c78859d00835b5974cabb62884a2d1ced147d7b Mon Sep 17 00:00:00 2001 From: 2byrds <2byrds@gmail.com> Date: Thu, 28 Jul 2022 11:50:42 -0400 Subject: [PATCH 6/6] auto accept test changes to fix flaky tests Signed-off-by: 2byrds <2byrds@gmail.com> --- .../v2-credentials-auto-accept.e2e.test.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts b/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts index b63f1fa07d..5036232d4a 100644 --- a/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts +++ b/packages/core/src/modules/credentials/protocol/v2/__tests__/v2-credentials-auto-accept.e2e.test.ts @@ -5,9 +5,7 @@ import type { Schema } from 'indy-sdk' import { setupCredentialTests, waitForCredentialRecord } from '../../../../../../tests/helpers' import testLogger from '../../../../../../tests/logger' -import { AriesFrameworkError } from '../../../../../error/AriesFrameworkError' import { JsonTransformer } from '../../../../../utils/JsonTransformer' -import { sleep } from '../../../../../utils/sleep' import { AutoAcceptCredential } from '../../../models/CredentialAutoAcceptType' import { CredentialState } from '../../../models/CredentialState' import { CredentialExchangeRecord } from '../../../repository/CredentialExchangeRecord' @@ -61,7 +59,7 @@ describe('v2 credentials', () => { }) testLogger.test('Alice sends credential proposal to Faber') - const aliceCredentialExchangeRecord = await aliceAgent.credentials.proposeCredential({ + await aliceAgent.credentials.proposeCredential({ connectionId: aliceConnection.id, protocolVersion: 'v2', credentialFormats: { @@ -108,7 +106,7 @@ describe('v2 credentials', () => { testLogger.test('Faber sends credential offer to Alice') const schemaId = schema.id - const faberCredentialExchangeRecord = await faberAgent.credentials.offerCredential({ + await faberAgent.credentials.offerCredential({ comment: 'some comment about credential', connectionId: faberConnection.id, credentialFormats: { @@ -218,7 +216,7 @@ describe('v2 credentials', () => { } testLogger.test('Faber sends credential offer to Alice') options.credentialRecordId = faberPropReceivedRecord.id - const faberAcceptPropRecord = await faberAgent.credentials.acceptProposal(options) + await faberAgent.credentials.acceptProposal(options) testLogger.test('Alice waits for credential from Faber') const aliceCredReceivedRecord = await aliceCredReceivedPromise @@ -272,7 +270,7 @@ describe('v2 credentials', () => { testLogger.test('Faber sends credential offer to Alice') const schemaId = schema.id - const faberOfferCredRecord = await faberAgent.credentials.offerCredential({ + await faberAgent.credentials.offerCredential({ comment: 'some comment about credential', connectionId: faberConnection.id, credentialFormats: { @@ -314,7 +312,7 @@ describe('v2 credentials', () => { credentialRecordId: aliceOfferReceivedRecord.id, } testLogger.test('alice sends credential request to faber') - const faberOfferedCredRecord = await aliceAgent.credentials.acceptOffer(acceptOfferOptions) + await aliceAgent.credentials.acceptOffer(acceptOfferOptions) testLogger.test('Alice waits for credential from Faber') const aliceCredReceivedRecord = await aliceCredReceivedPromise @@ -417,7 +415,7 @@ describe('v2 credentials', () => { }) testLogger.test('Faber sends credential offer to Alice') - const faberOfferCredentialRecord = await faberAgent.credentials.offerCredential({ + await faberAgent.credentials.offerCredential({ comment: 'some comment about credential', connectionId: faberConnection.id, credentialFormats: {