2020-04-29 18:44:27 +03:00
|
|
|
const should = require('should');
|
|
|
|
const sinon = require('sinon');
|
|
|
|
const rewire = require('rewire');
|
|
|
|
const Promise = require('bluebird');
|
2020-05-22 21:22:20 +03:00
|
|
|
const errors = require('@tryghost/errors');
|
2020-04-29 18:44:27 +03:00
|
|
|
const db = require('../../../../core/server/data/db');
|
|
|
|
const exporter = rewire('../../../../core/server/data/exporter');
|
|
|
|
const schema = require('../../../../core/server/data/schema');
|
|
|
|
const models = require('../../../../core/server/models');
|
|
|
|
const schemaTables = Object.keys(schema.tables);
|
2016-03-12 21:54:06 +03:00
|
|
|
|
|
|
|
describe('Exporter', function () {
|
2020-04-29 18:44:27 +03:00
|
|
|
let tablesStub;
|
|
|
|
let queryMock;
|
|
|
|
let knexMock;
|
2016-03-12 21:54:06 +03:00
|
|
|
|
2017-03-08 13:26:57 +03:00
|
|
|
before(function () {
|
|
|
|
models.init();
|
|
|
|
});
|
|
|
|
|
2016-03-12 21:54:06 +03:00
|
|
|
afterEach(function () {
|
2019-01-21 19:53:44 +03:00
|
|
|
sinon.restore();
|
2016-03-12 21:54:06 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('doExport', function () {
|
|
|
|
beforeEach(function () {
|
2019-01-21 19:53:44 +03:00
|
|
|
tablesStub = sinon.stub(schema.commands, 'getTables').returns(schemaTables);
|
2016-03-12 21:54:06 +03:00
|
|
|
|
|
|
|
queryMock = {
|
2019-01-21 19:53:44 +03:00
|
|
|
whereNot: sinon.stub(),
|
|
|
|
select: sinon.stub()
|
2016-03-12 21:54:06 +03:00
|
|
|
};
|
|
|
|
|
2019-01-21 19:53:44 +03:00
|
|
|
knexMock = sinon.stub().returns(queryMock);
|
2016-03-12 21:54:06 +03:00
|
|
|
|
2019-01-21 19:53:44 +03:00
|
|
|
sinon.stub(db, 'knex').get(function () {
|
2017-11-28 20:19:23 +03:00
|
|
|
return knexMock;
|
2017-03-08 13:26:57 +03:00
|
|
|
});
|
2016-03-12 21:54:06 +03:00
|
|
|
});
|
|
|
|
|
2018-07-30 18:21:52 +03:00
|
|
|
it('should try to export all the correct tables (without excluded)', function (done) {
|
2016-03-12 21:54:06 +03:00
|
|
|
exporter.doExport().then(function (exportData) {
|
2021-03-25 09:27:49 +03:00
|
|
|
// NOTE: 9 default tables
|
|
|
|
const expectedCallCount = 9;
|
2016-03-12 21:54:06 +03:00
|
|
|
|
|
|
|
should.exist(exportData);
|
|
|
|
|
2021-03-25 07:16:18 +03:00
|
|
|
exportData.meta.version.should.match(/\d+.\d+.\d+/gi);
|
2017-01-26 15:12:00 +03:00
|
|
|
|
2016-03-14 19:52:22 +03:00
|
|
|
tablesStub.calledOnce.should.be.true();
|
2017-11-28 20:19:23 +03:00
|
|
|
db.knex.called.should.be.true();
|
2016-03-14 19:52:22 +03:00
|
|
|
|
|
|
|
knexMock.callCount.should.eql(expectedCallCount);
|
|
|
|
queryMock.select.callCount.should.have.eql(expectedCallCount);
|
|
|
|
|
|
|
|
knexMock.getCall(0).args[0].should.eql('posts');
|
2019-09-16 11:45:55 +03:00
|
|
|
knexMock.getCall(1).args[0].should.eql('posts_meta');
|
|
|
|
knexMock.getCall(2).args[0].should.eql('users');
|
|
|
|
knexMock.getCall(3).args[0].should.eql('posts_authors');
|
|
|
|
knexMock.getCall(4).args[0].should.eql('roles');
|
|
|
|
knexMock.getCall(5).args[0].should.eql('roles_users');
|
2021-03-25 09:27:49 +03:00
|
|
|
knexMock.getCall(6).args[0].should.eql('settings');
|
|
|
|
knexMock.getCall(7).args[0].should.eql('tags');
|
|
|
|
knexMock.getCall(8).args[0].should.eql('posts_tags');
|
2016-03-14 19:52:22 +03:00
|
|
|
|
2016-03-12 21:54:06 +03:00
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
|
|
|
|
2021-03-25 07:10:22 +03:00
|
|
|
it('should try to export all the correct tables with extra tables', function (done) {
|
|
|
|
const include = ['mobiledoc_revisions', 'email_recipients'];
|
2021-03-25 09:27:49 +03:00
|
|
|
|
2021-03-25 07:10:22 +03:00
|
|
|
exporter.doExport({include}).then(function (exportData) {
|
2021-03-25 09:27:49 +03:00
|
|
|
// NOTE: 9 default tables + 2 includes
|
|
|
|
const expectedCallCount = 11;
|
2018-07-30 18:21:52 +03:00
|
|
|
|
|
|
|
should.exist(exportData);
|
|
|
|
|
2021-03-25 07:16:18 +03:00
|
|
|
exportData.meta.version.should.match(/\d+.\d+.\d+/gi);
|
2018-07-30 18:21:52 +03:00
|
|
|
|
|
|
|
tablesStub.calledOnce.should.be.true();
|
|
|
|
db.knex.called.should.be.true();
|
|
|
|
queryMock.select.called.should.be.true();
|
|
|
|
|
|
|
|
knexMock.callCount.should.eql(expectedCallCount);
|
|
|
|
queryMock.select.callCount.should.have.eql(expectedCallCount);
|
|
|
|
|
|
|
|
knexMock.getCall(0).args[0].should.eql('posts');
|
2019-09-16 11:45:55 +03:00
|
|
|
knexMock.getCall(1).args[0].should.eql('posts_meta');
|
|
|
|
knexMock.getCall(2).args[0].should.eql('users');
|
|
|
|
knexMock.getCall(3).args[0].should.eql('posts_authors');
|
|
|
|
knexMock.getCall(4).args[0].should.eql('roles');
|
|
|
|
knexMock.getCall(5).args[0].should.eql('roles_users');
|
2021-03-25 09:27:49 +03:00
|
|
|
knexMock.getCall(6).args[0].should.eql('settings');
|
|
|
|
knexMock.getCall(7).args[0].should.eql('tags');
|
|
|
|
knexMock.getCall(8).args[0].should.eql('posts_tags');
|
|
|
|
knexMock.getCall(9).args[0].should.eql('mobiledoc_revisions');
|
|
|
|
knexMock.getCall(10).args[0].should.eql('email_recipients');
|
2018-07-30 18:21:52 +03:00
|
|
|
|
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
|
|
|
|
2016-03-12 21:54:06 +03:00
|
|
|
it('should catch and log any errors', function (done) {
|
|
|
|
// Setup for failure
|
2017-11-28 20:19:23 +03:00
|
|
|
queryMock.select.returns(Promise.reject({}));
|
2016-03-12 21:54:06 +03:00
|
|
|
|
|
|
|
// Execute
|
2016-10-06 15:27:35 +03:00
|
|
|
exporter.doExport()
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('expected error for export'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
2020-05-22 21:22:20 +03:00
|
|
|
(err instanceof errors.DataExportError).should.eql(true);
|
2016-10-06 15:27:35 +03:00
|
|
|
done();
|
|
|
|
});
|
2016-03-12 21:54:06 +03:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('exportFileName', function () {
|
|
|
|
it('should return a correctly structured filename', function (done) {
|
2020-04-29 18:44:27 +03:00
|
|
|
const settingsStub = sinon.stub(models.Settings, 'findOne').returns(
|
2017-03-08 13:26:57 +03:00
|
|
|
new Promise.resolve({
|
|
|
|
get: function () {
|
|
|
|
return 'testblog';
|
|
|
|
}
|
|
|
|
})
|
2016-03-12 21:54:06 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
exporter.fileName().then(function (result) {
|
|
|
|
should.exist(result);
|
2016-03-14 19:52:22 +03:00
|
|
|
settingsStub.calledOnce.should.be.true();
|
2019-03-13 23:06:05 +03:00
|
|
|
result.should.match(/^testblog\.ghost\.[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}\.json$/);
|
2016-03-12 21:54:06 +03:00
|
|
|
|
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return a correctly structured filename if settings is empty', function (done) {
|
2020-04-29 18:44:27 +03:00
|
|
|
const settingsStub = sinon.stub(models.Settings, 'findOne').returns(
|
2016-03-12 21:54:06 +03:00
|
|
|
new Promise.resolve()
|
|
|
|
);
|
|
|
|
|
|
|
|
exporter.fileName().then(function (result) {
|
|
|
|
should.exist(result);
|
2016-03-14 19:52:22 +03:00
|
|
|
settingsStub.calledOnce.should.be.true();
|
2019-03-13 23:06:05 +03:00
|
|
|
result.should.match(/^ghost\.[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}\.json$/);
|
2016-03-12 21:54:06 +03:00
|
|
|
|
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should return a correctly structured filename if settings errors', function (done) {
|
2020-04-29 18:44:27 +03:00
|
|
|
const settingsStub = sinon.stub(models.Settings, 'findOne').returns(
|
2016-03-12 21:54:06 +03:00
|
|
|
new Promise.reject()
|
|
|
|
);
|
|
|
|
|
|
|
|
exporter.fileName().then(function (result) {
|
|
|
|
should.exist(result);
|
2016-03-14 19:52:22 +03:00
|
|
|
settingsStub.calledOnce.should.be.true();
|
2019-03-13 23:06:05 +03:00
|
|
|
result.should.match(/^ghost\.[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{2}\.json$/);
|
2016-03-12 21:54:06 +03:00
|
|
|
|
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|