Added ability to fetch collection posts by slug

closes https://github.com/TryGhost/Arch/issues/27

- We need a more convenient method of fetching posts belonging to a collection than by collection's "id". This change adds an alias to the existing endpoint `GET /collections/:id/posts/`. A non-valid ObjectID in the parameter is treated as a slug.
This commit is contained in:
Naz 2023-07-10 19:39:02 +08:00 committed by naz
parent 9dd1f97bb0
commit cdae2a978d
4 changed files with 544 additions and 2 deletions

View File

@ -1,5 +1,6 @@
import logging from '@tryghost/logging';
import tpl from '@tryghost/tpl';
import ObjectID from 'bson-objectid';
import {Collection} from './Collection';
import {CollectionResourceChangeEvent} from './CollectionResourceChangeEvent';
import {CollectionRepository} from './CollectionRepository';
@ -350,8 +351,19 @@ export class CollectionsService {
};
}
/**
* @param id {string | ObjectID} - collection id or slug
* @param pagingOpts {QueryOptions}
* @returns
*/
async getAllPosts(id: string, {limit = 15, page = 1}: QueryOptions): Promise<{data: CollectionPostListItemDTO[], meta: any}> {
const collection = await this.getById(id);
let collection;
if (ObjectID.isValid(id)) {
collection = await this.getById(id);
} else {
collection = await this.getBySlug(id);
}
if (!collection) {
throw new NotFoundError({

View File

@ -130,7 +130,7 @@ describe('CollectionsService', function () {
});
describe('getAllPosts', function () {
it('Can get paged posts of a collection', async function () {
it('Can get paged posts of a collection by collection id', async function () {
const collection = await collectionsService.createCollection({
title: 'testing paging',
type: 'manual'
@ -161,6 +161,38 @@ describe('CollectionsService', function () {
assert.equal(postsPage2.data[1].id, posts[3].id, 'Second post should be the correct one');
});
it('Can get paged posts of a collection by collection slug', async function () {
const collection = await collectionsService.createCollection({
title: 'testing fetch by slug',
slug: 'testing-fetch-by-slug',
type: 'manual'
});
for (const post of posts) {
await collectionsService.addPostToCollection(collection.id, post);
}
const postsPage1 = await collectionsService.getAllPosts(collection.slug, {page: 1, limit: 2});
assert.ok(postsPage1, 'Posts should be returned');
assert.equal(postsPage1.meta.pagination.page, 1, 'Page should be 1');
assert.equal(postsPage1.meta.pagination.limit, 2, 'Limit should be 2');
assert.equal(postsPage1.meta.pagination.pages, 2, 'Pages should be 2');
assert.equal(postsPage1.data.length, 2, 'There should be 2 posts');
assert.equal(postsPage1.data[0].id, posts[0].id, 'First post should be the correct one');
assert.equal(postsPage1.data[1].id, posts[1].id, 'Second post should be the correct one');
const postsPage2 = await collectionsService.getAllPosts(collection.slug, {page: 2, limit: 2});
assert.ok(postsPage2, 'Posts should be returned');
assert.equal(postsPage2.meta.pagination.page, 2, 'Page should be 2');
assert.equal(postsPage2.meta.pagination.limit, 2, 'Limit should be 2');
assert.equal(postsPage2.meta.pagination.pages, 2, 'Pages should be 2');
assert.equal(postsPage2.data.length, 2, 'There should be 2 posts');
assert.equal(postsPage2.data[0].id, posts[2].id, 'First post should be the correct one');
assert.equal(postsPage2.data[1].id, posts[3].id, 'Second post should be the correct one');
});
it('Throws when trying to get posts of a collection that does not exist', async function () {
await assert.rejects(async () => {
await collectionsService.getAllPosts('fake id', {});

File diff suppressed because one or more lines are too long

View File

@ -137,6 +137,19 @@ describe('Collections API', function () {
collection_posts: Array(2).fill(matchCollectionPost)
});
});
it('Can browse Collections Posts using collection slug', async function () {
await agent
.get(`/collections/index/posts/`)
.expectStatus(200)
.matchHeaderSnapshot({
'content-version': anyContentVersion,
etag: anyEtag
})
.matchBodySnapshot({
collection_posts: Array(11).fill(matchCollectionPost)
});
});
});
it('Can read a Collection', async function () {