From 0c4ea7f8bbab2c98448d4fd40ea8573ea6d39ce6 Mon Sep 17 00:00:00 2001 From: Gavin Palmer Date: Thu, 7 Jul 2022 14:56:01 +0100 Subject: [PATCH 1/2] Adding changes for an email deliverability switch, also a couple of minor housekeeping tasks, including the new .sf folder into gitignore and adding curly braces around the class import in the template to avoid liniting warnings --- .gitignore | 1 + _templates/plugin/new/index.e2e-spec.ejs.t | 2 +- src/plugins/email-deliverability/all.json | 8 ++ .../email-deliverability/index.e2e-spec.ts | 94 +++++++++++++++++++ src/plugins/email-deliverability/index.ts | 49 ++++++++++ src/plugins/email-deliverability/invalid.json | 8 ++ .../email-deliverability/no-access.json | 8 ++ src/plugins/email-deliverability/schema.json | 14 +++ src/plugins/email-deliverability/system.json | 8 ++ src/plugins/index.ts | 2 + src/plugins/schema.json | 3 + 11 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 src/plugins/email-deliverability/all.json create mode 100644 src/plugins/email-deliverability/index.e2e-spec.ts create mode 100644 src/plugins/email-deliverability/index.ts create mode 100644 src/plugins/email-deliverability/invalid.json create mode 100644 src/plugins/email-deliverability/no-access.json create mode 100644 src/plugins/email-deliverability/schema.json create mode 100644 src/plugins/email-deliverability/system.json diff --git a/.gitignore b/.gitignore index 61d166b7..b46a668c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,6 @@ /tmp node_modules /.sfdx +/.sf .vscode/settings.json diff --git a/_templates/plugin/new/index.e2e-spec.ejs.t b/_templates/plugin/new/index.e2e-spec.ejs.t index e2362644..20333b16 100644 --- a/_templates/plugin/new/index.e2e-spec.ejs.t +++ b/_templates/plugin/new/index.e2e-spec.ejs.t @@ -4,7 +4,7 @@ to: src/plugins/<%= h.changeCase.paramCase(name) %>/index.e2e-spec.ts import * as assert from 'assert'; import * as child from 'child_process'; import * as path from 'path'; -import <%= h.changeCase.pascalCase(name) %> from '.'; +import { <%= h.changeCase.pascalCase(name) %> } from '.'; describe(<%= h.changeCase.pascalCase(name) %>.name, function() { this.slow('30s'); diff --git a/src/plugins/email-deliverability/all.json b/src/plugins/email-deliverability/all.json new file mode 100644 index 00000000..1e556580 --- /dev/null +++ b/src/plugins/email-deliverability/all.json @@ -0,0 +1,8 @@ +{ + "$schema": "../schema.json", + "settings": { + "emailDeliverability": { + "accessLevel": "All email" + } + } +} diff --git a/src/plugins/email-deliverability/index.e2e-spec.ts b/src/plugins/email-deliverability/index.e2e-spec.ts new file mode 100644 index 00000000..256f92ae --- /dev/null +++ b/src/plugins/email-deliverability/index.e2e-spec.ts @@ -0,0 +1,94 @@ +import * as assert from 'assert'; +import * as child from 'child_process'; +import * as path from 'path'; +import { EmailDeliverability } from '.'; + +describe(EmailDeliverability.name, function() { + this.slow('30s'); + this.timeout('2m'); + // Note order is important here, the scratch org will be created with all access set, I have placed last so if a scratch is reused at least it is in the same state + it('should set "no access"', () => { + const applyNoAccessCmd = child.spawnSync(path.resolve('bin', 'run'), [ + 'browserforce:apply', + '-f', + path.resolve(path.join(__dirname, 'no-access.json')) + ]); + assert.deepStrictEqual(applyNoAccessCmd.status, 0, applyNoAccessCmd.output.toString()); + assert( + /to '"No access"'/.test(applyNoAccessCmd.output.toString()), + applyNoAccessCmd.output.toString() + ); + }); + it('should already be set to "no access"', () => { + const applyNoAccessCmd = child.spawnSync(path.resolve('bin', 'run'), [ + 'browserforce:apply', + '-f', + path.join(__dirname, 'no-access.json') + ]); + assert.deepStrictEqual(applyNoAccessCmd.status, 0, applyNoAccessCmd.output.toString()); + assert( + /no action necessary/.test(applyNoAccessCmd.output.toString()), + applyNoAccessCmd.output.toString() + ); + }); + it('should set "syetem only"', () => { + const systemEmailCmd = child.spawnSync(path.resolve('bin', 'run'), [ + 'browserforce:apply', + '-f', + path.resolve(path.join(__dirname, 'system.json')) + ]); + assert.deepStrictEqual(systemEmailCmd.status, 0, systemEmailCmd.output.toString()); + assert( + /to '"System email only"'/.test(systemEmailCmd.output.toString()), + systemEmailCmd.output.toString() + ); + }); + it('should already be set to no access', () => { + const systemEmailCmd = child.spawnSync(path.resolve('bin', 'run'), [ + 'browserforce:apply', + '-f', + path.join(__dirname, 'system.json') + ]); + assert.deepStrictEqual(systemEmailCmd.status, 0, systemEmailCmd.output.toString()); + assert( + /no action necessary/.test(systemEmailCmd.output.toString()), + systemEmailCmd.output.toString() + ); + }); + it('should apply all email', () => { + const applyAllCmd = child.spawnSync(path.resolve('bin', 'run'), [ + 'browserforce:apply', + '-f', + path.resolve(path.join(__dirname, 'all.json')) + ]); + assert.deepStrictEqual(applyAllCmd.status, 0, applyAllCmd.output.toString()); + assert( + /to '"All email"'/.test(applyAllCmd.output.toString()), + applyAllCmd.output.toString() + ); + }); + it('should already be have all enabled', () => { + const applyAllCmd = child.spawnSync(path.resolve('bin', 'run'), [ + 'browserforce:apply', + '-f', + path.join(__dirname, 'all.json') + ]); + assert.deepStrictEqual(applyAllCmd.status, 0, applyAllCmd.output.toString()); + assert( + /no action necessary/.test(applyAllCmd.output.toString()), + applyAllCmd.output.toString() + ); + }); + it('should error on invalid input', () => { + const systemEmailCmd = child.spawnSync(path.resolve('bin', 'run'), [ + 'browserforce:apply', + '-f', + path.join(__dirname, 'invalid.json') + ]); + assert.notDeepStrictEqual(systemEmailCmd.status, 0, systemEmailCmd.output.toString()); + assert( + /Invalid email access level/.test(systemEmailCmd.output.toString()), + systemEmailCmd.output.toString() + ); + }); +}); diff --git a/src/plugins/email-deliverability/index.ts b/src/plugins/email-deliverability/index.ts new file mode 100644 index 00000000..0031e7e6 --- /dev/null +++ b/src/plugins/email-deliverability/index.ts @@ -0,0 +1,49 @@ +import { BrowserforcePlugin } from '../../plugin'; + +const PATHS = { + BASE: 'email-admin/editOrgEmailSettings.apexp' +}; +const SELECTORS = { + ACCESS_LEVEL: 'select[id$=":sendEmailAccessControlSelect"]', + CONFIRM_MESSAGE: 'span[id$=":successText"]', + SAVE_BUTTON: 'input[id$=":saveBtn"]' +}; +const ACCESS_LEVEL_VALUES = new Map([ + ['No access', '0',], + ['System email only', '1',], + ['All email', '2'] +]); + +type Config = { + accessLevel: string; +}; + +export class EmailDeliverability extends BrowserforcePlugin { + public async retrieve(definition?: Config): Promise { + if (!ACCESS_LEVEL_VALUES.has(definition.accessLevel)) { + throw new Error(`Invalid email access level ${definition.accessLevel}`); + } + const page = await this.browserforce.openPage(PATHS.BASE); + await page.waitForSelector(SELECTORS.ACCESS_LEVEL); + const selectedOptions = await page.$$eval( + `${SELECTORS.ACCESS_LEVEL} > option[selected]`, + options => options.map(option => option.textContent) + ); + if (!selectedOptions) { + throw new Error('Selected access level not found...') + } + return { + accessLevel: selectedOptions[0] + };; + } + + public async apply(config: Config): Promise { + const page = await this.browserforce.openPage(PATHS.BASE); + await page.waitForSelector(SELECTORS.ACCESS_LEVEL); + await page.select(SELECTORS.ACCESS_LEVEL, ACCESS_LEVEL_VALUES.get(config.accessLevel)); + await Promise.all([ + page.waitForSelector(SELECTORS.CONFIRM_MESSAGE), + page.click(SELECTORS.SAVE_BUTTON) + ]); + } +} diff --git a/src/plugins/email-deliverability/invalid.json b/src/plugins/email-deliverability/invalid.json new file mode 100644 index 00000000..a5d9d3e3 --- /dev/null +++ b/src/plugins/email-deliverability/invalid.json @@ -0,0 +1,8 @@ +{ + "$schema": "../schema.json", + "settings": { + "emailDeliverability": { + "accessLevel": "Invalid" + } + } +} diff --git a/src/plugins/email-deliverability/no-access.json b/src/plugins/email-deliverability/no-access.json new file mode 100644 index 00000000..d58872bf --- /dev/null +++ b/src/plugins/email-deliverability/no-access.json @@ -0,0 +1,8 @@ +{ + "$schema": "../schema.json", + "settings": { + "emailDeliverability": { + "accessLevel": "No access" + } + } +} diff --git a/src/plugins/email-deliverability/schema.json b/src/plugins/email-deliverability/schema.json new file mode 100644 index 00000000..651f5833 --- /dev/null +++ b/src/plugins/email-deliverability/schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "https://github.com/amtrack/sfdx-browserforce-plugin/src/plugins/density-settings/schema.json", + "title": "Email Deliverability Settings", + "type": "object", + "properties": { + "accessLevel": { + "title": "Access Level", + "description": "Choose the email Deliverability Access Level required", + "type": "string", + "enum": ["No access", "System email only", "All email"] + } + } +} diff --git a/src/plugins/email-deliverability/system.json b/src/plugins/email-deliverability/system.json new file mode 100644 index 00000000..e5d2631f --- /dev/null +++ b/src/plugins/email-deliverability/system.json @@ -0,0 +1,8 @@ +{ + "$schema": "../schema.json", + "settings": { + "emailDeliverability": { + "accessLevel": "System email only" + } + } +} diff --git a/src/plugins/index.ts b/src/plugins/index.ts index 52c9700e..4e7f9dc4 100644 --- a/src/plugins/index.ts +++ b/src/plugins/index.ts @@ -3,6 +3,7 @@ import { Communities as communities } from './communities'; import { CustomerPortal as customerPortal } from './customer-portal'; import { DeferSharingCalculation as deferSharingCalculation } from './defer-sharing-calculation'; import { DensitySettings as densitySettings } from './density-settings'; +import { EmailDeliverability as emailDeliverability } from './email-deliverability'; import { HighVelocitySalesSettings as highVelocitySalesSettings } from './high-velocity-sales-settings'; import { HomePageLayouts as homePageLayouts } from './home-page-layouts'; import { LightningExperienceSettings as lightningExperienceSettings } from './lightning-experience-settings'; @@ -21,6 +22,7 @@ export { customerPortal, deferSharingCalculation, densitySettings, + emailDeliverability, highVelocitySalesSettings, homePageLayouts, lightningExperienceSettings, diff --git a/src/plugins/schema.json b/src/plugins/schema.json index 25666658..59866143 100644 --- a/src/plugins/schema.json +++ b/src/plugins/schema.json @@ -22,6 +22,9 @@ "deferSharingCalculation": { "$ref": "./defer-sharing-calculation/schema.json" }, + "emailDeliverability": { + "$ref": "./email-deliverability/schema.json" + }, "lightningExperienceSettings": { "$ref": "./lightning-experience-settings/schema.json" }, From 7ebc7d7a33bb712af7ce32f18f876eee547b6235 Mon Sep 17 00:00:00 2001 From: Matthias Rolke Date: Thu, 7 Jul 2022 16:29:54 +0200 Subject: [PATCH 2/2] fix typo --- src/plugins/email-deliverability/index.e2e-spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/email-deliverability/index.e2e-spec.ts b/src/plugins/email-deliverability/index.e2e-spec.ts index 256f92ae..52e8ede6 100644 --- a/src/plugins/email-deliverability/index.e2e-spec.ts +++ b/src/plugins/email-deliverability/index.e2e-spec.ts @@ -31,7 +31,7 @@ describe(EmailDeliverability.name, function() { applyNoAccessCmd.output.toString() ); }); - it('should set "syetem only"', () => { + it('should set "system only"', () => { const systemEmailCmd = child.spawnSync(path.resolve('bin', 'run'), [ 'browserforce:apply', '-f',