Skip to content

Commit

Permalink
feat(askar): use published test npm packages
Browse files Browse the repository at this point in the history
  • Loading branch information
genaris committed Jan 15, 2023
1 parent ae35f4b commit 035f848
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 46 deletions.
4 changes: 2 additions & 2 deletions packages/askar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@
},
"dependencies": {
"@aries-framework/core": "0.3.2",
"aries-askar-test-shared": "^0.0.1",
"aries-askar-test-shared": "^0.1.0-dev.2",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"rxjs": "^7.2.0",
"tsyringe": "^4.7.0"
},
"devDependencies": {
"aries-askar-test-nodejs": "^0.0.1",
"aries-askar-test-nodejs": "^0.1.0-dev.2",
"@aries-framework/node": "0.3.2",
"rimraf": "~3.0.2",
"typescript": "~4.3.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/askar/src/AskarModule.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { AskarModuleConfigOptions } from './AskarModuleConfig'
import type { DependencyManager, Module } from '@aries-framework/core'

import { registerAriesAskar } from 'aries-askar-shared'
import { registerAriesAskar } from 'aries-askar-test-shared'

import { AskarModuleConfig } from './AskarModuleConfig'
import { AskarSymbol } from './types'
Expand Down
73 changes: 58 additions & 15 deletions packages/askar/src/storage/AskarStorageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ import type {
} from '@aries-framework/core'
import type { EntryObject } from 'aries-askar-test-shared'

import { WalletError, RecordNotFoundError, injectable, JsonTransformer } from '@aries-framework/core'
import {
RecordDuplicateError,
WalletError,
RecordNotFoundError,
injectable,
JsonTransformer,
} from '@aries-framework/core'
import { Scan } from 'aries-askar-test-shared'

import { askarErrors, isAskarError } from '../utils/askarError'
import { assertAskarWallet } from '../utils/assertAskarWallet'

@injectable()
Expand Down Expand Up @@ -95,13 +102,13 @@ export class AskarStorageService<T extends BaseRecord> implements StorageService
* method.
*/
// TODO: Transform to Askar format
private indyQueryFromSearchQuery(query: Query<T>): Record<string, unknown> {
private askarQueryFromSearchQuery(query: Query<T>): Record<string, unknown> {
// eslint-disable-next-line prefer-const
let { $and, $or, $not, ...tags } = query

$and = ($and as Query<T>[] | undefined)?.map((q) => this.indyQueryFromSearchQuery(q))
$or = ($or as Query<T>[] | undefined)?.map((q) => this.indyQueryFromSearchQuery(q))
$not = $not ? this.indyQueryFromSearchQuery($not as Query<T>) : undefined
$and = ($and as Query<T>[] | undefined)?.map((q) => this.askarQueryFromSearchQuery(q))
$or = ($or as Query<T>[] | undefined)?.map((q) => this.askarQueryFromSearchQuery(q))
$not = $not ? this.askarQueryFromSearchQuery($not as Query<T>) : undefined

const indyQuery = {
...this.transformFromRecordTagValues(tags as unknown as TagsBase),
Expand Down Expand Up @@ -134,6 +141,10 @@ export class AskarStorageService<T extends BaseRecord> implements StorageService
try {
await session.insert({ category: record.type, name: record.id, value, tags })
} catch (error) {
if (isAskarError(error) && error.code === askarErrors.Duplicate) {
throw new RecordDuplicateError(`Record with id ${record.id} already exists`, { recordType: record.type })
}

throw new WalletError('Error saving record', { cause: error })
}
}
Expand All @@ -149,6 +160,13 @@ export class AskarStorageService<T extends BaseRecord> implements StorageService
try {
await session.replace({ category: record.type, name: record.id, value, tags })
} catch (error) {
if (isAskarError(error) && error.code === askarErrors.NotFound) {
throw new RecordNotFoundError(`record with id ${record.id} not found.`, {
recordType: record.type,
cause: error,
})
}

throw new WalletError('Error updating record', { cause: error })
}
}
Expand All @@ -161,6 +179,12 @@ export class AskarStorageService<T extends BaseRecord> implements StorageService
try {
await session.remove({ category: record.type, name: record.id })
} catch (error) {
if (isAskarError(error) && error.code === askarErrors.NotFound) {
throw new RecordNotFoundError(`record with id ${record.id} not found.`, {
recordType: record.type,
cause: error,
})
}
throw new WalletError('Error deleting record', { cause: error })
}
}
Expand All @@ -177,6 +201,12 @@ export class AskarStorageService<T extends BaseRecord> implements StorageService
try {
await session.remove({ category: recordClass.type, name: id })
} catch (error) {
if (isAskarError(error) && error.code === askarErrors.NotFound) {
throw new RecordNotFoundError(`record with id ${id} not found.`, {
recordType: recordClass.type,
cause: error,
})
}
throw new WalletError('Error deleting record', { cause: error })
}
}
Expand All @@ -186,15 +216,28 @@ export class AskarStorageService<T extends BaseRecord> implements StorageService
assertAskarWallet(agentContext.wallet)
const session = (agentContext.wallet as AskarWallet).session

