mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-01 13:54:35 +03:00
🎨 Backup redirects.json file before overriding (#9051)
refs #9028 - if you upload a redirects file and a redirects file exists already, we backup this file to `data/redirects-YYYY-MM-DD-HH-mm-ss.json` - decrease chance of random test failures by not comparing date format with seconds
This commit is contained in:
parent
472858f262
commit
22017b8ede
@ -1,7 +1,8 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const fs = require('fs'),
|
const fs = require('fs-extra'),
|
||||||
Promise = require('bluebird'),
|
Promise = require('bluebird'),
|
||||||
|
moment = require('moment'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
@ -51,20 +52,30 @@ redirectsAPI = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
upload: function upload(options) {
|
upload: function upload(options) {
|
||||||
let redirectsPath = path.join(config.getContentPath('data'), 'redirects.json');
|
let redirectsPath = path.join(config.getContentPath('data'), 'redirects.json'),
|
||||||
|
backupRedirectsPath = path.join(config.getContentPath('data'), `redirects-${moment().format('YYYY-MM-DD-HH-mm-ss')}.json`);
|
||||||
|
|
||||||
return apiUtils.handlePermissions('redirects', 'upload')(options)
|
return apiUtils.handlePermissions('redirects', 'upload')(options)
|
||||||
.then(function () {
|
.then(function backupOldRedirectsFile() {
|
||||||
return Promise.promisify(fs.unlink)(redirectsPath)
|
return Promise.promisify(fs.pathExists)(redirectsPath)
|
||||||
.catch(function handleError(err) {
|
.then(function (exists) {
|
||||||
// CASE: ignore file not found
|
if (!exists) {
|
||||||
if (err.code === 'ENOENT') {
|
return null;
|
||||||
return Promise.resolve();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw err;
|
return Promise.promisify(fs.pathExists)(backupRedirectsPath)
|
||||||
|
.then(function (exists) {
|
||||||
|
if (!exists) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.promisify(fs.unlink)(backupRedirectsPath);
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return Promise.promisify(fs.move)(redirectsPath, backupRedirectsPath);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.finally(function overrideFile() {
|
.then(function overrideFile() {
|
||||||
return _private.readRedirectsFile(options.path)
|
return _private.readRedirectsFile(options.path)
|
||||||
.then(function (content) {
|
.then(function (content) {
|
||||||
globalUtils.validateRedirects(content);
|
globalUtils.validateRedirects(content);
|
||||||
|
@ -87,8 +87,8 @@ describe('Redirects API', function () {
|
|||||||
|
|
||||||
describe('Upload', function () {
|
describe('Upload', function () {
|
||||||
describe('Ensure re-registering redirects works', function () {
|
describe('Ensure re-registering redirects works', function () {
|
||||||
var startGhost = function () {
|
var startGhost = function (options) {
|
||||||
return ghost().then(function (_ghostServer) {
|
return ghost(options).then(function (_ghostServer) {
|
||||||
ghostServer = _ghostServer;
|
ghostServer = _ghostServer;
|
||||||
return ghostServer.start();
|
return ghostServer.start();
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
@ -108,6 +108,50 @@ describe('Redirects API', function () {
|
|||||||
|
|
||||||
afterEach(stopGhost);
|
afterEach(stopGhost);
|
||||||
|
|
||||||
|
it('no redirects file exists', function (done) {
|
||||||
|
return startGhost({redirectsFile: false})
|
||||||
|
.then(function () {
|
||||||
|
return new Promise(function (resolve) {
|
||||||
|
setTimeout(resolve, 100);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return request
|
||||||
|
.get('/my-old-blog-post/')
|
||||||
|
.expect(404);
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
// Provide a redirects file in the root directory of the content test folder
|
||||||
|
fs.writeFileSync(path.join(config.get('paths:contentPath'), 'redirects-init.json'), JSON.stringify([{from: 'k', to: 'l'}]));
|
||||||
|
|
||||||
|
return new Promise(function (resolve) {
|
||||||
|
setTimeout(resolve, 100);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return request
|
||||||
|
.post(testUtils.API.getApiQuery('redirects/json/?client_id=ghost-admin&client_secret=not_available'))
|
||||||
|
.set('Authorization', 'Bearer ' + accesstoken)
|
||||||
|
.set('Origin', testUtils.API.getURL())
|
||||||
|
.attach('redirects', path.join(config.get('paths:contentPath'), 'redirects-init.json'))
|
||||||
|
.expect('Content-Type', /application\/json/)
|
||||||
|
.expect(200);
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return request
|
||||||
|
.get('/k/')
|
||||||
|
.expect(302);
|
||||||
|
})
|
||||||
|
.then(function (response) {
|
||||||
|
response.headers.location.should.eql('/l');
|
||||||
|
|
||||||
|
var dataFiles = fs.readdirSync(config.getContentPath('data'));
|
||||||
|
dataFiles.join(',').match(/(redirects)/g).length.should.eql(1);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('override', function (done) {
|
it('override', function (done) {
|
||||||
return startGhost()
|
return startGhost()
|
||||||
.then(function () {
|
.then(function () {
|
||||||
@ -162,6 +206,30 @@ describe('Redirects API', function () {
|
|||||||
})
|
})
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
response.headers.location.should.eql('/d');
|
response.headers.location.should.eql('/d');
|
||||||
|
|
||||||
|
var dataFiles = fs.readdirSync(config.getContentPath('data'));
|
||||||
|
dataFiles.join(',').match(/(redirects)/g).length.should.eql(2);
|
||||||
|
|
||||||
|
// Provide another redirects file in the root directory of the content test folder
|
||||||
|
fs.writeFileSync(path.join(config.get('paths:contentPath'), 'redirects-something.json'), JSON.stringify([{from: 'e', to: 'b'}]));
|
||||||
|
|
||||||
|
return new Promise(function (resolve) {
|
||||||
|
setTimeout(resolve, 1000 * 2);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
// Override redirects file again and ensure the backup file works twice
|
||||||
|
return request
|
||||||
|
.post(testUtils.API.getApiQuery('redirects/json/?client_id=ghost-admin&client_secret=not_available'))
|
||||||
|
.set('Authorization', 'Bearer ' + accesstoken)
|
||||||
|
.set('Origin', testUtils.API.getURL())
|
||||||
|
.attach('redirects', path.join(config.get('paths:contentPath'), 'redirects-something.json'))
|
||||||
|
.expect('Content-Type', /application\/json/)
|
||||||
|
.expect(200);
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
var dataFiles = fs.readdirSync(config.getContentPath('data'));
|
||||||
|
dataFiles.join(',').match(/(redirects)/g).length.should.eql(3);
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(done);
|
.catch(done);
|
||||||
|
@ -816,7 +816,9 @@ unmockNotExistingModule = function unmockNotExistingModule() {
|
|||||||
* 1. sephiroth init db
|
* 1. sephiroth init db
|
||||||
* 2. start ghost
|
* 2. start ghost
|
||||||
*/
|
*/
|
||||||
startGhost = function startGhost() {
|
startGhost = function startGhost(options) {
|
||||||
|
options = options || {redirectsFile: true};
|
||||||
|
|
||||||
var contentFolderForTests = path.join(os.tmpdir(), uuid.v1(), 'ghost-test');
|
var contentFolderForTests = path.join(os.tmpdir(), uuid.v1(), 'ghost-test');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -835,7 +837,10 @@ startGhost = function startGhost() {
|
|||||||
|
|
||||||
// Copy all themes into the new test content folder. Default active theme is always casper. If you want to use a different theme, you have to set the active theme (e.g. stub)
|
// Copy all themes into the new test content folder. Default active theme is always casper. If you want to use a different theme, you have to set the active theme (e.g. stub)
|
||||||
fs.copySync(path.join(__dirname, 'fixtures', 'themes'), path.join(contentFolderForTests, 'themes'));
|
fs.copySync(path.join(__dirname, 'fixtures', 'themes'), path.join(contentFolderForTests, 'themes'));
|
||||||
fs.copySync(path.join(__dirname, 'fixtures', 'data'), path.join(contentFolderForTests, 'data'));
|
|
||||||
|
if (options.redirectsFile) {
|
||||||
|
fs.copySync(path.join(__dirname, 'fixtures', 'data', 'redirects.json'), path.join(contentFolderForTests, 'data', 'redirects.json'));
|
||||||
|
}
|
||||||
|
|
||||||
return knexMigrator.reset()
|
return knexMigrator.reset()
|
||||||
.then(function initialiseDatabase() {
|
.then(function initialiseDatabase() {
|
||||||
|
Loading…
Reference in New Issue
Block a user