diff --git a/__tests__/shared/saveClaims.ts b/__tests__/shared/saveClaims.ts index 6ad205713..0e4d00927 100644 --- a/__tests__/shared/saveClaims.ts +++ b/__tests__/shared/saveClaims.ts @@ -44,7 +44,8 @@ export default (testContext: { issuer: { id: identifier.did }, '@context': ['https://www.w3.org/2018/credentials/v1'], type: ['VerifiableCredential'], - issuanceDate: new Date().toISOString(), + issuanceDate: '2023-09-15T10:22:07.506Z', + id: 'a', credentialSubject: { id: identifier.did, topic: 'math', @@ -59,7 +60,8 @@ export default (testContext: { issuer: { id: identifier.did }, '@context': ['https://www.w3.org/2018/credentials/v1'], type: ['VerifiableCredential'], - issuanceDate: new Date().toISOString(), + issuanceDate: '2023-09-16T10:22:07.506Z', + id: 'b', credentialSubject: { id: identifier.did, topic: 'science', @@ -74,7 +76,8 @@ export default (testContext: { issuer: { id: identifier.did }, '@context': ['https://www.w3.org/2018/credentials/v1'], type: ['VerifiableCredential'], - issuanceDate: new Date().toISOString(), + issuanceDate: '2023-09-17T10:22:07.506Z', + id: 'c', credentialSubject: { id: identifier.did, topic: 'art', @@ -113,6 +116,94 @@ export default (testContext: { expect(credentials).toHaveLength(2) }) + it('should be able to limit credentials when query by claim type and value', async () => { + const credentials = await agent.dataStoreORMGetVerifiableCredentialsByClaims({ + where: [ + { column: 'type', value: ['topic'] }, + { column: 'value', value: ['math', 'art'] }, + ], + order: [{ column: 'issuanceDate', direction: 'DESC' }], + take: 1 + }) + expect(credentials).toHaveLength(1) + }) + it('should be able to limit credentials when searching and sorting', async () => { + const credentials = await agent.dataStoreORMGetVerifiableCredentials({ + where: [ + { column: 'type', value: ['VerifiableCredential'] }, + ], + order: [{ column: 'issuanceDate', direction: 'DESC' }], + take: 1, + skip: 1 + }) + expect(credentials).toHaveLength(1) + }) + + it('should be able to limit credentials when sorting', async () => { + const credentialsAllDesc = await agent.dataStoreORMGetVerifiableCredentials({ + order: [{ column: 'issuanceDate', direction: 'DESC' }] + }) + + const credentialsAllAsc = await agent.dataStoreORMGetVerifiableCredentials({ + order: [{ column: 'issuanceDate', direction: 'ASC' }] + }) + + const credentialsIdAllDesc = await agent.dataStoreORMGetVerifiableCredentials({ + order: [{ column: 'id', direction: 'DESC' }] + }) + + const credentialsIdAllAsc = await agent.dataStoreORMGetVerifiableCredentials({ + order: [{ column: 'id', direction: 'ASC' }] + }) + + + const credentials1 = await agent.dataStoreORMGetVerifiableCredentials({ + order: [{ column: 'issuanceDate', direction: 'DESC' }], + take: 1, + skip: 0 + }) + const credentials2 = await agent.dataStoreORMGetVerifiableCredentials({ + order: [{ column: 'issuanceDate', direction: 'DESC' }], + take: 1, + skip: 1 + }) + const credentials3 = await agent.dataStoreORMGetVerifiableCredentials({ + order: [{ column: 'issuanceDate', direction: 'ASC' }], + take: 2, + skip: 0 + }) + const credentials4 = await agent.dataStoreORMGetVerifiableCredentials({ + order: [{ column: 'issuanceDate', direction: 'ASC' }], + take: 2, + skip: 1 + }) + + expect(credentialsAllDesc).toHaveLength(3) + expect(credentials1).toHaveLength(1) + expect(credentials2).toHaveLength(1) + + expect(credentialsIdAllAsc[0].verifiableCredential.id).toEqual('a') + expect(credentialsIdAllAsc[1].verifiableCredential.id).toEqual('b') + expect(credentialsIdAllAsc[2].verifiableCredential.id).toEqual('c') + + expect(credentialsIdAllDesc[0].verifiableCredential.id).toEqual('c') + expect(credentialsIdAllDesc[1].verifiableCredential.id).toEqual('b') + expect(credentialsIdAllDesc[2].verifiableCredential.id).toEqual('a') + + expect(credentialsAllDesc[0].verifiableCredential.issuanceDate).toEqual(credentials1[0].verifiableCredential.issuanceDate) + expect(credentialsAllDesc[1].verifiableCredential.issuanceDate).toEqual(credentials2[0].verifiableCredential.issuanceDate) + + expect(credentialsAllDesc[0].verifiableCredential.issuanceDate).toEqual(credentialsAllAsc[2].verifiableCredential.issuanceDate) + expect(credentialsAllDesc[1].verifiableCredential.issuanceDate).toEqual(credentialsAllAsc[1].verifiableCredential.issuanceDate) + expect(credentialsAllDesc[2].verifiableCredential.issuanceDate).toEqual(credentialsAllAsc[0].verifiableCredential.issuanceDate) + + expect(new Date(credentials1[0].verifiableCredential.issuanceDate).getTime()) + .toBeGreaterThan(new Date(credentials2[0].verifiableCredential.issuanceDate).getTime()) + + expect(new Date(credentials4[0].verifiableCredential.issuanceDate).getTime()) + .toBeGreaterThan(new Date(credentials3[0].verifiableCredential.issuanceDate).getTime()) + }) + it('should be able to delete credential', async () => { const findOptions: FindCredentialsArgs = { where: [{ column: 'issuer', value: [identifier.did] }] } const credentials = await agent.dataStoreORMGetVerifiableCredentials(findOptions) diff --git a/packages/data-store-json/src/data-store-json.ts b/packages/data-store-json/src/data-store-json.ts index 668b5b189..6d69cba9d 100644 --- a/packages/data-store-json/src/data-store-json.ts +++ b/packages/data-store-json/src/data-store-json.ts @@ -585,12 +585,7 @@ function buildQuery>>( return columnValues.includes(authFilterValue) }) } - if (input.skip) { - filteredCollection = filteredCollection.slice(input.skip) - } - if (input.take) { - filteredCollection = filteredCollection.slice(0, input.take) - } + if (input.order && input.order.length > 0) { filteredCollection.sort((a: T, b: T) => { let result = 0 @@ -603,7 +598,9 @@ function buildQuery>>( } const colA = a[col] const colB = b[col] - if (typeof colA?.localeCompare === 'function') { + if (typeof colA?.getTime === 'function') { + result = direction * (colA.getTime() - colB.getTime() || 0) + } else if (typeof colA?.localeCompare === 'function') { result = direction * colA.localeCompare(colB) } else { result = direction * (colA - colB || 0) @@ -613,5 +610,15 @@ function buildQuery>>( return result }) } + + if (input.skip) { + filteredCollection = filteredCollection.slice(input.skip) + } + if (input.take) { + const start = input.skip && input.skip - 1 || 0 + const end = start + input.take + filteredCollection = filteredCollection.slice(start, end) + } + return filteredCollection } diff --git a/packages/data-store/src/data-store-orm.ts b/packages/data-store/src/data-store-orm.ts index 387d5b9ee..8c76fa46d 100644 --- a/packages/data-store/src/data-store-orm.ts +++ b/packages/data-store/src/data-store-orm.ts @@ -201,7 +201,6 @@ export class DataStoreORM implements IAgentPlugin { args: FindArgs, context: AuthorizedDIDContext, ): Promise> { - // FIXME this breaks if args has order param const claims = await (await this.claimsQuery(args, context)).getMany() return claims.map((claim) => ({ hash: claim.credential.hash, @@ -417,8 +416,9 @@ function decorateQB( if (input?.order) { for (const item of input.order) { + qb = qb.addSelect(qb.connection.driver.escape(tableName) + '.' + qb.connection.driver.escape(item.column), item.column) qb = qb.orderBy( - qb.connection.driver.escape(tableName) + '.' + qb.connection.driver.escape(item.column), + qb.connection.driver.escape(item.column), item.direction, ) } diff --git a/packages/test-react-app/headless-tests/browserAgent.browser-test.ts b/packages/test-react-app/headless-tests/browserAgent.browser-test.ts index c945e2249..7558b91dc 100644 --- a/packages/test-react-app/headless-tests/browserAgent.browser-test.ts +++ b/packages/test-react-app/headless-tests/browserAgent.browser-test.ts @@ -1,4 +1,4 @@ -import { getAgent } from '../src/veramo/setup.js' +import { getAgent, setup } from '../src/veramo/setup.js' import keyManager from '../../../__tests__/shared/keyManager.js' import didManager from '../../../__tests__/shared/didManager.js' @@ -20,7 +20,7 @@ jest.setTimeout(JEST_TIMEOUT) describe('Browser integration tests', () => { describe('shared tests', () => { - const testContext = { getAgent, setup: async () => true, tearDown: async () => true } + const testContext = { getAgent, setup, tearDown: async () => true } verifiableDataJWT(testContext) verifiableDataLD(testContext) handleSdrMessage(testContext) diff --git a/packages/test-react-app/src/veramo/setup.ts b/packages/test-react-app/src/veramo/setup.ts index 349614862..b84714033 100644 --- a/packages/test-react-app/src/veramo/setup.ts +++ b/packages/test-react-app/src/veramo/setup.ts @@ -43,10 +43,17 @@ import { FakeDidProvider, FakeDidResolver } from '@veramo/test-utils' const INFURA_PROJECT_ID = '33aab9e0334c44b0a2e0c57c15302608' const DB_SECRET_KEY = '29739248cad1bd1a0fc4d9b75cd4d2990de535baf5caadfdf8d8f86664aa83' -const memoryJsonStore = { +let memoryJsonStore = { notifyUpdate: () => Promise.resolve(), } +export async function setup() { + memoryJsonStore = { + notifyUpdate: () => Promise.resolve(), + } + return true +} + type InstalledPlugins = IResolver & IKeyManager & IDIDManager &