Skip to content

Commit

Permalink
test: add unit tests (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
lotharking authored Feb 10, 2025
1 parent 3b69e6b commit d92adba
Show file tree
Hide file tree
Showing 11 changed files with 792 additions and 5 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"check-types:build": "yarn workspaces run tsc --noEmit -p tsconfig.build.json",
"format": "prettier \"packages/*/src/**/*.ts\" --write",
"check-format": "prettier -c \"packages/*/src/**/*.ts\"",
"test": "yarn workspaces run test --passWithNoTests",
"test": "yarn workspaces run test",
"lint": "eslint \"{packages,apps,libs}/**/*.ts\" --fix",
"validate": "yarn lint && yarn check-types && yarn check-format"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"clean": "rimraf -rf ./build",
"compile": "tsc -p tsconfig.build.json",
"prepublishOnly": "yarn run build",
"test": "jest"
"test": "jest --passWithNoTests"
},
"dependencies": {
"@2060.io/service-agent-model": "*",
Expand Down
2 changes: 1 addition & 1 deletion packages/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"test": "jest",
"test": "jest --passWithNoTests",
"postinstall": "patch-package"
},
"dependencies": {
Expand Down
4 changes: 2 additions & 2 deletions packages/nestjs-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
},
"dependencies": {
"@2060.io/credo-ts-didcomm-mrtd": "^0.0.12",
"@2060.io/service-agent-model": "*",
"@2060.io/service-agent-client": "*",
"@2060.io/service-agent-model": "*",
"@credo-ts/core": "^0.5.11",
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
Expand All @@ -34,8 +34,8 @@
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@nestjs/swagger": "^8.0.7",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.13",
"credo-ts-receipts": "^0.0.1-alpha.5",
"source-map-support": "^0.5.21",
Expand Down
45 changes: 45 additions & 0 deletions packages/nestjs-client/src/app.module.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ApiVersion } from '@2060.io/service-agent-client'

import { ConnectionsEventModule, EventsModule, MessageEventModule } from '../src'

describe('EventsModule', () => {
it('should register in EventModule some modules', () => {
const module = EventsModule.register({
modules: { messages: true, connections: true, credentials: false },
options: {
eventHandler: jest.fn(),
url: 'http://example.com',
version: ApiVersion.V1,
},
})

expect(module.imports).toEqual(
expect.arrayContaining([
MessageEventModule.forRoot({
eventHandler: expect.any(Function),
imports: [],
url: 'http://example.com',
version: ApiVersion.V1,
}),
ConnectionsEventModule.forRoot({
eventHandler: expect.any(Function),
imports: [],
useMessages: true,
}),
]),
)
})

it('should throw an error if eventHandler is not provided for MessageEventModule or ConnectionsEventModule', () => {
expect(() => {
EventsModule.register({
modules: { messages: true, connections: true, credentials: false },
options: {
// eventHandler is missing
url: 'http://example.com',
version: ApiVersion.V1,
},
})
}).toThrow(new Error('Event handler is required but not provided.'))
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { HttpUtils } from '@2060.io/service-agent-client'
import { ConnectionStateUpdated, ExtendedDidExchangeState } from '@2060.io/service-agent-model'
import { Logger } from '@nestjs/common'
import { Test, TestingModule } from '@nestjs/testing'

import { ConnectionsEventController } from './connection.controller'
import { ConnectionsEventService } from './connection.service'

jest.mock('@2060.io/service-agent-client', () => ({
HttpUtils: {
handleException: jest.fn(),
},
}))

describe('ConnectionsEventController', () => {
let controller: ConnectionsEventController
let service: ConnectionsEventService

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [ConnectionsEventController],
providers: [
{
provide: ConnectionsEventService,
useValue: {
update: jest.fn(),
},
},
],
}).compile()

controller = module.get<ConnectionsEventController>(ConnectionsEventController)
service = module.get<ConnectionsEventService>(ConnectionsEventService)
})

it('should be defined', () => {
expect(controller).toBeDefined()
})

describe('update', () => {
const mockBody = new ConnectionStateUpdated({
connectionId: '123',
invitationId: '456',
state: ExtendedDidExchangeState.Completed,
})

it('should call service.update and return success message', async () => {
jest.spyOn(service, 'update').mockResolvedValue(undefined)

const response = await controller.update(mockBody)

expect(service.update).toHaveBeenCalledWith(mockBody)
expect(response).toEqual({ message: 'Connection state updated successfully' })
})

it('should handle exceptions and call HttpUtils.handleException', async () => {
const error = new Error('Test error')
jest.spyOn(service, 'update').mockRejectedValue(error)

await controller.update(mockBody)

expect(HttpUtils.handleException).toHaveBeenCalledWith(
expect.any(Logger),
error,
'Failed to update connection state',
)
})
})
})
112 changes: 112 additions & 0 deletions packages/nestjs-client/src/connections/connection.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { ConnectionStateUpdated, ExtendedDidExchangeState } from '@2060.io/service-agent-model'
import { Test, TestingModule } from '@nestjs/testing'

