-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
303 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { imock, instance } from '@johanblumenberg/ts-mockito'; | ||
import { TCPServer } from './tcp.server'; | ||
import type { Commands, DeviceRepository } from '@agnoc/domain'; | ||
import type { EventHandlerRegistry, TaskHandlerRegistry } from '@agnoc/toolkit'; | ||
|
||
describe('TCPServer', function () { | ||
let domainEventHandlerRegistry: EventHandlerRegistry; | ||
let commandHandlerRegistry: TaskHandlerRegistry<Commands>; | ||
let deviceRepository: DeviceRepository; | ||
let tcpAdapter: TCPServer; | ||
|
||
beforeEach(function () { | ||
domainEventHandlerRegistry = imock(); | ||
commandHandlerRegistry = imock(); | ||
deviceRepository = imock(); | ||
tcpAdapter = new TCPServer( | ||
instance(deviceRepository), | ||
instance(domainEventHandlerRegistry), | ||
instance(commandHandlerRegistry), | ||
); | ||
}); | ||
|
||
it('should listen and close servers', async function () { | ||
await tcpAdapter.listen(); | ||
await tcpAdapter.close(); | ||
}); | ||
|
||
it('should listen and close servers with custom ports', async function () { | ||
await tcpAdapter.listen({ ports: { cmd: 0, map: 0, ntp: 0 } }); | ||
await tcpAdapter.close(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { DeviceRepository, LocateDeviceCommand } from '@agnoc/domain'; | ||
import { EventHandlerRegistry, ID, TaskHandlerRegistry } from '@agnoc/toolkit'; | ||
import { capture, fnmock, imock, instance, verify, when } from '@johanblumenberg/ts-mockito'; | ||
import { expect } from 'chai'; | ||
import { AgnocServer } from './agnoc.server'; | ||
import type { SubscribeHandler } from './agnoc.server'; | ||
import type { Device, DomainEventBus, DeviceLockedDomainEvent } from '@agnoc/domain'; | ||
import type { Server, TaskHandler } from '@agnoc/toolkit'; | ||
|
||
describe('AgnocServer', function () { | ||
let server: Server; | ||
let agnocServer: AgnocServer; | ||
|
||
beforeEach(function () { | ||
server = imock(); | ||
agnocServer = new AgnocServer(); | ||
}); | ||
|
||
it('should provide a container to build an adapter', function () { | ||
agnocServer.buildAdapter((container) => { | ||
expect(container.deviceRepository).to.be.instanceOf(DeviceRepository); | ||
expect(container.domainEventHandlerRegistry).to.be.instanceOf(EventHandlerRegistry); | ||
expect(container.commandHandlerRegistry).to.be.instanceOf(TaskHandlerRegistry); | ||
|
||
return instance(server); | ||
}); | ||
}); | ||
|
||
it('should listen adapters', async function () { | ||
agnocServer.buildAdapter(() => { | ||
return instance(server); | ||
}); | ||
|
||
await agnocServer.listen(); | ||
|
||
verify(server.listen()).once(); | ||
}); | ||
|
||
it('should close adapters', async function () { | ||
agnocServer.buildAdapter(() => { | ||
return instance(server); | ||
}); | ||
|
||
await agnocServer.close(); | ||
|
||
verify(server.close()).once(); | ||
}); | ||
|
||
it('should subscribe to domain events', async function () { | ||
const device: Device = imock(); | ||
const event: DeviceLockedDomainEvent = imock(); | ||
const handler: SubscribeHandler<'DeviceLockedDomainEvent'> = fnmock(); | ||
|
||
agnocServer.subscribe('DeviceLockedDomainEvent', instance(handler)); | ||
|
||
agnocServer.buildAdapter(({ deviceRepository }) => { | ||
void deviceRepository.saveOne(instance(device)); | ||
|
||
return instance(server); | ||
}); | ||
|
||
// Extract the eventBus from the `device.publishEvents` method. | ||
// This is just a way to obtain the eventBus to manually publish events. | ||
const args = capture(device.publishEvents).first(); | ||
const eventBus = args[0] as DomainEventBus; | ||
|
||
await eventBus.emit('DeviceLockedDomainEvent', instance(event)); | ||
|
||
verify(handler(instance(event))).once(); | ||
}); | ||
|
||
it('should trigger commands', async function () { | ||
const taskHandler: TaskHandler = imock(); | ||
const command = new LocateDeviceCommand({ deviceId: new ID(1) }); | ||
|
||
when(taskHandler.forName).thenReturn('LocateDeviceCommand'); | ||
|
||
agnocServer.buildAdapter(({ commandHandlerRegistry }) => { | ||
commandHandlerRegistry.register(instance(taskHandler)); | ||
|
||
return instance(server); | ||
}); | ||
|
||
await agnocServer.trigger(command); | ||
|
||
verify(taskHandler.handle(command)).once(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
packages/domain/src/commands/locate-device.command.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { ArgumentInvalidException, ArgumentNotProvidedException, Command, ID } from '@agnoc/toolkit'; | ||
import { expect } from 'chai'; | ||
import { LocateDeviceCommand } from './locate-device.command'; | ||
import type { LocateDeviceCommandInput } from './locate-device.command'; | ||
|
||
describe('LocateDeviceCommand', function () { | ||
it('should be created', function () { | ||
const input = givenALocateDeviceCommandInput(); | ||
const command = new LocateDeviceCommand(input); | ||
|
||
expect(command).to.be.instanceOf(Command); | ||
expect(command.deviceId).to.be.equal(input.deviceId); | ||
}); | ||
|
||
it("should throw an error when 'deviceId' is not provided", function () { | ||
// @ts-expect-error - missing property | ||
expect(() => new LocateDeviceCommand({ ...givenALocateDeviceCommandInput(), deviceId: undefined })).to.throw( | ||
ArgumentNotProvidedException, | ||
`Property 'deviceId' for LocateDeviceCommand not provided`, | ||
); | ||
}); | ||
|
||
it("should throw an error when 'deviceId' is not an ID", function () { | ||
// @ts-expect-error - invalid property | ||
expect(() => new LocateDeviceCommand({ ...givenALocateDeviceCommandInput(), deviceId: 'foo' })).to.throw( | ||
ArgumentInvalidException, | ||
`Value 'foo' for property 'deviceId' of LocateDeviceCommand is not an instance of ID`, | ||
); | ||
}); | ||
}); | ||
|
||
function givenALocateDeviceCommandInput(): LocateDeviceCommandInput { | ||
return { deviceId: ID.generate() }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { TaskBus } from '@agnoc/toolkit'; | ||
import { expect } from 'chai'; | ||
import { CommandBus } from './command.event-bus'; | ||
|
||
describe('CommandBus', function () { | ||
let commandBus: CommandBus; | ||
|
||
beforeEach(function () { | ||
commandBus = new CommandBus(); | ||
}); | ||
|
||
it('should be created', function () { | ||
expect(commandBus).to.be.instanceOf(TaskBus); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,20 @@ | ||
import { EventBus } from '@agnoc/toolkit'; | ||
import { EventBus, debug } from '@agnoc/toolkit'; | ||
import type { DomainEventNames, DomainEvents } from '../domain-events/domain-events'; | ||
|
||
export type DomainEventBusEvents = { [Name in DomainEventNames]: DomainEvents[Name] }; | ||
export class DomainEventBus extends EventBus<DomainEventBusEvents> {} | ||
export class DomainEventBus extends EventBus<DomainEventBusEvents> { | ||
constructor() { | ||
/* istanbul ignore next */ | ||
super({ | ||
debug: { | ||
enabled: true, | ||
name: DomainEventBus.name, | ||
logger: (type, _, eventName, eventData) => { | ||
debug(__filename).extend(type)( | ||
`event '${eventName?.toString() ?? 'undefined'}' with data: ${JSON.stringify(eventData)}`, | ||
); | ||
}, | ||
}, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
import { Repository } from '@agnoc/toolkit'; | ||
import type { Device } from '../entities/device.entity'; | ||
import type { Device } from '../aggregate-roots/device.aggregate-root'; | ||
|
||
export class DeviceRepository extends Repository<Device> {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.