mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-19 00:11:49 +03:00
bb4e2fcadb
closes https://github.com/TryGhost/Team/issues/3425 - Index collection is needed to support one of the usecases we have in the near future where we'd hold all posts that would be displayed on the "index" page.
345 lines
10 KiB
JavaScript
345 lines
10 KiB
JavaScript
const assert = require('assert');
|
|
const {
|
|
agentProvider,
|
|
fixtureManager,
|
|
mockManager,
|
|
matchers
|
|
} = require('../../utils/e2e-framework');
|
|
const {
|
|
anyContentVersion,
|
|
anyEtag,
|
|
anyErrorId,
|
|
anyLocationFor,
|
|
anyObjectId,
|
|
anyISODateTime,
|
|
anyNumber,
|
|
anyString
|
|
} = matchers;
|
|
|
|
const matchCollection = {
|
|
id: anyObjectId,
|
|
created_at: anyISODateTime,
|
|
updated_at: anyISODateTime
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param {number} postCount
|
|
*/
|
|
const buildMatcher = (postCount, opts = {}) => {
|
|
let obj = {
|
|
id: anyObjectId
|
|
};
|
|
if (opts.withSortOrder) {
|
|
obj.sort_order = anyNumber;
|
|
}
|
|
return {
|
|
...matchCollection,
|
|
posts: Array(postCount).fill(obj)
|
|
};
|
|
};
|
|
|
|
describe('Collections API', function () {
|
|
let agent;
|
|
|
|
before(async function () {
|
|
agent = await agentProvider.getAdminAPIAgent();
|
|
await fixtureManager.init('users', 'posts');
|
|
await agent.loginAsOwner();
|
|
});
|
|
|
|
afterEach(function () {
|
|
mockManager.restore();
|
|
});
|
|
|
|
it('Can add a Collection', async function () {
|
|
const collection = {
|
|
title: 'Test Collection',
|
|
description: 'Test Collection Description'
|
|
};
|
|
|
|
await agent
|
|
.post('/collections/')
|
|
.body({
|
|
collections: [collection]
|
|
})
|
|
.expectStatus(201)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag,
|
|
location: anyLocationFor('collections')
|
|
})
|
|
.matchBodySnapshot({
|
|
collections: [matchCollection]
|
|
});
|
|
});
|
|
|
|
it('Can browse Collections', async function () {
|
|
await agent
|
|
.get('/collections/')
|
|
.expectStatus(200)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag
|
|
})
|
|
.matchBodySnapshot({
|
|
collections: [
|
|
buildMatcher(11, {withSortOrder: true}),
|
|
buildMatcher(2, {withSortOrder: true}),
|
|
buildMatcher(0)
|
|
]
|
|
});
|
|
});
|
|
|
|
it('Can read a Collection', async function () {
|
|
const collection = {
|
|
title: 'Test Collection to Read'
|
|
};
|
|
|
|
const addResponse = await agent
|
|
.post('/collections/')
|
|
.body({
|
|
collections: [collection]
|
|
})
|
|
.expectStatus(201)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag,
|
|
location: anyLocationFor('collections')
|
|
})
|
|
.matchBodySnapshot({
|
|
collections: [matchCollection]
|
|
});
|
|
|
|
const collectionId = addResponse.body.collections[0].id;
|
|
|
|
const readResponse = await agent
|
|
.get(`/collections/${collectionId}/`)
|
|
.expectStatus(200)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag
|
|
})
|
|
.matchBodySnapshot({
|
|
collections: [matchCollection]
|
|
});
|
|
|
|
assert.equal(readResponse.body.collections[0].title, 'Test Collection to Read');
|
|
});
|
|
|
|
describe('Edit', function () {
|
|
let collectionToEdit;
|
|
|
|
before(async function () {
|
|
const collection = {
|
|
title: 'Test Collection to Edit'
|
|
};
|
|
|
|
const addResponse = await agent
|
|
.post('/collections/')
|
|
.body({
|
|
collections: [collection]
|
|
})
|
|
.expectStatus(201);
|
|
|
|
collectionToEdit = addResponse.body.collections[0];
|
|
});
|
|
|
|
it('Can edit a Collection', async function () {
|
|
const editResponse = await agent
|
|
.put(`/collections/${collectionToEdit.id}/`)
|
|
.body({
|
|
collections: [{
|
|
title: 'Test Collection Edited'
|
|
}]
|
|
})
|
|
.expectStatus(200)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag
|
|
})
|
|
.matchBodySnapshot({
|
|
collections: [matchCollection]
|
|
});
|
|
|
|
assert.equal(editResponse.body.collections[0].title, 'Test Collection Edited');
|
|
});
|
|
|
|
it('Fails to edit unexistent Collection', async function () {
|
|
const unexistentID = '5951f5fca366002ebd5dbef7';
|
|
await agent
|
|
.put(`/collections/${unexistentID}/`)
|
|
.body({
|
|
collections: [{
|
|
id: unexistentID,
|
|
title: 'Editing unexistent Collection'
|
|
}]
|
|
})
|
|
.expectStatus(404)
|
|
.matchBodySnapshot({
|
|
errors: [{
|
|
id: anyErrorId
|
|
}]
|
|
})
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Can delete a Collection', async function () {
|
|
const collection = {
|
|
title: 'Test Collection to Delete'
|
|
};
|
|
|
|
const addResponse = await agent
|
|
.post('/collections/')
|
|
.body({
|
|
collections: [collection]
|
|
})
|
|
.expectStatus(201)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag,
|
|
location: anyLocationFor('collections')
|
|
})
|
|
.matchBodySnapshot({
|
|
collections: [matchCollection]
|
|
});
|
|
|
|
const collectionId = addResponse.body.collections[0].id;
|
|
|
|
await agent
|
|
.delete(`/collections/${collectionId}/`)
|
|
.expectStatus(204)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag
|
|
})
|
|
.matchBodySnapshot();
|
|
|
|
await agent
|
|
.get(`/collections/${collectionId}/`)
|
|
.expectStatus(404)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag
|
|
})
|
|
.matchBodySnapshot({
|
|
errors: [{
|
|
id: anyErrorId
|
|
}]
|
|
});
|
|
});
|
|
|
|
it('Cannot delete a built in collection', async function () {
|
|
const builtInCollection = await agent
|
|
.get('/collections/?filter=slug:featured')
|
|
.expectStatus(200);
|
|
|
|
assert.ok(builtInCollection.body.collections);
|
|
assert.equal(builtInCollection.body.collections.length, 1);
|
|
|
|
await agent
|
|
.delete(`/collections/${builtInCollection.body.collections[0].id}/`)
|
|
.expectStatus(405)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag
|
|
})
|
|
.matchBodySnapshot({
|
|
errors: [{
|
|
id: anyErrorId,
|
|
context: anyString
|
|
}]
|
|
});
|
|
});
|
|
|
|
describe('Automatic Collection Filtering', function () {
|
|
it('Creates an automatic Collection with a featured filter', async function () {
|
|
const collection = {
|
|
title: 'Test Collection',
|
|
description: 'Test Collection Description',
|
|
type: 'automatic',
|
|
filter: 'featured:true'
|
|
};
|
|
|
|
await agent
|
|
.post('/collections/')
|
|
.body({
|
|
collections: [collection]
|
|
})
|
|
.expectStatus(201)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag,
|
|
location: anyLocationFor('collections')
|
|
})
|
|
.matchBodySnapshot({
|
|
collections: [buildMatcher(2)]
|
|
});
|
|
});
|
|
|
|
it('Creates an automatic Collection with a published_at filter', async function () {
|
|
const collection = {
|
|
title: 'Test Collection with published_at filter',
|
|
description: 'Test Collection Description with published_at filter',
|
|
type: 'automatic',
|
|
// should return all available posts
|
|
filter: 'published_at:>=2022-05-25'
|
|
};
|
|
|
|
await agent
|
|
.post('/collections/')
|
|
.body({
|
|
collections: [collection]
|
|
})
|
|
.expectStatus(201)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag,
|
|
location: anyLocationFor('collections')
|
|
})
|
|
.matchBodySnapshot({
|
|
collections: [buildMatcher(7)]
|
|
});
|
|
});
|
|
|
|
it('Creates an automatic Collection with a relational tag filter', async function () {
|
|
const collection = {
|
|
title: 'Test Collection with relational tag filter',
|
|
description: 'Test Collection Description with relational tag filter',
|
|
type: 'automatic',
|
|
filter: 'tag:kitchen-sink'
|
|
};
|
|
|
|
const automaticTagCollection = await agent
|
|
.post('/collections/')
|
|
.body({
|
|
collections: [collection]
|
|
})
|
|
.expectStatus(201)
|
|
.matchHeaderSnapshot({
|
|
'content-version': anyContentVersion,
|
|
etag: anyEtag,
|
|
location: anyLocationFor('collections')
|
|
})
|
|
.matchBodySnapshot({
|
|
collections: [buildMatcher(2)]
|
|
});
|
|
|
|
const kitchenSinkTagPosts = await agent
|
|
.get('/posts/?filter=tag:kitchen-sink');
|
|
|
|
assert.equal(automaticTagCollection.body.collections[0].posts.length, 2);
|
|
assert.equal(kitchenSinkTagPosts.body.posts.length, 2);
|
|
|
|
const collectionPostIds = automaticTagCollection.body.collections[0].posts.map(p => p.id);
|
|
const tagFilteredPosts = kitchenSinkTagPosts.body.posts.map(p => p.id);
|
|
|
|
assert.deepEqual(collectionPostIds, tagFilteredPosts);
|
|
});
|
|
});
|
|
});
|