diff --git a/core/server/models/base/pagination.js b/core/server/models/base/pagination.js index 637899086c..35bcea5dbe 100644 --- a/core/server/models/base/pagination.js +++ b/core/server/models/base/pagination.js @@ -140,12 +140,13 @@ pagination = function pagination(bookshelf) { // Get the table name and idAttribute for this model var tableName = _.result(this.constructor.prototype, 'tableName'), idAttribute = _.result(this.constructor.prototype, 'idAttribute'), - // Create a new collection for running `this` query, ensuring we're definitely using collection, - // rather than model + // Create a new collection for running `this` query, ensuring we're definitely using collection, + // rather than model collection = this.constructor.collection(), - // Clone the base query & set up a promise to get the count of total items in the full set + // Clone the base query & set up a promise to get the count of total items in the full set countPromise = this.query().clone().count(tableName + '.' + idAttribute + ' as aggregate'), - collectionPromise; + collectionPromise, + self; // Clone the base query into our collection collection._knex = this.query().clone(); @@ -162,7 +163,22 @@ pagination = function pagination(bookshelf) { }); } - // Setup the promise to do a fetch on our collection, running the specified query. + this.resetQuery(); + if (this.relatedData) { + collection.relatedData = this.relatedData; + } + + // ensure that our model (self) gets the correct events fired upon it + self = this; + collection + .on('fetching', function (collection, columns, options) { + return self.triggerThen('fetching:collection', collection, columns, options); + }) + .on('fetched', function (collection, resp, options) { + return self.triggerThen('fetched:collection', collection, resp, options); + }); + + // Setup the promise to do a fetch on our collection, running the specified query // @TODO: ensure option handling is done using an explicit pick elsewhere collectionPromise = collection.fetch(_.omit(options, ['page', 'limit'])); diff --git a/core/server/models/post.js b/core/server/models/post.js index 24c86a2abc..4f9946b631 100644 --- a/core/server/models/post.js +++ b/core/server/models/post.js @@ -61,6 +61,7 @@ Post = ghostBookshelf.Model.extend({ // Ensures local copy of permalink setting is kept up to date this.on('fetching', getPermalinkSetting); + this.on('fetching:collection', getPermalinkSetting); this.on('created', function onCreated(model) { model.emitChange('added'); diff --git a/core/test/integration/model/model_posts_spec.js b/core/test/integration/model/model_posts_spec.js index d603c0f04d..b1801dfc77 100644 --- a/core/test/integration/model/model_posts_spec.js +++ b/core/test/integration/model/model_posts_spec.js @@ -41,6 +41,7 @@ describe('Post Model', function () { function checkFirstPostData(firstPost) { should.not.exist(firstPost.author_id); firstPost.author.should.be.an.Object; + firstPost.url.should.equal('/html-ipsum/'); firstPost.fields.should.be.an.Array; firstPost.tags.should.be.an.Array; firstPost.author.name.should.equal(DataGenerator.Content.users[0].name); @@ -56,6 +57,14 @@ describe('Post Model', function () { } describe('findAll', function () { + beforeEach(function () { + sandbox.stub(SettingsModel, 'findOne', function () { + return Promise.resolve({toJSON: function () { + return {value: '/:slug/'}; + }}); + }); + }); + it('can findAll', function (done) { PostModel.findAll().then(function (results) { should.exist(results); @@ -85,6 +94,14 @@ describe('Post Model', function () { }); describe('findPage', function () { + beforeEach(function () { + sandbox.stub(SettingsModel, 'findOne', function () { + return Promise.resolve({toJSON: function () { + return {value: '/:slug/'}; + }}); + }); + }); + it('can findPage (default)', function (done) { PostModel.findPage().then(function (results) { should.exist(results); @@ -267,7 +284,13 @@ describe('Post Model', function () { it('can findOne, returning all related data', function (done) { var firstPost; - // TODO: should take author :-/ + + sandbox.stub(SettingsModel, 'findOne', function () { + return Promise.resolve({toJSON: function () { + return {value: '/:slug/'}; + }}); + }); + PostModel.findOne({}, {include: ['author', 'fields', 'tags', 'created_by', 'updated_by', 'published_by']}) .then(function (result) { should.exist(result); diff --git a/core/test/unit/models_pagination_spec.js b/core/test/unit/models_pagination_spec.js index 73a5384ce0..0e50bd957a 100644 --- a/core/test/unit/models_pagination_spec.js +++ b/core/test/unit/models_pagination_spec.js @@ -175,7 +175,7 @@ describe('pagination', function () { }); describe('fetchPage', function () { - var model, bookshelf, mockQuery, fetch, colQuery; + var model, bookshelf, on, mockQuery, fetch, colQuery; before(function () { paginationUtils = pagination.__get__('paginationUtils'); @@ -197,15 +197,19 @@ describe('pagination', function () { fetch = sandbox.stub().returns(Promise.resolve({})); colQuery = sandbox.stub(); + on = function () { return this; }; + on = sandbox.spy(on); model = function () {}; model.prototype.constructor = { collection: sandbox.stub().returns({ + on: on, fetch: fetch, query: colQuery }) }; model.prototype.query = sandbox.stub(); + model.prototype.resetQuery = sandbox.stub(); model.prototype.query.returns(mockQuery); bookshelf = {Model: model}; @@ -231,6 +235,8 @@ describe('pagination', function () { model.prototype.query, mockQuery.clone, paginationUtils.query, + on, + on, fetch, paginationUtils.formatResponse ); @@ -255,6 +261,10 @@ describe('pagination', function () { mockQuery.count.calledOnce.should.be.true; mockQuery.count.calledWith().should.be.true; + on.calledTwice.should.be.true; + on.firstCall.calledWith('fetching').should.be.true; + on.secondCall.calledWith('fetched').should.be.true; + fetch.calledOnce.should.be.true; fetch.calledWith({}).should.be.true; @@ -277,6 +287,8 @@ describe('pagination', function () { mockQuery.clone, paginationUtils.query, colQuery, + on, + on, fetch, paginationUtils.formatResponse ); @@ -304,6 +316,10 @@ describe('pagination', function () { colQuery.calledOnce.should.be.true; colQuery.calledWith('orderBy', 'undefined.id', 'DESC').should.be.true; + on.calledTwice.should.be.true; + on.firstCall.calledWith('fetching').should.be.true; + on.secondCall.calledWith('fetched').should.be.true; + fetch.calledOnce.should.be.true; fetch.calledWith(orderOptions).should.be.true;