mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
parent
8b54cfea81
commit
b899a6fec8
11 changed files with 583 additions and 7 deletions
|
@ -29,5 +29,9 @@ module.exports = {
|
|||
|
||||
get posts() {
|
||||
return shared.pipeline(require('./posts'), localUtils);
|
||||
},
|
||||
|
||||
get settings() {
|
||||
return shared.pipeline(require('./settings'), localUtils);
|
||||
}
|
||||
};
|
||||
|
|
177
core/server/api/v2/settings.js
Normal file
177
core/server/api/v2/settings.js
Normal file
|
@ -0,0 +1,177 @@
|
|||
const Promise = require('bluebird');
|
||||
const _ = require('lodash');
|
||||
const moment = require('moment-timezone');
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const config = require('../../config');
|
||||
const models = require('../../models');
|
||||
const urlService = require('../../services/url');
|
||||
const common = require('../../lib/common');
|
||||
const settingsCache = require('../../services/settings/cache');
|
||||
|
||||
module.exports = {
|
||||
docName: 'settings',
|
||||
|
||||
browse: {
|
||||
options: ['type'],
|
||||
permissions: true,
|
||||
query(frame) {
|
||||
let settings = settingsCache.getAll();
|
||||
|
||||
// CASE: no context passed (functional call)
|
||||
if (!frame.options.context) {
|
||||
return Promise.resolve(settings.filter((setting) => {
|
||||
return setting.type === 'blog';
|
||||
}));
|
||||
}
|
||||
|
||||
// CASE: omit core settings unless internal request
|
||||
if (!frame.options.context.internal) {
|
||||
settings = _.filter(settings, (setting) => {
|
||||
return setting.type !== 'core' && setting.key !== 'permalinks';
|
||||
});
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
},
|
||||
|
||||
read: {
|
||||
options: ['key'],
|
||||
validation: {
|
||||
options: {
|
||||
key: {
|
||||
required: true
|
||||
}
|
||||
}
|
||||
},
|
||||
permissions: {
|
||||
before(frame) {
|
||||
let setting = settingsCache.get(frame.options.key, {resolve: false});
|
||||
|
||||
if (setting.type === 'core' && !(frame.options.context && frame.options.context.internal)) {
|
||||
return Promise.reject(new common.errors.NoPermissionError({
|
||||
message: common.i18n.t('errors.api.settings.accessCoreSettingFromExtReq')
|
||||
}));
|
||||
}
|
||||
},
|
||||
identifier(frame) {
|
||||
return frame.options.key;
|
||||
}
|
||||
},
|
||||
query(frame) {
|
||||
let setting = settingsCache.get(frame.options.key, {resolve: false});
|
||||
|
||||
return {
|
||||
[frame.options.key]: setting
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
edit: {
|
||||
headers: {
|
||||
cacheInvalidate: true
|
||||
},
|
||||
permissions: {
|
||||
before(frame) {
|
||||
const errors = [];
|
||||
|
||||
frame.data.settings.map((setting) => {
|
||||
if (setting.type === 'core' && !(frame.options.context && frame.options.context.internal)) {
|
||||
errors.push(new common.errors.NoPermissionError({
|
||||
message: common.i18n.t('errors.api.settings.accessCoreSettingFromExtReq')
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
if (errors.length) {
|
||||
return Promise.reject(errors[0]);
|
||||
}
|
||||
}
|
||||
},
|
||||
query(frame) {
|
||||
let type = frame.data.settings.find((setting) => {
|
||||
return setting.key === 'type';
|
||||
});
|
||||
|
||||
if (_.isObject(type)) {
|
||||
type = type.value;
|
||||
}
|
||||
|
||||
frame.data.settings = _.reject(frame.data.settings, (setting) => {
|
||||
return setting.key === 'type';
|
||||
});
|
||||
|
||||
return models.Settings.edit(frame.data.settings, frame.options);
|
||||
}
|
||||
},
|
||||
|
||||
upload: {
|
||||
headers: {
|
||||
cacheInvalidate: true
|
||||
},
|
||||
permissions: {
|
||||
method: 'edit'
|
||||
},
|
||||
query(frame) {
|
||||
const backupRoutesPath = path.join(config.getContentPath('settings'), `routes-${moment().format('YYYY-MM-DD-HH-mm-ss')}.yaml`);
|
||||
|
||||
return fs.copy(`${config.getContentPath('settings')}/routes.yaml`, backupRoutesPath)
|
||||
.then(() => {
|
||||
return fs.copy(frame.file.path, `${config.getContentPath('settings')}/routes.yaml`);
|
||||
})
|
||||
.then(() => {
|
||||
urlService.resetGenerators({releaseResourcesOnly: true});
|
||||
})
|
||||
.then(() => {
|
||||
const siteApp = require('../../web/site/app');
|
||||
|
||||
try {
|
||||
return siteApp.reload();
|
||||
} catch (err) {
|
||||
// bring back backup, otherwise your Ghost blog is broken
|
||||
return fs.copy(backupRoutesPath, `${config.getContentPath('settings')}/routes.yaml`)
|
||||
.then(() => {
|
||||
return siteApp.reload();
|
||||
})
|
||||
.then(() => {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
download: {
|
||||
headers: {
|
||||
disposition: {
|
||||
type: 'yaml',
|
||||
value: 'Attachment; filename="routes.yaml"'
|
||||
}
|
||||
},
|
||||
response: {
|
||||
format: 'plain'
|
||||
},
|
||||
permissions: {
|
||||
method: 'browse'
|
||||
},
|
||||
query() {
|
||||
const routesPath = path.join(config.getContentPath('settings'), 'routes.yaml');
|
||||
|
||||
return fs.readFile(routesPath, 'utf-8')
|
||||
.catch((err) => {
|
||||
if (err.code === 'ENOENT') {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
if (common.errors.utils.isIgnitionError(err)) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
throw new common.errors.NotFoundError({
|
||||
err: err
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
|
@ -11,8 +11,8 @@ const nonePublicAuth = (apiConfig, frame) => {
|
|||
|
||||
let permissionIdentifier = frame.options.id;
|
||||
|
||||
if (apiConfig.permissionIdentifier) {
|
||||
permissionIdentifier = apiConfig.permissionIdentifier(frame);
|
||||
if (apiConfig.identifier) {
|
||||
permissionIdentifier = apiConfig.identifier(frame);
|
||||
}
|
||||
|
||||
const unsafeAttrObject = apiConfig.unsafeAttrs && _.has(frame, `data.[${apiConfig.docName}][0]`) ? _.pick(frame.data[apiConfig.docName][0], apiConfig.unsafeAttrs) : {};
|
||||
|
|
|
@ -5,5 +5,9 @@ module.exports = {
|
|||
|
||||
get posts() {
|
||||
return require('./posts');
|
||||
},
|
||||
|
||||
get settings() {
|
||||
return require('./settings');
|
||||
}
|
||||
};
|
||||
|
|
17
core/server/api/v2/utils/serializers/input/settings.js
Normal file
17
core/server/api/v2/utils/serializers/input/settings.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
const _ = require('lodash');
|
||||
|
||||
module.exports = {
|
||||
edit(apiConfig, frame) {
|
||||
// CASE: allow shorthand syntax where a single key and value are passed to edit instead of object and options
|
||||
if (_.isString(frame.data)) {
|
||||
frame.data = {settings: [{key: frame.data, value: frame.options}]};
|
||||
}
|
||||
|
||||
// prepare data
|
||||
frame.data.settings.forEach((setting) => {
|
||||
if (!_.isString(setting.value)) {
|
||||
setting.value = JSON.stringify(setting.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
|
@ -17,5 +17,9 @@ module.exports = {
|
|||
|
||||
get posts() {
|
||||
return require('./posts');
|
||||
},
|
||||
|
||||
get settings() {
|
||||
return require('./settings');
|
||||
}
|
||||
};
|
||||
|
|
51
core/server/api/v2/utils/serializers/output/settings.js
Normal file
51
core/server/api/v2/utils/serializers/output/settings.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
const _ = require('lodash');
|
||||
const _private = {};
|
||||
|
||||
/**
|
||||
* ### Settings Filter
|
||||
* Filters an object based on a given filter object
|
||||
* @private
|
||||
* @param {Object} settings
|
||||
* @param {String} filter
|
||||
* @returns {*}
|
||||
*/
|
||||
_private.settingsFilter = (settings, filter) => {
|
||||
return _.fromPairs(_.toPairs(settings).filter((setting) => {
|
||||
if (filter) {
|
||||
return _.some(filter.split(','), (f) => {
|
||||
return setting[1].type === f;
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
browse(models, apiConfig, frame) {
|
||||
let filteredSettings = _.values(_private.settingsFilter(models, frame.options.type));
|
||||
|
||||
frame.response = {
|
||||
settings: filteredSettings,
|
||||
meta: {}
|
||||
};
|
||||
|
||||
if (frame.options.type) {
|
||||
frame.response.meta.filters = {
|
||||
type: frame.options.type
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
read() {
|
||||
this.browse(...arguments);
|
||||
},
|
||||
|
||||
edit(models, apiConfig, frame) {
|
||||
const settingsKeyedJSON = _.keyBy(_.invokeMap(models, 'toJSON'), 'key');
|
||||
this.browse(settingsKeyedJSON, apiConfig, frame);
|
||||
},
|
||||
|
||||
download(bytes, apiConfig, frame) {
|
||||
frame.response = bytes;
|
||||
}
|
||||
};
|
|
@ -1,5 +1,9 @@
|
|||
module.exports = {
|
||||
get posts() {
|
||||
return require('./posts');
|
||||
},
|
||||
|
||||
get settings() {
|
||||
return require('./settings');
|
||||
}
|
||||
};
|
||||
|
|
54
core/server/api/v2/utils/validators/input/settings.js
Normal file
54
core/server/api/v2/utils/validators/input/settings.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
const Promise = require('bluebird');
|
||||
const _ = require('lodash');
|
||||
const common = require('../../../../../lib/common');
|
||||
const settingsCache = require('../../../../../services/settings/cache');
|
||||
|
||||
module.exports = {
|
||||
read(apiConfig, frame) {
|
||||
let setting = settingsCache.get(frame.options.key, {resolve: false});
|
||||
|
||||
if (!setting) {
|
||||
return Promise.reject(new common.errors.NotFoundError({
|
||||
message: common.i18n.t('errors.api.settings.problemFindingSetting', {key: frame.options.key})
|
||||
}));
|
||||
}
|
||||
|
||||
// @NOTE: was removed (https://github.com/TryGhost/Ghost/commit/8bb7088ba026efd4a1c9cf7d6f1a5e9b4fa82575)
|
||||
if (setting.key === 'permalinks') {
|
||||
return Promise.reject(new common.errors.NotFoundError({
|
||||
message: common.i18n.t('errors.errors.resourceNotFound')
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
edit(apiConfig, frame) {
|
||||
const errors = [];
|
||||
|
||||
_.each(frame.data.settings, (setting) => {
|
||||
const settingFromCache = settingsCache.get(setting.key, {resolve: false});
|
||||
|
||||
if (!settingFromCache) {
|
||||
errors.push(new common.errors.NotFoundError({
|
||||
message: common.i18n.t('errors.api.settings.problemFindingSetting', {key: setting.key})
|
||||
}));
|
||||
} else if (settingFromCache.key === 'active_theme') {
|
||||
// @NOTE: active theme has to be changed via theme endpoints
|
||||
errors.push(
|
||||
new common.errors.BadRequestError({
|
||||
message: common.i18n.t('errors.api.settings.activeThemeSetViaAPI.error'),
|
||||
help: common.i18n.t('errors.api.settings.activeThemeSetViaAPI.help')
|
||||
})
|
||||
);
|
||||
} else if (settingFromCache.key === 'permalinks') {
|
||||
// @NOTE: was removed (https://github.com/TryGhost/Ghost/commit/8bb7088ba026efd4a1c9cf7d6f1a5e9b4fa82575)
|
||||
errors.push(new common.errors.NotFoundError({
|
||||
message: common.i18n.t('errors.api.settings.problemFindingSetting', {key: setting.key})
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
if (errors.length) {
|
||||
return Promise.reject(errors[0]);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -40,17 +40,17 @@ module.exports = function apiRoutes() {
|
|||
], api.http(api.schedules.publishPost));
|
||||
|
||||
// ## Settings
|
||||
router.get('/settings/routes/yaml', mw.authAdminAPI, api.http(api.settings.download));
|
||||
router.get('/settings/routes/yaml', mw.authAdminAPI, apiv2.http(apiv2.settings.download));
|
||||
router.post('/settings/routes/yaml',
|
||||
mw.authAdminAPI,
|
||||
upload.single('routes'),
|
||||
shared.middlewares.validation.upload({type: 'routes'}),
|
||||
api.http(api.settings.upload)
|
||||
apiv2.http(apiv2.settings.upload)
|
||||
);
|
||||
|
||||
router.get('/settings', mw.authAdminAPI, api.http(api.settings.browse));
|
||||
router.get('/settings/:key', mw.authAdminAPI, api.http(api.settings.read));
|
||||
router.put('/settings', mw.authAdminAPI, api.http(api.settings.edit));
|
||||
router.get('/settings', mw.authAdminAPI, apiv2.http(apiv2.settings.browse));
|
||||
router.get('/settings/:key', mw.authAdminAPI, apiv2.http(apiv2.settings.read));
|
||||
router.put('/settings', mw.authAdminAPI, apiv2.http(apiv2.settings.edit));
|
||||
|
||||
// ## Users
|
||||
router.get('/users', mw.authAdminAPI, api.http(api.users.browse));
|
||||
|
|
261
core/test/functional/api/v2/admin/settings_spec.js
Normal file
261
core/test/functional/api/v2/admin/settings_spec.js
Normal file
|
@ -0,0 +1,261 @@
|
|||
const should = require('should');
|
||||
const _ = require('lodash');
|
||||
const supertest = require('supertest');
|
||||
const os = require('os');
|
||||
const fs = require('fs-extra');
|
||||
const config = require('../../../../../../core/server/config');
|
||||
const testUtils = require('../../../../utils');
|
||||
const localUtils = require('./utils');
|
||||
const ghost = testUtils.startGhost;
|
||||
let request;
|
||||
|
||||
describe('Settings API V2', function () {
|
||||
let ghostServer;
|
||||
|
||||
before(function () {
|
||||
return ghost()
|
||||
.then(function (_ghostServer) {
|
||||
ghostServer = _ghostServer;
|
||||
request = supertest.agent(config.get('url'));
|
||||
})
|
||||
.then(function () {
|
||||
return localUtils.doAuth(request);
|
||||
});
|
||||
});
|
||||
|
||||
after(function () {
|
||||
return ghostServer.stop();
|
||||
});
|
||||
|
||||
it('browse', function (done) {
|
||||
request.get(localUtils.API.getApiQuery('settings/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
should.not.exist(res.headers['x-cache-invalidate']);
|
||||
var jsonResponse = res.body;
|
||||
should.exist(jsonResponse);
|
||||
|
||||
testUtils.API.checkResponse(jsonResponse, 'settings');
|
||||
|
||||
JSON.parse(_.find(jsonResponse.settings, {key: 'unsplash'}).value).isActive.should.eql(true);
|
||||
JSON.parse(_.find(jsonResponse.settings, {key: 'amp'}).value).should.eql(true);
|
||||
should.not.exist(_.find(jsonResponse.settings, {key: 'permalinks'}));
|
||||
|
||||
testUtils.API.isISO8601(jsonResponse.settings[0].created_at).should.be.true();
|
||||
jsonResponse.settings[0].created_at.should.be.an.instanceof(String);
|
||||
|
||||
should.not.exist(_.find(jsonResponse.settings, function (setting) {
|
||||
return setting.type === 'core';
|
||||
}));
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('read', function (done) {
|
||||
request.get(localUtils.API.getApiQuery('settings/title/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
should.not.exist(res.headers['x-cache-invalidate']);
|
||||
var jsonResponse = res.body;
|
||||
|
||||
should.exist(jsonResponse);
|
||||
should.exist(jsonResponse.settings);
|
||||
|
||||
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'created_at', 'created_by', 'updated_at', 'updated_by']);
|
||||
jsonResponse.settings[0].key.should.eql('title');
|
||||
testUtils.API.isISO8601(jsonResponse.settings[0].created_at).should.be.true();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('read core setting', function () {
|
||||
return request
|
||||
.get(localUtils.API.getApiQuery('settings/db_hash/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(403);
|
||||
});
|
||||
|
||||
it('can\'t read permalinks', function (done) {
|
||||
request.get(localUtils.API.getApiQuery('settings/permalinks/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(404)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can\'t read non existent setting', function (done) {
|
||||
request.get(localUtils.API.getApiQuery('settings/testsetting/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.set('Accept', 'application/json')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(404)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
should.not.exist(res.headers['x-cache-invalidate']);
|
||||
var jsonResponse = res.body;
|
||||
should.exist(jsonResponse);
|
||||
should.exist(jsonResponse.errors);
|
||||
testUtils.API.checkResponseValue(jsonResponse.errors[0], ['message', 'errorType']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can edit settings', function (done) {
|
||||
request.get(localUtils.API.getApiQuery('settings/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
var jsonResponse = res.body,
|
||||
changedValue = [],
|
||||
settingToChange = {
|
||||
settings: [
|
||||
{key: 'title', value: changedValue}
|
||||
]
|
||||
};
|
||||
|
||||
should.exist(jsonResponse);
|
||||
should.exist(jsonResponse.settings);
|
||||
|
||||
request.put(localUtils.API.getApiQuery('settings/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.send(settingToChange)
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(200)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
var putBody = res.body;
|
||||
res.headers['x-cache-invalidate'].should.eql('/*');
|
||||
should.exist(putBody);
|
||||
putBody.settings[0].value.should.eql(JSON.stringify(changedValue));
|
||||
testUtils.API.checkResponse(putBody, 'settings');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can\'t edit permalinks', function (done) {
|
||||
const settingToChange = {
|
||||
settings: [{key: 'permalinks', value: '/:primary_author/:slug/'}]
|
||||
};
|
||||
|
||||
request.put(localUtils.API.getApiQuery('settings/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.send(settingToChange)
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(404)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('can\'t edit non existent setting', function (done) {
|
||||
request.get(localUtils.API.getApiQuery('settings/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.set('Accept', 'application/json')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
var jsonResponse = res.body,
|
||||
newValue = 'new value';
|
||||
should.exist(jsonResponse);
|
||||
should.exist(jsonResponse.settings);
|
||||
jsonResponse.settings = [{key: 'testvalue', value: newValue}];
|
||||
|
||||
request.put(localUtils.API.getApiQuery('settings/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.send(jsonResponse)
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
.expect(404)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
jsonResponse = res.body;
|
||||
should.not.exist(res.headers['x-cache-invalidate']);
|
||||
should.exist(jsonResponse.errors);
|
||||
testUtils.API.checkResponseValue(jsonResponse.errors[0], ['message', 'errorType']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can download routes.yaml', ()=> {
|
||||
return request.get(localUtils.API.getApiQuery('settings/routes/yaml/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.set('Accept', 'application/yaml')
|
||||
.expect(200)
|
||||
.then((res)=> {
|
||||
res.headers['content-disposition'].should.eql('Attachment; filename="routes.yaml"');
|
||||
res.headers['content-type'].should.eql('application/yaml; charset=utf-8');
|
||||
res.headers['content-length'].should.eql('138');
|
||||
});
|
||||
});
|
||||
|
||||
it('can upload routes.yaml', ()=> {
|
||||
const newRoutesYamlPath = `${os.tmpdir()}/routes.yaml`;
|
||||
|
||||
return fs.writeFile(newRoutesYamlPath, 'routes:\ncollections:\ntaxonomies:\n')
|
||||
.then(()=> {
|
||||
return request
|
||||
.post(localUtils.API.getApiQuery('settings/routes/yaml/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.attach('routes', newRoutesYamlPath)
|
||||
.expect('Content-Type', /application\/json/)
|
||||
.expect(200);
|
||||
})
|
||||
.then((res)=> {
|
||||
res.headers['x-cache-invalidate'].should.eql('/*');
|
||||
})
|
||||
.finally(()=> {
|
||||
return ghostServer.stop();
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Add table
Reference in a new issue