diff --git a/apps/shared/src/events/__tests__/baseEvents.spec.ts b/apps/shared/src/events/__tests__/baseEvents.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..a037c79981f78c8f8c48180b51486936db3fdc73 --- /dev/null +++ b/apps/shared/src/events/__tests__/baseEvents.spec.ts @@ -0,0 +1,16 @@ +import { BaseEvent } from '../baseEvents.js'; + +describe('Base Events', () => { + it('should return module', () => { + jest.requireActual('../baseEvents'); + }); + + it('should create a new base event', () => { + const baseEvent = new BaseEvent({ some: 'data' }); + + expect(typeof baseEvent.id).toStrictEqual('string'); + expect(baseEvent.type).toStrictEqual('BaseEvent'); + expect(baseEvent.timestamp).toBeInstanceOf(Date); + expect(baseEvent.data).toMatchObject({ some: 'data' }); + }); +}); diff --git a/apps/shared/src/events/__tests__/connectionEvents.spec.ts b/apps/shared/src/events/__tests__/connectionEvents.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..42ea6e6b7b46ed3c38bc46c279d5841ff444d2f2 --- /dev/null +++ b/apps/shared/src/events/__tests__/connectionEvents.spec.ts @@ -0,0 +1,52 @@ +import { + ConnectionRecord, + DidExchangeRole, + DidExchangeState, +} from '@aries-framework/core'; + +import { + EventDidcommConnectionsCreateWithSelf, + EventDidcommConnectionsGetAll, + EventDidcommConnectionsGetById, +} from '../connectionEvents.js'; + +describe('Connection Events', () => { + it('should return module', () => { + jest.requireActual('../connectionEvents'); + }); + + it('should create a new connections get all event', () => { + const event = new EventDidcommConnectionsGetAll([]); + + expect(typeof event.id).toStrictEqual('string'); + expect(event.type).toStrictEqual('EventDidcommConnectionsGetAll'); + expect(event.timestamp).toBeInstanceOf(Date); + expect(event.instance).toMatchObject([]); + }); + + it('should create a new connections get by id event', () => { + const event = new EventDidcommConnectionsGetById(null); + + expect(typeof event.id).toStrictEqual('string'); + expect(event.type).toStrictEqual('EventDidcommConnectionsGetById'); + expect(event.timestamp).toBeInstanceOf(Date); + expect(event.instance).toBeNull(); + }); + + it('should create a new connections create with self event', () => { + const event = new EventDidcommConnectionsCreateWithSelf( + new ConnectionRecord({ + role: DidExchangeRole.Requester, + state: DidExchangeState.Completed, + }), + ); + + expect(typeof event.id).toStrictEqual('string'); + expect(event.type).toStrictEqual('EventDidcommConnectionsCreateWithSelf'); + expect(event.timestamp).toBeInstanceOf(Date); + expect(event.instance).toMatchObject({ + role: DidExchangeRole.Requester, + state: DidExchangeState.Completed, + }); + }); +}); diff --git a/apps/shared/src/events/baseEvents.ts b/apps/shared/src/events/baseEvents.ts new file mode 100644 index 0000000000000000000000000000000000000000..7be7e863412e97cc954681c1a7145ec1c4984e20 --- /dev/null +++ b/apps/shared/src/events/baseEvents.ts @@ -0,0 +1,15 @@ +import { utils } from '@aries-framework/core'; + +export class BaseEvent<T = Record<string, unknown>> { + public readonly id: string; + public readonly type: string; + public readonly timestamp: Date; + public readonly data: T; + + public constructor(data: T, id?: string, type?: string, timestamp?: Date) { + this.id = id ?? utils.uuid(); + this.type = type ?? this.constructor.name; + this.timestamp = timestamp ?? new Date(); + this.data = data; + } +} diff --git a/apps/shared/src/events/connectionEvents.ts b/apps/shared/src/events/connectionEvents.ts new file mode 100644 index 0000000000000000000000000000000000000000..1831f5cd2249438ed2498eabfaa8e19e7a9b349b --- /dev/null +++ b/apps/shared/src/events/connectionEvents.ts @@ -0,0 +1,71 @@ +import { + ConnectionRecord, + DidDocument, + JsonTransformer, +} from '@aries-framework/core'; + +import { BaseEvent } from './baseEvents.js'; + +export class EventInfoPublicDid extends BaseEvent<DidDocument> { + public static token = 'didcomm.info.publicDid'; + + public get instance() { + return JsonTransformer.fromJSON(this.data, DidDocument); + } + + public static fromEvent(e: EventInfoPublicDid) { + return new EventInfoPublicDid(e.data, e.id, e.type, e.timestamp); + } +} + +export class EventDidcommConnectionsGetAll extends BaseEvent< + Array<ConnectionRecord> +> { + public static token = 'didcomm.connections.getAll'; + + public get instance() { + return this.data.map((d) => JsonTransformer.fromJSON(d, ConnectionRecord)); + } + + public static fromEvent(e: EventDidcommConnectionsGetAll) { + return new EventDidcommConnectionsGetAll(e.data, e.id, e.type, e.timestamp); + } +} + +export class EventDidcommConnectionsGetById extends BaseEvent<ConnectionRecord | null> { + public static token = 'didcomm.connections.getById'; + + public get instance() { + return this.data + ? JsonTransformer.fromJSON(this.data, ConnectionRecord) + : null; + } + + public static fromEvent(e: EventDidcommConnectionsGetById) { + return new EventDidcommConnectionsGetById( + e.data, + e.id, + e.type, + e.timestamp, + ); + } +} + +export class EventDidcommConnectionsCreateWithSelf extends BaseEvent<ConnectionRecord> { + public static token = 'didcomm.connections.createWithSelf'; + + public get instance() { + return JsonTransformer.fromJSON(this.data, ConnectionRecord, { + validate: true, + }); + } + + public static fromEvent(e: EventDidcommConnectionsCreateWithSelf) { + return new EventDidcommConnectionsCreateWithSelf( + e.data, + e.id, + e.type, + e.timestamp, + ); + } +} diff --git a/apps/shared/src/events/events.spec.ts b/apps/shared/src/events/events.spec.ts deleted file mode 100644 index cf3df5cbaa8ca2c5c939d3fdc45f7e62a0b40b3d..0000000000000000000000000000000000000000 --- a/apps/shared/src/events/events.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { BaseEvent, EventDidcommConnectionsGetAll } from './events.js'; - -describe('check logger', () => { - it('should return module', () => { - jest.requireActual('./events'); - }); - - it('should create a new base event', () => { - const baseEvent = new BaseEvent({ some: 'data' }); - - expect(typeof baseEvent.id).toStrictEqual('string'); - expect(baseEvent.type).toStrictEqual('BaseEvent'); - expect(baseEvent.timestamp).toBeInstanceOf(Date); - expect(baseEvent.data).toMatchObject({ some: 'data' }); - }); - - it('should create a new connections get all event', () => { - const getAllConnectionsEvent = new EventDidcommConnectionsGetAll({ - connections: [], - }); - - expect(typeof getAllConnectionsEvent.id).toStrictEqual('string'); - expect(getAllConnectionsEvent.type).toStrictEqual( - 'EventDidcommConnectionsGetAll', - ); - expect(getAllConnectionsEvent.timestamp).toBeInstanceOf(Date); - expect(getAllConnectionsEvent.data).toMatchObject({ connections: [] }); - }); -}); diff --git a/apps/shared/src/events/events.ts b/apps/shared/src/events/events.ts deleted file mode 100644 index 3702b4b5ae86521d04b031346eefbb8bfa2e165b..0000000000000000000000000000000000000000 --- a/apps/shared/src/events/events.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { DidDocument, ConnectionRecord } from '@aries-framework/core'; - -import { utils } from '@aries-framework/core'; - -export class BaseEvent< - T extends Record<string, unknown> = Record<string, unknown>, -> { - public id: string; - public type: string; - public timestamp: Date; - public data: T; - - public constructor(data: T) { - this.id = utils.uuid(); - this.type = this.constructor.name; - this.timestamp = new Date(); - this.data = data; - } -} - -export class EventInfoPublicDid extends BaseEvent<{ - didDocument: DidDocument; -}> {} - -export class EventDidcommConnectionsGetAll extends BaseEvent<{ - connections: Array<ConnectionRecord>; -}> {} - -export class EventDidcommConnectionsGetById extends BaseEvent<{ - connection: ConnectionRecord | null; -}> {} diff --git a/apps/shared/src/index.ts b/apps/shared/src/index.ts index 53e4cb004b239fe3dd92d20c6d9f0cfccf213533..bde9dc3bf812398014890ba91428b1a4a9219a0d 100644 --- a/apps/shared/src/index.ts +++ b/apps/shared/src/index.ts @@ -4,4 +4,4 @@ export * from './health/health.controller.js'; export * from './logging/logger.js'; export * from './logging/logAxiosError.js'; -export * from './events/events.js'; +export * from './events/connectionEvents.js'; diff --git a/apps/shared/src/logging/logger.spec.ts b/apps/shared/src/logging/__tests__/logger.spec.ts similarity index 68% rename from apps/shared/src/logging/logger.spec.ts rename to apps/shared/src/logging/__tests__/logger.spec.ts index e6126f22cf7278b5405739e5e4e52f7ab4d5dccf..a01b8629df32f23710896874e824a03ba6c69252 100644 --- a/apps/shared/src/logging/logger.spec.ts +++ b/apps/shared/src/logging/__tests__/logger.spec.ts @@ -1,5 +1,5 @@ describe('check logger', () => { it('should return module', () => { - jest.requireActual('./logger'); + jest.requireActual('../logger'); }); }); diff --git a/apps/ssi-abstraction/package.json b/apps/ssi-abstraction/package.json index 3a05f268eb6f1b7e5a683360f82b92cc6bb898ae..0d6e996af232b503bf9b2593320e6e78a8db66e6 100644 --- a/apps/ssi-abstraction/package.json +++ b/apps/ssi-abstraction/package.json @@ -17,7 +17,7 @@ "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:e2e": "jest --config ./test/jest.config.js" + "test:e2e": "jest --config ./test/jest.config.js --runInBand" }, "dependencies": { "@aries-framework/anoncreds": "0.4.2", diff --git a/apps/ssi-abstraction/src/agent/__tests__/agent.controller.spec.ts b/apps/ssi-abstraction/src/agent/__tests__/agent.controller.spec.ts index be3157d5f61eb7948a84f0dc32e38b7296052008..5de798e4f6d183ba21e5b251b64afe35b7046136 100644 --- a/apps/ssi-abstraction/src/agent/__tests__/agent.controller.spec.ts +++ b/apps/ssi-abstraction/src/agent/__tests__/agent.controller.spec.ts @@ -26,7 +26,7 @@ describe('AgentController', () => { jest.spyOn(agentService, 'getPublicDid').mockResolvedValue(result); const event = await agentController.publicDid(); - expect(event.data).toMatchObject({ didDocument: result }); + expect(event.data).toMatchObject(result); }); }); }); diff --git a/apps/ssi-abstraction/src/agent/agent.controller.ts b/apps/ssi-abstraction/src/agent/agent.controller.ts index e77bb16eecb7a7ab35bd2cc09ca7752eccbf39af..5469aecb6f29b568dae22308a704de57f6dc0477 100644 --- a/apps/ssi-abstraction/src/agent/agent.controller.ts +++ b/apps/ssi-abstraction/src/agent/agent.controller.ts @@ -8,10 +8,10 @@ import { AgentService } from './agent.service.js'; export class AgentController { public constructor(private agent: AgentService) {} - @MessagePattern('info.publicDid') + @MessagePattern(EventInfoPublicDid.token) public async publicDid() { const didDocument = await this.agent.getPublicDid(); - return new EventInfoPublicDid({ didDocument }); + return new EventInfoPublicDid(didDocument); } } diff --git a/apps/ssi-abstraction/src/agent/agent.service.ts b/apps/ssi-abstraction/src/agent/agent.service.ts index fd5f69ff538b33ba16f572a5c01743b3ff743734..0d68b5e3c1ea246439dcf3977901188f465cd45a 100644 --- a/apps/ssi-abstraction/src/agent/agent.service.ts +++ b/apps/ssi-abstraction/src/agent/agent.service.ts @@ -1,6 +1,7 @@ import type { LedgerIds } from '../config/ledger.js'; import type { InitConfig } from '@aries-framework/core'; import type { IndyVdrPoolConfig } from '@aries-framework/indy-vdr'; +import type { OnApplicationShutdown } from '@nestjs/common'; import { AnonCredsModule } from '@aries-framework/anoncreds'; import { AnonCredsRsModule } from '@aries-framework/anoncreds-rs'; @@ -41,7 +42,7 @@ import { AgentLogger } from './logger.js'; export type AppAgent = Agent<AgentService['modules']>; @Injectable() -export class AgentService { +export class AgentService implements OnApplicationShutdown { public agent: AppAgent; private configService: ConfigService; @@ -50,7 +51,6 @@ export class AgentService { this.configService = configService; const inboundPort = this.configService.get('agent.inboundPort'); - this.agent = new Agent({ config: this.config, modules: this.modules, @@ -70,7 +70,7 @@ export class AgentService { const { name, walletId, walletKey, host, inboundPort, path } = this.configService.get('agent'); - const endpoints = [`${host}${inboundPort}${path}`]; + const endpoints = [`${host}:${inboundPort}${path}`]; return { label: name, @@ -200,7 +200,9 @@ export class AgentService { logger.info('Agent initialized'); } - public async onModuleDestory() { + public async onApplicationShutdown() { + if (!this.agent.isInitialized) return; + await this.agent.shutdown(); } } diff --git a/apps/ssi-abstraction/src/agent/connections/__tests__/connections.controller.spec.ts b/apps/ssi-abstraction/src/agent/connections/__tests__/connections.controller.spec.ts index da7bf4384212a590059f4c62e33b345ecb4a2b61..2bcb88b5d4daf15197e5997ca990e4bad6218297 100644 --- a/apps/ssi-abstraction/src/agent/connections/__tests__/connections.controller.spec.ts +++ b/apps/ssi-abstraction/src/agent/connections/__tests__/connections.controller.spec.ts @@ -1,5 +1,8 @@ -import type { ConnectionRecord } from '@aries-framework/core'; - +import { + ConnectionRecord, + DidExchangeRole, + DidExchangeState, +} from '@aries-framework/core'; import { Test } from '@nestjs/testing'; import { mockConfigModule } from '../../../config/__tests__/mockConfig.js'; @@ -25,28 +28,42 @@ describe('ConnectionsController', () => { describe('get all', () => { it('should get all the connection records of the agent', async () => { const result: Array<ConnectionRecord> = []; - jest - .spyOn(connectionsService, 'getAll') - .mockImplementation(() => Promise.resolve(result)); + jest.spyOn(connectionsService, 'getAll').mockResolvedValue(result); const connectionsEvent = await connectionsController.getAll(); - expect(connectionsEvent.data).toStrictEqual({ connections: result }); + expect(connectionsEvent.data).toStrictEqual(result); }); }); describe('get by id', () => { it('should get a connection record by id', async () => { const result: ConnectionRecord | null = null; - jest - .spyOn(connectionsService, 'getById') - .mockImplementation(() => Promise.resolve(result)); + jest.spyOn(connectionsService, 'getById').mockResolvedValue(result); const connectionsEvent = await connectionsController.getById({ id: 'id', }); - expect(connectionsEvent.data).toStrictEqual({ connection: result }); + expect(connectionsEvent.data).toStrictEqual(result); + }); + }); + + describe('create connection with self', () => { + it('should create a connection with itself', async () => { + const result: ConnectionRecord = new ConnectionRecord({ + state: DidExchangeState.Completed, + role: DidExchangeRole.Requester, + }); + + jest + .spyOn(connectionsService, 'createConnectionWithSelf') + .mockResolvedValue(result); + + const connectionsEvent = + await connectionsController.createConnectionWithSelf(); + + expect(connectionsEvent.data).toStrictEqual(result); }); }); }); diff --git a/apps/ssi-abstraction/src/agent/connections/connections.controller.ts b/apps/ssi-abstraction/src/agent/connections/connections.controller.ts index fa034d562aaca7e42f7ffe456d1676a7c14ef526..322f3376da65439c0ee86d74047c76f28db96ac8 100644 --- a/apps/ssi-abstraction/src/agent/connections/connections.controller.ts +++ b/apps/ssi-abstraction/src/agent/connections/connections.controller.ts @@ -3,6 +3,7 @@ import { MessagePattern } from '@nestjs/microservices'; import { EventDidcommConnectionsGetById, EventDidcommConnectionsGetAll, + EventDidcommConnectionsCreateWithSelf, } from '@ocm/shared'; import { ConnectionsService } from './connections.service.js'; @@ -11,21 +12,28 @@ import { ConnectionsService } from './connections.service.js'; export class ConnectionsController { public constructor(private connectionsService: ConnectionsService) {} - @MessagePattern('didcomm.connections.getAll') + @MessagePattern(EventDidcommConnectionsGetAll.token) public async getAll(): Promise<EventDidcommConnectionsGetAll> { - return new EventDidcommConnectionsGetAll({ - connections: await this.connectionsService.getAll(), - }); + return new EventDidcommConnectionsGetAll( + await this.connectionsService.getAll(), + ); } - @MessagePattern('didcomm.connections.getById') + @MessagePattern(EventDidcommConnectionsGetById.token) public async getById({ id, }: { id: string; }): Promise<EventDidcommConnectionsGetById> { - return new EventDidcommConnectionsGetById({ - connection: await this.connectionsService.getById(id), - }); + return new EventDidcommConnectionsGetById( + await this.connectionsService.getById(id), + ); + } + + @MessagePattern(EventDidcommConnectionsCreateWithSelf.token) + public async createConnectionWithSelf(): Promise<EventDidcommConnectionsCreateWithSelf> { + return new EventDidcommConnectionsCreateWithSelf( + await this.connectionsService.createConnectionWithSelf(), + ); } } diff --git a/apps/ssi-abstraction/src/agent/connections/connections.service.ts b/apps/ssi-abstraction/src/agent/connections/connections.service.ts index fe3123f4d11dad728a9ac06137282134d5f461c4..4c6901cd52a6efb5d07993104564adfc4e6657ac 100644 --- a/apps/ssi-abstraction/src/agent/connections/connections.service.ts +++ b/apps/ssi-abstraction/src/agent/connections/connections.service.ts @@ -1,8 +1,17 @@ import type { AppAgent } from '../agent.service.js'; -import type { ConnectionRecord } from '@aries-framework/core'; +import type { + ConnectionRecord, + ConnectionStateChangedEvent, +} from '@aries-framework/core'; +import { + ConnectionEventTypes, + ConnectionRepository, + DidExchangeState, +} from '@aries-framework/core'; import { Injectable } from '@nestjs/common'; +import { MetadataTokens } from '../../common/constants.js'; import { AgentService } from '../agent.service.js'; @Injectable() @@ -20,4 +29,32 @@ export class ConnectionsService { public async getById(id: string): Promise<ConnectionRecord | null> { return await this.agent.connections.findById(id); } + + public async createConnectionWithSelf(): Promise<ConnectionRecord> { + const outOfBandRecord = await this.agent.oob.createInvitation(); + const invitation = outOfBandRecord.outOfBandInvitation; + + void this.agent.oob.receiveInvitation(invitation); + + return new Promise((resolve) => + this.agent.events.on<ConnectionStateChangedEvent>( + ConnectionEventTypes.ConnectionStateChanged, + async ({ payload: { connectionRecord } }) => { + if (connectionRecord.state !== DidExchangeState.Completed) return; + connectionRecord.metadata.set( + MetadataTokens.GAIA_X_CONNECTION_METADATA_KEY, + { + trusted: true, + }, + ); + + const connRepo = + this.agent.dependencyManager.resolve(ConnectionRepository); + await connRepo.update(this.agent.context, connectionRecord); + + resolve(connectionRecord); + }, + ), + ); + } } diff --git a/apps/ssi-abstraction/src/common/constants.ts b/apps/ssi-abstraction/src/common/constants.ts index ab0f748d91361cd4b590e77e8530aa864989c1f0..723add9e86ac1f1618c37e1babc3742cc90195dc 100644 --- a/apps/ssi-abstraction/src/common/constants.ts +++ b/apps/ssi-abstraction/src/common/constants.ts @@ -1,3 +1,7 @@ export enum NATSServices { SERVICE_NAME = 'SSI_ABSTRACTION_SERVICE', } + +export enum MetadataTokens { + GAIA_X_CONNECTION_METADATA_KEY = 'gaia_x_connection_metadata_key', +} diff --git a/apps/ssi-abstraction/src/config/__tests__/mockConfig.ts b/apps/ssi-abstraction/src/config/__tests__/mockConfig.ts index a1828c7843a28ddfc32e859201fd7d73753270f3..8a5eb2ed2efb4ddbcbea7f3d4975a60a29a83af7 100644 --- a/apps/ssi-abstraction/src/config/__tests__/mockConfig.ts +++ b/apps/ssi-abstraction/src/config/__tests__/mockConfig.ts @@ -1,27 +1,27 @@ import type { AppConfig } from '../config.js'; -import { AutoAcceptCredential } from '@aries-framework/core'; +import { AutoAcceptCredential, utils } from '@aries-framework/core'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { validationSchema } from '../validation.js'; const mockConfig = (port: number = 3001): AppConfig => ({ agentHost: '', - port:3000, + port: 3000, jwtSecret: '', nats: { url: 'localhost', }, agent: { name: 'my-test-agent', - walletId: 'some-id', + walletId: utils.uuid(), walletKey: 'some-key', ledgerIds: [], - host: '3000', + host: 'http://localhost', inboundPort: port, path: '', publicDidSeed: '', - autoAcceptConnection: false, + autoAcceptConnection: true, autoAcceptCredential: AutoAcceptCredential.ContentApproved, }, }); @@ -50,7 +50,7 @@ describe('configuration', () => { it('should be able to extract root value as object', () => { const configuration = new ConfigService(mockConfig()); - expect(configuration.get('agent')).toMatchObject(mockedConfig.agent); + expect(configuration.get('agent')).toHaveProperty('name'); }); it('should be able to extract nested values', () => { diff --git a/apps/ssi-abstraction/src/config/config.ts b/apps/ssi-abstraction/src/config/config.ts index d3446365c8e2c88c27ce0df29a3fc6a8eac6d536..c792418b8219dee1145dbf3b9903e6b2c4172f42 100644 --- a/apps/ssi-abstraction/src/config/config.ts +++ b/apps/ssi-abstraction/src/config/config.ts @@ -38,7 +38,7 @@ export const config = (): AppConfig => ({ walletKey: process.env.AGENT_WALLET_KEY || '', ledgerIds: process.env.AGENT_LEDGER_ID?.split(','), host: process.env.AGENT_HOST || '', - inboundPort: parseInt(process.env.AGENT_INBOUND_PORT || '3001'), + inboundPort: Number(process.env.AGENT_INBOUND_PORT || '3001'), path: process.env.AGENT_URL_PATH || '', publicDidSeed: process.env.AGENT_PUBLIC_DID_SEED || '', autoAcceptConnection: process.env.AGENT_AUTO_ACCEPT_CONNECTION === 'true', diff --git a/apps/ssi-abstraction/test/agent.e2e-spec.ts b/apps/ssi-abstraction/test/agent.e2e-spec.ts index 224b446ec1898ab09b2f0d9613883ce5fd43a29e..b66afcdd386ed2629984b4eb67fa0e050bae97f6 100644 --- a/apps/ssi-abstraction/test/agent.e2e-spec.ts +++ b/apps/ssi-abstraction/test/agent.e2e-spec.ts @@ -1,10 +1,12 @@ +import './setEnvVars.js'; + import type { INestApplication } from '@nestjs/common'; import type { ClientProxy } from '@nestjs/microservices'; -import type { EventInfoPublicDid } from '@ocm/shared'; import { DidDocument } from '@aries-framework/core'; import { ClientsModule, Transport } from '@nestjs/microservices'; import { Test } from '@nestjs/testing'; +import { EventInfoPublicDid } from '@ocm/shared'; import { firstValueFrom, type Observable } from 'rxjs'; import { AgentModule } from '../src/agent/agent.module.js'; @@ -12,7 +14,7 @@ import { AgentService } from '../src/agent/agent.service.js'; import { mockConfigModule } from '../src/config/__tests__/mockConfig.js'; const mockDidDocument = { - '@context': ['https://w3id.org/did/v1'], + context: ['https://w3id.org/did/v1'], id: 'did:indy:bcovrin:test:7KuDTpQh3GJ7Gp6kErpWvM', verificationMethod: [ { @@ -33,9 +35,7 @@ describe('Agent', () => { beforeAll(async () => { jest .spyOn(AgentService.prototype, 'getPublicDid') - .mockImplementation(() => - Promise.resolve(new DidDocument(mockDidDocument)), - ); + .mockResolvedValue(new DidDocument(mockDidDocument)); const moduleRef = await Test.createTestingModule({ imports: [ @@ -56,17 +56,16 @@ describe('Agent', () => { await client.connect(); }); - it('info.publicDid', async () => { + it(EventInfoPublicDid.token, async () => { const response$: Observable<EventInfoPublicDid> = client.send( - 'info.publicDid', + EventInfoPublicDid.token, {}, ); const response = await firstValueFrom(response$); + const eventInstance = EventInfoPublicDid.fromEvent(response); - expect(response.data).toMatchObject({ - didDocument: mockDidDocument, - }); + expect(eventInstance.instance).toMatchObject(mockDidDocument); }); afterAll(async () => { diff --git a/apps/ssi-abstraction/test/connections.e2e-spec.ts b/apps/ssi-abstraction/test/connections.e2e-spec.ts index 7c53e1a3ca7b8d3691bfe3a32f1857192c16372f..8fa8364d9dd5ec34e366cccdfe3c1e43f541bfff 100644 --- a/apps/ssi-abstraction/test/connections.e2e-spec.ts +++ b/apps/ssi-abstraction/test/connections.e2e-spec.ts @@ -1,16 +1,19 @@ import type { INestApplication } from '@nestjs/common'; import type { ClientProxy } from '@nestjs/microservices'; -import type { - EventDidcommConnectionsGetById, - EventDidcommConnectionsGetAll, -} from '@ocm/shared'; +import type { Observable } from 'rxjs'; import { ClientsModule, Transport } from '@nestjs/microservices'; import { Test } from '@nestjs/testing'; -import { firstValueFrom, type Observable } from 'rxjs'; +import { + EventDidcommConnectionsGetById, + EventDidcommConnectionsGetAll, + EventDidcommConnectionsCreateWithSelf, +} from '@ocm/shared'; +import { firstValueFrom } from 'rxjs'; import { AgentModule } from '../src/agent/agent.module.js'; import { ConnectionsModule } from '../src/agent/connections/connections.module.js'; +import { MetadataTokens } from '../src/common/constants.js'; import { mockConfigModule } from '../src/config/__tests__/mockConfig.js'; describe('Connections', () => { @@ -39,26 +42,45 @@ describe('Connections', () => { await client.connect(); }); - it('didcomm.connections.getAll', async () => { + afterAll(async () => { + await app.close(); + client.close(); + }); + + it(EventDidcommConnectionsGetAll.token, async () => { const response$: Observable<EventDidcommConnectionsGetAll> = client.send( - 'didcomm.connections.getAll', + EventDidcommConnectionsGetAll.token, {}, ); const response = await firstValueFrom(response$); - expect(response.data).toMatchObject({ connections: [] }); + const eventInstance = EventDidcommConnectionsGetAll.fromEvent(response); + + expect(eventInstance.instance).toEqual(expect.arrayContaining([])); }); - it('didcomm.connections.getById', async () => { + it(EventDidcommConnectionsGetById.token, async () => { const response$: Observable<EventDidcommConnectionsGetById> = client.send( - 'didcomm.connections.getById', + EventDidcommConnectionsGetById.token, { id: 'some-id' }, ); const response = await firstValueFrom(response$); - expect(response.data).toMatchObject({ connection: null }); + const eventInstance = EventDidcommConnectionsGetById.fromEvent(response); + + expect(eventInstance.instance).toBeNull(); }); - afterAll(async () => { - await app.close(); - client.close(); + it(EventDidcommConnectionsCreateWithSelf.token, async () => { + const response$: Observable<EventDidcommConnectionsCreateWithSelf> = + client.send(EventDidcommConnectionsCreateWithSelf.token, {}); + + const response = await firstValueFrom(response$); + const eventInstance = + EventDidcommConnectionsCreateWithSelf.fromEvent(response); + + expect(eventInstance.instance).toHaveProperty('id'); + const metadata = eventInstance.instance.metadata.get( + MetadataTokens.GAIA_X_CONNECTION_METADATA_KEY, + ); + expect(metadata).toMatchObject({ trusted: true }); }); }); diff --git a/apps/ssi-abstraction/test/setEnvVars.js b/apps/ssi-abstraction/test/setEnvVars.js index 74a71051d847e0ffb7080f294629d65356ee3e50..8135ed31d6eceaec4619de9081dda3f37b58589c 100644 --- a/apps/ssi-abstraction/test/setEnvVars.js +++ b/apps/ssi-abstraction/test/setEnvVars.js @@ -5,7 +5,7 @@ process.env.NATS_URL = 'nats://localhost:4222'; process.env.ECSURL = 'http://localhost:9200/'; process.env.AGENT_HOST = 'http://localhost'; process.env.AGENT_NAME = 'ssi-abstraction-agent'; -process.env.AGENT_INBOUND_PORT = ':4000'; +process.env.AGENT_INBOUND_PORT = 4000; process.env.AGENT_URL_PATH = '/ocm/abstraction'; process.env.AGENT_PUBLIC_DID_SEED = '6b8b882e2618fa5d45ee7229ca880083'; process.env.AGENT_AUTO_ACCEPT_CONNECTION = true;