mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-23 22:11:09 +03:00
Added 'post.added' event handling in Collections
refs https://github.com/TryGhost/Team/issues/3169 - This piece of logic handles the 'post.added' model event mapping to Collection's PostAddedEvent domain event and logic related to updating collections when the new post is added.
This commit is contained in:
parent
42539b954f
commit
36783e456b
@ -31,6 +31,7 @@
|
||||
"@tryghost/domain-events": "0.0.0",
|
||||
"@tryghost/errors": "^1.2.25",
|
||||
"@tryghost/in-memory-repository": "0.0.0",
|
||||
"@tryghost/nql": "^0.11.0",
|
||||
"@tryghost/tpl": "^0.1.25",
|
||||
"bson-objectid": "^2.0.4"
|
||||
},
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {ValidationError} from '@tryghost/errors';
|
||||
import tpl from '@tryghost/tpl';
|
||||
import nql = require('@tryghost/nql');
|
||||
|
||||
import ObjectID from 'bson-objectid';
|
||||
|
||||
@ -81,11 +82,15 @@ export class Collection {
|
||||
* @param post {{id: string}} - The post to add to the collection
|
||||
* @param index {number} - The index to insert the post at, use negative numbers to count from the end.
|
||||
*/
|
||||
addPost(post: {id: string}, index: number = -0) {
|
||||
// if (this.type === 'automatic') {
|
||||
// TODO: Test the post against the NQL filter stored in `this.filter`
|
||||
// This will need the `post` param to include more data.
|
||||
// }
|
||||
addPost(post: CollectionPost, index: number = -0) {
|
||||
if (this.type === 'automatic') {
|
||||
const filterNql = nql(this.filter);
|
||||
const matchesFilter = filterNql.queryJSON(post);
|
||||
|
||||
if (!matchesFilter) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.posts.includes(post.id)) {
|
||||
this._posts = this.posts.filter(id => id !== post.id);
|
||||
@ -96,6 +101,7 @@ export class Collection {
|
||||
}
|
||||
|
||||
this.posts.splice(index, 0, post.id);
|
||||
return true;
|
||||
}
|
||||
|
||||
removePost(id: string) {
|
||||
@ -172,6 +178,7 @@ export class Collection {
|
||||
}
|
||||
|
||||
if (data.type === 'automatic' && !data.filter) {
|
||||
// @NOTE: add filter validation here
|
||||
throw new ValidationError({
|
||||
message: tpl(messages.invalidFilterProvided.message),
|
||||
context: tpl(messages.invalidFilterProvided.context)
|
||||
|
@ -200,7 +200,7 @@ export class CollectionsService {
|
||||
collection.removeAllPosts();
|
||||
|
||||
for (const post of posts) {
|
||||
collection.addPost(post);
|
||||
await collection.addPost(post);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -222,10 +222,11 @@ export class CollectionsService {
|
||||
|
||||
for (const collection of collections) {
|
||||
await collection.addPost(post);
|
||||
// const added = await collection.addPost(post);
|
||||
// if (added) {
|
||||
await this.collectionsRepository.save(collection);
|
||||
// }
|
||||
const added = await collection.addPost(post);
|
||||
|
||||
if (added) {
|
||||
await this.collectionsRepository.save(collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ type PostData = {
|
||||
id: string;
|
||||
featured: boolean;
|
||||
published_at: Date;
|
||||
timestamp: Date;
|
||||
};
|
||||
|
||||
export class PostAddedEvent {
|
||||
@ -10,9 +9,9 @@ export class PostAddedEvent {
|
||||
data: PostData;
|
||||
timestamp: Date;
|
||||
|
||||
constructor(data: PostAddedEvent, timestamp: Date) {
|
||||
constructor(data: PostData, timestamp: Date) {
|
||||
this.id = data.id;
|
||||
this.data = data.data;
|
||||
this.data = data;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
|
1
ghost/collections/src/libraries.d.ts
vendored
1
ghost/collections/src/libraries.d.ts
vendored
@ -1,3 +1,4 @@
|
||||
declare module '@tryghost/errors';
|
||||
declare module '@tryghost/tpl';
|
||||
declare module '@tryghost/domain-events'
|
||||
declare module '@tryghost/nql'
|
||||
|
@ -163,7 +163,8 @@ describe('Collection', function () {
|
||||
|
||||
it('Can add posts to different positions', async function () {
|
||||
const collection = await Collection.create({
|
||||
title: 'Testing adding posts'
|
||||
title: 'Testing adding posts',
|
||||
type: 'manual'
|
||||
});
|
||||
|
||||
assert(collection.posts.length === 0);
|
||||
@ -191,6 +192,32 @@ describe('Collection', function () {
|
||||
assert(collection.posts[collection.posts.length - 2] === '3');
|
||||
});
|
||||
|
||||
it('Adds a post to an automatic collection when it matches the filter', async function () {
|
||||
const collection = await Collection.create({
|
||||
title: 'Testing adding posts',
|
||||
type: 'automatic',
|
||||
filter: 'featured:true'
|
||||
});
|
||||
|
||||
assert.equal(collection.posts.length, 0, 'Collection should have no posts');
|
||||
|
||||
const added = await collection.addPost({
|
||||
id: '0',
|
||||
featured: false
|
||||
});
|
||||
|
||||
assert.equal(added, false);
|
||||
assert.equal(collection.posts.length, 0, 'The non-featured post should not have been added');
|
||||
|
||||
const featuredAdded = await collection.addPost({
|
||||
id: '1',
|
||||
featured: true
|
||||
});
|
||||
|
||||
assert.equal(featuredAdded, true);
|
||||
assert.equal(collection.posts.length, 1, 'The featured post should have been added');
|
||||
});
|
||||
|
||||
it('Removes a post by id', async function () {
|
||||
const collection = await Collection.create({
|
||||
title: 'Testing adding posts'
|
||||
|
@ -5,7 +5,8 @@ import {
|
||||
CollectionsService,
|
||||
CollectionsRepositoryInMemory,
|
||||
CollectionResourceChangeEvent,
|
||||
PostDeletedEvent
|
||||
PostDeletedEvent,
|
||||
PostAddedEvent
|
||||
} from '../src/index';
|
||||
import {PostsRepositoryInMemory} from './fixtures/PostsRepositoryInMemory';
|
||||
import {posts} from './fixtures/posts';
|
||||
@ -393,6 +394,25 @@ describe('CollectionsService', function () {
|
||||
assert.equal((await collectionsService.getById(manualCollection.id))?.posts.length, 1);
|
||||
});
|
||||
|
||||
it('Updates only index collection when a non-featured post is added', async function () {
|
||||
assert.equal((await collectionsService.getById(automaticFeaturedCollection.id))?.posts?.length, 2);
|
||||
assert.equal((await collectionsService.getById(automaticNonFeaturedCollection.id))?.posts.length, 2);
|
||||
assert.equal((await collectionsService.getById(manualCollection.id))?.posts.length, 2);
|
||||
|
||||
collectionsService.subscribeToEvents();
|
||||
const postAddedEvent = PostAddedEvent.create({
|
||||
id: 'non-featured-post',
|
||||
featured: false
|
||||
});
|
||||
|
||||
DomainEvents.dispatch(postAddedEvent);
|
||||
await DomainEvents.allSettled();
|
||||
|
||||
assert.equal((await collectionsService.getById(automaticFeaturedCollection.id))?.posts?.length, 2);
|
||||
assert.equal((await collectionsService.getById(automaticNonFeaturedCollection.id))?.posts.length, 3);
|
||||
assert.equal((await collectionsService.getById(manualCollection.id))?.posts.length, 2);
|
||||
});
|
||||
|
||||
it('Updates automatic collections only when post is published', async function () {
|
||||
const newPost = {
|
||||
id: 'post-published',
|
||||
|
Loading…
Reference in New Issue
Block a user