eventric-testing
Version:
Testing helpers for eventric.js
243 lines (174 loc) • 9.03 kB
text/coffeescript
describe 'remote factory', ->
remoteFactory = require './remote_factory'
class ExampleProjection
initialize: (params, done) ->
@$subscribeHandlersWithAggregateId params.aggregateId
done()
handleExampleCreated: (domainEvent) ->
@projectedCreated = domainEvent.payload.assignedCreated
handleExampleModified: (domainEvent) ->
@projectedModified = domainEvent.payload.assignedModified
domainEvents =
ExampleCreated: (params) ->
@assignedCreated = params.emittedCreated
ExampleModified: (params) ->
@assignedModified = params.emittedModified
wiredRemote = null
beforeEach ->
wiredRemote = remoteFactory.wiredRemote 'context', domainEvents
afterEach ->
wiredRemote.$destroy()
describe '#wiredRemote', ->
it 'should create a wired remote with additional helper functions', ->
expect(wiredRemote.$populateWithDomainEvent).to.be.a 'function'
expect(wiredRemote.$emitDomainEvent).to.be.a 'function'
describe '#wiredRemote.$populateWithDomainEvent', ->
it 'should populate the remote with the given event which is applied to later created projections', ->
wiredRemote.$populateWithDomainEvent 'ExampleCreated', 123, emittedCreated: true
wiredRemote.$populateWithDomainEvent 'ExampleModified', 123, emittedModified: true
wiredRemote.addProjection 'ExampleProjection', ExampleProjection
wiredRemote.initializeProjectionInstance 'ExampleProjection',
aggregateId: 123
.then (projectionId) ->
projection = wiredRemote.getProjectionInstance projectionId
expect(projection.projectedCreated).to.be.true
expect(projection.projectedModified).to.be.true
it 'should throw an error if the event to populate with is not registered', ->
wiredRemote = remoteFactory.wiredRemote 'context', {}
expect(-> wiredRemote.populateWithDomainEvent 'Foobar').to.throw Error
describe '#wiredRemote.$emitDomainEvent', ->
describe 'emitting one event', ->
it 'should publish the domain event to all global subscribers', (done) ->
wiredRemote.subscribeToAllDomainEvents (domainEvent) ->
expect(domainEvent.payload.assignedCreated).to.be.ok
done()
wiredRemote.$emitDomainEvent 'ExampleCreated', 123, emittedCreated: true
it 'should publish the domain event to all subscribers with matching event name', (done) ->
wiredRemote.subscribeToDomainEvent 'ExampleCreated', (domainEvent) ->
expect(domainEvent.payload.assignedCreated).to.be.ok
done()
wiredRemote.$emitDomainEvent 'ExampleCreated', 123, emittedCreated: true
it 'should publish the domain event to all subscribers with matching event name and aggregate id', (done) ->
wiredRemote.subscribeToDomainEventWithAggregateId 'ExampleCreated', 123, (domainEvent) ->
expect(domainEvent.payload.assignedCreated).to.be.ok
done()
wiredRemote.$emitDomainEvent 'ExampleCreated', 123, emittedCreated: true
it 'should apply the emitted event to projections', ->
wiredRemote.addProjection 'ExampleProjection', ExampleProjection
wiredRemote.initializeProjectionInstance 'ExampleProjection',
aggregateId: 123
.then (projectionId) ->
wiredRemote.$emitDomainEvent 'ExampleCreated', 123, emittedCreated: true
.then ->
projection = wiredRemote.getProjectionInstance projectionId
expect(projection.projectedCreated).to.be.true
describe 'given two projections where the first projection handles one event and the other one both events', ->
projection = null
beforeEach ->
class FirstProjection
initialize: (params, done) ->
@$subscribeHandlersWithAggregateId params.aggregateId
done()
handleExampleCreated: (domainEvent) ->
class SecondProjection
initialize: (params, done) ->
@$subscribeHandlersWithAggregateId params.aggregateId
@actions = []
done()
handleExampleCreated: (domainEvent) ->
@actions.push 'created'
handleExampleModified: (domainEvent) ->
@actions.push 'modified'
wiredRemote.addProjection 'FirstProjection', FirstProjection
wiredRemote.addProjection 'SecondProjection', SecondProjection
wiredRemote.initializeProjectionInstance 'FirstProjection',
aggregateId: 123
.then (projectionId) ->
wiredRemote.initializeProjectionInstance 'SecondProjection',
aggregateId: 123
.then (projectionId) ->
projection = wiredRemote.getProjectionInstance projectionId
it 'should emit the domain events to the second projection in the correct order', (done) ->
wiredRemote.subscribeToDomainEvent 'ExampleModified', ->
setTimeout ->
expect(projection.actions[0]).to.equal 'created'
expect(projection.actions[1]).to.equal 'modified'
done()
wiredRemote.$emitDomainEvent 'ExampleCreated', 123, emittedCreated: true
wiredRemote.$emitDomainEvent 'ExampleModified', 123, emittedModified: true
describe '#wiredRemote.$onCommand', ->
it 'should emit the associated DomainEvent if a specific command is called', (done) ->
wiredRemote.$onCommand 'myCommand',
myKey: 'myValue'
.yieldsDomainEvent 'ExampleCreated', 123,
emittedCreated: true
.yieldsDomainEvent 'ExampleModified', 123,
emittedModified: true
wiredRemote.subscribeToDomainEventWithAggregateId 'ExampleCreated', 123, (domainEvent) ->
expect(domainEvent.payload.assignedCreated).to.be.true
wiredRemote.subscribeToDomainEventWithAggregateId 'ExampleModified', 123, (domainEvent) ->
expect(domainEvent.payload.assignedModified).to.be.true
done()
wiredRemote.command 'myCommand', myKey: 'myValue'
describe '#wiredRemote.command', ->
it 'should delegate the command function if there is no command stub registered', ->
wiredRemote.command 'myCustomCommand'
.catch (error) ->
expect(error).to.be.defined
it 'should return a fake promise if a domain event is emitted', ->
wiredRemote.$onCommand 'myCommand',
myKey: 'myValue'
.yieldsDomainEvent 'ExampleCreated', 123,
emittedCreated: true
wiredRemote.command 'myCommand',
myKey: 'myValue'
.then ->
expect(true).to.be.ok
describe '#wiredRemote.$waitForEmitDomainEvent', ->
it 'should wait until the most current emit domain event operation is finished', ->
domainEventHandlerSpy = sandbox.spy()
wiredRemote.subscribeToDomainEvent 'ExampleCreated', domainEventHandlerSpy
wiredRemote.$emitDomainEvent 'ExampleCreated', 123, emittedCreated: true
wiredRemote.$waitForEmitDomainEvent().then ->
expect(domainEventHandlerSpy).to.have.been.called
describe '#wiredRemote.$destroy', ->
class ExampleReportingProjection
initialize: (params, done) ->
@exampleCount = 0
@$subscribeHandlersWithAggregateId params.aggregateId
done()
handleExampleCreated: ->
@exampleCount++
it 'should remove the stored domain events', ->
projection = null
wiredRemote.$populateWithDomainEvent 'ExampleCreated', 123, emittedCreated: true
wiredRemote.$destroy()
wiredRemote.addProjection 'ExampleReportingProjection', ExampleReportingProjection
wiredRemote.initializeProjectionInstance 'ExampleReportingProjection',
aggregateId: 123
.then (projectionId) ->
projection = wiredRemote.getProjectionInstance projectionId
wiredRemote.$emitDomainEvent 'ExampleCreated', 123, emittedCreated: true
.then ->
expect(projection.exampleCount).to.equal 1
it 'should unsubscribe all subscribers', (done) ->
domainEventHandler = sandbox.spy()
wiredRemote.subscribeToDomainEvent 'ExampleCreated', domainEventHandler
.then ->
wiredRemote.subscribeToDomainEvent 'ExampleCreated', domainEventHandler
.then ->
wiredRemote.subscribeToDomainEvent 'ExampleCreated', domainEventHandler
.then ->
wiredRemote.$destroy()
.then ->
wiredRemote.subscribeToDomainEvent 'ExampleCreated', domainEventHandler
wiredRemote.subscribeToDomainEvent 'ExampleCreated', ->
expect(domainEventHandler.callCount).to.equal 1
done()
wiredRemote.$emitDomainEvent 'ExampleCreated', 123, emittedCreated: true
it 'should wait until the most current emit domain event operation is finished', ->
domainEventHandlerSpy = sandbox.spy()
wiredRemote.subscribeToDomainEvent 'ExampleCreated', domainEventHandlerSpy
wiredRemote.$emitDomainEvent 'ExampleCreated', 123, emittedCreated: true
wiredRemote.$destroy().then ->
expect(domainEventHandlerSpy).to.have.been.called