Cache invalidation for post update

closes #2833
- Handle status change of post
This commit is contained in:
Fabian Becker 2014-06-03 22:38:15 +00:00
parent 1ae98df995
commit 340192c5da
3 changed files with 104 additions and 14 deletions

View File

@ -55,24 +55,25 @@ cacheInvalidationHeader = function (req, result) {
cacheInvalidate,
jsonResult = result.toJSON ? result.toJSON() : result,
post,
wasPublished,
wasDeleted;
hasStatusChanged,
wasDeleted,
wasPublishedUpdated;
if (method === 'POST' || method === 'PUT' || method === 'DELETE') {
if (endpoint === 'settings' || endpoint === 'users' || endpoint === 'db') {
cacheInvalidate = '/*';
} else if (endpoint === 'posts') {
post = jsonResult.posts[0];
wasPublished = post.statusChanged && post.status === 'published';
hasStatusChanged = post.statusChanged;
wasDeleted = method === 'DELETE';
// Invalidate cache when post was updated but not when post is draft
wasPublishedUpdated = method === 'PUT' && post.status === 'published';
// Remove the statusChanged value from the response
if (post.statusChanged) {
delete post.statusChanged;
}
delete post.statusChanged;
// Don't set x-cache-invalidate header for drafts
if (wasPublished || wasDeleted) {
if (hasStatusChanged || wasDeleted || wasPublishedUpdated) {
cacheInvalidate = '/, /page/*, /rss/, /rss/*, /tag/*';
if (id && post.slug) {
return config.urlForPost(settings, post).then(function (postUrl) {

View File

@ -114,7 +114,8 @@ posts = {
if (result) {
var post = result.toJSON();
// If previously was not published and now is, signal the change
// If previously was not published and now is (or vice versa), signal the change
post.statusChanged = false;
if (result.updated('status') !== result.get('status')) {
post.statusChanged = true;
}

View File

@ -411,7 +411,8 @@ describe('Post API', function () {
}
var updatedPost = res.body;
_.has(res.headers, 'x-cache-invalidate').should.equal(false);
// Require cache invalidation when post was updated and published
_.has(res.headers, 'x-cache-invalidate').should.equal(true);
res.should.be.json;
updatedPost.should.exist;
@ -458,7 +459,7 @@ describe('Post API', function () {
}
var putBody = res.body;
_.has(res.headers, 'x-cache-invalidate').should.equal(false);
_.has(res.headers, 'x-cache-invalidate').should.equal(true);
res.should.be.json;
putBody.should.exist;
putBody.posts[0].title.should.eql(changedValue);
@ -469,6 +470,93 @@ describe('Post API', function () {
});
});
it('can edit a new draft and update post', function (done) {
var newTitle = 'My Post',
newTagName = 'My Tag',
publishedState = 'published',
newTag = {id: null, name: newTagName},
newPost = {posts: [{status: 'draft', title: newTitle, markdown: 'my post', tags: [newTag]}]};
request.post(testUtils.API.getApiQuery('posts/?include=tags'))
.set('X-CSRF-Token', csrfToken)
.send(newPost)
.expect(201)
.end(function (err, res) {
if (err) {
return done(err);
}
res.should.be.json;
var draftPost = res.body;
res.headers['location'].should.equal('/ghost/api/v0.1/posts/' + draftPost.posts[0].id + '/?status=draft');
draftPost.posts.should.exist;
draftPost.posts.length.should.be.above(0);
draftPost.posts[0].title.should.eql(newTitle);
testUtils.API.checkResponse(draftPost.posts[0], 'post');
draftPost.posts[0].title = 'Vote for Casper in red';
request.put(testUtils.API.getApiQuery('posts/' + draftPost.posts[0].id + '/?include=tags'))
.set('X-CSRF-Token', csrfToken)
.send(draftPost)
.expect(200)
.end(function (err, res) {
if (err) {
return done(err);
}
// Updating a draft should not send x-cache-invalidate headers
_.has(res.headers, 'x-cache-invalidate').should.equal(false);
done();
});
});
});
it('can edit a new published post and unpublish', function (done) {
var newTitle = 'My Post',
newTagName = 'My Tag',
draftState = 'draft',
newTag = {id: null, name: newTagName},
newPost = {posts: [{status: 'published', title: newTitle, markdown: 'my post', tags: [newTag]}]};
request.post(testUtils.API.getApiQuery('posts/?include=tags'))
.set('X-CSRF-Token', csrfToken)
.send(newPost)
.expect(201)
.end(function (err, res) {
if (err) {
return done(err);
}
res.should.be.json;
var draftPost = res.body;
res.headers['location'].should.equal('/ghost/api/v0.1/posts/' + draftPost.posts[0].id + '/?status=published');
draftPost.posts.should.exist;
draftPost.posts.length.should.be.above(0);
draftPost.posts[0].title.should.eql(newTitle);
testUtils.API.checkResponse(draftPost.posts[0], 'post');
draftPost.posts[0].title = 'Vote for Casper in red';
draftPost.posts[0].status = draftState;
request.put(testUtils.API.getApiQuery('posts/' + draftPost.posts[0].id + '/?include=tags'))
.set('X-CSRF-Token', csrfToken)
.send(draftPost)
.expect(200)
.end(function (err, res) {
if (err) {
return done(err);
}
var unpublishedPost = res.body;
// Unpublishing a post should send x-cache-invalidate headers
_.has(res.headers, 'x-cache-invalidate').should.equal(true);
done();
});
});
});
it('can change a post to a static page', function (done) {
request.get(testUtils.API.getApiQuery('posts/1/?include=tags'))
.end(function (err, res) {
@ -492,7 +580,7 @@ describe('Post API', function () {
}
var putBody = res.body;
_.has(res.headers, 'x-cache-invalidate').should.equal(false);
_.has(res.headers, 'x-cache-invalidate').should.equal(true);
res.should.be.json;
putBody.should.exist;
putBody.posts[0].page.should.eql(changedValue);
@ -527,7 +615,7 @@ describe('Post API', function () {
var putBody = res.body;
_.has(res.headers, 'x-cache-invalidate').should.equal(false);
_.has(res.headers, 'x-cache-invalidate').should.equal(true);
res.should.be.json;
putBody.should.exist;
putBody.posts[0].page.should.eql(changedValue);
@ -615,7 +703,7 @@ describe('Post API', function () {
}
var putBody = res.body;
_.has(res.headers, 'x-cache-invalidate').should.equal(false);
_.has(res.headers, 'x-cache-invalidate').should.equal(true);
res.should.be.json;
putBody.should.exist;
putBody.posts.should.exist;
@ -843,7 +931,7 @@ describe('Post API', function () {
yyyy = today.getFullYear(),
postLink = '/' + yyyy + '/' + mm + '/' + dd + '/' + putBody.posts[0].slug + '/';
_.has(res.headers, 'x-cache-invalidate').should.equal(false);
_.has(res.headers, 'x-cache-invalidate').should.equal(true);
res.should.be.json;
putBody.should.exist;
putBody.posts[0].title.should.eql(changedValue);