Merge pull request #6084 from ErisDS/filter-debug

Debugging tools for filters
This commit is contained in:
Sebastian Gierlinger 2015-11-18 20:31:59 +01:00
commit 67129fe2cf
8 changed files with 54 additions and 8 deletions

View File

@ -23,7 +23,7 @@ utils = {
// ### Manual Default Options
// These must be provided by the endpoint
// browseDefaultOptions - valid for all browse api endpoints
browseDefaultOptions: ['page', 'limit', 'fields', 'filter', 'order'],
browseDefaultOptions: ['page', 'limit', 'fields', 'filter', 'order', 'debug'],
// idDefaultOptions - valid whenever an id is valid
idDefaultOptions: ['id'],

View File

@ -275,6 +275,9 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
itemCollection = this.forge(null, {context: options.context}),
tableName = _.result(this.prototype, 'tableName');
// Set this to true or pass ?debug=true as an API option to get output
itemCollection.debug = options.debug && process.env.NODE_ENV !== 'production';
// Filter options so that only permitted ones remain
options = this.filterOptions(options, 'findPage');

View File

@ -143,6 +143,10 @@ filter = function filter(Bookshelf) {
}
if (this._filters) {
if (this.debug) {
gql.json.printStatements(this._filters.statements);
}
this.query(function (qb) {
gql.knexify(qb, self._filters);
});

View File

@ -38,12 +38,20 @@ module.exports = function (Bookshelf) {
fetch: function () {
this.addCounts.apply(this, arguments);
if (this.debug) {
console.log('QUERY', this.query().toQuery());
}
// Call parent fetch
return modelProto.fetch.apply(this, arguments);
},
fetchAll: function () {
this.addCounts.apply(this, arguments);
if (this.debug) {
console.log('QUERY', this.query().toQuery());
}
// Call parent fetchAll
return modelProto.fetchAll.apply(this, arguments);
}

View File

@ -172,6 +172,10 @@ pagination = function pagination(bookshelf) {
});
}
if (this.debug) {
console.log('COUNT', countPromise.toQuery());
}
// 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 = self.fetchAll(_.omit(options, ['page', 'limit']));

View File

@ -18,7 +18,7 @@ describe('API Utils', function () {
describe('Default Options', function () {
it('should provide a set of default options', function () {
apiUtils.globalDefaultOptions.should.eql(['context', 'include']);
apiUtils.browseDefaultOptions.should.eql(['page', 'limit', 'fields', 'filter', 'order']);
apiUtils.browseDefaultOptions.should.eql(['page', 'limit', 'fields', 'filter', 'order', 'debug']);
apiUtils.dataDefaultOptions.should.eql(['data']);
apiUtils.idDefaultOptions.should.eql(['id']);
});

View File

@ -206,6 +206,19 @@ describe('Filter', function () {
{prop: 'title', op: '=', value: 'Hello Word'}
]});
});
it('should print statements in debug mode', function () {
ghostBookshelf.Model.prototype.debug = true;
ghostBookshelf.Model.prototype._filters = {statements: [
{prop: 'tags', op: 'IN', value: ['photo', 'video']}
]};
ghostBookshelf.Model.prototype.applyFilters();
filterGQL.json.printStatements.calledOnce.should.be.true;
filterGQL.json.printStatements.firstCall.args[0].should.eql([
{prop: 'tags', op: 'IN', value: ['photo', 'video']}
]);
});
});
describe('Post Process Filters', function () {

View File

@ -190,7 +190,8 @@ describe('pagination', function () {
// Mock out bookshelf model
mockQuery = {
clone: sandbox.stub(),
select: sandbox.stub()
select: sandbox.stub(),
toQuery: sandbox.stub()
};
mockQuery.clone.returns(mockQuery);
mockQuery.select.returns([{aggregate: 1}]);
@ -213,7 +214,7 @@ describe('pagination', function () {
bookshelf.Model.prototype.fetchPage.should.be.a.Function;
});
it('fetchPage calls all paginationUtils and methods', function (done) {
it('calls all paginationUtils and methods', function (done) {
paginationUtils.parseOptions.returns({});
bookshelf.Model.prototype.fetchPage().then(function () {
@ -249,7 +250,7 @@ describe('pagination', function () {
}).catch(done);
});
it('fetchPage calls all paginationUtils and methods when order set', function (done) {
it('calls all paginationUtils and methods when order set', function (done) {
var orderOptions = {order: {id: 'DESC'}};
paginationUtils.parseOptions.returns(orderOptions);
@ -288,7 +289,7 @@ describe('pagination', function () {
}).catch(done);
});
it('fetchPage calls all paginationUtils and methods when group by set', function (done) {
it('calls all paginationUtils and methods when group by set', function (done) {
var groupOptions = {groups: ['posts.id']};
paginationUtils.parseOptions.returns(groupOptions);
@ -327,7 +328,7 @@ describe('pagination', function () {
}).catch(done);
});
it('fetchPage returns expected response', function (done) {
it('returns expected response', function (done) {
paginationUtils.parseOptions.returns({});
bookshelf.Model.prototype.fetchPage().then(function (result) {
result.should.have.ownProperty('collection');
@ -339,7 +340,7 @@ describe('pagination', function () {
});
});
it('fetchPage returns expected response even when aggregate is empty', function (done) {
it('returns expected response even when aggregate is empty', function (done) {
// override aggregate response
mockQuery.select.returns([]);
paginationUtils.parseOptions.returns({});
@ -353,5 +354,18 @@ describe('pagination', function () {
done();
});
});
it('will output sql statements in debug mode', function (done) {
model.prototype.debug = true;
mockQuery.select.returns({toQuery: function () {}});
paginationUtils.parseOptions.returns({});
var consoleSpy = sandbox.spy(console, 'log');
bookshelf.Model.prototype.fetchPage().then(function () {
consoleSpy.calledOnce.should.be.true;
done();
});
});
});
});