const record = await session.fetch({ category: recordClass.type, name: id })

if (!record) {
throw new RecordNotFoundError(`record with id ${id} not found.`, {
recordType: recordClass.type,
})
try {
const record = await session.fetch({ category: recordClass.type, name: id })
if (!record) {
throw new RecordNotFoundError(`record with id ${id} not found.`, {
recordType: recordClass.type,
})
}
return this.recordToInstance(record, recordClass)
} catch (error) {
if (
isAskarError(error) &&
(error.code === askarErrors.NotFound ||
// FIXME: this is current output from askar wrapper but does not describe specifically a not found scenario
error.message === 'Received null pointer. The native library could not find the value.')
) {
throw new RecordNotFoundError(`record with id ${id} not found.`, {
recordType: recordClass.type,
cause: error,
})
}
throw new WalletError(`Error getting record`, { cause: error })
}

return this.recordToInstance(record, recordClass)
}

/** @inheritDoc */
Expand All @@ -220,12 +263,12 @@ export class AskarStorageService<T extends BaseRecord> implements StorageService
assertAskarWallet(agentContext.wallet)
const store = agentContext.wallet.handle

const indyQuery = this.indyQueryFromSearchQuery(query)
const askarQuery = this.askarQueryFromSearchQuery(query)

const scan = new Scan({
category: recordClass.type,
store,
tagFilter: indyQuery,
tagFilter: askarQuery,
})

const records = await scan.fetchAll()
Expand Down
50 changes: 32 additions & 18 deletions packages/askar/src/storage/__tests__/AskarStorageService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { AgentContext, TagsBase } from '@aries-framework/core'
import { SigningProviderRegistry, RecordDuplicateError, RecordNotFoundError } from '@aries-framework/core'
import { NodeJSAriesAskar } from 'aries-askar-test-nodejs'
import { registerAriesAskar } from 'aries-askar-test-shared'
import { TextEncoder } from 'util'

