diff --git a/ghost/core/core/server/services/settings/settings-bread-service.js b/ghost/core/core/server/services/settings/settings-bread-service.js index d277d81f115..d15434c1dcd 100644 --- a/ghost/core/core/server/services/settings/settings-bread-service.js +++ b/ghost/core/core/server/services/settings/settings-bread-service.js @@ -9,6 +9,7 @@ const sentry = require('../../../shared/sentry'); const EMAIL_KEYS = ['members_support_address']; const PUBLIC_SITE_ACCESS_LOCKED_KEYS = ['is_private', 'password']; +const AUTOMATIONS_LABS_FLAG = 'automations'; const messages = { problemFindingSetting: 'Problem finding setting: {key}', accessCoreSettingFromExtReq: 'Attempted to access core setting from external request', @@ -16,6 +17,22 @@ const messages = { publicSiteAccessLocked: 'Site visibility and access code cannot be changed.' }; +function parseLabsValue(value) { + if (!value) { + return {}; + } + + if (typeof value === 'string') { + try { + return JSON.parse(value); + } catch (err) { + return {}; + } + } + + return value; +} + class SettingsBREADService { /** * @@ -244,6 +261,8 @@ class SettingsBREADService { } } + const shouldLogAutomationsEnabled = this._shouldLogAutomationsEnabled(filteredSettings); + // remove any email properties that are not allowed to be set without verification const {filteredSettings: refilteredSettings, emailsToVerify} = await this.prepSettingsForEmailVerification(filteredSettings, getSetting); @@ -251,6 +270,14 @@ class SettingsBREADService { return this._formatBrowse(_.keyBy(_.invokeMap(result, 'toJSON'), 'key'), options.context); }); + if (shouldLogAutomationsEnabled) { + logging.info({ + event: { + name: 'automations.beta_flag_enabled' + } + }, 'Automations beta flag enabled'); + } + return this.respondWithEmailVerification(modelArray, emailsToVerify); } @@ -333,6 +360,21 @@ class SettingsBREADService { return Boolean(this.limitsService && this.limitsService.isDisabled('publicSiteAccess')); } + _shouldLogAutomationsEnabled(settings) { + const labsSetting = settings.find(setting => setting.key === 'labs'); + if (!labsSetting) { + return false; + } + + const previousLabs = this.labs.getAll(); + if (previousLabs[AUTOMATIONS_LABS_FLAG] === true) { + return false; + } + + const nextLabs = parseLabsValue(labsSetting.value); + return nextLabs[AUTOMATIONS_LABS_FLAG] === true; + } + /** * @private */ diff --git a/ghost/core/test/unit/server/services/settings/settings-bread-service.test.js b/ghost/core/test/unit/server/services/settings/settings-bread-service.test.js index 3ce4abca987..45870969290 100644 --- a/ghost/core/test/unit/server/services/settings/settings-bread-service.test.js +++ b/ghost/core/test/unit/server/services/settings/settings-bread-service.test.js @@ -5,6 +5,7 @@ const SettingsBreadService = require('../../../../../core/server/services/settin const urlUtils = require('../../../../../core/shared/url-utils.js'); const {mockManager} = require('../../../../utils/e2e-framework'); const emailAddress = require('../../../../../core/server/services/email-address'); +const logging = require('@tryghost/logging'); describe('UNIT > Settings BREAD Service:', function () { let emailMockReceiver; @@ -133,6 +134,38 @@ describe('UNIT > Settings BREAD Service:', function () { }); describe('edit', function () { + function createLabsService({automations = false} = {}) { + const labsSetting = { + key: 'labs', + value: JSON.stringify({automations}), + group: 'labs' + }; + + return new SettingsBreadService({ + SettingsModel: { + async edit(changes) { + return changes.map(change => ({ + toJSON: () => ({...labsSetting, ...change}) + })); + } + }, + settingsCache: { + get: sinon + .stub() + .withArgs('labs', {resolve: false}) + .returns(labsSetting) + }, + mail, + urlUtils, + singleUseTokenProvider: {}, + labsService: { + getAll() { + return {automations}; + } + } + }); + } + it('cannot set stripe_connect_secret_key ', async function () { const defaultSettingsManager = new SettingsBreadService({ SettingsModel: { @@ -215,6 +248,46 @@ describe('UNIT > Settings BREAD Service:', function () { emailMockReceiver.matchPlaintextSnapshot(); emailMockReceiver.matchMetadataSnapshot(); }); + + it('logs when automations labs flag is enabled', async function () { + const logStub = sinon.stub(logging, 'info'); + const service = createLabsService({automations: false}); + + await service.edit([{ + key: 'labs', + value: JSON.stringify({automations: true}) + }], {}, null); + + sinon.assert.calledOnceWithExactly(logStub, { + event: { + name: 'automations.beta_flag_enabled' + } + }, 'Automations beta flag enabled'); + }); + + it('does not log when automations labs flag is already enabled', async function () { + const logStub = sinon.stub(logging, 'info'); + const service = createLabsService({automations: true}); + + await service.edit([{ + key: 'labs', + value: JSON.stringify({automations: true}) + }], {}, null); + + sinon.assert.notCalled(logStub); + }); + + it('does not log when automations labs flag is disabled', async function () { + const logStub = sinon.stub(logging, 'info'); + const service = createLabsService({automations: true}); + + await service.edit([{ + key: 'labs', + value: JSON.stringify({automations: false}) + }], {}, null); + + sinon.assert.notCalled(logStub); + }); }); describe('publicSiteAccess limit', function () {