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:
parent
7d388cb9e1
commit
958544ae90
3 changed files with 284 additions and 2 deletions
|
@ -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;
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -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 () {
|
||||
|
|
Loading…
Add table
Reference in a new issue