import { TestRecord } from '../../../../core/src/storage/__tests__/TestRecord'
import { agentDependencies, getAgentConfig, getAgentContext } from '../../../../core/tests/helpers'
Expand All @@ -13,10 +14,11 @@ describe('AskarStorageService', () => {
let wallet: AskarWallet
let storageService: AskarStorageService<TestRecord>
let agentContext: AgentContext
const askar = new NodeJSAriesAskar()

beforeEach(async () => {
const agentConfig = getAgentConfig('AskarStorageServiceTest')
registerAriesAskar({ askar: new NodeJSAriesAskar() })
registerAriesAskar({ askar })

wallet = new AskarWallet(agentConfig.logger, new agentDependencies.FileSystem(), new SigningProviderRegistry([]))
agentContext = getAgentContext({
Expand All @@ -43,7 +45,7 @@ describe('AskarStorageService', () => {
return record
}

describe.skip('tag transformation', () => {
describe('tag transformation', () => {
it('should correctly transform tag values to string before storing', async () => {
const record = await insertRecord({
id: 'test-id',
Expand All @@ -58,12 +60,15 @@ describe('AskarStorageService', () => {
},
})

const retrieveRecord = await indy.getWalletRecord(wallet.handle, record.type, record.id, {
retrieveType: true,
retrieveTags: true,
const retrieveRecord = await askar.sessionFetch({
category: record.type,
name: record.id,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
sessionHandle: wallet.session.handle!,
forUpdate: false,
})

expect(retrieveRecord.tags).toEqual({
expect(JSON.parse(retrieveRecord.getTags(0))).toEqual({
someBoolean: '1',
someOtherBoolean: '0',
someStringValue: 'string',
Expand All @@ -75,15 +80,23 @@ describe('AskarStorageService', () => {
})

it('should correctly transform tag values from string after retrieving', async () => {
await indy.addWalletRecord(wallet.handle, TestRecord.type, 'some-id', '{}', {
someBoolean: '1',
someOtherBoolean: '0',
someStringValue: 'string',
'anArrayValue:foo': '1',
'anArrayValue:bar': '1',
// booleans are stored as '1' and '0' so we store the string values '1' and '0' as 'n__1' and 'n__0'
someStringNumberValue: 'n__1',
anotherStringNumberValue: 'n__0',
await askar.sessionUpdate({
category: TestRecord.type,
name: 'some-id',
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
sessionHandle: wallet.session.handle!,
value: new Uint8Array(new TextEncoder().encode('{}')),
tags: {
someBoolean: '1',
someOtherBoolean: '0',
someStringValue: 'string',
'anArrayValue:foo': '1',
'anArrayValue:bar': '1',
// booleans are stored as '1' and '0' so we store the string values '1' and '0' as 'n__1' and 'n__0'
someStringNumberValue: 'n__1',
anotherStringNumberValue: 'n__0',
},
operation: 0, // EntryOperation.Insert
})

const record = await storageService.getById(agentContext, TestRecord, 'some-id')
Expand Down Expand Up @@ -187,15 +200,16 @@ describe('AskarStorageService', () => {
})
})

describe.skip('findByQuery()', () => {
describe('findByQuery()', () => {
it('should retrieve all records that match the query', async () => {
const expectedRecord = await insertRecord({ tags: { myTag: 'foobar' } })
const expectedRecord2 = await insertRecord({ tags: { myTag: 'foobar' } })
await insertRecord({ tags: { myTag: 'notfoobar' } })

const records = await storageService.findByQuery(agentContext, TestRecord, { myTag: 'foobar' })

expect(records.length).toBe(1)
expect(records[0]).toEqual(expectedRecord)
expect(records.length).toBe(2)
expect(records).toEqual(expect.arrayContaining([expectedRecord, expectedRecord2]))
})

it('finds records using $and statements', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/askar/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { AriesAskar } from 'aries-askar-shared'
import type { AriesAskar } from 'aries-askar-test-shared'

export const AskarSymbol = Symbol('Askar')
export type { AriesAskar }
16 changes: 16 additions & 0 deletions packages/askar/src/utils/askarError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { AriesAskarError } from 'aries-askar-test-shared'

export enum askarErrors {
Success = 0,
Backend = 1,
Busy = 2,
Duplicate = 3,
Encryption = 4,
Input = 5,
NotFound = 6,
Unexpected = 7,
Unsupported = 8,
Custom = 100,
}

export const isAskarError = (error: Error) => error instanceof AriesAskarError
1 change: 1 addition & 0 deletions packages/askar/src/wallet/AskarWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
TypedArrayEncoder,
FileSystem,
} from '@aries-framework/core'
// eslint-disable-next-line import/order
import { CryptoBox, Store, StoreKeyMethod, Key as AskarKey, keyAlgFromString } from 'aries-askar-test-shared'

const isError = (error: unknown): error is Error => error instanceof Error
Expand Down
34 changes: 25 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1791,6 +1791,21 @@
semver "^7.3.5"
tar "^6.1.11"

"@mapbox/node-pre-gyp@^1.0.10":
version "1.0.10"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c"
integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==
dependencies:
detect-libc "^2.0.0"
https-proxy-agent "^5.0.0"
make-dir "^3.1.0"
node-fetch "^2.6.7"
nopt "^5.0.0"
npmlog "^5.0.1"
rimraf "^3.0.2"
semver "^7.3.5"
tar "^6.1.11"

"@mattrglobal/bbs-signatures@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@mattrglobal/bbs-signatures/-/bbs-signatures-1.0.0.tgz#8ff272c6d201aadab7e08bd84dbfd6e0d48ba12d"
Expand Down Expand Up @@ -3007,22 +3022,23 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"

aries-askar-test-nodejs@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/aries-askar-test-nodejs/-/aries-askar-test-nodejs-0.0.1.tgz#bddb73e2bc2bdb5ed12f839282879e059c768076"
integrity sha512-I0SBjisZiyFxXQtVVmQzYAKaXneFhVm5W/ZK8Hn44FFkI++IYTzT5/iT1g1H+Jsj8LSY+Boex+CL1o4B6qGfGw==
aries-askar-test-nodejs@^0.1.0-dev.2:
version "0.1.0-dev.2"
resolved "https://registry.yarnpkg.com/aries-askar-test-nodejs/-/aries-askar-test-nodejs-0.1.0-dev.2.tgz#c7d92de5cd3afa2522c772491ad3be2766e603ee"
integrity sha512-CDYMpNn3rIjZvb+LAGMmEnH9Sx7f2vws/zZWl6TW6yaMJ5QfZgVGgCLDRlpFBuX5nXpt+mDuR91N0ppD/nhSoA==
dependencies:
aries-askar-test-shared "*"
"@mapbox/node-pre-gyp" "^1.0.10"
aries-askar-test-shared "0.1.0-dev.2"
ffi-napi "^4.0.3"
node-cache "^5.1.2"
ref-array-di "^1.2.2"
ref-napi "^3.0.3"
ref-struct-di "^1.1.1"

aries-askar-test-shared@*, aries-askar-test-shared@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/aries-askar-test-shared/-/aries-askar-test-shared-0.0.1.tgz#3f7492139ef902aa1371cc532f887b5eea2dd445"
integrity sha512-EhQW2j94cV7l3fgwDxr9mdS7JTAtOrgF6Ze0vA+i2dypOJrWzQpMdmLQKWyE90vEXoEP0yxjpSTKh6qPniySsA==
aries-askar-test-shared@0.1.0-dev.2, aries-askar-test-shared@^0.1.0-dev.2:
version "0.1.0-dev.2"
resolved "https://registry.yarnpkg.com/aries-askar-test-shared/-/aries-askar-test-shared-0.1.0-dev.2.tgz#052b5ef695609ad5c4dacafcb4e411651f97302e"
integrity sha512-P6lIHupmW42UaqUnjutDEJgbat8w/0nkndrwMYsDVk5Z4uzGSLKVnF0pwO72l8s6SH87V8wWnhNJ1DS2tBBGlA==
dependencies:
fast-text-encoding "^1.0.3"

Expand Down

0 comments on commit 035f848

Please sign in to comment.