0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-08 02:52:39 -05:00

Refactored usage of the pre v4 "slack" setting

refs https://github.com/TryGhost/Ghost/issues/10318

- Change/compatibility table for this changeset:

Importer

+ "slack_username"  import
- "slack_url" ignore
+ "slack.username" import
- "slack.url" ignore

v3 & canary/v4 Admin APIs
GET /settings/ (browse)

+ "slack_username" present in response
+ "slack_url" present in response
+ "slack" present in response

GET /settings/:settingName (read)

+ "slack_username" present in response
+ "slack_url" present in response
+ "slack" present in response

PUT /settings/ (edit)

+ "slack_username" updates setting
+ "slack_url" updates setting
+ "slack" !NOTE! updates setting unless "slack_username" or "slack_ur"l are set (updated keys take priority)

v2 Admin API
GET /settings/ (browse)

- "slack_username" NOT present in response
- "slack_url" NOT present in response
+ "slack" present in response

GET /settings/:settingName (read)

- "slack_username" ignored (404)
- "slack_url" ignored (404)
- "slack" present in response

PUT /settings/ (edit)

- "slack_username" ignored (no error)
- "slack_url" ignored (no error)
+ "slack" updates setting
This commit is contained in:
Fabien O'Carroll 2020-07-14 10:10:59 +02:00 committed by naz
parent 12c28fe66e
commit 8880cc82c7
26 changed files with 6515 additions and 83 deletions

View file