import { ConnectionsRepository, EventHandler, ConnectionsEventService } from '../../src'

describe('ConnectionsEventService', () => {
let service: ConnectionsEventService
let mockEventHandler: Partial<EventHandler>
let mockRepository: Partial<ConnectionsRepository>

beforeEach(async () => {
jest.clearAllMocks()

mockEventHandler = {
closeConnection: jest.fn(),
newConnection: jest.fn(),
}

mockRepository = {
updateMetadata: jest.fn(),
create: jest.fn(),
updateStatus: jest.fn(),
isCompleted: jest.fn().mockResolvedValue(false),
}

const module: TestingModule = await Test.createTestingModule({
providers: [
ConnectionsEventService,
{
provide: 'GLOBAL_MODULE_OPTIONS',
useValue: { useMessages: false },
},
{
provide: 'CONNECTIONS_EVENT',
useValue: mockEventHandler,
},
{
provide: ConnectionsRepository,
useValue: mockRepository,
},
],
}).compile()

service = module.get<ConnectionsEventService>(ConnectionsEventService)
})

it('should be defined', () => {
expect(service['messageEvent']).toBe(false)
})

describe('update', () => {
it('should update state to Terminated and call closeConnection', async () => {
const event = new ConnectionStateUpdated({
state: ExtendedDidExchangeState.Terminated,
connectionId: '123',
})

await service.update(event)

expect(mockRepository.updateStatus).toHaveBeenCalledWith('123', ExtendedDidExchangeState.Terminated)
expect(mockEventHandler.closeConnection).toHaveBeenCalledWith('123')
})

it('should update state to completed', async () => {
const event = new ConnectionStateUpdated({
state: ExtendedDidExchangeState.Completed,
connectionId: '123',
metadata: { key: 'value' },
})

await service.update(event)

expect(mockRepository.create).toHaveBeenCalledWith(
expect.objectContaining({
id: '123',
status: ExtendedDidExchangeState.Start,
metadata: event.metadata,
}),
)
})

it('should update state to Updated and call handleNewConnection', async () => {
const event = new ConnectionStateUpdated({
state: ExtendedDidExchangeState.Updated,
connectionId: '123',
metadata: { key: 'value' },
})

jest.spyOn(service, 'handleNewConnection').mockImplementation(jest.fn())

await service.update(event)

expect(service.handleNewConnection).toHaveBeenCalledWith('123')
})
})

describe('handleNewConnection', () => {
it('should not call newConnection when isCompleted returns false', async () => {
mockRepository.isCompleted = jest.fn().mockResolvedValue(false)
await service.handleNewConnection('123')
expect(mockRepository.isCompleted).toHaveBeenCalledWith('123', false)
expect(mockEventHandler.newConnection).not.toHaveBeenCalled()
})

it('should call newConnection when isCompleted returns true', async () => {
mockRepository.isCompleted = jest.fn().mockResolvedValue(true)
await service.handleNewConnection('123')
expect(mockRepository.isCompleted).toHaveBeenCalledWith('123', false)
expect(mockEventHandler.newConnection).toHaveBeenCalledWith('123')
})
})
})
Loading

0 comments on commit d92adba

Please sign in to comment.