mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 22:43:30 +03:00
Removed knex mock (#9685)
no issue - this mock eat already too much of my/our time - the idea of adding a knex mock was definitely a failed approach/try - it's too much to maintaince and have not found a module which does this already - we have to support any query format - this is too crazy - the idea was to use the knex mock for model unit tests, because if we want to unit test models we have to run through bookshelf, because the whole model layer depends on bookshelf e.g. events - for now we simply use the real database - we could use the sqlite3 memory mode, but that would mean every unit test runs on sqlite3 - something to consider for later e.g. run unit tests on one matrix - run the rest on another matrix for sqlite + mysql
This commit is contained in:
parent
5079830ddb
commit
835fd6c45b
@ -16,7 +16,14 @@ const should = require('should'),
|
||||
* either move to integration tests or rewrite!!!
|
||||
*/
|
||||
describe('{{ghost_head}} helper', function () {
|
||||
let posts = [], tags = [], users = [], knexMock, firstCollection;
|
||||
let posts = [], tags = [], users = [], firstCollection;
|
||||
|
||||
before(function () {
|
||||
testUtils.integrationTesting.defaultMocks(sandbox);
|
||||
});
|
||||
|
||||
before(testUtils.teardown);
|
||||
before(testUtils.setup('users:roles', 'posts'));
|
||||
|
||||
before(function () {
|
||||
models.init();
|
||||
@ -25,16 +32,11 @@ describe('{{ghost_head}} helper', function () {
|
||||
firstCollection.getRssUrl = sandbox.stub().returns('http://localhost:65530/rss/');
|
||||
sandbox.stub(routing.registry, 'getFirstCollectionRouter').returns(firstCollection);
|
||||
|
||||
testUtils.integrationTesting.defaultMocks(sandbox);
|
||||
|
||||
settingsCache.get.withArgs('title').returns('Ghost');
|
||||
settingsCache.get.withArgs('description').returns('blog description');
|
||||
settingsCache.get.withArgs('cover_image').returns('/content/images/blog-cover.png');
|
||||
settingsCache.get.withArgs('amp').returns(true);
|
||||
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
|
||||
return models.Post.add(testUtils.DataGenerator.forKnex.createPost({
|
||||
meta_description: 'all about our blog',
|
||||
title: 'About',
|
||||
@ -324,7 +326,6 @@ describe('{{ghost_head}} helper', function () {
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
testUtils.integrationTesting.urlService.resetGenerators();
|
||||
sandbox.restore();
|
||||
configUtils.restore();
|
||||
|
@ -1,5 +1,4 @@
|
||||
const _ = require('lodash');
|
||||
const Promise = require('bluebird');
|
||||
const should = require('should');
|
||||
const sinon = require('sinon');
|
||||
const rewire = require('rewire');
|
||||
@ -11,24 +10,15 @@ const UrlService = rewire('../../../../server/services/url/UrlService');
|
||||
const sandbox = sinon.sandbox.create();
|
||||
|
||||
describe('Unit: services/url/UrlService', function () {
|
||||
let knexMock, urlService;
|
||||
let urlService;
|
||||
|
||||
before(function () {
|
||||
models.init();
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
before(testUtils.teardown);
|
||||
before(testUtils.setup('users:roles', 'posts'));
|
||||
after(testUtils.teardown);
|
||||
|
||||
after(function () {
|
||||
sandbox.restore();
|
||||
@ -37,7 +27,7 @@ describe('Unit: services/url/UrlService', function () {
|
||||
describe('functional: default routing set', function () {
|
||||
let router1, router2, router3, router4;
|
||||
|
||||
beforeEach(function (done) {
|
||||
before(function (done) {
|
||||
urlService = new UrlService();
|
||||
|
||||
router1 = {
|
||||
@ -131,7 +121,7 @@ describe('Unit: services/url/UrlService', function () {
|
||||
})();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
after(function () {
|
||||
urlService.reset();
|
||||
});
|
||||
|
||||
@ -211,6 +201,9 @@ describe('Unit: services/url/UrlService', function () {
|
||||
});
|
||||
|
||||
describe('update resource', function () {
|
||||
afterEach(testUtils.teardown);
|
||||
afterEach(testUtils.setup('users:roles', 'posts'));
|
||||
|
||||
it('featured: false => featured:true', function () {
|
||||
return models.Post.edit({featured: true}, {id: testUtils.DataGenerator.forKnex.posts[1].id})
|
||||
.then(function (post) {
|
||||
@ -307,7 +300,14 @@ describe('Unit: services/url/UrlService', function () {
|
||||
describe('functional: extended/modified routing set', function () {
|
||||
let router1, router2, router3, router4, router5;
|
||||
|
||||
beforeEach(function (done) {
|
||||
before(testUtils.teardown);
|
||||
before(testUtils.setup('users:roles', 'posts'));
|
||||
|
||||
before(function () {
|
||||
urlService.resetGenerators();
|
||||
});
|
||||
|
||||
before(function (done) {
|
||||
urlService = new UrlService();
|
||||
|
||||
router1 = {
|
||||
@ -420,7 +420,7 @@ describe('Unit: services/url/UrlService', function () {
|
||||
})();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
after(function () {
|
||||
urlService.resetGenerators();
|
||||
});
|
||||
|
||||
@ -498,6 +498,9 @@ describe('Unit: services/url/UrlService', function () {
|
||||
});
|
||||
|
||||
describe('update resource', function () {
|
||||
afterEach(testUtils.teardown);
|
||||
afterEach(testUtils.setup('users:roles', 'posts'));
|
||||
|
||||
it('featured: false => featured:true', function () {
|
||||
return models.Post.edit({featured: true}, {id: testUtils.DataGenerator.forKnex.posts[1].id})
|
||||
.then(function (post) {
|
||||
@ -526,11 +529,11 @@ describe('Unit: services/url/UrlService', function () {
|
||||
|
||||
urlService.urlGenerators.forEach(function (generator) {
|
||||
if (generator.router.getType() === 'posts' && generator.router.getFilter() === 'featured:false') {
|
||||
generator.getUrls().length.should.eql(3);
|
||||
generator.getUrls().length.should.eql(2);
|
||||
}
|
||||
|
||||
if (generator.router.getType() === 'posts' && generator.router.getFilter() === 'featured:true') {
|
||||
generator.getUrls().length.should.eql(1);
|
||||
generator.getUrls().length.should.eql(2);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -10,18 +10,11 @@ const should = require('should'),
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
describe('Integration - Web - Site', function () {
|
||||
let app, knexMock;
|
||||
let app;
|
||||
|
||||
before(testUtils.setup('users:roles', 'posts'));
|
||||
|
||||
describe('default routes.yaml', function () {
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
sandbox.stub(themeConfig, 'create').returns({
|
||||
posts_per_page: 2
|
||||
@ -432,15 +425,6 @@ describe('Integration - Web - Site', function () {
|
||||
});
|
||||
|
||||
describe('extended routes.yaml (1): 2 collections', function () {
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
sandbox.stub(settingsService, 'get').returns({
|
||||
routes: {
|
||||
@ -575,15 +559,6 @@ describe('Integration - Web - Site', function () {
|
||||
});
|
||||
|
||||
describe('extended routes.yaml (2): static permalink route', function () {
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
sandbox.stub(settingsService, 'get').returns({
|
||||
routes: {},
|
||||
@ -691,15 +666,6 @@ describe('Integration - Web - Site', function () {
|
||||
|
||||
describe('extended routes.yaml (3): templates', function () {
|
||||
describe('(3) (1)', function () {
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
sandbox.stub(settingsService, 'get').returns({
|
||||
routes: {},
|
||||
@ -770,15 +736,6 @@ describe('Integration - Web - Site', function () {
|
||||
});
|
||||
|
||||
describe('(3) (2)', function () {
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
sandbox.stub(settingsService, 'get').returns({
|
||||
routes: {},
|
||||
@ -831,15 +788,6 @@ describe('Integration - Web - Site', function () {
|
||||
});
|
||||
|
||||
describe('(3) (3)', function () {
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
sandbox.stub(settingsService, 'get').returns({
|
||||
routes: {},
|
||||
@ -912,15 +860,6 @@ describe('Integration - Web - Site', function () {
|
||||
});
|
||||
|
||||
describe('extended routes.yaml (4): primary author permalink', function () {
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
sandbox.stub(settingsService, 'get').returns({
|
||||
routes: {},
|
||||
@ -1006,15 +945,6 @@ describe('Integration - Web - Site', function () {
|
||||
});
|
||||
|
||||
describe('extended routes.yaml (4): primary tag permalink', function () {
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
sandbox.stub(settingsService, 'get').returns({
|
||||
routes: {},
|
||||
|
@ -16,17 +16,11 @@ describe('Unit: models/invite', function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
before(testUtils.teardown);
|
||||
|
||||
describe('add', function () {
|
||||
let knexMock;
|
||||
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
beforeEach(testUtils.setup('roles'));
|
||||
afterEach(testUtils.teardown);
|
||||
|
||||
it('default', function () {
|
||||
return models.Invite.add({email: 'invited@test.org', role_id: testUtils.DataGenerator.forKnex.roles[1].id})
|
||||
|
@ -2,6 +2,7 @@ const should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
models = require('../../../server/models'),
|
||||
testUtils = require('../../utils'),
|
||||
configUtils = require('../../utils/configUtils'),
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
describe('Unit: models/permission', function () {
|
||||
@ -11,19 +12,14 @@ describe('Unit: models/permission', function () {
|
||||
|
||||
after(function () {
|
||||
sandbox.restore();
|
||||
configUtils.restore();
|
||||
});
|
||||
|
||||
before(testUtils.teardown);
|
||||
|
||||
describe('add', function () {
|
||||
let knexMock;
|
||||
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
beforeEach(testUtils.setup('roles'));
|
||||
afterEach(testUtils.teardown);
|
||||
|
||||
it('without roles', function () {
|
||||
return models.Permission.add({name: 'test', object_type: 'something', action_type: 'read something'})
|
||||
|
@ -5,26 +5,20 @@ const should = require('should'),
|
||||
_ = require('lodash'),
|
||||
testUtils = require('../../utils'),
|
||||
knex = require('../../../server/data/db').knex,
|
||||
settingsCache = require('../../../server/services/settings/cache'),
|
||||
urlService = require('../../../server/services/url'),
|
||||
schema = require('../../../server/data/schema'),
|
||||
models = require('../../../server/models'),
|
||||
common = require('../../../server/lib/common'),
|
||||
security = require('../../../server/lib/security'),
|
||||
utils = require('../../utils'),
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
describe('Unit: models/post', function () {
|
||||
let knexMock;
|
||||
|
||||
before(function () {
|
||||
models.init();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
before(testUtils.teardown);
|
||||
before(testUtils.setup('users:roles', 'posts'));
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox.stub(security.password, 'hash').resolves('$2a$10$we16f8rpbrFZ34xWj0/ZC.LTPUux8ler7bcdTs5qIleN6srRHhilG');
|
||||
@ -35,10 +29,6 @@ describe('Unit: models/post', function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
@ -286,7 +276,7 @@ describe('Unit: models/post', function () {
|
||||
// post will be updated, tags relation not
|
||||
return models.Post.edit({
|
||||
title: 'change',
|
||||
tags: post.related('tags').toJSON()
|
||||
tags: post.related('tags').attributes
|
||||
}, _.merge({id: testUtils.DataGenerator.forKnex.posts[3].id}, testUtils.context.editor));
|
||||
})
|
||||
.then((post) => {
|
||||
@ -820,9 +810,10 @@ describe('Unit: models/post', function () {
|
||||
});
|
||||
|
||||
describe('edit', function () {
|
||||
beforeEach(function () {
|
||||
knexMock.resetDb();
|
||||
beforeEach(testUtils.teardown);
|
||||
beforeEach(testUtils.setup('users:roles', 'posts'));
|
||||
|
||||
beforeEach(function () {
|
||||
// posts[3] has the following author_id
|
||||
testUtils.DataGenerator.forKnex.posts[3].author_id.should.eql(testUtils.DataGenerator.forKnex.users[0].id);
|
||||
|
||||
|
@ -13,18 +13,10 @@ describe('Unit: models/tags', function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
before(testUtils.teardown);
|
||||
before(testUtils.setup('tags'));
|
||||
|
||||
describe('Edit', function () {
|
||||
let knexMock;
|
||||
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
it('resets given empty value to null', function () {
|
||||
return models.Tag.findOne({slug: 'kitchen-sink'})
|
||||
.then(function (tag) {
|
||||
|
@ -8,30 +8,22 @@ const should = require('should'),
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
describe('Unit: models/user', function () {
|
||||
let knexMock;
|
||||
|
||||
before(function () {
|
||||
models.init();
|
||||
});
|
||||
|
||||
before(testUtils.teardown);
|
||||
before(testUtils.setup('users:roles'));
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe('validation', function () {
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox.stub(security.password, 'hash').resolves('$2a$10$we16f8rpbrFZ34xWj0/ZC.LTPUux8ler7bcdTs5qIleN6srRHhilG');
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
describe('password', function () {
|
||||
it('no password', function () {
|
||||
return models.User.add({email: 'test1@ghost.org', name: 'Ghosty'})
|
||||
@ -96,19 +88,10 @@ describe('Unit: models/user', function () {
|
||||
});
|
||||
|
||||
describe('fn: check', function () {
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox.stub(security.password, 'hash').resolves('$2a$10$we16f8rpbrFZ34xWj0/ZC.LTPUux8ler7bcdTs5qIleN6srRHhilG');
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
it('user status is warn', function () {
|
||||
sandbox.stub(security.password, 'compare').resolves(true);
|
||||
|
||||
@ -308,8 +291,6 @@ describe('Unit: models/user', function () {
|
||||
});
|
||||
|
||||
describe('Fetch', function () {
|
||||
let knexMock;
|
||||
|
||||
before(function () {
|
||||
models.init();
|
||||
});
|
||||
@ -318,15 +299,6 @@ describe('Unit: models/user', function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
it('ensure data type', function () {
|
||||
return models.User.findOne({slug: 'joe-bloggs'}, testUtils.context.internal)
|
||||
.then((user) => {
|
||||
@ -339,8 +311,6 @@ describe('Unit: models/user', function () {
|
||||
});
|
||||
|
||||
describe('Edit', function () {
|
||||
let knexMock;
|
||||
|
||||
before(function () {
|
||||
models.init();
|
||||
});
|
||||
@ -349,15 +319,6 @@ describe('Unit: models/user', function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
before(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
it('resets given empty value to null', function () {
|
||||
return models.User.findOne({slug: 'joe-bloggs'})
|
||||
.then(function (user) {
|
||||
|
@ -9,16 +9,16 @@ const Resources = require('../../../../server/services/url/Resources');
|
||||
const sandbox = sinon.sandbox.create();
|
||||
|
||||
describe('Unit: services/url/Resources', function () {
|
||||
let knexMock, onEvents, emitEvents, resources, queue;
|
||||
let onEvents, emitEvents, resources, queue;
|
||||
|
||||
before(function () {
|
||||
models.init();
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
knexMock = new testUtils.mocks.knex();
|
||||
knexMock.mock();
|
||||
before(testUtils.teardown);
|
||||
before(testUtils.setup('users:roles', 'posts'));
|
||||
|
||||
beforeEach(function () {
|
||||
onEvents = {};
|
||||
emitEvents = {};
|
||||
|
||||
@ -38,7 +38,6 @@ describe('Unit: services/url/Resources', function () {
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
resources.reset();
|
||||
knexMock.unmock();
|
||||
});
|
||||
|
||||
it('db.ready', function (done) {
|
||||
|
@ -467,7 +467,14 @@ DataGenerator.forKnex = (function () {
|
||||
}
|
||||
|
||||
function createUser(overrides) {
|
||||
var newObj = _.cloneDeep(overrides);
|
||||
var newObj = _.cloneDeep(overrides || {});
|
||||
|
||||
if (!newObj.slug) {
|
||||
newObj.slug = 'slug_' + Date.now();
|
||||
}
|
||||
if (!newObj.email) {
|
||||
newObj.email = `test${newObj.slug}@ghost.org`;
|
||||
}
|
||||
|
||||
return _.defaults(newObj, {
|
||||
id: ObjectId.generate(),
|
||||
@ -475,7 +482,6 @@ DataGenerator.forKnex = (function () {
|
||||
email: 'test@ghost.org',
|
||||
bio: 'bio',
|
||||
website: null,
|
||||
slug: 'slug_' + Date.now(),
|
||||
profile_image: null,
|
||||
status: 'active',
|
||||
password: 'Sl1m3rson99',
|
||||
|
@ -1031,6 +1031,7 @@ startGhost = function startGhost(options) {
|
||||
|
||||
module.exports = {
|
||||
startGhost: startGhost,
|
||||
|
||||
integrationTesting: {
|
||||
overrideGhostConfig: function overrideGhostConfig(configUtils) {
|
||||
configUtils.set('paths:contentPath', path.join(__dirname, 'fixtures'));
|
||||
|
@ -1,3 +1,2 @@
|
||||
exports.utils = require('./utils');
|
||||
exports.express = require('./express');
|
||||
exports.knex = require('./knex');
|
||||
|
@ -1,346 +0,0 @@
|
||||
/* eslint-disable */
|
||||
|
||||
const mockKnex = require('mock-knex'),
|
||||
_ = require('lodash'),
|
||||
debug = require('ghost-ignition').debug('tests:knex-mock'),
|
||||
DataGenerator = require('../fixtures/data-generator'),
|
||||
knex = require('../../../server/data/db').knex;
|
||||
|
||||
/**
|
||||
* Knex mock. The database values are taken from our Datagenerator.
|
||||
* You can either self register queries or you simply rely on the data generator data.
|
||||
*
|
||||
* Please extend if your use-case does not work.
|
||||
*
|
||||
* @TODO: sqlite3 :memory: mode wasn't working for me
|
||||
*/
|
||||
class KnexMock {
|
||||
initialiseDb() {
|
||||
this.db = {};
|
||||
|
||||
_.each(_.pick(_.cloneDeep(DataGenerator.forKnex), [
|
||||
'posts',
|
||||
'users',
|
||||
'tags',
|
||||
'invites',
|
||||
'permissions',
|
||||
'roles',
|
||||
'posts_authors',
|
||||
'posts_tags'
|
||||
]), (objects, tableName) => {
|
||||
this.db[tableName] = [];
|
||||
|
||||
_.each(objects, (object) => {
|
||||
this.db[tableName].push(object);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
resetDb() {
|
||||
return this.initialiseDb();
|
||||
}
|
||||
|
||||
mock(options) {
|
||||
options = options || {autoMock: true};
|
||||
mockKnex.mock(knex);
|
||||
|
||||
this.initialiseDb();
|
||||
|
||||
this.tracker = mockKnex.getTracker();
|
||||
this.tracker.install();
|
||||
|
||||
if (options.autoMock) {
|
||||
this.tracker.on('query', (query) => {
|
||||
query.sql = query.sql.replace(/`/g, '"');
|
||||
debug('#### Query start.');
|
||||
debug(query.sql);
|
||||
|
||||
// CASE: transactions
|
||||
if (query.sql.match(/BEGIN|COMMIT|ROLLBACK/)) {
|
||||
query.response();
|
||||
debug('#### Query end.\n');
|
||||
return;
|
||||
}
|
||||
|
||||
if (query.method === 'select') {
|
||||
if (query.bindings.length && query.sql.match(/where/)) {
|
||||
// CASE: joins should return e.g. `posts_tags=[tag,tag]`
|
||||
if (query.sql.match(/inner\sjoin/)) {
|
||||
let targetTable = query.sql.match(/inner\sjoin\s(\"\w+\")/)[1],
|
||||
targetAttribute = query.sql.match(/on\s\"\w+\"\.(\"\w+\")/)[1],
|
||||
joinAttribute = query.sql.match(/on\s\"\w+\"\.\"\w+\"\s\=\s\"\w+\"\.(\"\w+\")/)[1],
|
||||
joinTable = query.sql.match(/on\s\"\w+\"\.\"\w+\"\s\=\s(\"\w+\")/)[1],
|
||||
targetIdentifier = query.sql.match(/(\"\w+\")\sin\s\(\?\)/),
|
||||
values = query.bindings,
|
||||
targetEntries,
|
||||
toReturn = [];
|
||||
|
||||
if (!targetIdentifier) {
|
||||
targetIdentifier = query.sql.match(/where\s\"\w+\"\.\"(\w+)\"\s\=/);
|
||||
}
|
||||
|
||||
if (!targetIdentifier) {
|
||||
targetIdentifier = query.sql.match(/where\s\"\w+\"\.\"(\w+)\"\s\in\s/);
|
||||
}
|
||||
|
||||
if (targetIdentifier) {
|
||||
targetIdentifier = targetIdentifier[1];
|
||||
}
|
||||
|
||||
targetTable = targetTable.replace(/"/g, '');
|
||||
targetIdentifier = targetIdentifier.replace(/"/g, '');
|
||||
targetAttribute = targetAttribute.replace(/"/g, '');
|
||||
joinTable = joinTable.replace(/"/g, '');
|
||||
joinAttribute = joinAttribute.replace(/"/g, '');
|
||||
|
||||
debug(targetTable, targetIdentifier, targetAttribute, joinTable, joinAttribute);
|
||||
|
||||
targetEntries = _.filter(this.db[targetTable], ((existing) => {
|
||||
if (values.indexOf(existing[targetIdentifier]) !== -1) {
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
|
||||
if (targetEntries && targetEntries.length) {
|
||||
_.each(targetEntries, ((target) => {
|
||||
let found = _.cloneDeep(_.find(this.db[joinTable], ((joinEntry) => {
|
||||
if (joinEntry[joinAttribute] === target[targetAttribute]) {
|
||||
return true;
|
||||
}
|
||||
})));
|
||||
|
||||
_.each(target, function (value, key) {
|
||||
let match = query.sql.match(new RegExp('\\"' + targetTable + '\\"\\.\\"' + key + '"\\sas\\s(\\"\\w+\\")'));
|
||||
|
||||
// CASE: "posts_tags"."post_id" as "post_id"
|
||||
if (match) {
|
||||
match = match[1];
|
||||
match = match.replace(/"/g, '');
|
||||
found[match] = value;
|
||||
}
|
||||
});
|
||||
|
||||
let keys = query.sql.match(/select\s(\".*\"\,?)+\sfrom/)[1];
|
||||
|
||||
if (!keys.match(/\.*/)) {
|
||||
_.each(found, (value, key)=> {
|
||||
if (keys.indexOf(key) === -1) {
|
||||
delete found[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (found) {
|
||||
toReturn.push(found);
|
||||
}
|
||||
}));
|
||||
|
||||
// @TODO: This is not really generic ;)
|
||||
toReturn = _.orderBy(toReturn, ['_pivot_sort_order'], ['asc']);
|
||||
query.response(toReturn);
|
||||
debug('#### Query end.\n');
|
||||
} else {
|
||||
query.response([]);
|
||||
debug('#### Query end.\n');
|
||||
}
|
||||
} else {
|
||||
let tableName = query.sql.match(/from\s\"(\w+)\"/)[1],
|
||||
where = query.sql.match(/\"(\w+)\"\s\=\s\?/),
|
||||
values = query.bindings,
|
||||
dbEntry,
|
||||
wheres = [];
|
||||
|
||||
// where "users"."id" in ('1')
|
||||
if (!where) {
|
||||
where = query.sql.match(/\"\w+\"\.\"(\w+)\"\sin\s\(\?\)/)[1];
|
||||
} else {
|
||||
let wheresMatch = query.sql.match(/\(?\"(\w+)\"\.?\"?(\w+)?\"?\s=\s\?\)?/g);
|
||||
|
||||
// e.g. [ '("posts"."status" = ?)', '("posts"."page" = ?)' ]
|
||||
// e.g. [ '"status" = ?' ]
|
||||
_.each(wheresMatch, (result)=> {
|
||||
let attr = result.match(/\(?\"(\w+)\"\.?\"?(\w+)?\"?\s=\s\?\)?/);
|
||||
wheres.push(attr[2] || attr[1]);
|
||||
});
|
||||
}
|
||||
|
||||
values = query.bindings.slice(0, wheres.length);
|
||||
|
||||
debug(tableName, wheres, values);
|
||||
|
||||
dbEntry = _.filter(this.db[tableName], ((existing) => {
|
||||
if (_.isEqual(_.values(_.pick(existing, wheres)), values)) {
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
|
||||
if (dbEntry) {
|
||||
// select fields
|
||||
dbEntry = _.map(dbEntry, (obj) => {
|
||||
let keys = query.sql.match(/select\s(\".*\"\,?)+\sfrom/);
|
||||
|
||||
if (keys) {
|
||||
keys = keys[1];
|
||||
keys = keys.replace(/"/g, '');
|
||||
keys = keys.replace(/\s/g, '');
|
||||
keys = keys.split(',');
|
||||
return _.pick(obj, keys);
|
||||
}
|
||||
|
||||
return obj;
|
||||
});
|
||||
|
||||
if (query.sql.match(/count\(/)) {
|
||||
const as = query.sql.match(/count\(.*\)\sas\s(\w+)/)[1];
|
||||
return query.response([{[as]: dbEntry.length}]);
|
||||
}
|
||||
|
||||
if (query.sql.match(/limit\s\?\soffset\s\?/)) {
|
||||
const limit = query.bindings[query.bindings.length - 2];
|
||||
const offset = query.bindings[query.bindings.length - 1];
|
||||
|
||||
function separateIt(arr, size) {
|
||||
const newArr = [];
|
||||
for (let i = 0; i < arr.length; i += size) {
|
||||
let sliceIt = arr.slice(i, i + size);
|
||||
newArr.push(sliceIt);
|
||||
}
|
||||
return newArr;
|
||||
}
|
||||
|
||||
dbEntry = separateIt(dbEntry, limit)[offset - 1];
|
||||
} else if (query.sql.match(/limit\s\?$/)) {
|
||||
const limit = query.bindings[query.bindings.length - 1];
|
||||
dbEntry = dbEntry.splice(0, limit);
|
||||
}
|
||||
|
||||
query.response(dbEntry);
|
||||
debug('#### Query end.\n');
|
||||
} else {
|
||||
query.response([]);
|
||||
debug('#### Query end. Not found\n');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const tableName = query.sql.match(/from\s\"(\w+)\"/)[1];
|
||||
query.response(this.db[tableName]);
|
||||
}
|
||||
} else if (query.method === 'insert') {
|
||||
const tableName = query.sql.match(/into\s\"(\w+)\"/)[1];
|
||||
let keys = query.sql.match(/\(([^)]+)\)/)[1],
|
||||
entry = {};
|
||||
|
||||
keys = keys.replace(/"/g, '');
|
||||
keys = keys.replace(/\s/g, '');
|
||||
keys = keys.split(',');
|
||||
|
||||
_.each(keys, (key, index) => {
|
||||
entry[key] = query.bindings[index];
|
||||
});
|
||||
|
||||
if (!this.db[tableName]) {
|
||||
this.db[tableName] = [];
|
||||
}
|
||||
|
||||
this.db[tableName].push(entry);
|
||||
query.response(entry);
|
||||
debug('#### Query end.\n');
|
||||
} else if (query.method === 'update') {
|
||||
let tableName = query.sql.match(/update\s\"(\w+)\"/)[1],
|
||||
where = query.sql.match(/where\s\"(\w+)\"\s\=\s\?/)[1],
|
||||
andWhere = query.sql.match(/where\s\"\w+\"\s\=\s\?\sand\s\"(\w+)\"/),
|
||||
valueWhere,
|
||||
valueAndWhere,
|
||||
dbEntry;
|
||||
|
||||
if (andWhere) {
|
||||
andWhere = andWhere[1];
|
||||
valueWhere = query.bindings.slice(1, -1)[0];
|
||||
valueAndWhere = query.bindings.slice(-1)[0];
|
||||
} else {
|
||||
valueWhere = query.bindings.slice(-1)[0];
|
||||
}
|
||||
|
||||
debug(tableName, where, valueWhere, andWhere, valueAndWhere, query.bindings);
|
||||
|
||||
dbEntry = _.find(this.db[tableName], ((existing) => {
|
||||
if (existing[where] === valueWhere) {
|
||||
if (andWhere) {
|
||||
if (existing[andWhere] === valueAndWhere) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
if (!dbEntry) {
|
||||
query.response([]);
|
||||
debug('#### Query end. Can\'t update - not found.\n');
|
||||
} else {
|
||||
let keys = query.sql.match(/set(.*)where/)[1],
|
||||
entry = {};
|
||||
|
||||
keys = keys.match(/\"\w+\"/g).join(',');
|
||||
keys = keys.replace(/"/g, '');
|
||||
keys = keys.replace(/\s/g, '');
|
||||
keys = keys.split(',');
|
||||
|
||||
debug('set', keys);
|
||||
|
||||
_.each(keys, (key, index) => {
|
||||
entry[key] = query.bindings[index];
|
||||
dbEntry[key] = entry[key];
|
||||
});
|
||||
|
||||
query.response(entry);
|
||||
debug('#### Query end.\n');
|
||||
}
|
||||
} else {
|
||||
let tableName = query.sql.match(/from\s\"(\w+)\"/)[1],
|
||||
where = query.sql.match(/where\s\"(\w+)\"\s\=\s\?/)[1],
|
||||
andWhere = query.sql.match(/where\s\"\w+\"\s\=\s\?\sand\s\"(\w+)\"/),
|
||||
valueWhere,
|
||||
valueAndWhere;
|
||||
|
||||
valueWhere = query.bindings[0];
|
||||
|
||||
if (andWhere) {
|
||||
andWhere = andWhere[1];
|
||||
valueAndWhere = query.bindings[1];
|
||||
}
|
||||
|
||||
debug(tableName, where, valueWhere, andWhere, valueAndWhere, query.bindings);
|
||||
|
||||
this.db[tableName] = this.db[tableName].filter((existing) => {
|
||||
if (existing[where] === valueWhere) {
|
||||
if (andWhere) {
|
||||
if (existing[andWhere] === valueAndWhere) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
query.response([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return this.tracker;
|
||||
}
|
||||
|
||||
unmock() {
|
||||
this.tracker.uninstall();
|
||||
mockKnex.unmock(knex);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = KnexMock;
|
@ -123,7 +123,6 @@
|
||||
"matchdep": "2.0.0",
|
||||
"minimist": "1.2.0",
|
||||
"mocha": "4.1.0",
|
||||
"mock-knex": "0.4.0",
|
||||
"nock": "9.3.0",
|
||||
"rewire": "3.0.2",
|
||||
"should": "13.2.1",
|
||||
|
10
yarn.lock
10
yarn.lock
@ -3530,7 +3530,7 @@ lodash.uniq@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
|
||||
lodash@4.17.10, lodash@^4.13.1, lodash@^4.14.2, lodash@^4.16.4, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.7.0, lodash@^4.8.0, lodash@~4.17.10, lodash@~4.17.5:
|
||||
lodash@4.17.10, lodash@^4.13.1, lodash@^4.16.4, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.7.0, lodash@^4.8.0, lodash@~4.17.10, lodash@~4.17.5:
|
||||
version "4.17.10"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
|
||||
|
||||
@ -3870,14 +3870,6 @@ mocha@^3.1.2:
|
||||
mkdirp "0.5.1"
|
||||
supports-color "3.1.2"
|
||||
|
||||
mock-knex@0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/mock-knex/-/mock-knex-0.4.0.tgz#32c4ed97ff7cf9c86eca2400902f34e1f7f88de1"
|
||||
dependencies:
|
||||
bluebird "^3.4.1"
|
||||
lodash "^4.14.2"
|
||||
semver "^5.3.0"
|
||||
|
||||
moment-timezone@0.5.17:
|
||||
version "0.5.17"
|
||||
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.17.tgz#3c8fef32051d84c3af174d91dc52977dcb0ad7e5"
|
||||
|
Loading…
Reference in New Issue
Block a user