@ -53,7 +53,20 @@ module.exports = {
}
},
query(frame) {
let setting = settingsCache.get(frame.options.key, {resolve: false});
let setting;
if (frame.options.key === 'slack') {
const slackURL = settingsCache.get('slack_url', {resolve: false});
const slackUsername = settingsCache.get('slack_username', {resolve: false});
setting = slackURL || slackUsername;
setting.key = 'slack';
setting.value = [{
url: slackURL && slackURL.value,
username: slackUsername && slackUsername.value
}];
} else {
setting = settingsCache.get(frame.options.key, {resolve: false});
}
if (!setting) {
return Promise.reject(new NotFoundError({

View file

@ -3,6 +3,59 @@ const url = require('./utils/url');
const typeGroupMapper = require('../../../../shared/serializers/input/utils/settings-filter-type-group-mapper');
const settingsCache = require('../../../../../services/settings/cache');
const DEPRECATED_SETTINGS = [
'bulk_email_settings',
'slack'
];
const deprecatedSupportedSettingsOneToManyMap = {
slack: [{
from: '[0].url',
to: {
key: 'slack_url',
group: 'slack',
type: 'string'
}
}, {
from: '[0].username',
to: {
key: 'slack_username',
group: 'slack',
type: 'string'
}
}]
};
const getMappedDeprecatedSettings = (settings) => {
const mappedSettings = [];
for (const key in deprecatedSupportedSettingsOneToManyMap) {
const deprecatedSetting = settings.find(setting => setting.key === key);
if (deprecatedSetting) {
let deprecatedSettingValue;
try {
deprecatedSettingValue = JSON.parse(deprecatedSetting.value);
} catch (err) {
// ignore the value if it's invalid
}
if (deprecatedSettingValue) {
deprecatedSupportedSettingsOneToManyMap[key].forEach(({from, to}) => {
const value = _.get(deprecatedSettingValue, from);
mappedSettings.push({
key: to.key,
value: value
});
});
}
}
}
return mappedSettings;
};
module.exports = {
browse(apiConfig, frame) {
if (frame.options.type) {
@ -48,8 +101,14 @@ module.exports = {
return !settingFlagsArr.includes('RO');
});
frame.data.settings = frame.data.settings.filter((setting) => {
return setting.key !== 'bulk_email_settings';
const mappedDeprecatedSettings = getMappedDeprecatedSettings(frame.data.settings);
mappedDeprecatedSettings.forEach((setting) => {
// NOTE: give priority for non-deprecated setting values if they exist
const nonDeprecatedExists = frame.data.settings.find(s => s.key === setting.key);
if (!nonDeprecatedExists) {
frame.data.settings.push(setting);
}
});
frame.data.settings.forEach((setting) => {
@ -95,5 +154,10 @@ module.exports = {
setting = url.forSetting(setting);
}
});
// Ignore all deprecated settings
frame.data.settings = frame.data.settings.filter((setting) => {
return DEPRECATED_SETTINGS.includes(setting.key) === false;
});
}
};

View file

@ -72,8 +72,12 @@ module.exports.forSettings = (attrs, frame) => {
if (frame.original.params.key === 'lang') {
return;
}
}
if (frame.original.params.key === 'slack_url'
|| frame.original.params.key === 'slack_username') {
return;
}
}
// CASE: edit
if (frame.original.body && frame.original.body.settings) {
frame.original.body.settings.forEach((setting) => {
@ -89,6 +93,20 @@ module.exports.forSettings = (attrs, frame) => {
} else if (setting.key === 'default_locale') {
const target = _.find(attrs, {key: 'lang'});
target.key = 'default_locale';
} else if (setting.key === 'slack') {
const slackURL = _.cloneDeep(_.find(attrs, {key: 'slack_url'}));
const slackUsername = _.cloneDeep(_.find(attrs, {key: 'slack_username'}));
if (slackURL || slackUsername) {
const slack = slackURL || slackUsername;
slack.key = 'slack';
slack.value = JSON.stringify([{
url: slackURL && slackURL.value,
username: slackUsername && slackUsername.value
}]);
attrs.push(slack);
}
}
});
@ -100,6 +118,8 @@ module.exports.forSettings = (attrs, frame) => {
const ghostFoot = _.cloneDeep(_.find(attrs, {key: 'codeinjection_foot'}));
const timezone = _.cloneDeep(_.find(attrs, {key: 'timezone'}));
const lang = _.cloneDeep(_.find(attrs, {key: 'lang'}));
const slackURL = _.cloneDeep(_.find(attrs, {key: 'slack_url'}));
const slackUsername = _.cloneDeep(_.find(attrs, {key: 'slack_username'}));
if (ghostHead) {
ghostHead.key = 'ghost_head';
@ -120,5 +140,16 @@ module.exports.forSettings = (attrs, frame) => {
lang.key = 'default_locale';
attrs.push(lang);
}
if (slackURL || slackUsername) {
const slack = slackURL || slackUsername;
slack.key = 'slack';
slack.value = JSON.stringify([{
url: slackURL && slackURL.value,
username: slackUsername && slackUsername.value
}]);
attrs.push(slack);
}
}
};

View file

@ -102,9 +102,25 @@ const mapSettings = (attrs, frame) => {
// `forSettings` step. This logic can be rewritten once we get rid of deprecated
// fields completely.
if (_.isArray(attrs)) {
attrs = _.filter(attrs, (o) => {
return o.key !== 'ghost_head' && o.key !== 'ghost_foot';
});
const keysToFilter = ['ghost_head', 'ghost_foot'];
// NOTE: to support edits of deprecated 'slack' setting artificial 'slack_url' and 'slack_username'
// were added to the request body in the input serializer. These should not be returned in response
// body unless directly requested
if (frame.original.body && frame.original.body.settings) {
const requestedEditSlackUrl = frame.original.body.settings.find(s => s.key === 'slack_url');
const requestedEditSlackUsername = frame.original.body.settings.find(s => s.key === 'slack_username');
if (!requestedEditSlackUrl) {
keysToFilter.push('slack_url');
}
if (!requestedEditSlackUsername) {
keysToFilter.push('slack_username');
}
}
attrs = _.filter(attrs, attr => !(keysToFilter.includes(attr.key)));
}
return attrs;

View file

@ -51,7 +51,22 @@ module.exports = {
}
},
query(frame) {
let setting = settingsCache.get(frame.options.key, {resolve: false});
let setting;
if (frame.options.key === 'slack') {
const slackURL = settingsCache.get('slack_url', {resolve: false});
const slackUsername = settingsCache.get('slack_username', {resolve: false});
setting = slackURL || slackUsername;
setting.key = 'slack';
setting.value = [{
url: slackURL && slackURL.value,
username: slackUsername && slackUsername.value
}];
} else if (frame.options.key === 'slack_url' || frame.options.key === 'slack_username') {
// leave the value empty returning 404 for unknown in current API keys
} else {
setting = settingsCache.get(frame.options.key, {resolve: false});
}
if (!setting) {
return Promise.reject(new NotFoundError({

View file

@ -3,6 +3,59 @@ const url = require('./utils/url');
const typeGroupMapper = require('../../../../shared/serializers/input/utils/settings-filter-type-group-mapper');
const settingsCache = require('../../../../../services/settings/cache');
const DEPRECATED_SETTINGS = [
'bulk_email_settings',
'slack'
];
const deprecatedSupportedSettingsOneToManyMap = {
slack: [{
from: '[0].url',
to: {
key: 'slack_url',
group: 'slack',
type: 'string'
}
}, {
from: '[0].username',
to: {
key: 'slack_username',
group: 'slack',
type: 'string'
}
}]
};
const getMappedDeprecatedSettings = (settings) => {
const mappedSettings = [];
for (const key in deprecatedSupportedSettingsOneToManyMap) {
const deprecatedSetting = settings.find(setting => setting.key === key);
if (deprecatedSetting) {
let deprecatedSettingValue;
try {
deprecatedSettingValue = JSON.parse(deprecatedSetting.value);
} catch (err) {
// ignore the value if it's invalid
}
if (deprecatedSettingValue) {
deprecatedSupportedSettingsOneToManyMap[key].forEach(({from, to}) => {
const value = _.get(deprecatedSettingValue, from);
mappedSettings.push({
key: to.key,
value: value
});
});
}
}
}
return mappedSettings;
};
module.exports = {
browse(apiConfig, frame) {
if (frame.options.type) {
@ -45,9 +98,7 @@ module.exports = {
return !settingFlagsArr.includes('RO');
});
frame.data.settings = frame.data.settings.filter((setting) => {
return setting.key !== 'bulk_email_settings';
});
frame.data.settings.push(...getMappedDeprecatedSettings(frame.data.settings));
frame.data.settings.forEach((setting) => {
const settingType = settings[setting.key] ? settings[setting.key].type : '';
@ -87,5 +138,10 @@ module.exports = {
setting = url.forSetting(setting);
}
});
// Ignore all deprecated settings
frame.data.settings = frame.data.settings.filter((setting) => {
return DEPRECATED_SETTINGS.includes(setting.key) === false;
});
}
};

View file

@ -75,6 +75,20 @@ module.exports.forSettings = (attrs, frame) => {
} else if (setting.key === 'default_locale') {
const target = _.find(attrs, {key: 'timezone'});
target.key = 'lang';
} else if (setting.key === 'slack') {
const slackURL = _.cloneDeep(_.find(attrs, {key: 'slack_url'}));
const slackUsername = _.cloneDeep(_.find(attrs, {key: 'slack_username'}));
if (slackURL || slackUsername) {
const slack = slackURL || slackUsername;
slack.key = 'slack';
slack.value = JSON.stringify([{
url: slackURL && slackURL.value,
username: slackUsername && slackUsername.value
}]);
attrs.push(slack);
}
}
});
@ -86,6 +100,8 @@ module.exports.forSettings = (attrs, frame) => {
const ghostFoot = _.cloneDeep(_.find(attrs, {key: 'codeinjection_foot'}));
const timezone = _.cloneDeep(_.find(attrs, {key: 'timezone'}));
const lang = _.cloneDeep(_.find(attrs, {key: 'lang'}));
const slackURL = _.cloneDeep(_.find(attrs, {key: 'slack_url'}));
const slackUsername = _.cloneDeep(_.find(attrs, {key: 'slack_username'}));
if (ghostHead) {
ghostHead.key = 'ghost_head';
@ -106,6 +122,17 @@ module.exports.forSettings = (attrs, frame) => {
lang.key = 'default_locale';
attrs.push(lang);
}
if (slackURL || slackUsername) {
const slack = slackURL || slackUsername;
slack.key = 'slack';
slack.value = JSON.stringify([{
url: slackURL && slackURL.value,
username: slackUsername && slackUsername.value
}]);
attrs.push(slack);
}
} else {
attrs.ghost_head = attrs.codeinjection_head;
attrs.ghost_foot = attrs.codeinjection_foot;

View file

@ -87,8 +87,9 @@ const mapSettings = (attrs, frame) => {
extraAttrs.forSettings(attrs, frame);
if (_.isArray(attrs)) {
const DEPRECATED_KEYS = ['lang', 'timezone', 'accent_color', 'slack_url', 'slack_username'];
attrs = _.filter(attrs, (o) => {
return o.key !== 'lang' && o.key !== 'timezone' && o.key !== 'accent_color';
return !DEPRECATED_KEYS.includes(o.key);
});
} else {
delete attrs.lang;

View file

@ -53,7 +53,20 @@ module.exports = {
}
},
query(frame) {
let setting = settingsCache.get(frame.options.key, {resolve: false});
let setting;
if (frame.options.key === 'slack') {
const slackURL = settingsCache.get('slack_url', {resolve: false});
const slackUsername = settingsCache.get('slack_username', {resolve: false});
setting = slackURL || slackUsername;
setting.key = 'slack';
setting.value = [{
url: slackURL && slackURL.value,
username: slackUsername && slackUsername.value
}];
} else {
setting = settingsCache.get(frame.options.key, {resolve: false});
}
if (!setting) {
return Promise.reject(new NotFoundError({

View file

@ -3,6 +3,59 @@ const url = require('./utils/url');
const typeGroupMapper = require('../../../../shared/serializers/input/utils/settings-filter-type-group-mapper');
const settingsCache = require('../../../../../services/settings/cache');
const DEPRECATED_SETTINGS = [
'bulk_email_settings',
'slack'
];
const deprecatedSupportedSettingsOneToManyMap = {
slack: [{
from: '[0].url',
to: {
key: 'slack_url',
group: 'slack',
type: 'string'
}
}, {
from: '[0].username',
to: {
key: 'slack_username',
group: 'slack',
type: 'string'
}
}]
};
const getMappedDeprecatedSettings = (settings) => {
const mappedSettings = [];
for (const key in deprecatedSupportedSettingsOneToManyMap) {
const deprecatedSetting = settings.find(setting => setting.key === key);
if (deprecatedSetting) {
let deprecatedSettingValue;
try {
deprecatedSettingValue = JSON.parse(deprecatedSetting.value);
} catch (err) {
// ignore the value if it's invalid
}
if (deprecatedSettingValue) {
deprecatedSupportedSettingsOneToManyMap[key].forEach(({from, to}) => {
const value = _.get(deprecatedSettingValue, from);
mappedSettings.push({
key: to.key,
value: value
});
});
}
}
}
return mappedSettings;
};
module.exports = {
browse(apiConfig, frame) {
if (frame.options.type) {
@ -48,8 +101,14 @@ module.exports = {
return !settingFlagsArr.includes('RO');
});
frame.data.settings = frame.data.settings.filter((setting) => {
return setting.key !== 'bulk_email_settings';
const mappedDeprecatedSettings = getMappedDeprecatedSettings(frame.data.settings);
mappedDeprecatedSettings.forEach((setting) => {
// NOTE: give priority for non-deprecated setting values if they exist
const nonDeprecatedExists = frame.data.settings.find(s => s.key === setting.key);
if (!nonDeprecatedExists) {
frame.data.settings.push(setting);
}
});
frame.data.settings.forEach((setting) => {
@ -95,5 +154,10 @@ module.exports = {
setting = url.forSetting(setting);
}
});
// Ignore all deprecated settings
frame.data.settings = frame.data.settings.filter((setting) => {
return DEPRECATED_SETTINGS.includes(setting.key) === false;
});
}
};

View file

@ -72,8 +72,12 @@ module.exports.forSettings = (attrs, frame) => {
if (frame.original.params.key === 'lang') {
return;
}
}
if (frame.original.params.key === 'slack_url'
|| frame.original.params.key === 'slack_username') {
return;
}
}
// CASE: edit
if (frame.original.body && frame.original.body.settings) {
frame.original.body.settings.forEach((setting) => {
@ -89,6 +93,20 @@ module.exports.forSettings = (attrs, frame) => {
} else if (setting.key === 'default_locale') {
const target = _.find(attrs, {key: 'lang'});
target.key = 'default_locale';
} else if (setting.key === 'slack') {
const slackURL = _.cloneDeep(_.find(attrs, {key: 'slack_url'}));
const slackUsername = _.cloneDeep(_.find(attrs, {key: 'slack_username'}));
if (slackURL || slackUsername) {
const slack = slackURL || slackUsername;
slack.key = 'slack';
slack.value = JSON.stringify([{
url: slackURL && slackURL.value,
username: slackUsername && slackUsername.value
}]);
attrs.push(slack);
}
}
});
@ -100,6 +118,8 @@ module.exports.forSettings = (attrs, frame) => {
const ghostFoot = _.cloneDeep(_.find(attrs, {key: 'codeinjection_foot'}));
const timezone = _.cloneDeep(_.find(attrs, {key: 'timezone'}));
const lang = _.cloneDeep(_.find(attrs, {key: 'lang'}));
const slackURL = _.cloneDeep(_.find(attrs, {key: 'slack_url'}));
const slackUsername = _.cloneDeep(_.find(attrs, {key: 'slack_username'}));
if (ghostHead) {
ghostHead.key = 'ghost_head';
@ -120,5 +140,16 @@ module.exports.forSettings = (attrs, frame) => {
lang.key = 'default_locale';
attrs.push(lang);
}
if (slackURL || slackUsername) {
const slack = slackURL || slackUsername;
slack.key = 'slack';
slack.value = [{
url: slackURL && slackURL.value,
username: slackUsername && slackUsername.value
}];
attrs.push(slack);
}
}
};

View file

@ -111,9 +111,25 @@ const mapSettings = (attrs, frame) => {
// `forSettings` step. This logic can be rewritten once we get rid of deprecated
// fields completely.
if (_.isArray(attrs)) {
attrs = _.filter(attrs, (o) => {
return o.key !== 'ghost_head' && o.key !== 'ghost_foot';
});
const keysToFilter = ['ghost_head', 'ghost_foot'];
// NOTE: to support edits of deprecated 'slack' setting artificial 'slack_url' and 'slack_username'
// were added to the request body in the input serializer. These should not be returned in response
// body unless directly requested
if (frame.original.body && frame.original.body.settings) {
const requestedEditSlackUrl = frame.original.body.settings.find(s => s.key === 'slack_url');
const requestedEditSlackUsername = frame.original.body.settings.find(s => s.key === 'slack_username');
if (!requestedEditSlackUrl) {
keysToFilter.push('slack_url');
}
if (!requestedEditSlackUsername) {
keysToFilter.push('slack_username');
}
}
attrs = _.filter(attrs, attr => !(keysToFilter.includes(attr.key)));
}
return attrs;

View file

@ -1,5 +1,6 @@
const debug = require('ghost-ignition').debug('importer:settings');
const Promise = require('bluebird');
const ObjectId = require('bson-objectid').default;
const _ = require('lodash');
const BaseImporter = require('./base');
const models = require('../../../../models');
@ -8,7 +9,8 @@ const keyGroupMapper = require('../../../../api/shared/serializers/input/utils/s
const keyTypeMapper = require('../../../../api/shared/serializers/input/utils/settings-key-type-mapper');
const labsDefaults = JSON.parse(defaultSettings.labs.labs.defaultValue);
const ignoredSettings = ['members_from_address', 'members_support_address'];
const ignoredSettings = ['slack_url', 'members_from_address', 'members_support_address'];
// NOTE: drop support in Ghost 5.0
const deprecatedSupportedSettingsMap = {
default_locale: 'lang',
@ -16,6 +18,17 @@ const deprecatedSupportedSettingsMap = {
ghost_head: 'codeinjection_head',
ghost_foot: 'codeinjection_foot'
};
const deprecatedSupportedSettingsOneToManyMap = {
// NOTE: intentionally ignoring slack_url setting
slack: [{
from: '[0].username',
to: {
key: 'slack_username',
group: 'slack',
type: 'string'
}
}]
};
const isFalse = (value) => {
// Catches false, null, undefined, empty string
@ -90,6 +103,44 @@ class SettingsImporter extends BaseImporter {
return data;
});
for (const key in deprecatedSupportedSettingsOneToManyMap) {
const deprecatedSetting = this.dataToImport.find(setting => setting.key === key);
if (deprecatedSetting) {
let deprecatedSettingValue;
try {
deprecatedSettingValue = JSON.parse(deprecatedSetting.value);
} catch (err) {
this.problems.push({
message: `Failed to parse the value of ${deprecatedSetting.key} setting value`,
help: this.modelName,
context: deprecatedSetting
});
}
if (deprecatedSettingValue) {
deprecatedSupportedSettingsOneToManyMap[key].forEach(({from, to}) => {
const value = _.get(deprecatedSettingValue, from);
this.dataToImport.push({
id: ObjectId.generate(),
key: to.key,
value: value,
group: to.group,
type: to.type,
flags: null,
created_by: deprecatedSetting.created_by,
created_at: deprecatedSetting.created_at,
updated_by: deprecatedSetting.updated_by,
updated_at: deprecatedSetting.updated_at
});
});
}
}
this.dataToImport = _.filter(this.dataToImport, data => (key !== data.key));
}
// NOTE: keep back compatibility with settings object structure present before migration
// ref. https://github.com/TryGhost/Ghost/issues/10318
this.dataToImport = this.dataToImport.map((data) => {
@ -138,11 +189,6 @@ class SettingsImporter extends BaseImporter {
obj.value = JSON.stringify(_.assign({}, JSON.parse(obj.value), labsDefaults));
}
// CASE: we do not import slack hooks, otherwise it can happen very fast that you are pinging someone's slack channel
if (obj.key === 'slack') {
obj.value = JSON.stringify([{url: ''}]);
}
// CASE: we do not import "from address" for members settings as that needs to go via validation with magic link
if ((obj.key === 'members_from_address') || (obj.key === 'members_support_address')) {
obj.value = null;

View file

@ -20,10 +20,13 @@ const defaultPostSlugs = [
];
function getSlackSettings() {
const setting = settingsCache.get('slack');
// This might one day have multiple entries, for now its always a array
// and we return the first item or an empty object
return setting ? setting[0] : {};
const username = settingsCache.get('slack_username');
const url = settingsCache.get('slack_url');
return {
username,
url
};
}
function ping(post) {

View file

@ -50,7 +50,7 @@ describe('DB API', function () {
Object.keys(jsonResponse.db[0].data).length.should.eql(34);
});
it('Can import a JSON database', async function () {
it('Can import a JSON database exported from Ghost v2', async function () {
await request.delete(localUtils.API.getApiQuery('db/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
@ -60,7 +60,61 @@ describe('DB API', function () {
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.attach('importfile', path.join(__dirname, '/../../utils/fixtures/export/default_export.json'))
.attach('importfile', path.join(__dirname, '/../../utils/fixtures/export/v2_export.json'))
.expect(200);
const jsonResponse = res.body;
should.exist(jsonResponse.db);
should.exist(jsonResponse.problems);
jsonResponse.problems.should.have.length(3);
const res2 = await request.get(localUtils.API.getApiQuery('posts/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200);
res2.body.posts.should.have.length(7);
});
it('Can import a JSON database exported from Ghost v3', async function () {
await request.delete(localUtils.API.getApiQuery('db/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
.expect(204);
const res = await request.post(localUtils.API.getApiQuery('db/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.attach('importfile', path.join(__dirname, '/../../utils/fixtures/export/v3_export.json'))
.expect(200);
const jsonResponse = res.body;
should.exist(jsonResponse.db);
should.exist(jsonResponse.problems);
jsonResponse.problems.should.have.length(3);
const res2 = await request.get(localUtils.API.getApiQuery('posts/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200);
res2.body.posts.should.have.length(7);
});
it('Can import a JSON database exported from Ghost v4', async function () {
await request.delete(localUtils.API.getApiQuery('db/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
.expect(204);
const res = await request.post(localUtils.API.getApiQuery('db/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.attach('importfile', path.join(__dirname, '/../../utils/fixtures/export/v4_export.json'))
.expect(200);
const jsonResponse = res.body;

View file

@ -93,7 +93,14 @@ describe('Settings API', function () {
},
{
key: 'slack',
value: JSON.stringify({username: 'username'})
value: JSON.stringify([{
url: 'https://overrides.tld',
username: 'Overrides Username'
}])
},
{
key: 'slack_username',
value: 'New Slack Username'
},
{
key: 'is_private',
@ -160,6 +167,8 @@ describe('Settings API', function () {
headers['x-cache-invalidate'].should.eql('/*');
should.exist(putBody);
putBody.settings.length.should.equal(17);
putBody.settings[0].key.should.eql('title');
putBody.settings[0].value.should.eql(JSON.stringify(changedValue));
@ -169,8 +178,8 @@ describe('Settings API', function () {
putBody.settings[2].key.should.eql('navigation');
should.equal(putBody.settings[2].value, JSON.stringify({label: 'label1'}));
putBody.settings[3].key.should.eql('slack');
should.equal(putBody.settings[3].value, JSON.stringify({username: 'username'}));
putBody.settings[3].key.should.eql('slack_username');
should.equal(putBody.settings[3].value, 'New Slack Username');
putBody.settings[4].key.should.eql('is_private');
should.equal(putBody.settings[4].value, false);
@ -211,6 +220,12 @@ describe('Settings API', function () {
putBody.settings[15].key.should.eql('timezone');
should.equal(putBody.settings[15].value, 'Pacific/Auckland');
putBody.settings[16].key.should.eql('slack');
should.equal(putBody.settings[16].value, JSON.stringify([{
url: 'https://overrides.tld',
username: 'New Slack Username'
}]));
localUtils.API.checkResponse(putBody, 'settings');
});

View file

@ -64,6 +64,8 @@ const defaultSettingsKeyTypes = [
{key: 'amp_gtag_id', type: 'blog'},
{key: 'labs', type: 'blog'},
{key: 'slack', type: 'blog'},
{key: 'slack_url', type: 'blog'},
{key: 'slack_username', type: 'blog'},
{key: 'unsplash', type: 'blog'},
{key: 'shared_views', type: 'blog'},
{key: 'active_timezone', type: 'blog'},
@ -108,6 +110,7 @@ describe('Settings API (canary)', function () {
jsonResponse.settings.should.be.an.Object();
const settings = jsonResponse.settings;
should.equal(settings.length, defaultSettingsKeyTypes.length);
for (const defaultSetting of defaultSettingsKeyTypes) {
should.exist(settings.find((setting) => {
@ -171,6 +174,28 @@ describe('Settings API (canary)', function () {
});
});
it('Requesting core settings type ignores the parameter and returns all settings', function () {
return request.get(localUtils.API.getApiQuery(`settings/?type=core`))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.then((res) => {
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse.settings);
should.exist(jsonResponse.meta);
jsonResponse.settings.should.be.an.Object();
const settings = jsonResponse.settings;
Object.keys(settings).length.should.equal(68);
localUtils.API.checkResponse(jsonResponse, 'settings');
});
});
it('Can\'t read core setting', function () {
return request
.get(localUtils.API.getApiQuery('settings/db_hash/'))
@ -195,6 +220,33 @@ describe('Settings API (canary)', function () {
});
});
it('Can read slack_url introduced in v4', function (done) {
request.get(localUtils.API.getApiQuery('settings/slack_url/'))
.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);
}
if (err) {
return done(err);
}
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.settings);
jsonResponse.settings.length.should.eql(1);
jsonResponse.settings[0].key.should.eql('slack_url');
done();
});
});
it('Can read deprecated default_locale', function (done) {
request.get(localUtils.API.getApiQuery('settings/default_locale/'))
.set('Origin', config.get('url'))
@ -220,7 +272,7 @@ describe('Settings API (canary)', function () {
});
});
it('can edit deprecated default_locale setting', function () {
it('Can edit deprecated default_locale setting', function () {
return request.get(localUtils.API.getApiQuery('settings/default_locale/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
@ -333,7 +385,32 @@ describe('Settings API (canary)', function () {
});
});
it('can\'t read non existent setting', function (done) {
it('Can read slack renamed&reformatted in v4', function (done) {
request.get(localUtils.API.getApiQuery('settings/slack/'))
.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']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.settings);
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('slack');
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')
@ -363,7 +440,7 @@ describe('Settings API (canary)', function () {
});
});
it('can\'t edit permalinks', function (done) {
it('Can\'t edit permalinks', function (done) {
const settingToChange = {
settings: [{key: 'permalinks', value: '/:primary_author/:slug/'}]
};
@ -383,7 +460,7 @@ describe('Settings API (canary)', function () {
});
});
it('can\'t edit non existent setting', function () {
it('Can\'t edit non existent setting', function () {
return request.get(localUtils.API.getApiQuery('settings/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
@ -396,18 +473,15 @@ describe('Settings API (canary)', function () {
should.exist(jsonResponse.settings);
jsonResponse.settings = [{key: 'testvalue', value: newValue}];
return jsonResponse;
})
.then((jsonResponse) => {
return 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)
.then(function (res) {
jsonResponse = res.body;
should.not.exist(res.headers['x-cache-invalidate']);
.then(function ({body, headers}) {
jsonResponse = body;
should.not.exist(headers['x-cache-invalidate']);
should.exist(jsonResponse.errors);
testUtils.API.checkResponseValue(jsonResponse.errors[0], [
'message',
@ -461,6 +535,74 @@ describe('Settings API (canary)', function () {
});
});
});
it('Can edit multiple setting along with a deprecated one from v4', async function () {
const settingToChange = {
settings: [
{
key: 'slack',
value: JSON.stringify([{
url: 'https://newurl.tld/slack',
username: 'New Slack Username'
}])
}, {
key: 'title',
value: 'Test site title'
}
]
};
const {body, headers} = await 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);
const putBody = body;
headers['x-cache-invalidate'].should.eql('/*');
should.exist(putBody);
putBody.settings.length.should.equal(2);
putBody.settings[0].key.should.eql('title');
should.equal(putBody.settings[0].value, 'Test site title');
putBody.settings[1].key.should.eql('slack');
should.equal(putBody.settings[1].value, JSON.stringify([{
url: 'https://newurl.tld/slack',
username: 'New Slack Username'
}]));
localUtils.API.checkResponse(putBody, 'settings');
});
it('Can edit a setting introduced in v4', async function () {
const settingToChange = {
settings: [
{
key: 'slack_username',
value: 'can edit me'
}
]
};
const {body, headers} = await 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);
const putBody = body;
headers['x-cache-invalidate'].should.eql('/*');
should.exist(putBody);
putBody.settings.length.should.equal(1);
localUtils.API.checkResponse(putBody, 'settings');
putBody.settings[0].key.should.eql('slack_username');
putBody.settings[0].value.should.eql('can edit me');
});
});
describe('As Admin', function () {
@ -519,7 +661,7 @@ describe('Settings API (canary)', function () {
.expect('Cache-Control', testUtils.cacheRules.private)
.then(function (res) {
let jsonResponse = res.body;
const newValue = 'new value';
should.exist(jsonResponse);
should.exist(jsonResponse.settings);
jsonResponse.settings = [{key: 'visibility', value: 'public'}];

View file

@ -111,7 +111,7 @@ describe('Settings API (v2)', function () {
for (const defaultSetting of defaultSettingsKeyTypes) {
should.exist(settings.find((setting) => {
return setting.key === defaultSetting.key && setting.type === defaultSetting.type;
}));
}), `Expected to find a setting with key ${defaultSetting.key} and type ${defaultSetting.type}`);
}
localUtils.API.checkResponse(jsonResponse, 'settings');
@ -238,6 +238,21 @@ describe('Settings API (v2)', function () {
});
});
it('Can\'t read slack_url introduced in v4', function (done) {
request.get(localUtils.API.getApiQuery('settings/slack_url/'))
.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 read default_locale deprecated in v3', function (done) {
request.get(localUtils.API.getApiQuery('settings/default_locale/'))
.set('Origin', config.get('url'))
@ -338,7 +353,32 @@ describe('Settings API (v2)', function () {
});
});
it('can\'t read non existent setting', function (done) {
it('Can read slack renamed&reformatted in v4', function (done) {
request.get(localUtils.API.getApiQuery('settings/slack/'))
.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']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.settings);
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('slack');
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')
@ -368,7 +408,7 @@ describe('Settings API (v2)', function () {
});
});
it('can\'t edit permalinks', function (done) {
it('Can\'t edit permalinks', function (done) {
const settingToChange = {
settings: [{key: 'permalinks', value: '/:primary_author/:slug/'}]
};
@ -388,7 +428,7 @@ describe('Settings API (v2)', function () {
});
});
it('can\'t edit non existent setting', function () {
it('Can\'t edit non existent setting', function () {
return request.get(localUtils.API.getApiQuery('settings/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
@ -445,7 +485,7 @@ describe('Settings API (v2)', function () {
should.exist(jsonResponse);
should.exist(jsonResponse.settings);
request.put(localUtils.API.getApiQuery('settings/'))
return request.put(localUtils.API.getApiQuery('settings/'))
.set('Origin', config.get('url'))
.send(settingToChange)
.expect('Content-Type', /json/)
@ -463,6 +503,66 @@ describe('Settings API (v2)', function () {
});
});
});
it('Can edit a setting deprecated in v4', async function () {
const settingToChange = {
settings: [
{
key: 'slack',
value: JSON.stringify([{
url: 'https://newurl.tld/slack',
username: 'New Slack Username'
}])
}
]
};
const {body, headers} = await 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);
const putBody = body;
headers['x-cache-invalidate'].should.eql('/*');
should.exist(putBody);
putBody.settings.length.should.equal(1);
putBody.settings[0].key.should.eql('slack');
should.equal(putBody.settings[0].value, JSON.stringify([{
url: 'https://newurl.tld/slack',
username: 'New Slack Username'
}]));
localUtils.API.checkResponse(putBody, 'settings');
});
it('Ignores editing a setting introduced in v4', async function () {
const settingToChange = {
settings: [
{
key: 'slack_username',
value: 'wont edit me'
}
]
};
const {body, headers} = await 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);
const putBody = body;
headers['x-cache-invalidate'].should.eql('/*');
should.exist(putBody);
putBody.settings.length.should.equal(0);
localUtils.API.checkResponse(putBody, 'settings');
});
});
describe('As Admin', function () {

View file

@ -64,6 +64,8 @@ const defaultSettingsKeyTypes = [
{key: 'amp_gtag_id', type: 'blog'},
{key: 'labs', type: 'blog'},
{key: 'slack', type: 'blog'},
{key: 'slack_url', type: 'blog'},
{key: 'slack_username', type: 'blog'},
{key: 'unsplash', type: 'blog'},
{key: 'shared_views', type: 'blog'},
{key: 'active_timezone', type: 'blog'},
@ -108,6 +110,7 @@ describe('Settings API (v3)', function () {
jsonResponse.settings.should.be.an.Object();
const settings = jsonResponse.settings;
should.equal(settings.length, defaultSettingsKeyTypes.length);
for (const defaultSetting of defaultSettingsKeyTypes) {
should.exist(settings.find((setting) => {
@ -189,7 +192,7 @@ describe('Settings API (v3)', function () {
settings[0].key.should.equal('active_theme');
settings[0].value.should.equal('casper');
settings[0].type.should.equal('theme');
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'key', 'value', 'group', 'type', 'flags', 'created_at', 'updated_at']);
localUtils.API.checkResponse(jsonResponse, 'settings');
});
});
@ -240,6 +243,33 @@ describe('Settings API (v3)', function () {
});
});
it('Can read slack_url introduced in v4', function (done) {
request.get(localUtils.API.getApiQuery('settings/slack_url/'))
.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);
}
if (err) {
return done(err);
}
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.settings);
jsonResponse.settings.length.should.eql(1);
jsonResponse.settings[0].key.should.eql('slack_url');
done();
});
});
it('Can read deprecated default_locale', function (done) {
request.get(localUtils.API.getApiQuery('settings/default_locale/'))
.set('Origin', config.get('url'))
@ -265,7 +295,7 @@ describe('Settings API (v3)', function () {
});
});
it('can edit deprecated default_locale setting', function () {
it('Can edit deprecated default_locale setting', function () {
return request.get(localUtils.API.getApiQuery('settings/default_locale/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
@ -378,7 +408,32 @@ describe('Settings API (v3)', function () {
});
});
it('can\'t read non existent setting', function (done) {
it('Can read slack renamed&reformatted in v4', function (done) {
request.get(localUtils.API.getApiQuery('settings/slack/'))
.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']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.settings);
jsonResponse.settings.length.should.eql(1);
testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']);
jsonResponse.settings[0].key.should.eql('slack');
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')
@ -408,7 +463,7 @@ describe('Settings API (v3)', function () {
});
});
it('can\'t edit permalinks', function (done) {
it('Can\'t edit permalinks', function (done) {
const settingToChange = {
settings: [{key: 'permalinks', value: '/:primary_author/:slug/'}]
};
@ -428,7 +483,7 @@ describe('Settings API (v3)', function () {
});
});
it('can\'t edit non existent setting', function () {
it('Can\'t edit non existent setting', function () {
return request.get(localUtils.API.getApiQuery('settings/'))
.set('Origin', config.get('url'))
.set('Accept', 'application/json')
@ -441,18 +496,15 @@ describe('Settings API (v3)', function () {
should.exist(jsonResponse.settings);
jsonResponse.settings = [{key: 'testvalue', value: newValue}];
return jsonResponse;
})
.then((jsonResponse) => {
return 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)
.then(function (res) {
jsonResponse = res.body;
should.not.exist(res.headers['x-cache-invalidate']);
.then(function ({body, headers}) {
jsonResponse = body;
should.not.exist(headers['x-cache-invalidate']);
should.exist(jsonResponse.errors);
testUtils.API.checkResponseValue(jsonResponse.errors[0], [
'message',
@ -506,6 +558,74 @@ describe('Settings API (v3)', function () {
});
});
});
it('Can edit multiple setting along with a deprecated one from v4', async function () {
const settingToChange = {
settings: [
{
key: 'slack',
value: JSON.stringify([{
url: 'https://newurl.tld/slack',
username: 'New Slack Username'
}])
}, {
key: 'title',
value: 'Test site title'
}
]
};
const {body, headers} = await 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);
const putBody = body;
headers['x-cache-invalidate'].should.eql('/*');
should.exist(putBody);
putBody.settings.length.should.equal(2);
putBody.settings[0].key.should.eql('title');
should.equal(putBody.settings[0].value, 'Test site title');
putBody.settings[1].key.should.eql('slack');
should.equal(putBody.settings[1].value, JSON.stringify([{
url: 'https://newurl.tld/slack',
username: 'New Slack Username'
}]));
localUtils.API.checkResponse(putBody, 'settings');
});
it('Can edit a setting introduced in v4', async function () {
const settingToChange = {
settings: [
{
key: 'slack_username',
value: 'can edit me'
}
]
};
const {body, headers} = await 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);
const putBody = body;
headers['x-cache-invalidate'].should.eql('/*');
should.exist(putBody);
putBody.settings.length.should.equal(1);
localUtils.API.checkResponse(putBody, 'settings');
putBody.settings[0].key.should.eql('slack_username');
putBody.settings[0].value.should.eql('can edit me');
});
});
describe('As Admin', function () {
@ -564,7 +684,7 @@ describe('Settings API (v3)', function () {
.expect('Cache-Control', testUtils.cacheRules.private)
.then(function (res) {
let jsonResponse = res.body;
const newValue = 'new value';
should.exist(jsonResponse);
should.exist(jsonResponse.settings);
jsonResponse.settings = [{key: 'visibility', value: 'public'}];

View file

@ -912,21 +912,39 @@ describe('Integration: Importer', function () {
});
});
it('does not import settings: slack hook, permalinks', function () {
it('does not import settings: slack_url', function () {
const exportData = exportedLatestBody().db[0];
exportData.data.settings[0] = testUtils.DataGenerator.forKnex.createSetting({
key: 'slack',
value: '[{\\"url\\":\\"https://hook.slack.com\\"}]'
key: 'slack_url',
value: 'https://ignoreme.tld'
});
return dataImporter.doImport(exportData, importOptions)
.then(function (imported) {
imported.problems.length.should.eql(0);
return models.Settings.findOne(_.merge({key: 'slack'}, testUtils.context.internal));
return models.Settings.findOne(_.merge({key: 'slack_url'}, testUtils.context.internal));
})
.then(function (result) {
result.attributes.value.should.eql('[{"url":""}]');
result.attributes.value.should.eql('');
});
});
it('does not import settings: slack_url from slack object', function () {
const exportData = exportedLatestBody().db[0];
exportData.data.settings[0] = testUtils.DataGenerator.forKnex.createSetting({
key: 'slack',
value: '[{"url":"https://hook.slack.com"}]'
});
return dataImporter.doImport(exportData, importOptions)
.then(function (imported) {
imported.problems.length.should.eql(0);
return models.Settings.findOne(_.merge({key: 'slack_url'}, testUtils.context.internal));
})
.then(function (result) {
result.attributes.value.should.eql('');
});
});

View file

@ -95,5 +95,52 @@ describe('SettingsImporter', function () {
should.exist(problem);
});
it('Adds a problem if unable to parse data from slack configuration', function () {
const fakeSettings = [{
key: 'slack',
value: 'invalid JSON here'
}];
const fakeExistingSettings = [{
key: 'slack_username',
value: 'Ghost'
}];
const importer = new SettingsImporter({settings: fakeSettings}, {dataKeyToImport: 'settings'});
importer.existingData = fakeExistingSettings;
importer.beforeImport();
const problem = find(importer.problems, {
message: 'Failed to parse the value of slack setting value'
});
should.exist(problem);
});
it('Ignores slack URL from import files in all forms', function () {
const fakeSettings = [{
key: 'slack',
value: `[{"url":"https://slack.url","username":"Test Name"}]`,
created_at: '2021-02-10T01:26:08.452Z',
updated_at: '2021-02-10T01:26:08.452Z'
}, {
key: 'slack_url',
value: 'https://second-slack.url',
created_at: '2021-02-10T01:26:08.452Z',
updated_at: '2021-02-10T01:26:08.452Z'
}];
const importer = new SettingsImporter({settings: fakeSettings}, {dataKeyToImport: 'settings'});
importer.beforeImport();
importer.problems.length.should.equal(0);
importer.dataToImport.length.should.equal(1);
importer.dataToImport[0].key.should.equal('slack_username');
importer.dataToImport[0].value.should.equal('Test Name');
});
});
});

View file

@ -15,9 +15,7 @@ const schema = require('../../../core/server/data/schema').checks;
const settingsCache = require('../../../core/server/services/settings/cache');
// Test data
const slackObjNoUrl = [{url: ''}];
const slackObjWithUrl = [{url: 'https://hooks.slack.com/services/a-b-c-d'}];
const slackURL = 'https://hooks.slack.com/services/a-b-c-d';
describe('Slack', function () {
let eventStub;
@ -130,7 +128,7 @@ describe('Slack', function () {
urlService.getUrlByResourceId.withArgs(post.id, {absolute: true}).returns('http://myblog.com/' + post.slug + '/');
isPostStub.returns(true);
settingsCacheStub.withArgs('slack').returns(slackObjWithUrl);
settingsCacheStub.withArgs('slack_url').returns(slackURL);
// execute code
ping(post);
@ -139,12 +137,12 @@ describe('Slack', function () {
makeRequestStub.calledOnce.should.be.true();
isPostStub.calledTwice.should.be.true();
urlService.getUrlByResourceId.calledOnce.should.be.true();
settingsCacheStub.calledWith('slack').should.be.true();
settingsCacheStub.calledWith('slack_url').should.be.true();
requestUrl = makeRequestStub.firstCall.args[0];
requestData = JSON.parse(makeRequestStub.firstCall.args[1].body);
requestUrl.should.equal(slackObjWithUrl[0].url);
requestUrl.should.equal(slackURL);
requestData.attachments[0].title.should.equal(post.title);
requestData.attachments[0].title_link.should.equal('http://myblog.com/webhook-test/');
requestData.attachments[0].fields[0].value.should.equal('## markdown.');
@ -160,7 +158,7 @@ describe('Slack', function () {
let requestData;
isPostStub.returns(false);
settingsCacheStub.withArgs('slack').returns(slackObjWithUrl);
settingsCacheStub.withArgs('slack_url').returns(slackURL);
// execute code
ping({message: 'Hi!'});
@ -169,12 +167,12 @@ describe('Slack', function () {
makeRequestStub.calledOnce.should.be.true();
isPostStub.calledTwice.should.be.true();
urlService.getUrlByResourceId.called.should.be.false();
settingsCacheStub.calledWith('slack').should.be.true();
settingsCacheStub.calledWith('slack_url').should.be.true();
requestUrl = makeRequestStub.firstCall.args[0];
requestData = JSON.parse(makeRequestStub.firstCall.args[1].body);
requestUrl.should.equal(slackObjWithUrl[0].url);
requestUrl.should.equal(slackURL);
requestData.text.should.equal('Hi!');
requestData.icon_url.should.equal('http://myblog.com/favicon.ico');
requestData.username.should.equal('Ghost');
@ -183,7 +181,7 @@ describe('Slack', function () {
it('makes a request and errors', function (done) {
makeRequestStub.rejects();
settingsCacheStub.withArgs('slack').returns(slackObjWithUrl);
settingsCacheStub.withArgs('slack_url').returns(slackURL);
// execute code
ping({});
@ -201,7 +199,7 @@ describe('Slack', function () {
it('does not make a request if post is a page', function () {
const post = testUtils.DataGenerator.forKnex.createPost({type: 'page'});
isPostStub.returns(true);
settingsCacheStub.withArgs('slack').returns(slackObjWithUrl);
settingsCacheStub.withArgs('slack_url').returns(slackURL);
// execute code
ping(post);
@ -210,13 +208,13 @@ describe('Slack', function () {
makeRequestStub.calledOnce.should.be.false();
isPostStub.calledOnce.should.be.true();
urlService.getUrlByResourceId.calledOnce.should.be.true();
settingsCacheStub.calledWith('slack').should.be.true();
settingsCacheStub.calledWith('slack_url').should.be.true();
});
it('does not send webhook for \'welcome\' post', function () {
const post = testUtils.DataGenerator.forKnex.createPost({slug: 'welcome'});
isPostStub.returns(true);
settingsCacheStub.withArgs('slack').returns(slackObjWithUrl);
settingsCacheStub.withArgs('slack_url').returns(slackURL);
// execute code
ping(post);
@ -225,12 +223,12 @@ describe('Slack', function () {
makeRequestStub.calledOnce.should.be.false();
isPostStub.calledOnce.should.be.true();
urlService.getUrlByResourceId.calledOnce.should.be.true();
settingsCacheStub.calledWith('slack').should.be.true();
settingsCacheStub.calledWith('slack_url').should.be.true();
});
it('handles broken slack settings', function () {
const post = testUtils.DataGenerator.forKnex.createPost({slug: 'any'});
settingsCacheStub.withArgs('slack').returns();
settingsCacheStub.withArgs('slack_url').returns();
// execute code
ping(post);
@ -239,7 +237,7 @@ describe('Slack', function () {
makeRequestStub.calledOnce.should.be.false();
isPostStub.calledOnce.should.be.true();
urlService.getUrlByResourceId.called.should.be.false();
settingsCacheStub.calledWith('slack').should.be.true();
settingsCacheStub.calledWith('slack_url').should.be.true();
});
});
});

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff