mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-22 10:21:36 +03:00
2ea8c3e33b
no issue - Switched acceptance tests to run against canary branch - Corrected actions specs - Corrected authentication spec - Moved test suites our of 'old' folder
385 lines
16 KiB
JavaScript
385 lines
16 KiB
JavaScript
const should = require('should');
|
|
const supertest = require('supertest');
|
|
const _ = require('lodash');
|
|
const ObjectId = require('bson-objectid');
|
|
const moment = require('moment-timezone');
|
|
const testUtils = require('../../utils');
|
|
const config = require('../../../server/config');
|
|
const models = require('../../../server/models');
|
|
const localUtils = require('./utils');
|
|
|
|
const ghost = testUtils.startGhost;
|
|
let request;
|
|
|
|
describe('Posts API', function () {
|
|
let ghostServer;
|
|
let ownerCookie;
|
|
|
|
before(function () {
|
|
return ghost()
|
|
.then(function (_ghostServer) {
|
|
ghostServer = _ghostServer;
|
|
request = supertest.agent(config.get('url'));
|
|
})
|
|
.then(function () {
|
|
return localUtils.doAuth(request, 'users:extra', 'posts');
|
|
})
|
|
.then(function (cookie) {
|
|
ownerCookie = cookie;
|
|
});
|
|
});
|
|
|
|
it('Can retrieve all posts', function (done) {
|
|
request.get(localUtils.API.getApiQuery('posts/'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
const jsonResponse = res.body;
|
|
should.exist(jsonResponse.posts);
|
|
localUtils.API.checkResponse(jsonResponse, 'posts');
|
|
jsonResponse.posts.should.have.length(13);
|
|
localUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
|
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
|
|
_.isBoolean(jsonResponse.posts[0].featured).should.eql(true);
|
|
|
|
// Ensure default order
|
|
jsonResponse.posts[0].slug.should.eql('scheduled-post');
|
|
jsonResponse.posts[12].slug.should.eql('html-ipsum');
|
|
|
|
// Absolute urls by default
|
|
jsonResponse.posts[0].url.should.match(new RegExp(`${config.get('url')}/p/[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}`));
|
|
jsonResponse.posts[2].url.should.eql(`${config.get('url')}/welcome/`);
|
|
jsonResponse.posts[11].feature_image.should.eql(`${config.get('url')}/content/images/2018/hey.jpg`);
|
|
|
|
jsonResponse.posts[0].tags.length.should.eql(0);
|
|
jsonResponse.posts[2].tags.length.should.eql(1);
|
|
jsonResponse.posts[2].authors.length.should.eql(1);
|
|
jsonResponse.posts[2].tags[0].url.should.eql(`${config.get('url')}/tag/getting-started/`);
|
|
jsonResponse.posts[2].authors[0].url.should.eql(`${config.get('url')}/author/ghost/`);
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can retrieve multiple post formats', function (done) {
|
|
request.get(localUtils.API.getApiQuery('posts/?formats=plaintext,mobiledoc&limit=3&order=title%20ASC'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
const jsonResponse = res.body;
|
|
should.exist(jsonResponse.posts);
|
|
localUtils.API.checkResponse(jsonResponse, 'posts');
|
|
jsonResponse.posts.should.have.length(3);
|
|
localUtils.API.checkResponse(jsonResponse.posts[0], 'post', ['plaintext']);
|
|
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
|
|
_.isBoolean(jsonResponse.posts[0].featured).should.eql(true);
|
|
|
|
// ensure order works
|
|
jsonResponse.posts[0].slug.should.eql('apps-integrations');
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can includes single relation', function (done) {
|
|
request.get(localUtils.API.getApiQuery('posts/?include=tags'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
const jsonResponse = res.body;
|
|
should.exist(jsonResponse.posts);
|
|
localUtils.API.checkResponse(jsonResponse, 'posts');
|
|
jsonResponse.posts.should.have.length(13);
|
|
localUtils.API.checkResponse(
|
|
jsonResponse.posts[0],
|
|
'post',
|
|
null,
|
|
['authors', 'primary_author']
|
|
);
|
|
|
|
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can filter posts', function (done) {
|
|
request.get(localUtils.API.getApiQuery('posts/?filter=featured:true'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
const jsonResponse = res.body;
|
|
should.exist(jsonResponse.posts);
|
|
localUtils.API.checkResponse(jsonResponse, 'posts');
|
|
jsonResponse.posts.should.have.length(2);
|
|
localUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
|
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Cannot receive pages', function (done) {
|
|
request.get(localUtils.API.getApiQuery('posts/?filter=page:true'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
const jsonResponse = res.body;
|
|
should.exist(jsonResponse.posts);
|
|
localUtils.API.checkResponse(jsonResponse, 'posts');
|
|
jsonResponse.posts.should.have.length(0);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can paginate posts', function (done) {
|
|
request.get(localUtils.API.getApiQuery('posts/?page=2'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
const jsonResponse = res.body;
|
|
should.equal(jsonResponse.meta.pagination.page, 2);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can request a post by id', function (done) {
|
|
request.get(localUtils.API.getApiQuery('posts/' + testUtils.DataGenerator.Content.posts[0].id + '/'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
var jsonResponse = res.body;
|
|
should.exist(jsonResponse);
|
|
should.exist(jsonResponse.posts);
|
|
localUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
|
jsonResponse.posts[0].id.should.equal(testUtils.DataGenerator.Content.posts[0].id);
|
|
|
|
_.isBoolean(jsonResponse.posts[0].featured).should.eql(true);
|
|
|
|
testUtils.API.isISO8601(jsonResponse.posts[0].created_at).should.be.true();
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can retrieve a post by slug', function (done) {
|
|
request.get(localUtils.API.getApiQuery('posts/slug/welcome/'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
var jsonResponse = res.body;
|
|
should.exist(jsonResponse);
|
|
should.exist(jsonResponse.posts);
|
|
localUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
|
jsonResponse.posts[0].slug.should.equal('welcome');
|
|
|
|
_.isBoolean(jsonResponse.posts[0].featured).should.eql(true);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can include relations for a single post', function (done) {
|
|
request
|
|
.get(localUtils.API.getApiQuery('posts/' + testUtils.DataGenerator.Content.posts[0].id + '/?include=authors,tags'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200)
|
|
.end(function (err, res) {
|
|
if (err) {
|
|
return done(err);
|
|
}
|
|
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
var jsonResponse = res.body;
|
|
should.exist(jsonResponse);
|
|
should.exist(jsonResponse.posts);
|
|
|
|
localUtils.API.checkResponse(jsonResponse.posts[0], 'post');
|
|
|
|
jsonResponse.posts[0].authors[0].should.be.an.Object();
|
|
localUtils.API.checkResponse(jsonResponse.posts[0].authors[0], 'user');
|
|
|
|
jsonResponse.posts[0].tags[0].should.be.an.Object();
|
|
localUtils.API.checkResponse(jsonResponse.posts[0].tags[0], 'tag', ['url']);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('Can add a post', function () {
|
|
const post = {
|
|
title: 'My post',
|
|
status: 'draft',
|
|
published_at: '2016-05-30T07:00:00.000Z',
|
|
mobiledoc: testUtils.DataGenerator.markdownToMobiledoc('my post'),
|
|
created_at: moment().subtract(2, 'days').toDate(),
|
|
updated_at: moment().subtract(2, 'days').toDate(),
|
|
created_by: ObjectId.generate(),
|
|
updated_by: ObjectId.generate()
|
|
};
|
|
|
|
return request.post(localUtils.API.getApiQuery('posts'))
|
|
.set('Origin', config.get('url'))
|
|
.send({posts: [post]})
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(201)
|
|
.then((res) => {
|
|
res.body.posts.length.should.eql(1);
|
|
localUtils.API.checkResponse(res.body.posts[0], 'post');
|
|
res.body.posts[0].url.should.match(new RegExp(`${config.get('url')}/p/[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}`));
|
|
should.not.exist(res.headers['x-cache-invalidate']);
|
|
|
|
return models.Post.findOne({
|
|
id: res.body.posts[0].id,
|
|
status: 'draft'
|
|
}, testUtils.context.internal);
|
|
})
|
|
.then((model) => {
|
|
model.get('title').should.eql(post.title);
|
|
model.get('status').should.eql(post.status);
|
|
model.get('published_at').toISOString().should.eql('2016-05-30T07:00:00.000Z');
|
|
model.get('created_at').toISOString().should.not.eql(post.created_at.toISOString());
|
|
model.get('updated_at').toISOString().should.not.eql(post.updated_at.toISOString());
|
|
model.get('updated_by').should.not.eql(post.updated_by);
|
|
model.get('created_by').should.not.eql(post.created_by);
|
|
});
|
|
});
|
|
|
|
it('Can update draft', function () {
|
|
const post = {
|
|
title: 'update draft'
|
|
};
|
|
|
|
return request
|
|
.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[3].id}/`))
|
|
.set('Origin', config.get('url'))
|
|
.expect(200)
|
|
.then((res) => {
|
|
post.updated_at = res.body.posts[0].updated_at;
|
|
|
|
return request.put(localUtils.API.getApiQuery('posts/' + testUtils.DataGenerator.Content.posts[3].id))
|
|
.set('Origin', config.get('url'))
|
|
.send({posts: [post]})
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200);
|
|
})
|
|
.then((res) => {
|
|
res.headers['x-cache-invalidate'].should.eql('/p/' + res.body.posts[0].uuid + '/');
|
|
});
|
|
});
|
|
|
|
it('Can unpublish a post', function () {
|
|
const post = {
|
|
status: 'draft'
|
|
};
|
|
|
|
return request
|
|
.get(localUtils.API.getApiQuery(`posts/${testUtils.DataGenerator.Content.posts[1].id}/?`))
|
|
.set('Origin', config.get('url'))
|
|
.expect(200)
|
|
.then((res) => {
|
|
post.updated_at = res.body.posts[0].updated_at;
|
|
|
|
return request
|
|
.put(localUtils.API.getApiQuery('posts/' + testUtils.DataGenerator.Content.posts[1].id + '/'))
|
|
.set('Origin', config.get('url'))
|
|
.send({posts: [post]})
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(200);
|
|
})
|
|
.then((res) => {
|
|
res.headers['x-cache-invalidate'].should.eql('/*');
|
|
res.body.posts[0].status.should.eql('draft');
|
|
});
|
|
});
|
|
|
|
it('Can destroy a post', function () {
|
|
return request
|
|
.del(localUtils.API.getApiQuery('posts/' + testUtils.DataGenerator.Content.posts[0].id + '/'))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(204)
|
|
.then((res) => {
|
|
res.body.should.be.empty();
|
|
res.headers['x-cache-invalidate'].should.eql('/*');
|
|
});
|
|
});
|
|
|
|
it('Cannot get post via pages endpoint', function () {
|
|
return request.get(localUtils.API.getApiQuery(`pages/${testUtils.DataGenerator.Content.posts[3].id}/`))
|
|
.set('Origin', config.get('url'))
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404);
|
|
});
|
|
|
|
it('Cannot update post via pages endpoint', function () {
|
|
const post = {
|
|
title: 'fails',
|
|
updated_at: new Date().toISOString()
|
|
};
|
|
|
|
return request.put(localUtils.API.getApiQuery('pages/' + testUtils.DataGenerator.Content.posts[3].id))
|
|
.set('Origin', config.get('url'))
|
|
.send({pages: [post]})
|
|
.expect('Content-Type', /json/)
|
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
|
.expect(404);
|
|
});
|
|
});
|