var Promise = require('bluebird');
var expect = require('chai').expect;
var sinon = require('sinon');

module.exports = function (bookshelf) {

  describe('Pagination Plugin', function () {

    bookshelf.plugin('pagination');
    var knex = bookshelf.knex;
    var Models = require('../helpers/objects')(bookshelf).Models;



    describe('Model instance fetchPage', function () {

      it('fetches a single page of results with defaults', function () {
        return Models.Customer.forge().fetchPage().then(function (results) {
          ['models', 'pagination'].forEach(function (prop) {
            expect(results).to.have.property(prop);
          });

          ['rowCount', 'pageCount', 'page', 'pageSize'].forEach(function (prop) {
            expect(results.pagination).to.have.property(prop);
          })

          var md = results.pagination;

          expect(md.rowCount).to.equal(4);
          expect(md.pageCount).to.equal(1);
          expect(md.page).to.equal(1);
          expect(md.pageSize).to.equal(10);
        })
      })

      it('returns the limit and offset instead of page and pageSize', function () {
        return Models.Customer.forge().fetchPage({ limit: 2, offset: 2 }).then(function (results) {
          var md = results.pagination;
          ['rowCount', 'pageCount', 'limit', 'offset'].forEach(function (prop) {
            expect(md).to.have.property(prop);
          })
        });
      })

      it('fetches a page of results with specified page size', function () {
        return Models.Customer.forge().fetchPage({ pageSize: 2 }).then(function (results) {
          var md = results.pagination;
          expect(md.rowCount).to.equal(4);
          expect(md.pageCount).to.equal(2);
          expect(md.page).to.equal(1);
        })
      })

      it('fetches a page with specified offset', function () {
        return Models.Customer.forge().orderBy('id', 'ASC').fetchPage({ limit: 2, offset: 2 }).then(function (results) {
          var m = results.models
          expect(parseInt(m[0].get('id'))).to.equal(3);
          expect(parseInt(m[1].get('id'))).to.equal(4);
        })
      })

      it('fetches a page by page number', function () {
        return Models.Customer.forge().orderBy('id', 'ASC').fetchPage({ pageSize: 2, page: 2 }).then(function (results) {
          var m = results.models;
          expect(parseInt(m[0].get('id'))).to.equal(3);
          expect(parseInt(m[1].get('id'))).to.equal(4);
        })
      })

      it('fetches a page when other columns are specified on the original query', function () {
        return Models.Customer.forge().query(function (qb) {
          qb.column.apply(qb, ['name'])
        }).fetchPage().then(function (results) {
          var md = results.pagination;
          expect(md.rowCount).to.equal(4);
        })
      })
    })

    describe('Model static fetchPage', function () {
      it('fetches a page without calling forge', function () {
        return Models.Customer.fetchPage().then(function (results) {
          ['models', 'pagination'].forEach(function (prop) {
            expect(results).to.have.property(prop);
          });
        })
      })
    })

    describe('Collection fetchPage', function () {
      it('fetches a page from a collection', function () {
        return Models.Customer.collection().fetchPage().then(function (results) {
          ['models', 'pagination'].forEach(function (prop) {
            expect(results).to.have.property(prop);
          });
        })
      })
      it('fetches a page from a relation collection', function () {
        return Models.User.forge({uid: 1}).roles().fetchPage().then(function (results) {
          expect(results.length).to.equal(1);
          ['models', 'pagination'].forEach(function (prop) {
            expect(results).to.have.property(prop);
          });
        });
      })
      it('fetches a page from a relation collection with additional condition', function () {
        return Models.User.forge({uid: 1}).roles().query(function (query) {
          query.where('roles.rid', '!=', 4);
        }).fetchPage().then(function (results) {
          expect(results.length).to.equal(0);
          ['models', 'pagination'].forEach(function (prop) {
            expect(results).to.have.property(prop);
          });
        });
      })
    })
  });
};

@@ -1,39 +1,4 @@
-var Promise = require('bluebird');%0A
 var 
@@ -33,38 +33,8 @@
 ect;
-%0Avar sinon = require('sinon');
 %0A%0Amo
@@ -71,17 +71,16 @@
 helf) %7B%0A
-%0A
   descri
@@ -113,25 +113,24 @@
 nction () %7B%0A
-%0A
     bookshel
@@ -157,39 +157,8 @@
 ');%0A
-    var knex = bookshelf.knex;%0A
     
@@ -220,18 +220,16 @@
 odels;%0A%0A
-%0A%0A
     desc
@@ -275,17 +275,16 @@
 on () %7B%0A
-%0A
       it
@@ -4229,16 +4229,619 @@
 )%0A    %7D)
+%0A%0A    describe('Inside a transaction', function() %7B%0A      it('returns consistent results for rowCount and number of models', function() %7B%0A        return bookshelf.transaction(function(t) %7B%0A          var options = %7Btransacting: t%7D;%0A%0A          return Models.Site.forge(%7Bname: 'A new site'%7D).save(null, options).then(function() %7B%0A            options.pageSize = 25;%0A            options.page = 1;%0A            return Models.Site.forge().fetchPage(options);%0A          %7D).then(function(sites) %7B%0A            expect(sites.pagination.rowCount).to.eql(sites.models.length);%0A          %7D);%0A        %7D);%0A      %7D)%0A    %7D)
 %0A  %7D);%0A%7D

Add test for fetchPage inside a transaction