Ghost/test/regression/api/v2/admin/db.test.js
Hannah Wolfe f08a55c21f
Renamed tests to .test.js & updated commands
refs: https://github.com/TryGhost/Team/issues/856
refs: https://github.com/TryGhost/Team/issues/756

- The .test.js extension is better than _spec.js as it's more obvious that it's an extension
- It also meaans we can use the --extension parameter in mocha, which should result in a better default behaviour for `yarn test`
- It also highlights that some of our tests were named incorrectly and were not (and still will not be) run (see https://github.com/TryGhost/Team/issues/856)
- Note: even with this change, `yarn test` is throwing errors, I believe because of this issue https://github.com/TryGhost/Team/issues/756
2021-07-06 20:45:01 +01:00

166 lines
6.0 KiB
JavaScript

const path = require('path');
const _ = require('lodash');
const os = require('os');
const fs = require('fs-extra');
const uuid = require('uuid');
const should = require('should');
const supertest = require('supertest');
const sinon = require('sinon');
const config = require('../../../../../core/shared/config');
const events = require('../../../../../core/server/lib/common/events');
const testUtils = require('../../../../utils');
const localUtils = require('./utils');
let ghost = testUtils.startGhost;
let request;
let eventsTriggered;
describe('DB API', function () {
let backupKey;
let schedulerKey;
before(function () {
return ghost()
.then(() => {
request = supertest.agent(config.get('url'));
})
.then(() => {
return localUtils.doAuth(request);
})
.then(() => {
backupKey = _.find(testUtils.getExistingData().apiKeys, {integration: {slug: 'ghost-backup'}});
schedulerKey = _.find(testUtils.getExistingData().apiKeys, {integration: {slug: 'ghost-scheduler'}});
});
});
beforeEach(function () {
eventsTriggered = {};
sinon.stub(events, 'emit').callsFake((eventName, eventObj) => {
if (!eventsTriggered[eventName]) {
eventsTriggered[eventName] = [];
}
eventsTriggered[eventName].push(eventObj);
});
});
afterEach(function () {
sinon.restore();
});
it('can export the database with more tables', function () {
return request.get(localUtils.API.getApiQuery('db/?include=mobiledoc_revisions'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect(200)
.then((res) => {
const jsonResponse = res.body;
should.exist(jsonResponse.db);
jsonResponse.db.should.have.length(1);
// NOTE: 9 default tables + 1 from include parameters
Object.keys(jsonResponse.db[0].data).length.should.eql(10);
});
});
it('can export & import', function () {
const exportFolder = path.join(os.tmpdir(), uuid.v4());
const exportPath = path.join(exportFolder, 'export.json');
return request.put(localUtils.API.getApiQuery('settings/'))
.set('Origin', config.get('url'))
.send({
settings: [
{
key: 'is_private',
value: true
}
]
})
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.then(() => {
return request.get(localUtils.API.getApiQuery('db/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect(200);
})
.then((res) => {
const jsonResponse = res.body;
should.exist(jsonResponse.db);
fs.ensureDirSync(exportFolder);
fs.writeJSONSync(exportPath, jsonResponse);
return request.post(localUtils.API.getApiQuery('db/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.attach('importfile', exportPath)
.expect(200);
})
.then((res) => {
res.body.problems.length.should.eql(3);
fs.removeSync(exportFolder);
});
});
it('import should fail without file', function () {
return request.post(localUtils.API.getApiQuery('db/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(422);
});
it('import should fail with unsupported file', function () {
return request.post(localUtils.API.getApiQuery('db/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.attach('importfile', path.join(__dirname, '/../../../../utils/fixtures/csv/single-column-with-header.csv'))
.expect(415);
});
it('export can be triggered by backup integration', function () {
const backupQuery = `?filename=test`;
const fsStub = sinon.stub(fs, 'writeFile').resolves();
return request.post(localUtils.API.getApiQuery(`db/backup${backupQuery}`))
.set('Authorization', `Ghost ${localUtils.getValidAdminToken('/v2/admin/', backupKey)}`)
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect(200)
.then((res) => {
res.body.should.be.Object();
res.body.db[0].filename.should.match(/test\.json/);
fsStub.calledOnce.should.eql(true);
});
});
it('export can not be triggered by integration other than backup', function () {
const fsStub = sinon.stub(fs, 'writeFile').resolves();
return request.post(localUtils.API.getApiQuery(`db/backup`))
.set('Authorization', `Ghost ${localUtils.getValidAdminToken('/v2/admin/', schedulerKey)}`)
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect(403)
.then((res) => {
should.exist(res.body.errors);
res.body.errors[0].type.should.eql('NoPermissionError');
fsStub.called.should.eql(false);
});
});
it('export can be triggered by Admin authentication', function () {
const fsStub = sinon.stub(fs, 'writeFile').resolves();
return request.post(localUtils.API.getApiQuery(`db/backup`))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect(200);
});
});