From 5d625cebca21c8ca900d61a7120f37e3976beda1 Mon Sep 17 00:00:00 2001 From: Dustin Breese Date: Tue, 13 Jun 2023 07:21:59 -0600 Subject: [PATCH 1/5] Refactored orgutils to use a reject() when checking for username. --- src/commands/authorizeCommand.ts | 44 +++++++++---------- .../commands/authorizeToOrgCommand.test.ts | 2 +- src/test/suite/utils/orgUtils.test.ts | 28 ++++++++++++ src/utils/orgUtils.ts | 9 ++-- 4 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/commands/authorizeCommand.ts b/src/commands/authorizeCommand.ts index 68e8f4f..c7bda8e 100644 --- a/src/commands/authorizeCommand.ts +++ b/src/commands/authorizeCommand.ts @@ -5,37 +5,37 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ -import { commands, window } from 'vscode'; +import { commands, window, l10n } from 'vscode'; import { OrgUtils } from '../utils/orgUtils'; export class AuthorizeCommand { static async authorizeToOrg(): Promise { - const user = await OrgUtils.getDefaultUser(); + let userAuthorized = false; + await OrgUtils.getDefaultUser() + .then(() => { + userAuthorized = true; + }) + .catch(async (err) => { + // Ask user to authorize to an org now only if not authorized yet. + const result = await window.showInformationMessage( + l10n.t('Do you want to authorize an Org now?'), + { title: l10n.t('Authorize') }, + { title: l10n.t('No') } + ); - // Ask user to authorize to an org now only if not authorized yet. - if (user === 'undefined') { - const result = await window.showInformationMessage( - 'Do you want to authorize an Org now?', - { title: 'Authorize' }, - { title: 'No' } - ); - - if (result) { - if (result.title === 'No') { - return Promise.resolve(false); + if (!result || result.title === l10n.t('No')) { + userAuthorized = false; } else { await commands.executeCommand('sfdx.force.auth.web.login'); await window.showInformationMessage( - "Once you've authorized your Org, click here to continue.", - { title: 'OK' } + l10n.t( + "Once you've authorized your Org, click here to continue." + ), + { title: l10n.t('OK') } ); - return Promise.resolve(true); + userAuthorized = true; } - } else { - return Promise.resolve(false); - } - } else { - return Promise.resolve(true); - } + }); + return Promise.resolve(userAuthorized); } } diff --git a/src/test/suite/commands/authorizeToOrgCommand.test.ts b/src/test/suite/commands/authorizeToOrgCommand.test.ts index 592973b..341f285 100644 --- a/src/test/suite/commands/authorizeToOrgCommand.test.ts +++ b/src/test/suite/commands/authorizeToOrgCommand.test.ts @@ -30,7 +30,7 @@ suite('Authorize Org Command Test Suite', () => { test('Authorization cancelled by the user', async () => { // setup up so that org is not authorized yet const getDefaultUserStub = sinon.stub(OrgUtils, 'getDefaultUser'); - getDefaultUserStub.onCall(0).resolves('undefined'); + getDefaultUserStub.onCall(0).rejects(false); // simulate user choosing not to authorize const showInformationMessageStub = sinon.stub( diff --git a/src/test/suite/utils/orgUtils.test.ts b/src/test/suite/utils/orgUtils.test.ts index fd845de..931f262 100644 --- a/src/test/suite/utils/orgUtils.test.ts +++ b/src/test/suite/utils/orgUtils.test.ts @@ -90,6 +90,34 @@ suite('Org Utils Test Suite', () => { assert.equal(reloadSpy.called, true, 'reload should be invoked'); }); + test('Username is not determined.', async () => { + const reloadSpy = sinon.spy(() => { + return Promise.resolve; + }); + + const config: SinonStub = sinon.stub(ConfigAggregator, 'create'); + config.returns({ + getInfo: (key: OrgConfigProperties) => { + switch (key) { + case OrgConfigProperties.TARGET_ORG: + return undefined; + default: + return 'BAD'; + } + }, + reload: reloadSpy + }); + + let expectedConditionReached = false; + const defaultUser = await OrgUtils.getDefaultUser() + .catch((err) => { + expectedConditionReached = true; + }); + + assert.equal(expectedConditionReached, true); + }); + + test('Returns list of sobjects', async () => { const orgStub: SinonStub = sinon.stub(Org, 'create'); const stubConnection = sinon.createStubInstance(Connection); diff --git a/src/utils/orgUtils.ts b/src/utils/orgUtils.ts index 0238ccc..22a1dd9 100644 --- a/src/utils/orgUtils.ts +++ b/src/utils/orgUtils.ts @@ -75,9 +75,10 @@ export class OrgUtils { const currentUserConfig = aggregator.getInfo( OrgConfigProperties.TARGET_ORG ); - const currentUser = currentUserConfig.value - ? currentUserConfig.value - : 'undefined'; - return Promise.resolve(currentUser.toString()); + + if (currentUserConfig && currentUserConfig.value) { + return Promise.resolve(currentUserConfig.value.toString()); + } + return Promise.reject("no user"); } } From 39f46d04290d1a6a39532c09e2fd38006d622915 Mon Sep 17 00:00:00 2001 From: Dustin Breese Date: Tue, 13 Jun 2023 07:31:59 -0600 Subject: [PATCH 2/5] L10n strings --- src/commands/briefcaseCommand.ts | 8 ++--- src/commands/configureProjectCommand.ts | 44 +++++++++++++++---------- src/commands/deployToOrgCommand.ts | 14 ++++---- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/commands/briefcaseCommand.ts b/src/commands/briefcaseCommand.ts index 533b2b1..1a56329 100644 --- a/src/commands/briefcaseCommand.ts +++ b/src/commands/briefcaseCommand.ts @@ -12,16 +12,16 @@ import { InstructionsWebviewProvider } from '../webviews'; export class BriefcaseCommand { static async setupBriefcase(extensionUri: Uri): Promise { await window.showInformationMessage( - 'Click OK to launch your org to the Briefcase Builder page. After ' + - 'launching, return here for instructions to set up a Briefcase rule.', - { title: 'OK' } + l10n.t('Click OK to launch your org to the Briefcase Builder page. After ' + + 'launching, return here for instructions to set up a Briefcase rule.'), + { title: l10n.t('OK') } ); // TODO: this `withProgress` call probably needs tweaking on UX. await window.withProgress( { location: ProgressLocation.Notification, - title: 'Launching Briefcase Builder...' + title: l10n.t('Launching Briefcase Builder...') }, async (progress, token) => { await CommonUtils.executeCommandAsync( diff --git a/src/commands/configureProjectCommand.ts b/src/commands/configureProjectCommand.ts index 8434cc2..08b7af1 100644 --- a/src/commands/configureProjectCommand.ts +++ b/src/commands/configureProjectCommand.ts @@ -5,9 +5,13 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ -import { QuickPickItem, QuickPickOptions, commands, window } from 'vscode'; -import { CommonUtils } from '@salesforce/lwc-dev-mobile-core/lib/common/CommonUtils'; -import { InstructionsWebviewProvider } from '../webviews'; +import { + QuickPickItem, + QuickPickOptions, + commands, + window, + l10n +} from 'vscode'; export class ConfigureProjectCommand { static async configureProject( @@ -15,18 +19,22 @@ export class ConfigureProjectCommand { ): Promise { return new Promise(async (resolve, reject) => { const header: QuickPickOptions = { - placeHolder: 'Create a new project, or open an existing project' + placeHolder: l10n.t( + 'Create a new project, or open an existing project' + ) }; const items: QuickPickItem[] = [ { - label: 'Create New Project...', - description: + label: l10n.t('Create New Project...'), + description: l10n.t( 'Creates a new local project configured with the Offline Starter Kit' + ) }, { - label: 'Open Existing Project...', - description: + label: l10n.t('Open Existing Project...'), + description: l10n.t( 'Opens an existing local project configured with the Offline Starter Kit' + ) } ]; const selected = await window.showQuickPick(items, header); @@ -34,9 +42,9 @@ export class ConfigureProjectCommand { return resolve(''); } - if (selected.label === 'Create New Project...') { + if (selected.label === l10n.t('Create New Project...')) { const folderUri = await window.showOpenDialog({ - openLabel: 'Select project folder', + openLabel: l10n.t('Select project folder'), canSelectFolders: true, canSelectFiles: false, canSelectMany: false @@ -45,14 +53,16 @@ export class ConfigureProjectCommand { return resolve(''); } - let infoMessage = - 'Follow the prompts to configure the project.'; + let infoMessage = l10n.t( + 'Follow the prompts to configure the project.' + ); if (fromWizard) { - infoMessage += - ' NOTE: after the project is loaded, please be patient while the wizard resumes.'; + infoMessage += l10n.t( + ' NOTE: after the project is loaded, please be patient while the wizard resumes.' + ); } await window.showInformationMessage(infoMessage, { - title: 'OK' + title: l10n.t('OK') }); const githubRepoUri: string = 'https://github.com/salesforce/offline-app-developer-starter-kit.git'; @@ -64,10 +74,10 @@ export class ConfigureProjectCommand { ); return resolve(folderUri[0].fsPath); } catch (error) { - window.showErrorMessage(`Failed to clone: ${error}`); + window.showErrorMessage(l10n.t('Failed to clone: {error}', [error])); return reject(error); } - } else if (selected.label === 'Open Existing Project...') { + } else if (selected.label === l10n.t('Open Existing Project...')) { console.log('Open existing project'); return resolve(''); } else { diff --git a/src/commands/deployToOrgCommand.ts b/src/commands/deployToOrgCommand.ts index 29fd5c9..b24f6dd 100644 --- a/src/commands/deployToOrgCommand.ts +++ b/src/commands/deployToOrgCommand.ts @@ -6,26 +6,26 @@ */ import path = require('path'); -import { Uri, commands, window, workspace } from 'vscode'; +import { Uri, commands, window, workspace, l10n } from 'vscode'; export class DeployToOrgCommand { static async deployToOrg(): Promise { const currentWorkspace = workspace; if (!currentWorkspace.workspaceFolders) { await window.showErrorMessage( - 'There are no workspace folders defined in your project.', - { title: 'OK' } + l10n.t('There are no workspace folders defined in your project.'), + { title: l10n.t('OK') } ); return Promise.resolve(false); } const result = await window.showInformationMessage( - 'Do you want to deploy to an already-authorized Org?', - { title: 'Deploy' }, - { title: 'Cancel' } + l10n.t('Do you want to deploy to an already-authorized Org?'), + { title: l10n.t('Deploy') }, + { title: l10n.t('Cancel') } ); - if (!result || result.title === 'Cancel') { + if (!result || result.title === l10n.t('Cancel')) { return Promise.resolve(false); } From 6e1d9471c1b2d3e337b8deb7089704edb30e00c4 Mon Sep 17 00:00:00 2001 From: Dustin Breese Date: Tue, 13 Jun 2023 11:29:55 -0600 Subject: [PATCH 3/5] Reverting configureProjectCommand.ts to avoid merge conflicts. --- src/commands/configureProjectCommand.ts | 44 ++++++++++--------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/src/commands/configureProjectCommand.ts b/src/commands/configureProjectCommand.ts index 08b7af1..8434cc2 100644 --- a/src/commands/configureProjectCommand.ts +++ b/src/commands/configureProjectCommand.ts @@ -5,13 +5,9 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT */ -import { - QuickPickItem, - QuickPickOptions, - commands, - window, - l10n -} from 'vscode'; +import { QuickPickItem, QuickPickOptions, commands, window } from 'vscode'; +import { CommonUtils } from '@salesforce/lwc-dev-mobile-core/lib/common/CommonUtils'; +import { InstructionsWebviewProvider } from '../webviews'; export class ConfigureProjectCommand { static async configureProject( @@ -19,22 +15,18 @@ export class ConfigureProjectCommand { ): Promise { return new Promise(async (resolve, reject) => { const header: QuickPickOptions = { - placeHolder: l10n.t( - 'Create a new project, or open an existing project' - ) + placeHolder: 'Create a new project, or open an existing project' }; const items: QuickPickItem[] = [ { - label: l10n.t('Create New Project...'), - description: l10n.t( + label: 'Create New Project...', + description: 'Creates a new local project configured with the Offline Starter Kit' - ) }, { - label: l10n.t('Open Existing Project...'), - description: l10n.t( + label: 'Open Existing Project...', + description: 'Opens an existing local project configured with the Offline Starter Kit' - ) } ]; const selected = await window.showQuickPick(items, header); @@ -42,9 +34,9 @@ export class ConfigureProjectCommand { return resolve(''); } - if (selected.label === l10n.t('Create New Project...')) { + if (selected.label === 'Create New Project...') { const folderUri = await window.showOpenDialog({ - openLabel: l10n.t('Select project folder'), + openLabel: 'Select project folder', canSelectFolders: true, canSelectFiles: false, canSelectMany: false @@ -53,16 +45,14 @@ export class ConfigureProjectCommand { return resolve(''); } - let infoMessage = l10n.t( - 'Follow the prompts to configure the project.' - ); + let infoMessage = + 'Follow the prompts to configure the project.'; if (fromWizard) { - infoMessage += l10n.t( - ' NOTE: after the project is loaded, please be patient while the wizard resumes.' - ); + infoMessage += + ' NOTE: after the project is loaded, please be patient while the wizard resumes.'; } await window.showInformationMessage(infoMessage, { - title: l10n.t('OK') + title: 'OK' }); const githubRepoUri: string = 'https://github.com/salesforce/offline-app-developer-starter-kit.git'; @@ -74,10 +64,10 @@ export class ConfigureProjectCommand { ); return resolve(folderUri[0].fsPath); } catch (error) { - window.showErrorMessage(l10n.t('Failed to clone: {error}', [error])); + window.showErrorMessage(`Failed to clone: ${error}`); return reject(error); } - } else if (selected.label === l10n.t('Open Existing Project...')) { + } else if (selected.label === 'Open Existing Project...') { console.log('Open existing project'); return resolve(''); } else { From 26ca8b536a582c8fa06dff5ed8fc5d3e0b413508 Mon Sep 17 00:00:00 2001 From: Dustin Breese Date: Tue, 13 Jun 2023 15:14:01 -0600 Subject: [PATCH 4/5] Updated to not use then() and catch() Ran prettier, too. --- src/commands/authorizeCommand.ts | 49 +++++++++++++-------------- src/commands/briefcaseCommand.ts | 6 ++-- src/commands/deployToOrgCommand.ts | 4 ++- src/test/suite/utils/orgUtils.test.ts | 6 ++-- src/utils/orgUtils.ts | 2 +- 5 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/commands/authorizeCommand.ts b/src/commands/authorizeCommand.ts index c7bda8e..33d4319 100644 --- a/src/commands/authorizeCommand.ts +++ b/src/commands/authorizeCommand.ts @@ -10,32 +10,29 @@ import { OrgUtils } from '../utils/orgUtils'; export class AuthorizeCommand { static async authorizeToOrg(): Promise { - let userAuthorized = false; - await OrgUtils.getDefaultUser() - .then(() => { - userAuthorized = true; - }) - .catch(async (err) => { - // Ask user to authorize to an org now only if not authorized yet. - const result = await window.showInformationMessage( - l10n.t('Do you want to authorize an Org now?'), - { title: l10n.t('Authorize') }, - { title: l10n.t('No') } - ); + try { + await OrgUtils.getDefaultUser(); + return Promise.resolve(true); + } catch { + // Ask user to authorize to an org now only if not authorized yet. + const result = await window.showInformationMessage( + l10n.t('Do you want to authorize an Org now?'), + { title: l10n.t('Authorize') }, + { title: l10n.t('No') } + ); - if (!result || result.title === l10n.t('No')) { - userAuthorized = false; - } else { - await commands.executeCommand('sfdx.force.auth.web.login'); - await window.showInformationMessage( - l10n.t( - "Once you've authorized your Org, click here to continue." - ), - { title: l10n.t('OK') } - ); - userAuthorized = true; - } - }); - return Promise.resolve(userAuthorized); + if (!result || result.title === l10n.t('No')) { + return Promise.resolve(false); + } else { + await commands.executeCommand('sfdx.force.auth.web.login'); + await window.showInformationMessage( + l10n.t( + "Once you've authorized your Org, click here to continue." + ), + { title: l10n.t('OK') } + ); + return Promise.resolve(true); + } + } } } diff --git a/src/commands/briefcaseCommand.ts b/src/commands/briefcaseCommand.ts index 1a56329..38e130b 100644 --- a/src/commands/briefcaseCommand.ts +++ b/src/commands/briefcaseCommand.ts @@ -12,8 +12,10 @@ import { InstructionsWebviewProvider } from '../webviews'; export class BriefcaseCommand { static async setupBriefcase(extensionUri: Uri): Promise { await window.showInformationMessage( - l10n.t('Click OK to launch your org to the Briefcase Builder page. After ' + - 'launching, return here for instructions to set up a Briefcase rule.'), + l10n.t( + 'Click OK to launch your org to the Briefcase Builder page. After ' + + 'launching, return here for instructions to set up a Briefcase rule.' + ), { title: l10n.t('OK') } ); diff --git a/src/commands/deployToOrgCommand.ts b/src/commands/deployToOrgCommand.ts index b24f6dd..0dc20b4 100644 --- a/src/commands/deployToOrgCommand.ts +++ b/src/commands/deployToOrgCommand.ts @@ -13,7 +13,9 @@ export class DeployToOrgCommand { const currentWorkspace = workspace; if (!currentWorkspace.workspaceFolders) { await window.showErrorMessage( - l10n.t('There are no workspace folders defined in your project.'), + l10n.t( + 'There are no workspace folders defined in your project.' + ), { title: l10n.t('OK') } ); return Promise.resolve(false); diff --git a/src/test/suite/utils/orgUtils.test.ts b/src/test/suite/utils/orgUtils.test.ts index 931f262..8295bef 100644 --- a/src/test/suite/utils/orgUtils.test.ts +++ b/src/test/suite/utils/orgUtils.test.ts @@ -94,7 +94,7 @@ suite('Org Utils Test Suite', () => { const reloadSpy = sinon.spy(() => { return Promise.resolve; }); - + const config: SinonStub = sinon.stub(ConfigAggregator, 'create'); config.returns({ getInfo: (key: OrgConfigProperties) => { @@ -109,15 +109,13 @@ suite('Org Utils Test Suite', () => { }); let expectedConditionReached = false; - const defaultUser = await OrgUtils.getDefaultUser() - .catch((err) => { + const defaultUser = await OrgUtils.getDefaultUser().catch((err) => { expectedConditionReached = true; }); assert.equal(expectedConditionReached, true); }); - test('Returns list of sobjects', async () => { const orgStub: SinonStub = sinon.stub(Org, 'create'); const stubConnection = sinon.createStubInstance(Connection); diff --git a/src/utils/orgUtils.ts b/src/utils/orgUtils.ts index 22a1dd9..87429d2 100644 --- a/src/utils/orgUtils.ts +++ b/src/utils/orgUtils.ts @@ -79,6 +79,6 @@ export class OrgUtils { if (currentUserConfig && currentUserConfig.value) { return Promise.resolve(currentUserConfig.value.toString()); } - return Promise.reject("no user"); + return Promise.reject('no user'); } } From 9f617b3134eb6223a3d7476b437dab96e6339f33 Mon Sep 17 00:00:00 2001 From: Dustin Breese Date: Tue, 13 Jun 2023 15:28:39 -0600 Subject: [PATCH 5/5] Concatenated strings are not picked up by the l10n dev script (npm run genl10n) --- src/commands/briefcaseCommand.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/commands/briefcaseCommand.ts b/src/commands/briefcaseCommand.ts index 38e130b..cc0e01b 100644 --- a/src/commands/briefcaseCommand.ts +++ b/src/commands/briefcaseCommand.ts @@ -13,8 +13,7 @@ export class BriefcaseCommand { static async setupBriefcase(extensionUri: Uri): Promise { await window.showInformationMessage( l10n.t( - 'Click OK to launch your org to the Briefcase Builder page. After ' + - 'launching, return here for instructions to set up a Briefcase rule.' + 'Click OK to launch your org to the Briefcase Builder page. After launching, return here for instructions to set up a Briefcase rule.' ), { title: l10n.t('OK') } );