0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-08 02:52:39 -05:00

support prev/next filtering by author (#9149)

refs #9141

- adds support for `{{#prev_post in="author"}}{{/prev_post}}` & `{{#next_post in="author"}}{{/next_post}}` 
- "author.slug" is the author equivalent of "primary_tag.slug" - there is only one
- added tests to cover both cases in the prev/next helpers
This commit is contained in:
aimingoo 2017-10-19 01:12:20 +08:00 committed by Hannah Wolfe
parent 7d388cb9e1
commit 958544ae90
3 changed files with 284 additions and 2 deletions

View file

@ -32,8 +32,12 @@ buildApiOptions = function buildApiOptions(options, post) {
filter: "slug:-" + slug + "+published_at:" + op + "'" + publishedAt + "'", // jscs:ignore
};
if (_.get(options, 'hash.in') && options.hash.in === 'primary_tag' && _.get(post, 'primary_tag.slug')) {
apiOptions.filter += '+primary_tag:' + post.primary_tag.slug;
if (_.get(options, 'hash.in')) {
if (options.hash.in === 'primary_tag' && _.get(post, 'primary_tag.slug')) {
apiOptions.filter += '+primary_tag:' + post.primary_tag.slug;
} else if (options.hash.in === 'author' && _.get(post, 'author.slug')) {
apiOptions.filter += '+author:' + post.author.slug;
}
}
return apiOptions;

View file

@ -193,6 +193,145 @@ describe('{{next_post}} helper', function () {
});
});
describe('with "in" option', function () {
beforeEach(function () {
browsePostStub = sandbox.stub(api.posts, 'browse', function (options) {
if (options.filter.indexOf('published_at:>') > -1) {
return Promise.resolve({
posts: [{slug: '/next/', title: 'post 1'}]
});
}
});
});
it('shows \'if\' template with prev post data with primary_tag set', function (done) {
var fn = sinon.spy(),
inverse = sinon.spy(),
optionsData = {name: 'next_post', fn: fn, inverse: inverse, hash: {in: 'primary_tag'}};
helpers.next_post
.call({
html: 'content',
status: 'published',
mobiledoc: markdownToMobiledoc('ff'),
title: 'post2',
slug: 'current',
published_at: new Date(0),
primary_tag: {slug: 'test'},
url: '/current/'
}, optionsData)
.then(function () {
fn.calledOnce.should.be.true();
inverse.calledOnce.should.be.false();
fn.firstCall.args.should.have.lengthOf(2);
fn.firstCall.args[0].should.have.properties('slug', 'title');
fn.firstCall.args[1].should.be.an.Object().and.have.property('data');
browsePostStub.calledOnce.should.be.true();
browsePostStub.firstCall.args[0].include.should.eql('author,tags');
browsePostStub.firstCall.args[0].filter.should.match(/\+primary_tag:test/);
done();
})
.catch(done);
});
it('shows \'if\' template with prev post data with author set', function (done) {
var fn = sinon.spy(),
inverse = sinon.spy(),
optionsData = {name: 'next_post', fn: fn, inverse: inverse, hash: {in: 'author'}};
helpers.next_post
.call({
html: 'content',
status: 'published',
mobiledoc: markdownToMobiledoc('ff'),
title: 'post2',
slug: 'current',
published_at: new Date(0),
author: {slug: 'author-name'},
url: '/current/'
}, optionsData)
.then(function () {
fn.calledOnce.should.be.true();
inverse.calledOnce.should.be.false();
fn.firstCall.args.should.have.lengthOf(2);
fn.firstCall.args[0].should.have.properties('slug', 'title');
fn.firstCall.args[1].should.be.an.Object().and.have.property('data');
browsePostStub.calledOnce.should.be.true();
browsePostStub.firstCall.args[0].include.should.eql('author,tags');
browsePostStub.firstCall.args[0].filter.should.match(/\+author:author-name/);
done();
})
.catch(done);
});
it('shows \'if\' template with prev post data & ignores in author if author isnt present', function (done) {
var fn = sinon.spy(),
inverse = sinon.spy(),
optionsData = {name: 'next_post', fn: fn, inverse: inverse, hash: {in: 'author'}};
helpers.next_post
.call({
html: 'content',
status: 'published',
mobiledoc: markdownToMobiledoc('ff'),
title: 'post2',
slug: 'current',
published_at: new Date(0),
url: '/current/'
}, optionsData)
.then(function () {
fn.calledOnce.should.be.true();
inverse.calledOnce.should.be.false();
fn.firstCall.args.should.have.lengthOf(2);
fn.firstCall.args[0].should.have.properties('slug', 'title');
fn.firstCall.args[1].should.be.an.Object().and.have.property('data');
browsePostStub.calledOnce.should.be.true();
browsePostStub.firstCall.args[0].include.should.eql('author,tags');
browsePostStub.firstCall.args[0].filter.should.not.match(/\+author:/);
done();
})
.catch(done);
});
it('shows \'if\' template with prev post data & ignores unknown in value', function (done) {
var fn = sinon.spy(),
inverse = sinon.spy(),
optionsData = {name: 'next_post', fn: fn, inverse: inverse, hash: {in: 'magic'}};
helpers.next_post
.call({
html: 'content',
status: 'published',
mobiledoc: markdownToMobiledoc('ff'),
title: 'post2',
slug: 'current',
published_at: new Date(0),
author: {slug: 'author-name'},
url: '/current/'
}, optionsData)
.then(function () {
fn.calledOnce.should.be.true();
inverse.calledOnce.should.be.false();
fn.firstCall.args.should.have.lengthOf(2);
fn.firstCall.args[0].should.have.properties('slug', 'title');
fn.firstCall.args[1].should.be.an.Object().and.have.property('data');
browsePostStub.calledOnce.should.be.true();
browsePostStub.firstCall.args[0].include.should.eql('author,tags');
browsePostStub.firstCall.args[0].filter.should.not.match(/\+magic/);
done();
})
.catch(done);
});
});
describe('general error handling', function () {
beforeEach(function () {
browsePostStub = sandbox.stub(api.posts, 'browse', function () {

View file

@ -193,6 +193,145 @@ describe('{{prev_post}} helper', function () {
});
});
describe('with "in" option', function () {
beforeEach(function () {
browsePostStub = sandbox.stub(api.posts, 'browse', function (options) {
if (options.filter.indexOf('published_at:<=') > -1) {
return Promise.resolve({
posts: [{slug: '/previous/', title: 'post 1'}]
});
}
});
});
it('shows \'if\' template with prev post data with primary_tag set', function (done) {
var fn = sinon.spy(),
inverse = sinon.spy(),
optionsData = {name: 'prev_post', fn: fn, inverse: inverse, hash: {in: 'primary_tag'}};
helpers.prev_post
.call({
html: 'content',
status: 'published',
mobiledoc: markdownToMobiledoc('ff'),
title: 'post2',
slug: 'current',
published_at: new Date(0),
primary_tag: {slug: 'test'},
url: '/current/'
}, optionsData)
.then(function () {
fn.calledOnce.should.be.true();
inverse.calledOnce.should.be.false();
fn.firstCall.args.should.have.lengthOf(2);
fn.firstCall.args[0].should.have.properties('slug', 'title');
fn.firstCall.args[1].should.be.an.Object().and.have.property('data');
browsePostStub.calledOnce.should.be.true();
browsePostStub.firstCall.args[0].include.should.eql('author,tags');
browsePostStub.firstCall.args[0].filter.should.match(/\+primary_tag:test/);
done();
})
.catch(done);
});
it('shows \'if\' template with prev post data with author set', function (done) {
var fn = sinon.spy(),
inverse = sinon.spy(),
optionsData = {name: 'prev_post', fn: fn, inverse: inverse, hash: {in: 'author'}};
helpers.prev_post
.call({
html: 'content',
status: 'published',
mobiledoc: markdownToMobiledoc('ff'),
title: 'post2',
slug: 'current',
published_at: new Date(0),
author: {slug: 'author-name'},
url: '/current/'
}, optionsData)
.then(function () {
fn.calledOnce.should.be.true();
inverse.calledOnce.should.be.false();
fn.firstCall.args.should.have.lengthOf(2);
fn.firstCall.args[0].should.have.properties('slug', 'title');
fn.firstCall.args[1].should.be.an.Object().and.have.property('data');
browsePostStub.calledOnce.should.be.true();
browsePostStub.firstCall.args[0].include.should.eql('author,tags');
browsePostStub.firstCall.args[0].filter.should.match(/\+author:author-name/);
done();
})
.catch(done);
});
it('shows \'if\' template with prev post data & ignores in author if author isnt present', function (done) {
var fn = sinon.spy(),
inverse = sinon.spy(),
optionsData = {name: 'prev_post', fn: fn, inverse: inverse, hash: {in: 'author'}};
helpers.prev_post
.call({
html: 'content',
status: 'published',
mobiledoc: markdownToMobiledoc('ff'),
title: 'post2',
slug: 'current',
published_at: new Date(0),
url: '/current/'
}, optionsData)
.then(function () {
fn.calledOnce.should.be.true();
inverse.calledOnce.should.be.false();
fn.firstCall.args.should.have.lengthOf(2);
fn.firstCall.args[0].should.have.properties('slug', 'title');
fn.firstCall.args[1].should.be.an.Object().and.have.property('data');
browsePostStub.calledOnce.should.be.true();
browsePostStub.firstCall.args[0].include.should.eql('author,tags');
browsePostStub.firstCall.args[0].filter.should.not.match(/\+author:/);
done();
})
.catch(done);
});
it('shows \'if\' template with prev post data & ignores unknown in value', function (done) {
var fn = sinon.spy(),
inverse = sinon.spy(),
optionsData = {name: 'prev_post', fn: fn, inverse: inverse, hash: {in: 'magic'}};
helpers.prev_post
.call({
html: 'content',
status: 'published',
mobiledoc: markdownToMobiledoc('ff'),
title: 'post2',
slug: 'current',
published_at: new Date(0),
author: {slug: 'author-name'},
url: '/current/'
}, optionsData)
.then(function () {
fn.calledOnce.should.be.true();
inverse.calledOnce.should.be.false();
fn.firstCall.args.should.have.lengthOf(2);
fn.firstCall.args[0].should.have.properties('slug', 'title');
fn.firstCall.args[1].should.be.an.Object().and.have.property('data');
browsePostStub.calledOnce.should.be.true();
browsePostStub.firstCall.args[0].include.should.eql('author,tags');
browsePostStub.firstCall.args[0].filter.should.not.match(/\+magic/);
done();
})
.catch(done);
});
});
describe('general error handling', function () {
beforeEach(function () {
browsePostStub = sandbox.stub(api.posts, 'browse', function () {