Added read endpoint to the Recommendations Admin API (#18221)
closes https://github.com/TryGhost/Product/issues/3910
This commit is contained in:
parent
72110d101e
commit
d5ad5d2dd0
@ -19,6 +19,20 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
read: {
|
||||
headers: {
|
||||
cacheInvalidate: false
|
||||
},
|
||||
options: [
|
||||
'id'
|
||||
],
|
||||
permissions: true,
|
||||
validation: {},
|
||||
async query(frame) {
|
||||
return await recommendations.controller.read(frame);
|
||||
}
|
||||
},
|
||||
|
||||
add: {
|
||||
statusCode: 201,
|
||||
headers: {
|
||||
|
@ -349,6 +349,7 @@ module.exports = function apiRoutes() {
|
||||
|
||||
// Recommendations
|
||||
router.get('/recommendations', mw.authAdminApi, http(api.recommendations.browse));
|
||||
router.get('/recommendations/:id', mw.authAdminApi, http(api.recommendations.read));
|
||||
router.post('/recommendations', mw.authAdminApi, http(api.recommendations.add));
|
||||
router.put('/recommendations/:id', mw.authAdminApi, http(api.recommendations.edit));
|
||||
router.del('/recommendations/:id', mw.authAdminApi, http(api.recommendations.destroy));
|
||||
|
@ -1144,3 +1144,959 @@ Object {
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API add Can add a full recommendation 1: [body] 1`] = `
|
||||
Object {
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Dogs are cute",
|
||||
"favicon": "https://dogpictures.com/favicon.ico",
|
||||
"featured_image": "https://dogpictures.com/dog.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Because dogs are cute",
|
||||
"title": "Dog Pictures",
|
||||
"updated_at": null,
|
||||
"url": "https://dogpictures.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API add Can add a full recommendation 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "354",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/recommendations\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-cache-invalidate": "/*",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API add Can add a minimal recommendation 1: [body] 1`] = `
|
||||
Object {
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": null,
|
||||
"favicon": null,
|
||||
"featured_image": null,
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": false,
|
||||
"reason": null,
|
||||
"title": "Dog Pictures",
|
||||
"updated_at": null,
|
||||
"url": "https://dogpictures.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API add Can add a minimal recommendation 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "263",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/recommendations\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-cache-invalidate": "/*",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API add Cannot add the same recommendation twice 1: [body] 1`] = `
|
||||
Object {
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": null,
|
||||
"favicon": null,
|
||||
"featured_image": null,
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": false,
|
||||
"reason": null,
|
||||
"title": "Dog Pictures",
|
||||
"updated_at": null,
|
||||
"url": "https://dogpictures.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API add Cannot add the same recommendation twice 2: [body] 1`] = `
|
||||
Object {
|
||||
"errors": Array [
|
||||
Object {
|
||||
"code": null,
|
||||
"context": "A recommendation with this URL already exists.",
|
||||
"details": null,
|
||||
"ghostErrorCode": null,
|
||||
"help": null,
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/,
|
||||
"message": "Validation error, cannot save recommendation.",
|
||||
"property": null,
|
||||
"type": "ValidationError",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can browse 1: [body] 1`] = `
|
||||
Object {
|
||||
"meta": Object {
|
||||
"pagination": Object {
|
||||
"limit": 5,
|
||||
"next": null,
|
||||
"page": 1,
|
||||
"pages": 1,
|
||||
"prev": null,
|
||||
"total": 1,
|
||||
},
|
||||
},
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation0.com/favicon.ico",
|
||||
"featured_image": "https://recommendation0.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 0",
|
||||
"title": "Recommendation 0",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation0.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can browse 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "470",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can fetch recommendations with relations when there are no recommendations 1: [body] 1`] = `
|
||||
Object {
|
||||
"meta": Object {
|
||||
"pagination": Object {
|
||||
"limit": 5,
|
||||
"next": null,
|
||||
"page": 1,
|
||||
"pages": 0,
|
||||
"prev": null,
|
||||
"total": 0,
|
||||
},
|
||||
},
|
||||
"recommendations": Array [],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can fetch recommendations with relations when there are no recommendations 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "109",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can include click and subscribe counts 1: [body] 1`] = `
|
||||
Object {
|
||||
"meta": Object {
|
||||
"pagination": Object {
|
||||
"limit": 5,
|
||||
"next": null,
|
||||
"page": 1,
|
||||
"pages": 1,
|
||||
"prev": null,
|
||||
"total": 5,
|
||||
},
|
||||
},
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"count": Object {
|
||||
"clicks": 2,
|
||||
"subscribers": 3,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation4.com/favicon.ico",
|
||||
"featured_image": "https://recommendation4.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 4",
|
||||
"title": "Recommendation 4",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation4.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"clicks": 3,
|
||||
"subscribers": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation3.com/favicon.ico",
|
||||
"featured_image": "https://recommendation3.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 3",
|
||||
"title": "Recommendation 3",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation3.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"subscribers": 2,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation2.com/favicon.ico",
|
||||
"featured_image": "https://recommendation2.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 2",
|
||||
"title": "Recommendation 2",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation2.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"subscribers": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation1.com/favicon.ico",
|
||||
"featured_image": "https://recommendation1.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 1",
|
||||
"title": "Recommendation 1",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation1.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"subscribers": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation0.com/favicon.ico",
|
||||
"featured_image": "https://recommendation0.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 0",
|
||||
"title": "Recommendation 0",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation0.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can include click and subscribe counts 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "2103",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can include only clicks 1: [body] 1`] = `
|
||||
Object {
|
||||
"meta": Object {
|
||||
"pagination": Object {
|
||||
"limit": 5,
|
||||
"next": null,
|
||||
"page": 1,
|
||||
"pages": 1,
|
||||
"prev": null,
|
||||
"total": 5,
|
||||
},
|
||||
},
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"count": Object {
|
||||
"clicks": 2,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation4.com/favicon.ico",
|
||||
"featured_image": "https://recommendation4.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 4",
|
||||
"title": "Recommendation 4",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation4.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"clicks": 3,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation3.com/favicon.ico",
|
||||
"featured_image": "https://recommendation3.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 3",
|
||||
"title": "Recommendation 3",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation3.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation2.com/favicon.ico",
|
||||
"featured_image": "https://recommendation2.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 2",
|
||||
"title": "Recommendation 2",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation2.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation1.com/favicon.ico",
|
||||
"featured_image": "https://recommendation1.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 1",
|
||||
"title": "Recommendation 1",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation1.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation0.com/favicon.ico",
|
||||
"featured_image": "https://recommendation0.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 0",
|
||||
"title": "Recommendation 0",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation0.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can include only clicks 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "2023",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can include only subscribers 1: [body] 1`] = `
|
||||
Object {
|
||||
"meta": Object {
|
||||
"pagination": Object {
|
||||
"limit": 5,
|
||||
"next": null,
|
||||
"page": 1,
|
||||
"pages": 1,
|
||||
"prev": null,
|
||||
"total": 5,
|
||||
},
|
||||
},
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"count": Object {
|
||||
"subscribers": 3,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation4.com/favicon.ico",
|
||||
"featured_image": "https://recommendation4.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 4",
|
||||
"title": "Recommendation 4",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation4.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"subscribers": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation3.com/favicon.ico",
|
||||
"featured_image": "https://recommendation3.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 3",
|
||||
"title": "Recommendation 3",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation3.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"subscribers": 2,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation2.com/favicon.ico",
|
||||
"featured_image": "https://recommendation2.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 2",
|
||||
"title": "Recommendation 2",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation2.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"subscribers": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation1.com/favicon.ico",
|
||||
"featured_image": "https://recommendation1.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 1",
|
||||
"title": "Recommendation 1",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation1.com/",
|
||||
},
|
||||
Object {
|
||||
"count": Object {
|
||||
"subscribers": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation0.com/favicon.ico",
|
||||
"featured_image": "https://recommendation0.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 0",
|
||||
"title": "Recommendation 0",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation0.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can include only subscribers 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "2048",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can request pages 1: [body] 1`] = `
|
||||
Object {
|
||||
"meta": Object {
|
||||
"pagination": Object {
|
||||
"limit": 10,
|
||||
"next": 2,
|
||||
"page": 1,
|
||||
"pages": 2,
|
||||
"prev": null,
|
||||
"total": 15,
|
||||
},
|
||||
},
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation14.com/favicon.ico",
|
||||
"featured_image": "https://recommendation14.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 14",
|
||||
"title": "Recommendation 14",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation14.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation13.com/favicon.ico",
|
||||
"featured_image": "https://recommendation13.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 13",
|
||||
"title": "Recommendation 13",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation13.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation12.com/favicon.ico",
|
||||
"featured_image": "https://recommendation12.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 12",
|
||||
"title": "Recommendation 12",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation12.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation11.com/favicon.ico",
|
||||
"featured_image": "https://recommendation11.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 11",
|
||||
"title": "Recommendation 11",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation11.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation10.com/favicon.ico",
|
||||
"featured_image": "https://recommendation10.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 10",
|
||||
"title": "Recommendation 10",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation10.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation9.com/favicon.ico",
|
||||
"featured_image": "https://recommendation9.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 9",
|
||||
"title": "Recommendation 9",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation9.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation8.com/favicon.ico",
|
||||
"featured_image": "https://recommendation8.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 8",
|
||||
"title": "Recommendation 8",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation8.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation7.com/favicon.ico",
|
||||
"featured_image": "https://recommendation7.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 7",
|
||||
"title": "Recommendation 7",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation7.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation6.com/favicon.ico",
|
||||
"featured_image": "https://recommendation6.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 6",
|
||||
"title": "Recommendation 6",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation6.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation5.com/favicon.ico",
|
||||
"featured_image": "https://recommendation5.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 5",
|
||||
"title": "Recommendation 5",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation5.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can request pages 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "3752",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can request pages 3: [body] 1`] = `
|
||||
Object {
|
||||
"meta": Object {
|
||||
"pagination": Object {
|
||||
"limit": 10,
|
||||
"next": null,
|
||||
"page": 2,
|
||||
"pages": 2,
|
||||
"prev": 1,
|
||||
"total": 15,
|
||||
},
|
||||
},
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation4.com/favicon.ico",
|
||||
"featured_image": "https://recommendation4.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 4",
|
||||
"title": "Recommendation 4",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation4.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation3.com/favicon.ico",
|
||||
"featured_image": "https://recommendation3.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 3",
|
||||
"title": "Recommendation 3",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation3.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation2.com/favicon.ico",
|
||||
"featured_image": "https://recommendation2.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 2",
|
||||
"title": "Recommendation 2",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation2.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation1.com/favicon.ico",
|
||||
"featured_image": "https://recommendation1.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 1",
|
||||
"title": "Recommendation 1",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation1.com/",
|
||||
},
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation0.com/favicon.ico",
|
||||
"featured_image": "https://recommendation0.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 0",
|
||||
"title": "Recommendation 0",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation0.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Can request pages 4: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "1917",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API browse Uses default limit of 5 1: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "1915",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API delete Can delete recommendation 1: [body] 1`] = `Object {}`;
|
||||
|
||||
exports[`Recommendations Admin API delete Can delete recommendation 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin",
|
||||
"x-cache-invalidate": "/*",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API edit Can edit recommendation 1: [body] 1`] = `
|
||||
Object {
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Cats are cute",
|
||||
"favicon": "https://catpictures.com/favicon.ico",
|
||||
"featured_image": "https://catpictures.com/cat.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": false,
|
||||
"reason": "Because cats are cute",
|
||||
"title": "Cat Pictures",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://dogpictures.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API edit Can edit recommendation 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "377",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-cache-invalidate": "/*",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API edit Can edit recommendation and set nullable fields to null 1: [body] 1`] = `
|
||||
Object {
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": null,
|
||||
"favicon": null,
|
||||
"featured_image": null,
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": null,
|
||||
"title": "Recommendation 0",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation0.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API edit Can edit recommendation and set nullable fields to null 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "292",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-cache-invalidate": "/*",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API edit Can edit some fields of a recommendation without changing others 1: [body] 1`] = `
|
||||
Object {
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation0.com/favicon.ico",
|
||||
"featured_image": "https://recommendation0.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 0",
|
||||
"title": "Changed",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation0.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API edit Can edit some fields of a recommendation without changing others 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "374",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-cache-invalidate": "/*",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API edit Cannot use invalid protocols when editing 1: [body] 1`] = `
|
||||
Object {
|
||||
"errors": Array [
|
||||
Object {
|
||||
"code": null,
|
||||
"context": "recommendations.0.featured_image must be a valid URL",
|
||||
"details": null,
|
||||
"ghostErrorCode": null,
|
||||
"help": null,
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/,
|
||||
"message": "Validation error, cannot edit recommendation.",
|
||||
"property": null,
|
||||
"type": "ValidationError",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API edit Cannot use invalid protocols when editing 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "283",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API read can get a recommendation by ID 1: [body] 1`] = `
|
||||
Object {
|
||||
"recommendations": Array [
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"excerpt": "Test excerpt",
|
||||
"favicon": "https://recommendation1.com/favicon.ico",
|
||||
"featured_image": "https://recommendation1.com/featured.jpg",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"one_click_subscribe": true,
|
||||
"reason": "Reason 1",
|
||||
"title": "Recommendation 1",
|
||||
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"url": "https://recommendation1.com/",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API read can get a recommendation by ID 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "383",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API read returns an empty array when the recommendation is not found 1: [body] 1`] = `
|
||||
Object {
|
||||
"errors": Array [
|
||||
Object {
|
||||
"code": null,
|
||||
"context": "Validation (matches) failed for id undefined.id",
|
||||
"details": null,
|
||||
"ghostErrorCode": null,
|
||||
"help": null,
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/,
|
||||
"message": "Validation error, cannot read recommendation.",
|
||||
"property": null,
|
||||
"type": "ValidationError",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Recommendations Admin API read returns an empty array when the recommendation is not found 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "278",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
@ -88,428 +88,487 @@ describe('Recommendations Admin API', function () {
|
||||
mockManager.restore();
|
||||
});
|
||||
|
||||
it('Can fetch recommendations with relations when there are no recommendations', async function () {
|
||||
const recommendations = await recommendationsService.repository.getCount();
|
||||
assert.equal(recommendations, 0, 'This test expects there to be no recommendations');
|
||||
describe('browse', function () {
|
||||
it('Can browse', async function () {
|
||||
await addDummyRecommendation();
|
||||
|
||||
const {body: page1} = await agent.get('recommendations/?include=count.clicks,count.subscribers')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({});
|
||||
await agent.get('recommendations/')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: [
|
||||
{
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
assert.equal(page1.recommendations.length, 0);
|
||||
});
|
||||
it('Can request pages', async function () {
|
||||
// Add 15 recommendations using the repository
|
||||
await addDummyRecommendations(15);
|
||||
|
||||
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');
|
||||
assert.equal(body.recommendations[0].url, 'https://dogpictures.com/');
|
||||
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');
|
||||
assert.equal(body.recommendations[0].url, 'https://dogpictures.com/');
|
||||
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('Cannot add the same recommendation twice', async function () {
|
||||
await agent.post('recommendations/')
|
||||
.body({
|
||||
recommendations: [{
|
||||
title: 'Dog Pictures',
|
||||
url: 'https://dogpictures.com'
|
||||
}]
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: [
|
||||
{
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await agent.post('recommendations/')
|
||||
.body({
|
||||
recommendations: [{
|
||||
title: 'Dog Pictures 2',
|
||||
url: 'https://dogpictures.com'
|
||||
}]
|
||||
})
|
||||
.expectStatus(422)
|
||||
.matchBodySnapshot({
|
||||
errors: [
|
||||
{
|
||||
id: anyErrorId
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('Can edit recommendation', async function () {
|
||||
const id = await addDummyRecommendation();
|
||||
const {body} = await agent.put(`recommendations/${id}/`)
|
||||
.body({
|
||||
recommendations: [{
|
||||
title: 'Cat Pictures',
|
||||
url: 'https://dogpictures.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: [
|
||||
{
|
||||
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
|
||||
}
|
||||
]
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
// Check everything is set correctly
|
||||
assert.equal(body.recommendations[0].id, id);
|
||||
assert.equal(body.recommendations[0].title, 'Cat Pictures');
|
||||
assert.equal(body.recommendations[0].url, 'https://dogpictures.com/');
|
||||
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);
|
||||
});
|
||||
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, 15);
|
||||
|
||||
it('Can edit recommendation and set nullable fields to null', async function () {
|
||||
const id = await addDummyRecommendation();
|
||||
const {body} = await agent.put(`recommendations/${id}/`)
|
||||
.body({
|
||||
recommendations: [{
|
||||
reason: null,
|
||||
excerpt: null,
|
||||
featured_image: null,
|
||||
favicon: null
|
||||
}]
|
||||
})
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: [
|
||||
{
|
||||
const {body: page2} = await agent.get('recommendations/?page=2&limit=10')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: new Array(5).fill({
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
}
|
||||
]
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
// Check everything is set correctly
|
||||
assert.equal(body.recommendations[0].id, id);
|
||||
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(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, 15);
|
||||
});
|
||||
|
||||
it('Can edit some fields of a recommendation without changing others', async function () {
|
||||
const id = await addDummyRecommendation();
|
||||
const {body} = await agent.put(`recommendations/${id}/`)
|
||||
.body({
|
||||
recommendations: [{
|
||||
title: 'Changed'
|
||||
}]
|
||||
})
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: [
|
||||
{
|
||||
it('Uses default limit of 5', async function () {
|
||||
await addDummyRecommendations(6);
|
||||
const {body: page1} = await agent.get('recommendations/')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
});
|
||||
|
||||
assert.equal(page1.meta.pagination.limit, 5);
|
||||
});
|
||||
|
||||
it('Can include click and subscribe counts', async function () {
|
||||
await addDummyRecommendations(5);
|
||||
await addClicksAndSubscribers({memberId});
|
||||
|
||||
const {body: page1} = await agent.get('recommendations/?include=count.clicks,count.subscribers')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: new Array(5).fill({
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
}
|
||||
]
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
// Check everything is set correctly
|
||||
assert.equal(body.recommendations[0].id, id);
|
||||
assert.equal(body.recommendations[0].title, 'Changed');
|
||||
assert.equal(body.recommendations[0].url, 'https://recommendation0.com/');
|
||||
assert.equal(body.recommendations[0].reason, 'Reason 0');
|
||||
assert.equal(body.recommendations[0].excerpt, 'Test excerpt');
|
||||
assert.equal(body.recommendations[0].featured_image, 'https://recommendation0.com/featured.jpg');
|
||||
assert.equal(body.recommendations[0].favicon, 'https://recommendation0.com/favicon.ico');
|
||||
assert.equal(body.recommendations[0].one_click_subscribe, true);
|
||||
});
|
||||
assert.equal(page1.recommendations[0].count.clicks, 2);
|
||||
assert.equal(page1.recommendations[1].count.clicks, 3);
|
||||
|
||||
it('Cannot use invalid protocols when editing', async function () {
|
||||
const id = await addDummyRecommendation();
|
||||
assert.equal(page1.recommendations[0].count.subscribers, 3);
|
||||
assert.equal(page1.recommendations[1].count.subscribers, 0);
|
||||
assert.equal(page1.recommendations[2].count.subscribers, 2);
|
||||
});
|
||||
|
||||
await agent.put(`recommendations/${id}/`)
|
||||
.body({
|
||||
recommendations: [{
|
||||
title: 'Cat Pictures',
|
||||
url: 'https://dogpictures.com',
|
||||
reason: 'Because cats are cute',
|
||||
excerpt: 'Cats are cute',
|
||||
featured_image: 'ftp://dogpictures.com/dog.jpg',
|
||||
favicon: 'ftp://dogpictures.com/favicon.ico',
|
||||
one_click_subscribe: false
|
||||
}]
|
||||
})
|
||||
.expectStatus(422)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
errors: [
|
||||
{
|
||||
id: anyErrorId
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
it('Can include only clicks', async function () {
|
||||
await addDummyRecommendations(5);
|
||||
await addClicksAndSubscribers({memberId});
|
||||
|
||||
it('Can delete recommendation', async function () {
|
||||
const id = await addDummyRecommendation();
|
||||
await agent.delete(`recommendations/${id}/`)
|
||||
.expectStatus(204)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({});
|
||||
});
|
||||
|
||||
it('Can browse', async function () {
|
||||
await addDummyRecommendation();
|
||||
|
||||
await agent.get('recommendations/')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: [
|
||||
{
|
||||
const {body: page1} = await agent.get('recommendations/?include=count.clicks')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: new Array(5).fill({
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
}
|
||||
]
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
assert.equal(page1.recommendations[0].count.clicks, 2);
|
||||
assert.equal(page1.recommendations[1].count.clicks, 3);
|
||||
|
||||
assert.equal(page1.recommendations[0].count.subscribers, undefined);
|
||||
assert.equal(page1.recommendations[1].count.subscribers, undefined);
|
||||
assert.equal(page1.recommendations[2].count.subscribers, undefined);
|
||||
});
|
||||
|
||||
it('Can include only subscribers', async function () {
|
||||
await addDummyRecommendations(5);
|
||||
await addClicksAndSubscribers({memberId});
|
||||
|
||||
const {body: page1} = await agent.get('recommendations/?include=count.subscribers')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: new Array(5).fill({
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
})
|
||||
});
|
||||
|
||||
assert.equal(page1.recommendations[0].count.clicks, undefined);
|
||||
assert.equal(page1.recommendations[1].count.clicks, undefined);
|
||||
|
||||
assert.equal(page1.recommendations[0].count.subscribers, 3);
|
||||
assert.equal(page1.recommendations[1].count.subscribers, 0);
|
||||
assert.equal(page1.recommendations[2].count.subscribers, 2);
|
||||
});
|
||||
|
||||
it('Can fetch recommendations with relations when there are no recommendations', async function () {
|
||||
const recommendations = await recommendationsService.repository.getCount();
|
||||
assert.equal(recommendations, 0, 'This test expects there to be no recommendations');
|
||||
|
||||
const {body: page1} = await agent.get('recommendations/?include=count.clicks,count.subscribers')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({});
|
||||
|
||||
assert.equal(page1.recommendations.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
it('Can request pages', async function () {
|
||||
// Add 15 recommendations using the repository
|
||||
await addDummyRecommendations(15);
|
||||
|
||||
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
|
||||
describe('read', function () {
|
||||
it('can get a recommendation by ID', async function () {
|
||||
const id = await addDummyRecommendation(1);
|
||||
const {body} = await agent.get(`recommendations/${id}/`)
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
});
|
||||
.matchBodySnapshot({
|
||||
recommendations: [
|
||||
{
|
||||
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, 15);
|
||||
// Check data
|
||||
assert.equal(body.recommendations[0].id, id);
|
||||
assert.equal(body.recommendations[0].title, 'Recommendation 1');
|
||||
assert.equal(body.recommendations[0].url, 'https://recommendation1.com/');
|
||||
assert.equal(body.recommendations[0].reason, 'Reason 1');
|
||||
assert.equal(body.recommendations[0].excerpt, 'Test excerpt');
|
||||
assert.equal(body.recommendations[0].featured_image, 'https://recommendation1.com/featured.jpg');
|
||||
assert.equal(body.recommendations[0].favicon, 'https://recommendation1.com/favicon.ico');
|
||||
assert.equal(body.recommendations[0].one_click_subscribe, true);
|
||||
});
|
||||
|
||||
const {body: page2} = await agent.get('recommendations/?page=2&limit=10')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: new Array(5).fill({
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
it('returns an empty array when the recommendation is not found', async function () {
|
||||
const id = 'i-dont-exist';
|
||||
const {body} = await agent.get(`recommendations/${id}/`)
|
||||
.expectStatus(422)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
});
|
||||
.matchBodySnapshot({
|
||||
errors: [
|
||||
{
|
||||
id: anyErrorId
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
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, 15);
|
||||
assert.equal(body.errors[0].type, 'ValidationError');
|
||||
assert.equal(body.errors[0].message, 'Validation error, cannot read recommendation.');
|
||||
});
|
||||
});
|
||||
|
||||
it('Uses default limit of 5', async function () {
|
||||
await addDummyRecommendations(6);
|
||||
const {body: page1} = await agent.get('recommendations/')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
});
|
||||
describe('edit', function () {
|
||||
it('Can edit recommendation', async function () {
|
||||
const id = await addDummyRecommendation();
|
||||
const {body} = await agent.put(`recommendations/${id}/`)
|
||||
.body({
|
||||
recommendations: [{
|
||||
title: 'Cat Pictures',
|
||||
url: 'https://dogpictures.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,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
assert.equal(page1.meta.pagination.limit, 5);
|
||||
// Check everything is set correctly
|
||||
assert.equal(body.recommendations[0].id, id);
|
||||
assert.equal(body.recommendations[0].title, 'Cat Pictures');
|
||||
assert.equal(body.recommendations[0].url, 'https://dogpictures.com/');
|
||||
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);
|
||||
});
|
||||
|
||||
it('Can edit recommendation and set nullable fields to null', async function () {
|
||||
const id = await addDummyRecommendation();
|
||||
const {body} = await agent.put(`recommendations/${id}/`)
|
||||
.body({
|
||||
recommendations: [{
|
||||
reason: null,
|
||||
excerpt: null,
|
||||
featured_image: null,
|
||||
favicon: null
|
||||
}]
|
||||
})
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: [
|
||||
{
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Check everything is set correctly
|
||||
assert.equal(body.recommendations[0].id, id);
|
||||
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);
|
||||
});
|
||||
|
||||
it('Can edit some fields of a recommendation without changing others', async function () {
|
||||
const id = await addDummyRecommendation();
|
||||
const {body} = await agent.put(`recommendations/${id}/`)
|
||||
.body({
|
||||
recommendations: [{
|
||||
title: 'Changed'
|
||||
}]
|
||||
})
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: [
|
||||
{
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Check everything is set correctly
|
||||
assert.equal(body.recommendations[0].id, id);
|
||||
assert.equal(body.recommendations[0].title, 'Changed');
|
||||
assert.equal(body.recommendations[0].url, 'https://recommendation0.com/');
|
||||
assert.equal(body.recommendations[0].reason, 'Reason 0');
|
||||
assert.equal(body.recommendations[0].excerpt, 'Test excerpt');
|
||||
assert.equal(body.recommendations[0].featured_image, 'https://recommendation0.com/featured.jpg');
|
||||
assert.equal(body.recommendations[0].favicon, 'https://recommendation0.com/favicon.ico');
|
||||
assert.equal(body.recommendations[0].one_click_subscribe, true);
|
||||
});
|
||||
|
||||
it('Cannot use invalid protocols when editing', async function () {
|
||||
const id = await addDummyRecommendation();
|
||||
|
||||
await agent.put(`recommendations/${id}/`)
|
||||
.body({
|
||||
recommendations: [{
|
||||
title: 'Cat Pictures',
|
||||
url: 'https://dogpictures.com',
|
||||
reason: 'Because cats are cute',
|
||||
excerpt: 'Cats are cute',
|
||||
featured_image: 'ftp://dogpictures.com/dog.jpg',
|
||||
favicon: 'ftp://dogpictures.com/favicon.ico',
|
||||
one_click_subscribe: false
|
||||
}]
|
||||
})
|
||||
.expectStatus(422)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
errors: [
|
||||
{
|
||||
id: anyErrorId
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Can include click and subscribe counts', async function () {
|
||||
await addDummyRecommendations(5);
|
||||
await addClicksAndSubscribers({memberId});
|
||||
|
||||
const {body: page1} = await agent.get('recommendations/?include=count.clicks,count.subscribers')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: new Array(5).fill({
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
describe('add', function () {
|
||||
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
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
assert.equal(page1.recommendations[0].count.clicks, 2);
|
||||
assert.equal(page1.recommendations[1].count.clicks, 3);
|
||||
// Check everything is set correctly
|
||||
assert.equal(body.recommendations[0].title, 'Dog Pictures');
|
||||
assert.equal(body.recommendations[0].url, 'https://dogpictures.com/');
|
||||
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);
|
||||
});
|
||||
|
||||
assert.equal(page1.recommendations[0].count.subscribers, 3);
|
||||
assert.equal(page1.recommendations[1].count.subscribers, 0);
|
||||
assert.equal(page1.recommendations[2].count.subscribers, 2);
|
||||
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');
|
||||
assert.equal(body.recommendations[0].url, 'https://dogpictures.com/');
|
||||
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('Cannot add the same recommendation twice', async function () {
|
||||
await agent.post('recommendations/')
|
||||
.body({
|
||||
recommendations: [{
|
||||
title: 'Dog Pictures',
|
||||
url: 'https://dogpictures.com'
|
||||
}]
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: [
|
||||
{
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
await agent.post('recommendations/')
|
||||
.body({
|
||||
recommendations: [{
|
||||
title: 'Dog Pictures 2',
|
||||
url: 'https://dogpictures.com'
|
||||
}]
|
||||
})
|
||||
.expectStatus(422)
|
||||
.matchBodySnapshot({
|
||||
errors: [
|
||||
{
|
||||
id: anyErrorId
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Can include only clicks', async function () {
|
||||
await addDummyRecommendations(5);
|
||||
await addClicksAndSubscribers({memberId});
|
||||
|
||||
const {body: page1} = await agent.get('recommendations/?include=count.clicks')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: new Array(5).fill({
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
describe('delete', function () {
|
||||
it('Can delete recommendation', async function () {
|
||||
const id = await addDummyRecommendation();
|
||||
await agent.delete(`recommendations/${id}/`)
|
||||
.expectStatus(204)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
});
|
||||
|
||||
assert.equal(page1.recommendations[0].count.clicks, 2);
|
||||
assert.equal(page1.recommendations[1].count.clicks, 3);
|
||||
|
||||
assert.equal(page1.recommendations[0].count.subscribers, undefined);
|
||||
assert.equal(page1.recommendations[1].count.subscribers, undefined);
|
||||
assert.equal(page1.recommendations[2].count.subscribers, undefined);
|
||||
});
|
||||
|
||||
it('Can include only subscribers', async function () {
|
||||
await addDummyRecommendations(5);
|
||||
await addClicksAndSubscribers({memberId});
|
||||
|
||||
const {body: page1} = await agent.get('recommendations/?include=count.subscribers')
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
'content-version': anyContentVersion,
|
||||
etag: anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
recommendations: new Array(5).fill({
|
||||
id: anyObjectId,
|
||||
created_at: anyISODateTime,
|
||||
updated_at: anyISODateTime
|
||||
})
|
||||
});
|
||||
|
||||
assert.equal(page1.recommendations[0].count.clicks, undefined);
|
||||
assert.equal(page1.recommendations[1].count.clicks, undefined);
|
||||
|
||||
assert.equal(page1.recommendations[0].count.subscribers, 3);
|
||||
assert.equal(page1.recommendations[1].count.subscribers, 0);
|
||||
assert.equal(page1.recommendations[2].count.subscribers, 2);
|
||||
.matchBodySnapshot({});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -18,6 +18,17 @@ export class RecommendationController {
|
||||
this.service = deps.service;
|
||||
}
|
||||
|
||||
async read(frame: Frame) {
|
||||
const options = new UnsafeData(frame.options);
|
||||
const id = options.key('id').string;
|
||||
|
||||
const recommendation = await this.service.readRecommendation(id);
|
||||
|
||||
return this.#serialize(
|
||||
[recommendation]
|
||||
);
|
||||
}
|
||||
|
||||
async add(frame: Frame) {
|
||||
const data = new UnsafeData(frame.data);
|
||||
const recommendation = data.key('recommendations').index(0);
|
||||
|
@ -89,6 +89,18 @@ export class RecommendationService {
|
||||
}).catch(console.error); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
async readRecommendation(id: string): Promise<RecommendationPlain> {
|
||||
const recommendation = await this.repository.getById(id);
|
||||
|
||||
if (!recommendation) {
|
||||
throw new errors.NotFoundError({
|
||||
message: tpl(messages.notFound, {id})
|
||||
});
|
||||
}
|
||||
|
||||
return recommendation.plain;
|
||||
}
|
||||
|
||||
async addRecommendation(addRecommendation: AddRecommendation): Promise<RecommendationPlain> {
|
||||
const recommendation = Recommendation.create(addRecommendation);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user