2023-08-29 18:06:57 +03:00
|
|
|
const {agentProvider, fixtureManager, mockManager, matchers} = require('../../utils/e2e-framework');
|
2023-09-01 12:52:16 +03:00
|
|
|
const {anyObjectId, anyErrorId, anyISODateTime, anyContentVersion, anyLocationFor, anyEtag} = matchers;
|
2023-08-29 18:06:57 +03:00
|
|
|
const assert = require('assert/strict');
|
|
|
|
const recommendationsService = require('../../../core/server/services/recommendations');
|
2023-09-08 13:32:06 +03:00
|
|
|
const {Recommendation} = require('@tryghost/recommendations');
|
2023-08-29 18:06:57 +03:00
|
|
|
|
|
|
|
describe('Recommendations Admin API', function () {
|
|
|
|
let agent;
|
|
|
|
|
|
|
|
before(async function () {
|
|
|
|
agent = await agentProvider.getAdminAPIAgent();
|
|
|
|
await fixtureManager.init('posts');
|
|
|
|
await agent.loginAsOwner();
|
2023-08-30 13:25:31 +03:00
|
|
|
|
|
|
|
// Clear placeholders
|
|
|
|
for (const recommendation of (await recommendationsService.repository.getAll())) {
|
2023-09-01 11:48:14 +03:00
|
|
|
recommendation.delete();
|
|
|
|
await recommendationsService.repository.save(recommendation);
|
2023-08-30 13:25:31 +03:00
|
|
|
}
|
2023-08-29 18:06:57 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(function () {
|
|
|
|
mockManager.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Can add a minimal recommendation', async function () {
|
|
|
|
const {body} = await agent.post('recommendations/')
|
|
|
|
.body({
|
|
|
|
recommendations: [{
|
|
|
|
title: 'Dog Pictures',
|
|
|
|
url: 'https://dogpictures.com'
|
|
|
|
}]
|
|
|
|
})
|
|
|
|
.expectStatus(201)
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
'content-version': anyContentVersion,
|
|
|
|
etag: anyEtag,
|
|
|
|
location: anyLocationFor('recommendations')
|
|
|
|
})
|
|
|
|
.matchBodySnapshot({
|
|
|
|
recommendations: [
|
|
|
|
{
|
|
|
|
id: anyObjectId,
|
|
|
|
created_at: anyISODateTime
|
|
|
|
}
|
|
|
|
]
|
|
|
|
});
|
|
|
|
|
|
|
|
// Check everything is set correctly
|
|
|
|
assert.equal(body.recommendations[0].title, 'Dog Pictures');
|
2023-08-31 17:57:18 +03:00
|
|
|
assert.equal(body.recommendations[0].url, 'https://dogpictures.com/');
|
2023-08-29 18:06:57 +03:00
|
|
|
assert.equal(body.recommendations[0].reason, null);
|
|
|
|
assert.equal(body.recommendations[0].excerpt, null);
|
|
|
|
assert.equal(body.recommendations[0].featured_image, null);
|
|
|
|
assert.equal(body.recommendations[0].favicon, null);
|
|
|
|
assert.equal(body.recommendations[0].one_click_subscribe, false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Can add a full recommendation', async function () {
|
|
|
|
const {body} = await agent.post('recommendations/')
|
|
|
|
.body({
|
|
|
|
recommendations: [{
|
|
|
|
title: 'Dog Pictures',
|
|
|
|
url: 'https://dogpictures.com',
|
|
|
|
reason: 'Because dogs are cute',
|
|
|
|
excerpt: 'Dogs are cute',
|
|
|
|
featured_image: 'https://dogpictures.com/dog.jpg',
|
|
|
|
favicon: 'https://dogpictures.com/favicon.ico',
|
|
|
|
one_click_subscribe: true
|
|
|
|
}]
|
|
|
|
})
|
|
|
|
.expectStatus(201)
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
'content-version': anyContentVersion,
|
|
|
|
etag: anyEtag,
|
|
|
|
location: anyLocationFor('recommendations')
|
|
|
|
})
|
|
|
|
.matchBodySnapshot({
|
|
|
|
recommendations: [
|
|
|
|
{
|
|
|
|
id: anyObjectId,
|
|
|
|
created_at: anyISODateTime
|
|
|
|
}
|
|
|
|
]
|
|
|
|
});
|
|
|
|
|
|
|
|
// Check everything is set correctly
|
|
|
|
assert.equal(body.recommendations[0].title, 'Dog Pictures');
|
2023-08-31 17:57:18 +03:00
|
|
|
assert.equal(body.recommendations[0].url, 'https://dogpictures.com/');
|
2023-08-29 18:06:57 +03:00
|
|
|
assert.equal(body.recommendations[0].reason, 'Because dogs are cute');
|
|
|
|
assert.equal(body.recommendations[0].excerpt, 'Dogs are cute');
|
|
|
|
assert.equal(body.recommendations[0].featured_image, 'https://dogpictures.com/dog.jpg');
|
|
|
|
assert.equal(body.recommendations[0].favicon, 'https://dogpictures.com/favicon.ico');
|
|
|
|
assert.equal(body.recommendations[0].one_click_subscribe, true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Can edit recommendation', async function () {
|
|
|
|
const id = (await recommendationsService.repository.getAll())[0].id;
|
|
|
|
const {body} = await agent.put(`recommendations/${id}/`)
|
|
|
|
.body({
|
|
|
|
recommendations: [{
|
|
|
|
title: 'Cat Pictures',
|
|
|
|
url: 'https://catpictures.com',
|
|
|
|
reason: 'Because cats are cute',
|
|
|
|
excerpt: 'Cats are cute',
|
|
|
|
featured_image: 'https://catpictures.com/cat.jpg',
|
|
|
|
favicon: 'https://catpictures.com/favicon.ico',
|
|
|
|
one_click_subscribe: false
|
|
|
|
}]
|
|
|
|
})
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
'content-version': anyContentVersion,
|
|
|
|
etag: anyEtag
|
|
|
|
})
|
|
|
|
.matchBodySnapshot({
|
|
|
|
recommendations: [
|
|
|
|
{
|
|
|
|
id: anyObjectId,
|
2023-09-01 11:48:14 +03:00
|
|
|
created_at: anyISODateTime,
|
|
|
|
updated_at: anyISODateTime
|
2023-08-29 18:06:57 +03:00
|
|
|
}
|
|
|
|
]
|
|
|
|
});
|
|
|
|
|
|
|
|
// Check everything is set correctly
|
|
|
|
assert.equal(body.recommendations[0].id, id);
|
|
|
|
assert.equal(body.recommendations[0].title, 'Cat Pictures');
|
2023-08-31 17:57:18 +03:00
|
|
|
assert.equal(body.recommendations[0].url, 'https://catpictures.com/');
|
2023-08-29 18:06:57 +03:00
|
|
|
assert.equal(body.recommendations[0].reason, 'Because cats are cute');
|
|
|
|
assert.equal(body.recommendations[0].excerpt, 'Cats are cute');
|
|
|
|
assert.equal(body.recommendations[0].featured_image, 'https://catpictures.com/cat.jpg');
|
|
|
|
assert.equal(body.recommendations[0].favicon, 'https://catpictures.com/favicon.ico');
|
|
|
|
assert.equal(body.recommendations[0].one_click_subscribe, false);
|
|
|
|
});
|
|
|
|
|
2023-09-01 12:52:16 +03:00
|
|
|
it('Cannot use invalid protocols when editing', async function () {
|
|
|
|
const id = (await recommendationsService.repository.getAll())[0].id;
|
|
|
|
await agent.put(`recommendations/${id}/`)
|
|
|
|
.body({
|
|
|
|
recommendations: [{
|
|
|
|
title: 'Cat Pictures',
|
|
|
|
url: 'https://catpictures.com',
|
|
|
|
reason: 'Because cats are cute',
|
|
|
|
excerpt: 'Cats are cute',
|
|
|
|
featured_image: 'ftp://catpictures.com/cat.jpg',
|
|
|
|
favicon: 'ftp://catpictures.com/favicon.ico',
|
|
|
|
one_click_subscribe: false
|
|
|
|
}]
|
|
|
|
})
|
|
|
|
.expectStatus(422)
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
'content-version': anyContentVersion,
|
|
|
|
etag: anyEtag
|
|
|
|
})
|
|
|
|
.matchBodySnapshot({
|
|
|
|
errors: [
|
|
|
|
{
|
|
|
|
id: anyErrorId
|
|
|
|
}
|
|
|
|
]
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2023-08-29 18:06:57 +03:00
|
|
|
it('Can delete recommendation', async function () {
|
|
|
|
const id = (await recommendationsService.repository.getAll())[0].id;
|
|
|
|
await agent.delete(`recommendations/${id}/`)
|
|
|
|
.expectStatus(204)
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
'content-version': anyContentVersion,
|
|
|
|
etag: anyEtag
|
|
|
|
})
|
|
|
|
.matchBodySnapshot({});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Can browse', async function () {
|
|
|
|
await agent.get('recommendations/')
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
'content-version': anyContentVersion,
|
|
|
|
etag: anyEtag
|
|
|
|
})
|
|
|
|
.matchBodySnapshot({
|
|
|
|
recommendations: [
|
|
|
|
{
|
|
|
|
id: anyObjectId,
|
2023-09-01 12:52:16 +03:00
|
|
|
created_at: anyISODateTime,
|
|
|
|
updated_at: anyISODateTime
|
2023-08-29 18:06:57 +03:00
|
|
|
}
|
|
|
|
]
|
|
|
|
});
|
|
|
|
});
|
2023-09-08 13:32:06 +03:00
|
|
|
|
|
|
|
it('Can request pages', async function () {
|
|
|
|
// Add 15 recommendations using the repository
|
|
|
|
for (let i = 0; i < 15; i++) {
|
|
|
|
const recommendation = Recommendation.create({
|
|
|
|
title: `Recommendation ${i}`,
|
|
|
|
reason: `Reason ${i}`,
|
|
|
|
url: new URL(`https://recommendation${i}.com`),
|
|
|
|
favicon: null,
|
|
|
|
featuredImage: null,
|
|
|
|
excerpt: null,
|
|
|
|
oneClickSubscribe: false
|
|
|
|
});
|
|
|
|
|
|
|
|
await recommendationsService.repository.save(recommendation);
|
|
|
|
}
|
|
|
|
|
|
|
|
const {body: page1} = await agent.get('recommendations/?page=1&limit=10')
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
'content-version': anyContentVersion,
|
|
|
|
etag: anyEtag
|
|
|
|
})
|
|
|
|
.matchBodySnapshot({
|
|
|
|
recommendations: new Array(10).fill({
|
|
|
|
id: anyObjectId,
|
|
|
|
created_at: anyISODateTime,
|
|
|
|
updated_at: anyISODateTime
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(page1.meta.pagination.page, 1);
|
|
|
|
assert.equal(page1.meta.pagination.limit, 10);
|
|
|
|
assert.equal(page1.meta.pagination.pages, 2);
|
|
|
|
assert.equal(page1.meta.pagination.next, 2);
|
|
|
|
assert.equal(page1.meta.pagination.prev, null);
|
|
|
|
assert.equal(page1.meta.pagination.total, 16);
|
|
|
|
|
|
|
|
const {body: page2} = await agent.get('recommendations/?page=2&limit=10')
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
'content-version': anyContentVersion,
|
|
|
|
etag: anyEtag
|
|
|
|
})
|
|
|
|
.matchBodySnapshot({
|
|
|
|
recommendations: new Array(6).fill({
|
|
|
|
id: anyObjectId,
|
|
|
|
created_at: anyISODateTime,
|
|
|
|
updated_at: anyISODateTime
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(page2.meta.pagination.page, 2);
|
|
|
|
assert.equal(page2.meta.pagination.limit, 10);
|
|
|
|
assert.equal(page2.meta.pagination.pages, 2);
|
|
|
|
assert.equal(page2.meta.pagination.next, null);
|
|
|
|
assert.equal(page2.meta.pagination.prev, 1);
|
|
|
|
assert.equal(page2.meta.pagination.total, 16);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Uses default limit of 5', async function () {
|
|
|
|
const {body: page1} = await agent.get('recommendations/')
|
|
|
|
.expectStatus(200)
|
|
|
|
.matchHeaderSnapshot({
|
|
|
|
'content-version': anyContentVersion,
|
|
|
|
etag: anyEtag
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(page1.meta.pagination.limit, 5);
|
|
|
|
});
|
2023-08-29 18:06:57 +03:00
|
|
|
});
|