cddd23f926
This frees us up to enforce one single point of access, thus paving the way towards allowing us to initialize the models at are request, and not when it's require(). addresses #2170
576 lines
23 KiB
JavaScript
576 lines
23 KiB
JavaScript
/*globals describe, beforeEach, afterEach, it*/
|
|
/*jshint expr:true*/
|
|
var testUtils = require('../utils'),
|
|
should = require('should'),
|
|
sinon = require('sinon'),
|
|
when = require('when'),
|
|
assert = require('assert'),
|
|
_ = require('lodash'),
|
|
|
|
// Stuff we are testing
|
|
config = require('../../server/config'),
|
|
migration = require('../../server/data/migration'),
|
|
versioning = require('../../server/data/versioning'),
|
|
exporter = require('../../server/data/export'),
|
|
importer = require('../../server/data/import'),
|
|
Importer000 = require('../../server/data/import/000'),
|
|
Importer001 = require('../../server/data/import/001'),
|
|
Importer002 = require('../../server/data/import/002'),
|
|
Importer003 = require('../../server/data/import/003');
|
|
|
|
describe('Import', function () {
|
|
|
|
should.exist(exporter);
|
|
should.exist(importer);
|
|
|
|
var sandbox,
|
|
knex = config().database.knex;
|
|
|
|
beforeEach(function (done) {
|
|
sandbox = sinon.sandbox.create();
|
|
// clear database... we need to initialise it manually for each test
|
|
testUtils.clearData().then(function () {
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
afterEach(function () {
|
|
sandbox.restore();
|
|
});
|
|
|
|
it('resolves 000', function (done) {
|
|
var importStub = sandbox.stub(Importer000, 'importData', function () {
|
|
return when.resolve();
|
|
}),
|
|
fakeData = { test: true };
|
|
|
|
importer('000', fakeData).then(function () {
|
|
importStub.calledWith(fakeData).should.equal(true);
|
|
|
|
importStub.restore();
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('resolves 001', function (done) {
|
|
var importStub = sandbox.stub(Importer001, 'importData', function () {
|
|
return when.resolve();
|
|
}),
|
|
fakeData = { test: true };
|
|
|
|
importer('001', fakeData).then(function () {
|
|
importStub.calledWith(fakeData).should.equal(true);
|
|
|
|
importStub.restore();
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('resolves 002', function (done) {
|
|
var importStub = sandbox.stub(Importer002, 'importData', function () {
|
|
return when.resolve();
|
|
}),
|
|
fakeData = { test: true };
|
|
|
|
importer('002', fakeData).then(function () {
|
|
importStub.calledWith(fakeData).should.equal(true);
|
|
|
|
importStub.restore();
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('resolves 003', function (done) {
|
|
var importStub = sandbox.stub(Importer003, 'importData', function () {
|
|
return when.resolve();
|
|
}),
|
|
fakeData = { test: true };
|
|
|
|
importer('003', fakeData).then(function () {
|
|
importStub.calledWith(fakeData).should.equal(true);
|
|
|
|
importStub.restore();
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
describe('000', function () {
|
|
should.exist(Importer000);
|
|
|
|
beforeEach(function (done) {
|
|
// migrate to current version
|
|
migration.migrateUpFreshDb().then(function () {
|
|
return testUtils.insertDefaultUser();
|
|
}).then(function () {
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
|
|
it('imports data from 000', function (done) {
|
|
var exportData,
|
|
versioningStub = sandbox.stub(versioning, 'getDatabaseVersion', function () {
|
|
return when.resolve('000');
|
|
});
|
|
|
|
testUtils.loadExportFixture('export-000').then(function (exported) {
|
|
exportData = exported;
|
|
|
|
return importer('000', exportData);
|
|
}).then(function () {
|
|
// Grab the data from tables
|
|
return when.all([
|
|
knex('users').select(),
|
|
knex('posts').select(),
|
|
knex('settings').select(),
|
|
knex('tags').select()
|
|
]);
|
|
}).then(function (importedData) {
|
|
should.exist(importedData);
|
|
|
|
importedData.length.should.equal(4, 'Did not get data successfully');
|
|
|
|
var users = importedData[0],
|
|
posts = importedData[1],
|
|
settings = importedData[2],
|
|
tags = importedData[3];
|
|
|
|
// we always have 1 user, the default user we added
|
|
users.length.should.equal(1, 'There should only be one user');
|
|
// import no longer requires all data to be dropped, and adds posts
|
|
posts.length.should.equal(exportData.data.posts.length + 1, 'Wrong number of posts');
|
|
|
|
// test settings
|
|
settings.length.should.be.above(0, 'Wrong number of settings');
|
|
_.findWhere(settings, {key: 'databaseVersion'}).value.should.equal('003', 'Wrong database version');
|
|
|
|
// test tags
|
|
tags.length.should.equal(exportData.data.tags.length, 'no new tags');
|
|
|
|
versioningStub.restore();
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
});
|
|
|
|
describe('001', function () {
|
|
should.exist(Importer001);
|
|
|
|
beforeEach(function (done) {
|
|
// migrate to current version
|
|
migration.migrateUpFreshDb().then(function () {
|
|
return testUtils.insertDefaultUser();
|
|
}).then(function () {
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('safely imports data from 001', function (done) {
|
|
var exportData,
|
|
timestamp = 1349928000000;
|
|
|
|
testUtils.loadExportFixture('export-001').then(function (exported) {
|
|
exportData = exported;
|
|
|
|
// Modify timestamp data for testing
|
|
exportData.data.posts[0].created_at = timestamp;
|
|
exportData.data.posts[0].updated_at = timestamp;
|
|
exportData.data.posts[0].published_at = timestamp;
|
|
|
|
return importer('001', exportData);
|
|
}).then(function () {
|
|
// Grab the data from tables
|
|
return when.all([
|
|
knex('users').select(),
|
|
knex('posts').select(),
|
|
knex('settings').select(),
|
|
knex('tags').select()
|
|
]);
|
|
}).then(function (importedData) {
|
|
should.exist(importedData);
|
|
|
|
importedData.length.should.equal(4, 'Did not get data successfully');
|
|
|
|
var users = importedData[0],
|
|
posts = importedData[1],
|
|
settings = importedData[2],
|
|
tags = importedData[3],
|
|
exportEmail;
|
|
|
|
// we always have 1 user, the default user we added
|
|
users.length.should.equal(1, 'There should only be one user');
|
|
|
|
// user should still have the credentials from the original insert, not the import
|
|
users[0].email.should.equal(testUtils.DataGenerator.Content.users[0].email);
|
|
users[0].password.should.equal(testUtils.DataGenerator.Content.users[0].password);
|
|
// but the name, slug, and bio should have been overridden
|
|
users[0].name.should.equal(exportData.data.users[0].name);
|
|
users[0].slug.should.equal(exportData.data.users[0].slug);
|
|
users[0].bio.should.equal(exportData.data.users[0].bio);
|
|
|
|
// import no longer requires all data to be dropped, and adds posts
|
|
posts.length.should.equal(exportData.data.posts.length + 1, 'Wrong number of posts');
|
|
|
|
// test settings
|
|
settings.length.should.be.above(0, 'Wrong number of settings');
|
|
_.findWhere(settings, {key: 'databaseVersion'}).value.should.equal('003', 'Wrong database version');
|
|
|
|
// activeTheme should NOT have been overridden
|
|
_.findWhere(settings, {key: 'activeTheme'}).value.should.equal('casper', 'Wrong theme');
|
|
|
|
// email address should have been overridden
|
|
exportEmail = _.findWhere(exportData.data.settings, {key: 'email'}).value;
|
|
_.findWhere(settings, {key: 'email'}).value.should.equal(exportEmail, 'Wrong email in settings');
|
|
|
|
// test tags
|
|
tags.length.should.equal(exportData.data.tags.length, 'no new tags');
|
|
|
|
// Ensure imported post retains set timestamp
|
|
// When in sqlite we are returned a unix timestamp number,
|
|
// in MySQL we're returned a date object.
|
|
// We pass the returned post always through the date object
|
|
// to ensure the return is consistant for all DBs.
|
|
assert.equal(new Date(posts[1].created_at).getTime(), timestamp);
|
|
assert.equal(new Date(posts[1].updated_at).getTime(), timestamp);
|
|
assert.equal(new Date(posts[1].published_at).getTime(), timestamp);
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('doesn\'t import invalid post data from 001', function (done) {
|
|
var exportData;
|
|
|
|
|
|
testUtils.loadExportFixture('export-001').then(function (exported) {
|
|
exportData = exported;
|
|
|
|
//change title to 151 characters
|
|
exportData.data.posts[0].title = new Array(152).join('a');
|
|
exportData.data.posts[0].tags = 'Tag';
|
|
return importer('001', exportData);
|
|
}).then(function () {
|
|
(1).should.eql(0, 'Data import should not resolve promise.');
|
|
}, function (error) {
|
|
|
|
error[0].message.should.eql('Value in [posts.title] exceeds maximum length of 150 characters.');
|
|
error[0].type.should.eql('ValidationError');
|
|
|
|
when.all([
|
|
knex('users').select(),
|
|
knex('posts').select(),
|
|
knex('settings').select(),
|
|
knex('tags').select()
|
|
]).then(function (importedData) {
|
|
should.exist(importedData);
|
|
|
|
importedData.length.should.equal(4, 'Did not get data successfully');
|
|
|
|
var users = importedData[0],
|
|
posts = importedData[1],
|
|
settings = importedData[2],
|
|
tags = importedData[3];
|
|
|
|
// we always have 1 user, the default user we added
|
|
users.length.should.equal(1, 'There should only be one user');
|
|
// import no longer requires all data to be dropped, and adds posts
|
|
posts.length.should.equal(exportData.data.posts.length, 'Wrong number of posts');
|
|
|
|
// test settings
|
|
settings.length.should.be.above(0, 'Wrong number of settings');
|
|
_.findWhere(settings, {key: 'databaseVersion'}).value.should.equal('003', 'Wrong database version');
|
|
|
|
// test tags
|
|
tags.length.should.equal(exportData.data.tags.length, 'no new tags');
|
|
|
|
done();
|
|
});
|
|
|
|
}).catch(done);
|
|
});
|
|
|
|
it('doesn\'t import invalid settings data from 001', function (done) {
|
|
var exportData;
|
|
|
|
testUtils.loadExportFixture('export-001').then(function (exported) {
|
|
exportData = exported;
|
|
//change to blank settings key
|
|
exportData.data.settings[3].key = null;
|
|
return importer('001', exportData);
|
|
}).then(function () {
|
|
(1).should.eql(0, 'Data import should not resolve promise.');
|
|
}, function (error) {
|
|
|
|
error[0].message.should.eql('Setting key cannot be empty.');
|
|
error[0].type.should.eql('ValidationError');
|
|
|
|
when.all([
|
|
knex('users').select(),
|
|
knex('posts').select(),
|
|
knex('settings').select(),
|
|
knex('tags').select()
|
|
]).then(function (importedData) {
|
|
should.exist(importedData);
|
|
|
|
importedData.length.should.equal(4, 'Did not get data successfully');
|
|
|
|
var users = importedData[0],
|
|
posts = importedData[1],
|
|
settings = importedData[2],
|
|
tags = importedData[3];
|
|
|
|
// we always have 1 user, the default user we added
|
|
users.length.should.equal(1, 'There should only be one user');
|
|
// import no longer requires all data to be dropped, and adds posts
|
|
posts.length.should.equal(exportData.data.posts.length, 'Wrong number of posts');
|
|
|
|
// test settings
|
|
settings.length.should.be.above(0, 'Wrong number of settings');
|
|
_.findWhere(settings, {key: 'databaseVersion'}).value.should.equal('003', 'Wrong database version');
|
|
|
|
// test tags
|
|
tags.length.should.equal(exportData.data.tags.length, 'no new tags');
|
|
|
|
done();
|
|
});
|
|
|
|
}).catch(done);
|
|
});
|
|
});
|
|
|
|
describe('002', function () {
|
|
should.exist(Importer002);
|
|
|
|
beforeEach(function (done) {
|
|
// migrate to current version
|
|
migration.migrateUpFreshDb().then(function () {
|
|
return testUtils.insertDefaultUser();
|
|
}).then(function () {
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('safely imports data from 002', function (done) {
|
|
var exportData,
|
|
timestamp = 1349928000000;
|
|
|
|
testUtils.loadExportFixture('export-002').then(function (exported) {
|
|
exportData = exported;
|
|
|
|
// Modify timestamp data for testing
|
|
exportData.data.posts[0].created_at = timestamp;
|
|
exportData.data.posts[0].updated_at = timestamp;
|
|
exportData.data.posts[0].published_at = timestamp;
|
|
|
|
return importer('002', exportData);
|
|
}).then(function () {
|
|
// Grab the data from tables
|
|
return when.all([
|
|
knex('users').select(),
|
|
knex('posts').select(),
|
|
knex('settings').select(),
|
|
knex('tags').select()
|
|
]);
|
|
}).then(function (importedData) {
|
|
should.exist(importedData);
|
|
|
|
importedData.length.should.equal(4, 'Did not get data successfully');
|
|
|
|
var users = importedData[0],
|
|
posts = importedData[1],
|
|
settings = importedData[2],
|
|
tags = importedData[3],
|
|
exportEmail;
|
|
|
|
// we always have 1 user, the default user we added
|
|
users.length.should.equal(1, 'There should only be one user');
|
|
|
|
// user should still have the credentials from the original insert, not the import
|
|
users[0].email.should.equal(testUtils.DataGenerator.Content.users[0].email);
|
|
users[0].password.should.equal(testUtils.DataGenerator.Content.users[0].password);
|
|
// but the name, slug, and bio should have been overridden
|
|
users[0].name.should.equal(exportData.data.users[0].name);
|
|
users[0].slug.should.equal(exportData.data.users[0].slug);
|
|
users[0].bio.should.equal(exportData.data.users[0].bio);
|
|
|
|
// import no longer requires all data to be dropped, and adds posts
|
|
posts.length.should.equal(exportData.data.posts.length + 1, 'Wrong number of posts');
|
|
|
|
// test settings
|
|
settings.length.should.be.above(0, 'Wrong number of settings');
|
|
_.findWhere(settings, {key: 'databaseVersion'}).value.should.equal('003', 'Wrong database version');
|
|
|
|
// activeTheme should NOT have been overridden
|
|
_.findWhere(settings, {key: 'activeTheme'}).value.should.equal('casper', 'Wrong theme');
|
|
|
|
// email address should have been overridden
|
|
exportEmail = _.findWhere(exportData.data.settings, {key: 'email'}).value;
|
|
_.findWhere(settings, {key: 'email'}).value.should.equal(exportEmail, 'Wrong email in settings');
|
|
|
|
// test tags
|
|
tags.length.should.equal(exportData.data.tags.length, 'no new tags');
|
|
|
|
// Ensure imported post retains set timestamp
|
|
// When in sqlite we are returned a unix timestamp number,
|
|
// in MySQL we're returned a date object.
|
|
// We pass the returned post always through the date object
|
|
// to ensure the return is consistant for all DBs.
|
|
assert.equal(new Date(posts[1].created_at).getTime(), timestamp);
|
|
assert.equal(new Date(posts[1].updated_at).getTime(), timestamp);
|
|
assert.equal(new Date(posts[1].published_at).getTime(), timestamp);
|
|
|
|
done();
|
|
}).catch(function (error) {
|
|
done(new Error(error));
|
|
});
|
|
});
|
|
|
|
it('doesn\'t import invalid post data from 002', function (done) {
|
|
var exportData;
|
|
|
|
|
|
testUtils.loadExportFixture('export-002').then(function (exported) {
|
|
exportData = exported;
|
|
|
|
//change title to 151 characters
|
|
exportData.data.posts[0].title = new Array(152).join('a');
|
|
exportData.data.posts[0].tags = 'Tag';
|
|
return importer('002', exportData);
|
|
}).then(function () {
|
|
(1).should.eql(0, 'Data import should not resolve promise.');
|
|
}, function (error) {
|
|
|
|
error[0].message.should.eql('Value in [posts.title] exceeds maximum length of 150 characters.');
|
|
error[0].type.should.eql('ValidationError');
|
|
|
|
when.all([
|
|
knex('users').select(),
|
|
knex('posts').select(),
|
|
knex('settings').select(),
|
|
knex('tags').select()
|
|
]).then(function (importedData) {
|
|
should.exist(importedData);
|
|
|
|
importedData.length.should.equal(4, 'Did not get data successfully');
|
|
|
|
var users = importedData[0],
|
|
posts = importedData[1],
|
|
settings = importedData[2],
|
|
tags = importedData[3];
|
|
|
|
// we always have 1 user, the default user we added
|
|
users.length.should.equal(1, 'There should only be one user');
|
|
// import no longer requires all data to be dropped, and adds posts
|
|
posts.length.should.equal(exportData.data.posts.length, 'Wrong number of posts');
|
|
|
|
// test settings
|
|
settings.length.should.be.above(0, 'Wrong number of settings');
|
|
_.findWhere(settings, {key: 'databaseVersion'}).value.should.equal('003', 'Wrong database version');
|
|
|
|
// test tags
|
|
tags.length.should.equal(exportData.data.tags.length, 'no new tags');
|
|
|
|
done();
|
|
});
|
|
|
|
}).catch(done);
|
|
});
|
|
|
|
it('doesn\'t import invalid settings data from 002', function (done) {
|
|
var exportData;
|
|
|
|
testUtils.loadExportFixture('export-002').then(function (exported) {
|
|
exportData = exported;
|
|
//change to blank settings key
|
|
exportData.data.settings[3].key = null;
|
|
return importer('002', exportData);
|
|
}).then(function () {
|
|
(1).should.eql(0, 'Data import should not resolve promise.');
|
|
}, function (error) {
|
|
|
|
error[0].message.should.eql('Setting key cannot be empty.');
|
|
error[0].type.should.eql('ValidationError');
|
|
|
|
when.all([
|
|
knex('users').select(),
|
|
knex('posts').select(),
|
|
knex('settings').select(),
|
|
knex('tags').select()
|
|
]).then(function (importedData) {
|
|
should.exist(importedData);
|
|
|
|
importedData.length.should.equal(4, 'Did not get data successfully');
|
|
|
|
var users = importedData[0],
|
|
posts = importedData[1],
|
|
settings = importedData[2],
|
|
tags = importedData[3];
|
|
|
|
// we always have 1 user, the default user we added
|
|
users.length.should.equal(1, 'There should only be one user');
|
|
// import no longer requires all data to be dropped, and adds posts
|
|
posts.length.should.equal(exportData.data.posts.length, 'Wrong number of posts');
|
|
|
|
// test settings
|
|
settings.length.should.be.above(0, 'Wrong number of settings');
|
|
_.findWhere(settings, {key: 'databaseVersion'}).value.should.equal('003', 'Wrong database version');
|
|
|
|
// test tags
|
|
tags.length.should.equal(exportData.data.tags.length, 'no new tags');
|
|
|
|
done();
|
|
});
|
|
|
|
}).catch(done);
|
|
});
|
|
});
|
|
|
|
describe('003', function () {
|
|
should.exist(Importer003);
|
|
|
|
beforeEach(function (done) {
|
|
// migrate to current version
|
|
migration.migrateUpFreshDb().then(function () {
|
|
return testUtils.insertDefaultUser();
|
|
}).then(function () {
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
|
|
it('safely imports data from 003', function (done) {
|
|
var exportData;
|
|
|
|
testUtils.loadExportFixture('export-003').then(function (exported) {
|
|
exportData = exported;
|
|
return importer('003', exportData);
|
|
}).then(function () {
|
|
// Grab the data from tables
|
|
return when.all([
|
|
knex('apps').select(),
|
|
knex('app_settings').select()
|
|
]);
|
|
}).then(function (importedData) {
|
|
should.exist(importedData);
|
|
|
|
importedData.length.should.equal(2, 'Did not get data successfully');
|
|
|
|
var apps = importedData[0];
|
|
// app_settings = importedData[1];
|
|
|
|
// test apps
|
|
apps.length.should.equal(exportData.data.apps.length, 'imported apps');
|
|
|
|
// test app settings
|
|
// app_settings.length.should.equal(exportData.data.app_settings.length, 'imported app settings');
|
|
|
|
done();
|
|
}).catch(done);
|
|
});
|
|
});
|
|
});
|