UNPKG

eventric-testing

Version:
155 lines (115 loc) 5.67 kB
_ = require 'lodash' eventric = require 'eventric' fakePromise = require './fake_promise' inmemoryRemote = require 'eventric-remote-inmemory' # TODO: Find a better way to solve the dependency to these eventric internal components DomainEvent = require 'eventric/src/domain_event' domainEventIdGenerator = require 'eventric/src/aggregate/domain_event_id_generator' class RemoteFactory wiredRemote: (contextName, domainEvents) -> wiredRemote = eventric.remote contextName wiredRemote._mostCurrentEmitOperation = fakePromise.resolve() wiredRemote._domainEvents = [] wiredRemote._subscriberIds = [] wiredRemote._commandStubs = [] wiredRemote._context = eventric.context contextName wiredRemote._context.defineDomainEvents domainEvents wiredRemote.setClient inmemoryRemote.client wiredRemote.$populateWithDomainEvent = (domainEventName, aggregateId, domainEventPayload) -> @_domainEvents.push @_createDomainEvent domainEventName, aggregateId, domainEventPayload wiredRemote.$emitDomainEvent = (domainEventName, aggregateId, domainEventPayload) -> domainEvent = @_createDomainEvent domainEventName, aggregateId, domainEventPayload @_domainEvents.push domainEvent endpoint = inmemoryRemote.endpoint @_mostCurrentEmitOperation = @_mostCurrentEmitOperation.then -> contextEventPublish = endpoint.publish contextName, domainEvent contextAndNameEventPublish = endpoint.publish contextName, domainEvent.name, domainEvent if domainEvent.aggregate fullEventNamePublish = endpoint.publish contextName, domainEvent.name, domainEvent.aggregate.id, domainEvent Promise.all([contextEventPublish, contextAndNameEventPublish, fullEventNamePublish]) else Promise.all([contextEventPublish, contextAndNameEventPublish]) wiredRemote.$waitForEmitDomainEvent = -> wiredRemote._mostCurrentEmitOperation wiredRemote._createDomainEvent = (domainEventName, aggregateId, domainEventConstructorParams) -> DomainEventPayloadConstructor = wiredRemote._context.getDomainEventPayloadConstructor domainEventName if !DomainEventPayloadConstructor throw new Error "Tried to create domain event '#{domainEventName}' which is not defined" payload = {} DomainEventPayloadConstructor.apply payload, [domainEventConstructorParams] new DomainEvent id: domainEventIdGenerator.generateId() name: domainEventName aggregate: id: aggregateId name: 'EventricTesting' context: @_context.name payload: payload wiredRemote.findDomainEventsByName = (names) -> names = [names] unless names instanceof Array fakePromise.resolve @_domainEvents.filter (x) -> names.indexOf(x.name) > -1 wiredRemote.findDomainEventsByNameAndAggregateId = (names, aggregateIds) -> names = [names] unless names instanceof Array aggregateIds = [aggregateIds] unless aggregateIds instanceof Array fakePromise.resolve @_domainEvents.filter (x) -> names.indexOf(x.name) > -1 and x.aggregate and aggregateIds.indexOf(x.aggregate.id) > -1 originalSubscribeToAllDomainEvents = wiredRemote.subscribeToAllDomainEvents wiredRemote.subscribeToAllDomainEvents = -> originalSubscribeToAllDomainEvents.apply @, arguments .then (subscriberId) => @_subscriberIds.push subscriberId subscriberId originalSubscribeToDomainEvent = wiredRemote.subscribeToDomainEvent wiredRemote.subscribeToDomainEvent = -> originalSubscribeToDomainEvent.apply @, arguments .then (subscriberId) => @_subscriberIds.push subscriberId subscriberId originalSubscribeToDomainEventWithAggregateId = wiredRemote.subscribeToDomainEventWithAggregateId wiredRemote.subscribeToDomainEventWithAggregateId = -> originalSubscribeToDomainEventWithAggregateId.apply @, arguments .then (subscriberId) => @_subscriberIds.push subscriberId subscriberId wiredRemote.$destroy = -> @_domainEvents = [] @_commandStubs = [] @_mostCurrentEmitOperation.then => @_mostCurrentEmitOperation = fakePromise.resolve() subscriptionRemovals = [] for subscriberId in @_subscriberIds subscriptionRemovals.push wiredRemote.unsubscribeFromDomainEvent subscriberId @_subscriberIds = [] Promise.all subscriptionRemovals wiredRemote.$onCommand = (command, payload) -> commandStub = command: command payload: payload domainEvents: [] yieldsDomainEvent: (eventName, aggregateId, payload) -> @domainEvents.push eventName: eventName aggregateId: aggregateId payload: payload @ @_commandStubs.push commandStub commandStub originalCommand = wiredRemote.command wiredRemote.command = (command, payload) -> filteredCommandStubs = @_commandStubs.filter (commandStub) -> return false unless command is commandStub.command _.isEqual payload, commandStub.payload unless filteredCommandStubs.length return originalCommand.apply @, arguments emitDomainEventAsync = (domainEvent) => setTimeout => @$emitDomainEvent domainEvent.eventName, domainEvent.aggregateId, domainEvent.payload for filteredCommandStub in filteredCommandStubs for domainEvent in filteredCommandStub.domainEvents emitDomainEventAsync domainEvent fakePromise.resolveAsync() wiredRemote module.exports = new RemoteFactory