8d71841918
refs https://github.com/TryGhost/Arch/issues/61 Because the tags system is still written in the old way, the tag.deleted bookshelf event needs to be mapped to the DomainEvents to bridge the gap with the collections package.
201 lines
6.4 KiB
TypeScript
201 lines
6.4 KiB
TypeScript
import assert from 'assert/strict';
|
|
import events from 'events';
|
|
import sinon from 'sinon';
|
|
import DomainEvents from '@tryghost/domain-events';
|
|
import {
|
|
PostDeletedEvent,
|
|
PostEditedEvent,
|
|
PostAddedEvent,
|
|
TagDeletedEvent
|
|
} from '@tryghost/collections';
|
|
|
|
import {ModelToDomainEventInterceptor} from '../src';
|
|
|
|
class EventRegistry extends events.EventEmitter {
|
|
hasRegisteredListener(eventName: string, listenerName: string) {
|
|
return !!(this.listeners(eventName).find(listener => (listener.name === listenerName)));
|
|
}
|
|
}
|
|
|
|
describe('ModelToDomainEventInterceptor', function () {
|
|
it('Can instantiate a ModelToDomainEventInterceptor', function () {
|
|
const modelToDomainEventInterceptor = new ModelToDomainEventInterceptor({
|
|
ModelEvents: new EventRegistry(),
|
|
DomainEvents: DomainEvents
|
|
});
|
|
|
|
assert.ok(modelToDomainEventInterceptor);
|
|
});
|
|
|
|
it('Starts event listeners after initialization', function () {
|
|
let eventRegistry = new EventRegistry();
|
|
const modelToDomainEventInterceptor = new ModelToDomainEventInterceptor({
|
|
ModelEvents: eventRegistry,
|
|
DomainEvents: DomainEvents
|
|
});
|
|
|
|
modelToDomainEventInterceptor.init();
|
|
|
|
assert.ok(eventRegistry.hasRegisteredListener('post.added', 'post.added.domainEventInterceptorListener'), 'post.added listener is registered');
|
|
});
|
|
|
|
it('Intercepts post.added Model event and dispatches PostAddedEvent Domain event', async function () {
|
|
let eventRegistry = new EventRegistry();
|
|
const modelToDomainEventInterceptor = new ModelToDomainEventInterceptor({
|
|
ModelEvents: eventRegistry,
|
|
DomainEvents: DomainEvents
|
|
});
|
|
|
|
modelToDomainEventInterceptor.init();
|
|
|
|
let interceptedEvent;
|
|
DomainEvents.subscribe(PostAddedEvent, (event: any) => {
|
|
assert.equal(event.id, '1234-added');
|
|
interceptedEvent = event;
|
|
});
|
|
|
|
eventRegistry.emit('post.added', {
|
|
id: '1234-added',
|
|
attributes: {
|
|
status: 'draft',
|
|
featured: false,
|
|
published_at: new Date()
|
|
}
|
|
});
|
|
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.ok(interceptedEvent);
|
|
});
|
|
|
|
it('Intercepts post.edited Model event and dispatches PostEditedEvent Domain event', async function () {
|
|
let eventRegistry = new EventRegistry();
|
|
const modelToDomainEventInterceptor = new ModelToDomainEventInterceptor({
|
|
ModelEvents: eventRegistry,
|
|
DomainEvents: DomainEvents
|
|
});
|
|
|
|
modelToDomainEventInterceptor.init();
|
|
|
|
let interceptedEvent;
|
|
DomainEvents.subscribe(PostEditedEvent, async (event: any) => {
|
|
assert.equal(event.id, '1234-edited');
|
|
assert.ok(event.data);
|
|
assert.ok(event.data.current);
|
|
assert.equal(event.data.current.status, 'draft');
|
|
assert.equal(event.data.previous.status, 'published');
|
|
|
|
assert.deepEqual(event.data.current.tags[0], {slug: 'tag-current-slug'});
|
|
assert.deepEqual(event.data.previous.tags[0], {slug: 'tag-previous-slug'});
|
|
interceptedEvent = event;
|
|
});
|
|
|
|
eventRegistry.emit('post.edited', {
|
|
id: '1234-edited',
|
|
attributes: {
|
|
status: 'draft',
|
|
featured: false,
|
|
published_at: new Date()
|
|
},
|
|
_previousAttributes: {
|
|
status: 'published',
|
|
featured: true
|
|
},
|
|
relations: {
|
|
tags: {
|
|
models: [{
|
|
get: function (key: string) {
|
|
return `tag-current-${key}`;
|
|
}
|
|
}]
|
|
}
|
|
},
|
|
_previousRelations: {
|
|
tags: {
|
|
models: [{
|
|
get: function (key: string) {
|
|
return `tag-previous-${key}`;
|
|
}
|
|
}]
|
|
}
|
|
}
|
|
});
|
|
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.ok(interceptedEvent);
|
|
});
|
|
|
|
it('Intercepts post.deleted Model event and dispatches PostAddedEvent Domain event', async function () {
|
|
let eventRegistry = new EventRegistry();
|
|
const modelToDomainEventInterceptor = new ModelToDomainEventInterceptor({
|
|
ModelEvents: eventRegistry,
|
|
DomainEvents: DomainEvents
|
|
});
|
|
|
|
modelToDomainEventInterceptor.init();
|
|
|
|
let interceptedEvent;
|
|
DomainEvents.subscribe(PostDeletedEvent, (event: any) => {
|
|
assert.equal(event.id, '1234-deleted');
|
|
interceptedEvent = event;
|
|
});
|
|
|
|
eventRegistry.emit('post.deleted', {
|
|
id: '1234-deleted'
|
|
});
|
|
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.ok(interceptedEvent);
|
|
});
|
|
|
|
it('Intercepts tag.deleted Model event and dispatches TagDeletedEvent Domain event', async function () {
|
|
let eventRegistry = new EventRegistry();
|
|
const modelToDomainEventInterceptor = new ModelToDomainEventInterceptor({
|
|
ModelEvents: eventRegistry,
|
|
DomainEvents: DomainEvents
|
|
});
|
|
|
|
modelToDomainEventInterceptor.init();
|
|
|
|
let interceptedEvent;
|
|
DomainEvents.subscribe(TagDeletedEvent, (event: TagDeletedEvent) => {
|
|
assert.equal(event.id, '1234-deleted');
|
|
assert.equal(event.data.slug, 'tag-slug');
|
|
interceptedEvent = event;
|
|
});
|
|
|
|
eventRegistry.emit('tag.deleted', {
|
|
id: '1234-deleted',
|
|
attributes: {
|
|
slug: 'tag-slug'
|
|
}
|
|
});
|
|
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.ok(interceptedEvent);
|
|
});
|
|
|
|
it('Intercepts unmapped Model event and dispatches nothing', async function () {
|
|
let eventRegistry = new EventRegistry();
|
|
const modelToDomainEventInterceptor = new ModelToDomainEventInterceptor({
|
|
ModelEvents: eventRegistry,
|
|
DomainEvents: DomainEvents
|
|
});
|
|
|
|
const domainEventsSpy = sinon.spy(DomainEvents, 'dispatch');
|
|
|
|
modelToDomainEventInterceptor.init();
|
|
|
|
eventRegistry.emit('tag.added', {
|
|
id: '1234-tag'
|
|
});
|
|
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(domainEventsSpy.called, false);
|
|
});
|
|
});
|