From c2d16492157a2e1c6221b5eb36b7abc8bf72c63e Mon Sep 17 00:00:00 2001 From: Willie Ruemmele Date: Tue, 18 Apr 2023 13:26:51 -0600 Subject: [PATCH] fix: remove -o conflict, add short char UTs, add short chars to NUTs --- messages/deployCommand.md | 8 + src/commands/force/mdapi/deploy.ts | 14 +- src/commands/force/source/deploy.ts | 14 +- src/deployCommand.ts | 37 +- test/commands/source/deploy.test.ts | 1040 ++++++++++++----- test/nuts/REST/deploy.mpd.nut.ts | 4 +- test/nuts/mdapi.nut.ts | 2 +- .../deployRetrieveDelete.nut.ts | 33 + 8 files changed, 846 insertions(+), 306 deletions(-) diff --git a/messages/deployCommand.md b/messages/deployCommand.md index 44586ff6d..f8e2ee4de 100644 --- a/messages/deployCommand.md +++ b/messages/deployCommand.md @@ -17,3 +17,11 @@ Deploying metadata to %s using the v%s %s API. # apiVersionMsgDetailed %s v%s metadata to %s using the v%s %s API. + +# missingUsername + +Unable to determine the username of the org to delete. Specify the username with the --target-org | -u flag. + +# flags.targetusername.summary + +Username or alias of the target org. diff --git a/src/commands/force/mdapi/deploy.ts b/src/commands/force/mdapi/deploy.ts index 036710351..a1d368577 100644 --- a/src/commands/force/mdapi/deploy.ts +++ b/src/commands/force/mdapi/deploy.ts @@ -12,11 +12,16 @@ import { Flags, loglevel, orgApiVersionFlagWithDeprecations, - requiredOrgFlagWithDeprecations, Ux, } from '@salesforce/sf-plugins-core'; import { Interfaces } from '@oclif/core'; -import { DeployCommand, getCoverageFormattersOptions, reportsFormatters, TestLevel } from '../../../deployCommand'; +import { + DeployCommand, + getCoverageFormattersOptions, + reportsFormatters, + targetUsernameFlag, + TestLevel, +} from '../../../deployCommand'; import { DeployCommandAsyncResult } from '../../../formatters/source/deployAsyncResultFormatter'; import { MdDeployResult, MdDeployResultFormatter } from '../../../formatters/mdapi/mdDeployResultFormatter'; import { ProgressFormatter } from '../../../formatters/progressFormatter'; @@ -44,7 +49,7 @@ export class Deploy extends DeployCommand { public static readonly flags = { 'api-version': orgApiVersionFlagWithDeprecations, loglevel, - 'target-org': requiredOrgFlagWithDeprecations, + 'target-org': targetUsernameFlag, checkonly: Flags.boolean({ char: 'c', description: messages.getMessage('flags.checkOnly.description'), @@ -75,6 +80,7 @@ export class Deploy extends DeployCommand { summary: messages.getMessage('flags.runTests.summary'), }), ignoreerrors: Flags.boolean({ + // break this char: 'o', description: messages.getMessage('flags.ignoreErrors.description'), summary: messages.getMessage('flags.ignoreErrors.summary'), @@ -134,7 +140,7 @@ export class Deploy extends DeployCommand { public async run(): Promise { this.flags = (await this.parse(Deploy)).flags; - this.org = this.flags['target-org']; + this.org = await Org.create({ aliasOrUsername: this.flags['target-org'] }); await this.deploy(); this.resolveSuccess(); return this.formatResult(); diff --git a/src/commands/force/source/deploy.ts b/src/commands/force/source/deploy.ts index cf4b8aea7..1feea470a 100644 --- a/src/commands/force/source/deploy.ts +++ b/src/commands/force/source/deploy.ts @@ -14,11 +14,16 @@ import { Flags, loglevel, orgApiVersionFlagWithDeprecations, - requiredOrgFlagWithDeprecations, Ux, } from '@salesforce/sf-plugins-core'; import { Interfaces } from '@oclif/core'; -import { DeployCommand, getCoverageFormattersOptions, reportsFormatters, TestLevel } from '../../../deployCommand'; +import { + DeployCommand, + getCoverageFormattersOptions, + reportsFormatters, + targetUsernameFlag, + TestLevel, +} from '../../../deployCommand'; import { DeployCommandResult, DeployResultFormatter } from '../../../formatters/deployResultFormatter'; import { DeployAsyncResultFormatter, @@ -53,7 +58,7 @@ export class Deploy extends DeployCommand { public static readonly flags = { 'api-version': orgApiVersionFlagWithDeprecations, loglevel, - 'target-org': requiredOrgFlagWithDeprecations, + 'target-org': targetUsernameFlag, checkonly: Flags.boolean({ char: 'c', description: messages.getMessage('flags.checkonly.description'), @@ -83,6 +88,7 @@ export class Deploy extends DeployCommand { }), ignoreerrors: Flags.boolean({ char: 'o', + // brfeak this description: messages.getMessage('flags.ignoreErrors.description'), summary: messages.getMessage('flags.ignoreErrors.summary'), }), @@ -159,7 +165,7 @@ export class Deploy extends DeployCommand { private org: Org; public async run(): Promise { this.flags = (await this.parse(Deploy)).flags; - this.org = this.flags['target-org']; + this.org = await Org.create({ aliasOrUsername: this.flags['target-org'] }); await this.preChecks(); await this.deploy(); this.resolveSuccess(); diff --git a/src/deployCommand.ts b/src/deployCommand.ts index b61eb37ac..3f6d3cd65 100644 --- a/src/deployCommand.ts +++ b/src/deployCommand.ts @@ -15,7 +15,17 @@ import { MetadataApiDeployStatus, RequestStatus, } from '@salesforce/source-deploy-retrieve'; -import { Connection, Messages, Org, PollingClient, SfdxPropertyKeys, SfError, StatusResult } from '@salesforce/core'; +import { + ConfigAggregator, + Connection, + Messages, + Org, + PollingClient, + SfdxPropertyKeys, + SfError, + StateAggregator, + StatusResult, +} from '@salesforce/core'; import { AnyJson, getBoolean, isString } from '@salesforce/ts-types'; import { Duration, once, ensureArray } from '@salesforce/kit'; import { @@ -25,6 +35,7 @@ import { DefaultReportOptions, JUnitReporter, } from '@salesforce/apex-node'; +import { Flags } from '@salesforce/sf-plugins-core'; import { SourceCommand } from './sourceCommand'; import { DeployData, Stash } from './stash'; import { transformCoverageToApexCoverage, transformDeployTestsResultsToTestResult } from './coverageUtils'; @@ -53,6 +64,7 @@ export abstract class DeployCommand extends SourceCommand { const stashKey = Stash.getKey(this.id); Stash.set(stashKey, { jobid: id }); }); + /** * Request a report of an in-progress or completed deployment. * @@ -259,3 +271,26 @@ export const getCoverageFormattersOptions = (formatters: string[] = []): Coverag reportOptions, }; }; + +export const targetUsernameFlag = Flags.string({ + required: true, + char: 'u', + deprecateAliases: true, + // DO NOT alias to 'o', it will conflict with '--ignoreerrors' + aliases: ['targetusername', 'u'], + summary: messages.getMessage('flags.targetusername.summary'), + parse: async (input: string | undefined) => resolveUsername(input), + default: async () => resolveUsername(), + defaultHelp: async () => resolveUsername(), +}); + +export const resolveUsername = async (usernameOrAlias?: string): Promise => { + const stateAggregator = await StateAggregator.getInstance(); + // we have a value, but don't know if it's a username or an alias + if (usernameOrAlias) return stateAggregator.aliases.resolveUsername(usernameOrAlias); + // we didn't get a value, so let's see if the config has a default target org + const configAggregator = await ConfigAggregator.create(); + const defaultUsernameOrAlias: string = configAggregator.getPropertyValue('target-org'); + if (defaultUsernameOrAlias) return stateAggregator.aliases.resolveUsername(defaultUsernameOrAlias); + throw new SfError(messages.getMessage('missingUsername'), 'MissingUsernameError'); +}; diff --git a/test/commands/source/deploy.test.ts b/test/commands/source/deploy.test.ts index 6291255e3..08299da4b 100644 --- a/test/commands/source/deploy.test.ts +++ b/test/commands/source/deploy.test.ts @@ -171,276 +171,265 @@ describe('force:source:deploy', () => { expect(initProgressBarStub.callCount).to.equal(callCount); }; - it('should pass along sourcepath', async () => { - const sourcepath = ['somepath']; - const result = await runDeployCmd(['--sourcepath', sourcepath[0], '--json']); - expect(result).to.deep.equal(expectedResults); - ensureCreateComponentSetArgs({ sourcepath }); - ensureDeployArgs(); - ensureHookArgs(); - ensureProgressBar(0); - }); - - it('should pass along metadata', async () => { - const metadata = ['ApexClass:MyClass']; - const result = await runDeployCmd(['--metadata', metadata[0], '--json']); - expect(result).to.deep.equal(expectedResults); - ensureCreateComponentSetArgs({ - metadata: { - metadataEntries: metadata, - directoryPaths: [defaultDir], - }, + describe('long command flags', () => { + it('should pass along sourcepath', async () => { + const sourcepath = ['somepath']; + const result = await runDeployCmd(['--sourcepath', sourcepath[0], '--json']); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ sourcepath }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); }); - ensureDeployArgs(); - ensureHookArgs(); - ensureProgressBar(0); - }); - it('should pass along manifest', async () => { - const manifest = 'package.xml'; - const result = await runDeployCmd(['--manifest', manifest, '--json']); - expect(result).to.deep.equal(expectedResults); - ensureCreateComponentSetArgs({ - manifest: { - manifestPath: manifest, - directoryPaths: [defaultDir], - destructiveChangesPost: undefined, - destructiveChangesPre: undefined, - }, + it('should pass along metadata', async () => { + const metadata = ['ApexClass:MyClass']; + const result = await runDeployCmd(['--metadata', metadata[0], '--json']); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + metadata: { + metadataEntries: metadata, + directoryPaths: [defaultDir], + }, + }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); }); - ensureDeployArgs(); - ensureHookArgs(); - ensureProgressBar(0); - }); - it('should pass along apiversion', async () => { - const manifest = 'package.xml'; - const apiversion = '50.0'; - const result = await runDeployCmd(['--manifest', manifest, '--apiversion', apiversion, '--json']); - expect(result).to.deep.equal(expectedResults); - ensureCreateComponentSetArgs({ - apiversion, - manifest: { - manifestPath: manifest, - directoryPaths: [defaultDir], - destructiveChangesPost: undefined, - destructiveChangesPre: undefined, - }, + it('should pass along manifest', async () => { + const manifest = 'package.xml'; + const result = await runDeployCmd(['--manifest', manifest, '--json']); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); }); - ensureDeployArgs(); - ensureHookArgs(); - ensureProgressBar(0); - }); - it('should pass along sourceapiversion', async () => { - const sourceApiVersion = '50.0'; - resolveProjectConfigStub.resolves({ sourceApiVersion }); - const manifest = 'package.xml'; - const result = await runDeployCmd(['--manifest', manifest, '--json'], { sourceApiVersion }); - expect(result).to.deep.equal(expectedResults); - ensureCreateComponentSetArgs({ - sourceapiversion: sourceApiVersion, - manifest: { - manifestPath: manifest, - directoryPaths: [defaultDir], - destructiveChangesPost: undefined, - destructiveChangesPre: undefined, - }, + it('should pass along apiversion', async () => { + const manifest = 'package.xml'; + const apiversion = '50.0'; + const result = await runDeployCmd(['--manifest', manifest, '--apiversion', apiversion, '--json']); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + apiversion, + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); }); - ensureDeployArgs(); - ensureHookArgs(); - ensureProgressBar(0); - }); - it('should pass purgeOnDelete flag', async () => { - const manifest = 'package.xml'; - const destructiveChanges = 'destructiveChangesPost.xml'; - const runTests = ['MyClassTest']; - const testLevel = 'RunSpecifiedTests'; - const result = await runDeployCmd([ - `--manifest=${manifest}`, - `--postdestructivechanges=${destructiveChanges}`, - '--ignorewarnings', - '--ignoreerrors', - '--checkonly', - `--runtests=${runTests[0]}`, - `--testlevel=${testLevel}`, - '--purgeondelete', - '--json', - ]); - - expect(result).to.deep.equal(expectedResults); - ensureDeployArgs({ - apiOptions: { - checkOnly: true, - ignoreWarnings: true, - purgeOnDelete: true, - rest: false, - rollbackOnError: false, - runTests, - testLevel, - }, - }); - ensureCreateComponentSetArgs({ - manifest: { - manifestPath: manifest, - directoryPaths: [defaultDir], - destructiveChangesPost: destructiveChanges, - destructiveChangesPre: undefined, - }, + it('should pass along sourceapiversion', async () => { + const sourceApiVersion = '50.0'; + resolveProjectConfigStub.resolves({ sourceApiVersion }); + const manifest = 'package.xml'; + const result = await runDeployCmd(['--manifest', manifest, '--json'], { sourceApiVersion }); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + sourceapiversion: sourceApiVersion, + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); }); - ensureHookArgs(); - ensureProgressBar(0); - }); - it('should pass default purgeondelete flag to false', async () => { - const manifest = 'package.xml'; - const destructiveChanges = 'destructiveChangesPost.xml'; - const runTests = ['MyClassTest']; - const testLevel = 'RunSpecifiedTests'; - const result = await runDeployCmd([ - `--manifest=${manifest}`, - `--postdestructivechanges=${destructiveChanges}`, - '--ignorewarnings', - '--ignoreerrors', - '--checkonly', - `--runtests=${runTests[0]}`, - `--testlevel=${testLevel}`, - '--json', - ]); - - expect(result).to.deep.equal(expectedResults); - ensureDeployArgs({ - apiOptions: { - checkOnly: true, - ignoreWarnings: true, - purgeOnDelete: false, - rest: false, - rollbackOnError: false, - runTests, - testLevel, - }, - }); - ensureCreateComponentSetArgs({ - manifest: { - manifestPath: manifest, - directoryPaths: [defaultDir], - destructiveChangesPost: destructiveChanges, - destructiveChangesPre: undefined, - }, - }); - ensureHookArgs(); - ensureProgressBar(0); - }); + it('should pass purgeOnDelete flag', async () => { + const manifest = 'package.xml'; + const destructiveChanges = 'destructiveChangesPost.xml'; + const runTests = ['MyClassTest']; + const testLevel = 'RunSpecifiedTests'; + const result = await runDeployCmd([ + `--manifest=${manifest}`, + `--postdestructivechanges=${destructiveChanges}`, + '--ignorewarnings', + '--ignoreerrors', + '--checkonly', + `--runtests=${runTests[0]}`, + `--testlevel=${testLevel}`, + '--purgeondelete', + '--json', + ]); - it('should pass along all deploy options', async () => { - const manifest = 'package.xml'; - const runTests = ['MyClassTest']; - const testLevel = 'RunSpecifiedTests'; - const result = await runDeployCmd([ - `--manifest=${manifest}`, - '--ignorewarnings', - '--ignoreerrors', - '--checkonly', - `--runtests=${runTests[0]}`, - `--testlevel=${testLevel}`, - '--json', - ]); - - expect(result).to.deep.equal(expectedResults); - ensureCreateComponentSetArgs({ - manifest: { - manifestPath: manifest, - directoryPaths: [defaultDir], - destructiveChangesPost: undefined, - destructiveChangesPre: undefined, - }, + expect(result).to.deep.equal(expectedResults); + ensureDeployArgs({ + apiOptions: { + checkOnly: true, + ignoreWarnings: true, + purgeOnDelete: true, + rest: false, + rollbackOnError: false, + runTests, + testLevel, + }, + }); + ensureCreateComponentSetArgs({ + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: destructiveChanges, + destructiveChangesPre: undefined, + }, + }); + ensureHookArgs(); + ensureProgressBar(0); }); - // Ensure ComponentSet.deploy() overridden args - ensureDeployArgs({ - apiOptions: { - ignoreWarnings: true, - rollbackOnError: false, - checkOnly: true, - runTests, - testLevel, - }, - }); - ensureHookArgs(); - ensureProgressBar(0); - }); + it('should pass default purgeondelete flag to false', async () => { + const manifest = 'package.xml'; + const destructiveChanges = 'destructiveChangesPost.xml'; + const runTests = ['MyClassTest']; + const testLevel = 'RunSpecifiedTests'; + const result = await runDeployCmd([ + `--manifest=${manifest}`, + `--postdestructivechanges=${destructiveChanges}`, + '--ignorewarnings', + '--ignoreerrors', + '--checkonly', + `--runtests=${runTests[0]}`, + `--testlevel=${testLevel}`, + '--json', + ]); - describe('SOAP/REST', () => { - it('should use SOAP by default', () => { - delete process.env.SFDX_REST_DEPLOY; - const sourcepath = ['somepath']; - const cmd = new TestDeploy(['--sourcepath', sourcepath[0]], oclifConfigStub); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore private method - expect(cmd.isRest).to.be.false; + expect(result).to.deep.equal(expectedResults); + ensureDeployArgs({ + apiOptions: { + checkOnly: true, + ignoreWarnings: true, + purgeOnDelete: false, + rest: false, + rollbackOnError: false, + runTests, + testLevel, + }, + }); + ensureCreateComponentSetArgs({ + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: destructiveChanges, + destructiveChangesPre: undefined, + }, + }); + ensureHookArgs(); + ensureProgressBar(0); }); - it('should use SOAP from the env var', () => { - try { - process.env.SFDX_REST_DEPLOY = 'false'; - const sourcepath = ['somepath']; - const cmd = new TestDeploy(['--sourcepath', sourcepath[0]], oclifConfigStub); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore private method - expect(cmd.isRest).to.be.false; - } finally { - delete process.env.SFDX_REST_DEPLOY; - } + it('should pass along all deploy options', async () => { + const manifest = 'package.xml'; + const runTests = ['MyClassTest']; + const testLevel = 'RunSpecifiedTests'; + const result = await runDeployCmd([ + `--manifest=${manifest}`, + '--ignorewarnings', + '--ignoreerrors', + '--checkonly', + `--runtests=${runTests[0]}`, + `--testlevel=${testLevel}`, + '--json', + ]); + + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + + // Ensure ComponentSet.deploy() overridden args + ensureDeployArgs({ + apiOptions: { + ignoreWarnings: true, + rollbackOnError: false, + checkOnly: true, + runTests, + testLevel, + }, + }); + ensureHookArgs(); + ensureProgressBar(0); }); - it('should use REST from the env var', () => { - try { - process.env.SFDX_REST_DEPLOY = 'true'; + describe('SOAP/REST', () => { + it('should use SOAP by default', () => { + delete process.env.SFDX_REST_DEPLOY; const sourcepath = ['somepath']; const cmd = new TestDeploy(['--sourcepath', sourcepath[0]], oclifConfigStub); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore private method expect(cmd.isRest).to.be.false; - } finally { - delete process.env.SFDX_REST_DEPLOY; - } - }); - - it('should use SOAP by overriding env var with flag', () => { - try { - process.env.SFDX_REST_DEPLOY = 'true'; + }); + + it('should use SOAP from the env var', () => { + try { + process.env.SFDX_REST_DEPLOY = 'false'; + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['--sourcepath', sourcepath[0]], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + } finally { + delete process.env.SFDX_REST_DEPLOY; + } + }); + + it('should use REST from the env var', () => { + try { + process.env.SFDX_REST_DEPLOY = 'true'; + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['--sourcepath', sourcepath[0]], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + } finally { + delete process.env.SFDX_REST_DEPLOY; + } + }); + + it('should use SOAP by overriding env var with flag', () => { + try { + process.env.SFDX_REST_DEPLOY = 'true'; + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['--sourcepath', sourcepath[0], '--soapdeploy'], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + } finally { + delete process.env.SFDX_REST_DEPLOY; + } + }); + + it('should use SOAP from flag', () => { const sourcepath = ['somepath']; const cmd = new TestDeploy(['--sourcepath', sourcepath[0], '--soapdeploy'], oclifConfigStub); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore private method expect(cmd.isRest).to.be.false; - } finally { - delete process.env.SFDX_REST_DEPLOY; - } - }); - - it('should use SOAP from flag', () => { - const sourcepath = ['somepath']; - const cmd = new TestDeploy(['--sourcepath', sourcepath[0], '--soapdeploy'], oclifConfigStub); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore private method - expect(cmd.isRest).to.be.false; - }); - - it('should use SOAP from config', () => { - stubMethod(sandbox, ConfigAggregator, 'create').resolves(ConfigAggregator.prototype); - stubMethod(sandbox, ConfigAggregator.prototype, 'getPropertyValue').returns('false'); - const sourcepath = ['somepath']; - const cmd = new TestDeploy(['--sourcepath', sourcepath[0], '--soapdeploy'], oclifConfigStub); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore private method - expect(cmd.isRest).to.be.false; - }); + }); - it('should use SOAP by overriding env var with config', () => { - try { - process.env.SFDX_REST_DEPLOY = 'true'; + it('should use SOAP from config', () => { stubMethod(sandbox, ConfigAggregator, 'create').resolves(ConfigAggregator.prototype); stubMethod(sandbox, ConfigAggregator.prototype, 'getPropertyValue').returns('false'); const sourcepath = ['somepath']; @@ -448,87 +437,550 @@ describe('force:source:deploy', () => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore private method expect(cmd.isRest).to.be.false; - } finally { - delete process.env.SFDX_REST_DEPLOY; - } + }); + + it('should use SOAP by overriding env var with config', () => { + try { + process.env.SFDX_REST_DEPLOY = 'true'; + stubMethod(sandbox, ConfigAggregator, 'create').resolves(ConfigAggregator.prototype); + stubMethod(sandbox, ConfigAggregator.prototype, 'getPropertyValue').returns('false'); + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['--sourcepath', sourcepath[0], '--soapdeploy'], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + } finally { + delete process.env.SFDX_REST_DEPLOY; + } + }); }); - }); - describe('Hooks', () => { - it('should emit postdeploy hooks for validateddeployrequestid deploys', async () => { - await runDeployCmd(['--validateddeployrequestid', '0Af0x00000pkAXLCA2']); - expect(lifecycleEmitStub.firstCall.args[0]).to.equal('postdeploy'); - }); + describe('Hooks', () => { + it('should emit postdeploy hooks for validateddeployrequestid deploys', async () => { + await runDeployCmd(['--validateddeployrequestid', '0Af0x00000pkAXLCA2']); + expect(lifecycleEmitStub.firstCall.args[0]).to.equal('postdeploy'); + }); - it('should emit predeploy hooks for async deploys', async () => { - const sourcepath = ['somepath']; - await runDeployCmd(['--sourcepath', sourcepath[0], '--wait', '0']); - expect(lifecycleEmitStub.firstCall.args[0]).to.equal('predeploy'); + it('should emit predeploy hooks for async deploys', async () => { + const sourcepath = ['somepath']; + await runDeployCmd(['--sourcepath', sourcepath[0], '--wait', '0']); + expect(lifecycleEmitStub.firstCall.args[0]).to.equal('predeploy'); + }); }); - }); - describe('Progress Bar', () => { - it('should NOT call progress bar because of environment variable', async () => { - try { - process.env.SFDX_USE_PROGRESS_BAR = 'false'; + describe('Progress Bar', () => { + it('should NOT call progress bar because of environment variable', async () => { + try { + process.env.SFDX_USE_PROGRESS_BAR = 'false'; + const sourcepath = ['somepath']; + const result = await runDeployCmd(['--sourcepath', sourcepath[0]]); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ sourcepath }); + ensureDeployArgs(); + ensureHookArgs(); + expect(progressStatusStub.calledOnce).to.be.true; + expect(progressBarStub.calledOnce).to.be.false; + } finally { + delete process.env.SFDX_USE_PROGRESS_BAR; + } + }); + + it('should call progress bar', async () => { const sourcepath = ['somepath']; const result = await runDeployCmd(['--sourcepath', sourcepath[0]]); expect(result).to.deep.equal(expectedResults); ensureCreateComponentSetArgs({ sourcepath }); ensureDeployArgs(); ensureHookArgs(); - expect(progressStatusStub.calledOnce).to.be.true; - expect(progressBarStub.calledOnce).to.be.false; - } finally { - delete process.env.SFDX_USE_PROGRESS_BAR; - } + expect(progressStatusStub.calledOnce).to.be.false; + expect(progressBarStub.calledOnce).to.be.true; + }); + + it('should NOT call progress bar because of --json', async () => { + const sourcepath = ['somepath']; + const result = await runDeployCmd(['--json', '--sourcepath', sourcepath[0]]); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ sourcepath }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); + }); + }); + + it('should return JSON format and not display for a synchronous deploy', async () => { + const result = await runDeployCmd(['--sourcepath', 'somepath', '--json']); + expect(formatterDisplayStub.calledOnce).to.equal(false); + expect(result).to.deep.equal(expectedResults); }); - it('should call progress bar', async () => { + it('should return JSON format and not display for an asynchronous deploy', async () => { + const formatterAsyncDisplayStub = stubMethod(sandbox, DeployAsyncResultFormatter.prototype, 'display'); + const result = await runDeployCmd(['--sourcepath', 'somepath', '--json', '--wait', '0']); + expect(formatterAsyncDisplayStub.calledOnce).to.equal(false); + expect(result).to.deep.equal(expectedAsyncResults); + }); + + it('should return JSON format and display for a synchronous deploy', async () => { + const result = await runDeployCmd(['--sourcepath', 'somepath']); + expect(formatterDisplayStub.calledOnce).to.equal(true); + expect(result).to.deep.equal(expectedResults); + }); + + it('should return JSON format and display for an asynchronous deploy', async () => { + const formatterAsyncDisplayStub = stubMethod(sandbox, DeployAsyncResultFormatter.prototype, 'display'); + const result = await runDeployCmd(['--sourcepath', 'somepath', '--wait', '0']); + expect(formatterAsyncDisplayStub.calledOnce).to.equal(true); + expect(result).to.deep.equal(expectedAsyncResults); + }); + }); + + describe('short command flags', () => { + it('should pass along sourcepath', async () => { const sourcepath = ['somepath']; - const result = await runDeployCmd(['--sourcepath', sourcepath[0]]); + const result = await runDeployCmd(['-p', sourcepath[0], '--json']); expect(result).to.deep.equal(expectedResults); ensureCreateComponentSetArgs({ sourcepath }); ensureDeployArgs(); ensureHookArgs(); - expect(progressStatusStub.calledOnce).to.be.false; - expect(progressBarStub.calledOnce).to.be.true; + ensureProgressBar(0); }); - it('should NOT call progress bar because of --json', async () => { - const sourcepath = ['somepath']; - const result = await runDeployCmd(['--json', '--sourcepath', sourcepath[0]]); + it('should pass along metadata', async () => { + const metadata = ['ApexClass:MyClass']; + const result = await runDeployCmd(['-m', metadata[0], '--json']); expect(result).to.deep.equal(expectedResults); - ensureCreateComponentSetArgs({ sourcepath }); + ensureCreateComponentSetArgs({ + metadata: { + metadataEntries: metadata, + directoryPaths: [defaultDir], + }, + }); ensureDeployArgs(); ensureHookArgs(); ensureProgressBar(0); }); - }); - it('should return JSON format and not display for a synchronous deploy', async () => { - const result = await runDeployCmd(['--sourcepath', 'somepath', '--json']); - expect(formatterDisplayStub.calledOnce).to.equal(false); - expect(result).to.deep.equal(expectedResults); - }); + it('should pass along manifest', async () => { + const manifest = 'package.xml'; + const result = await runDeployCmd(['-x', manifest, '--json']); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); + }); - it('should return JSON format and not display for an asynchronous deploy', async () => { - const formatterAsyncDisplayStub = stubMethod(sandbox, DeployAsyncResultFormatter.prototype, 'display'); - const result = await runDeployCmd(['--sourcepath', 'somepath', '--json', '--wait', '0']); - expect(formatterAsyncDisplayStub.calledOnce).to.equal(false); - expect(result).to.deep.equal(expectedAsyncResults); - }); + it('should pass along apiversion', async () => { + const manifest = 'package.xml'; + const apiversion = '50.0'; + const result = await runDeployCmd(['-x', manifest, '--apiversion', apiversion, '--json']); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + apiversion, + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); + }); - it('should return JSON format and display for a synchronous deploy', async () => { - const result = await runDeployCmd(['--sourcepath', 'somepath']); - expect(formatterDisplayStub.calledOnce).to.equal(true); - expect(result).to.deep.equal(expectedResults); - }); + it('should pass along sourceapiversion', async () => { + const sourceApiVersion = '50.0'; + resolveProjectConfigStub.resolves({ sourceApiVersion }); + const manifest = 'package.xml'; + const result = await runDeployCmd(['-x', manifest, '--json', '-u', testOrg.username], { sourceApiVersion }); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + sourceapiversion: sourceApiVersion, + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); + }); + + it('should pass along --targetusername', async () => { + const sourceApiVersion = '50.0'; + resolveProjectConfigStub.resolves({ sourceApiVersion }); + const manifest = 'package.xml'; + const result = await runDeployCmd(['-x', manifest, '--json', '--targetusername', testOrg.username], { + sourceApiVersion, + }); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + sourceapiversion: sourceApiVersion, + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); + }); + + it('should pass along --targetusername with -o', async () => { + const sourceApiVersion = '50.0'; + resolveProjectConfigStub.resolves({ sourceApiVersion }); + const manifest = 'package.xml'; + const result = await runDeployCmd(['-x', manifest, '--json', '-o', '--targetusername', testOrg.username], { + sourceApiVersion, + }); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + sourceapiversion: sourceApiVersion, + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + ensureDeployArgs({ apiOptions: { rollbackOnError: false } }); + ensureHookArgs(); + ensureProgressBar(0); + }); + + it('should pass along --target-org with -o', async () => { + const sourceApiVersion = '50.0'; + resolveProjectConfigStub.resolves({ sourceApiVersion }); + const manifest = 'package.xml'; + const result = await runDeployCmd(['-x', manifest, '--json', '-o', '--target-org', testOrg.username], { + sourceApiVersion, + }); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + sourceapiversion: sourceApiVersion, + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + ensureDeployArgs({ apiOptions: { rollbackOnError: false } }); + ensureHookArgs(); + ensureProgressBar(0); + }); + it('should pass along -u with -o', async () => { + const sourceApiVersion = '50.0'; + resolveProjectConfigStub.resolves({ sourceApiVersion }); + const manifest = 'package.xml'; + const result = await runDeployCmd(['-x', manifest, '--json', '-o', '-u', testOrg.username], { + sourceApiVersion, + }); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + sourceapiversion: sourceApiVersion, + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + ensureDeployArgs({ apiOptions: { rollbackOnError: false } }); + ensureHookArgs(); + ensureProgressBar(0); + }); - it('should return JSON format and display for an asynchronous deploy', async () => { - const formatterAsyncDisplayStub = stubMethod(sandbox, DeployAsyncResultFormatter.prototype, 'display'); - const result = await runDeployCmd(['--sourcepath', 'somepath', '--wait', '0']); - expect(formatterAsyncDisplayStub.calledOnce).to.equal(true); - expect(result).to.deep.equal(expectedAsyncResults); + it('should pass purgeOnDelete flag', async () => { + const manifest = 'package.xml'; + const destructiveChanges = 'destructiveChangesPost.xml'; + const runTests = ['MyClassTest']; + const testLevel = 'RunSpecifiedTests'; + const result = await runDeployCmd([ + `-x=${manifest}`, + `--postdestructivechanges=${destructiveChanges}`, + '-g', + '-o', + '-c', + `-r=${runTests[0]}`, + `-l=${testLevel}`, + '--purgeondelete', + '--json', + ]); + + expect(result).to.deep.equal(expectedResults); + ensureDeployArgs({ + apiOptions: { + checkOnly: true, + ignoreWarnings: true, + purgeOnDelete: true, + rest: false, + rollbackOnError: false, + runTests, + testLevel, + }, + }); + ensureCreateComponentSetArgs({ + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: destructiveChanges, + destructiveChangesPre: undefined, + }, + }); + ensureHookArgs(); + ensureProgressBar(0); + }); + + it('should pass default purgeondelete flag to false', async () => { + const manifest = 'package.xml'; + const destructiveChanges = 'destructiveChangesPost.xml'; + const runTests = ['MyClassTest']; + const testLevel = 'RunSpecifiedTests'; + const result = await runDeployCmd([ + `-x=${manifest}`, + `--postdestructivechanges=${destructiveChanges}`, + '-g', + '-o', + '-c', + `-r=${runTests[0]}`, + `-l=${testLevel}`, + '--json', + ]); + + expect(result).to.deep.equal(expectedResults); + ensureDeployArgs({ + apiOptions: { + checkOnly: true, + ignoreWarnings: true, + purgeOnDelete: false, + rest: false, + rollbackOnError: false, + runTests, + testLevel, + }, + }); + ensureCreateComponentSetArgs({ + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: destructiveChanges, + destructiveChangesPre: undefined, + }, + }); + ensureHookArgs(); + ensureProgressBar(0); + }); + + it('should pass along all deploy options', async () => { + const manifest = 'package.xml'; + const runTests = ['MyClassTest']; + const testLevel = 'RunSpecifiedTests'; + const result = await runDeployCmd([ + `-x=${manifest}`, + '-g', + '-o', + '-c', + `-r=${runTests[0]}`, + `-l=${testLevel}`, + '--json', + ]); + + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ + manifest: { + manifestPath: manifest, + directoryPaths: [defaultDir], + destructiveChangesPost: undefined, + destructiveChangesPre: undefined, + }, + }); + + // Ensure ComponentSet.deploy() overridden args + ensureDeployArgs({ + apiOptions: { + ignoreWarnings: true, + rollbackOnError: false, + checkOnly: true, + runTests, + testLevel, + }, + }); + ensureHookArgs(); + ensureProgressBar(0); + }); + + describe('SOAP/REST', () => { + it('should use SOAP by default', () => { + delete process.env.SFDX_REST_DEPLOY; + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['-p', sourcepath[0]], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + }); + + it('should use SOAP from the env var', () => { + try { + process.env.SFDX_REST_DEPLOY = 'false'; + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['-p', sourcepath[0]], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + } finally { + delete process.env.SFDX_REST_DEPLOY; + } + }); + + it('should use REST from the env var', () => { + try { + process.env.SFDX_REST_DEPLOY = 'true'; + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['-p', sourcepath[0]], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + } finally { + delete process.env.SFDX_REST_DEPLOY; + } + }); + + it('should use SOAP by overriding env var with flag', () => { + try { + process.env.SFDX_REST_DEPLOY = 'true'; + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['-p', sourcepath[0], '--soapdeploy'], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + } finally { + delete process.env.SFDX_REST_DEPLOY; + } + }); + + it('should use SOAP from flag', () => { + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['-p', sourcepath[0], '--soapdeploy'], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + }); + + it('should use SOAP from config', () => { + stubMethod(sandbox, ConfigAggregator, 'create').resolves(ConfigAggregator.prototype); + stubMethod(sandbox, ConfigAggregator.prototype, 'getPropertyValue').returns('false'); + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['-p', sourcepath[0], '--soapdeploy'], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + }); + + it('should use SOAP by overriding env var with config', () => { + try { + process.env.SFDX_REST_DEPLOY = 'true'; + stubMethod(sandbox, ConfigAggregator, 'create').resolves(ConfigAggregator.prototype); + stubMethod(sandbox, ConfigAggregator.prototype, 'getPropertyValue').returns('false'); + const sourcepath = ['somepath']; + const cmd = new TestDeploy(['-p', sourcepath[0], '--soapdeploy'], oclifConfigStub); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private method + expect(cmd.isRest).to.be.false; + } finally { + delete process.env.SFDX_REST_DEPLOY; + } + }); + }); + + describe('Hooks', () => { + it('should emit postdeploy hooks for validateddeployrequestid deploys', async () => { + await runDeployCmd(['-q', '0Af0x00000pkAXLCA2']); + expect(lifecycleEmitStub.firstCall.args[0]).to.equal('postdeploy'); + }); + + it('should emit predeploy hooks for async deploys', async () => { + const sourcepath = ['somepath']; + await runDeployCmd(['-p', sourcepath[0], '-w', '0']); + expect(lifecycleEmitStub.firstCall.args[0]).to.equal('predeploy'); + }); + }); + + describe('Progress Bar', () => { + it('should NOT call progress bar because of environment variable', async () => { + try { + process.env.SFDX_USE_PROGRESS_BAR = 'false'; + const sourcepath = ['somepath']; + const result = await runDeployCmd(['-p', sourcepath[0]]); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ sourcepath }); + ensureDeployArgs(); + ensureHookArgs(); + expect(progressStatusStub.calledOnce).to.be.true; + expect(progressBarStub.calledOnce).to.be.false; + } finally { + delete process.env.SFDX_USE_PROGRESS_BAR; + } + }); + + it('should call progress bar', async () => { + const sourcepath = ['somepath']; + const result = await runDeployCmd(['-p', sourcepath[0]]); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ sourcepath }); + ensureDeployArgs(); + ensureHookArgs(); + expect(progressStatusStub.calledOnce).to.be.false; + expect(progressBarStub.calledOnce).to.be.true; + }); + + it('should NOT call progress bar because of --json', async () => { + const sourcepath = ['somepath']; + const result = await runDeployCmd(['--json', '-p', sourcepath[0]]); + expect(result).to.deep.equal(expectedResults); + ensureCreateComponentSetArgs({ sourcepath }); + ensureDeployArgs(); + ensureHookArgs(); + ensureProgressBar(0); + }); + }); + + it('should return JSON format and not display for a synchronous deploy', async () => { + const result = await runDeployCmd(['-p', 'somepath', '--json']); + expect(formatterDisplayStub.calledOnce).to.equal(false); + expect(result).to.deep.equal(expectedResults); + }); + + it('should return JSON format and not display for an asynchronous deploy', async () => { + const formatterAsyncDisplayStub = stubMethod(sandbox, DeployAsyncResultFormatter.prototype, 'display'); + const result = await runDeployCmd(['-p', 'somepath', '--json', '-w', '0']); + expect(formatterAsyncDisplayStub.calledOnce).to.equal(false); + expect(result).to.deep.equal(expectedAsyncResults); + }); + + it('should return JSON format and display for a synchronous deploy', async () => { + const result = await runDeployCmd(['-p', 'somepath']); + expect(formatterDisplayStub.calledOnce).to.equal(true); + expect(result).to.deep.equal(expectedResults); + }); + + it('should return JSON format and display for an asynchronous deploy', async () => { + const formatterAsyncDisplayStub = stubMethod(sandbox, DeployAsyncResultFormatter.prototype, 'display'); + const result = await runDeployCmd(['-p', 'somepath', '-w', '0']); + expect(formatterAsyncDisplayStub.calledOnce).to.equal(true); + expect(result).to.deep.equal(expectedAsyncResults); + }); }); }); diff --git a/test/nuts/REST/deploy.mpd.nut.ts b/test/nuts/REST/deploy.mpd.nut.ts index 5307acc81..cb86ab35b 100644 --- a/test/nuts/REST/deploy.mpd.nut.ts +++ b/test/nuts/REST/deploy.mpd.nut.ts @@ -133,7 +133,7 @@ context(`MPD REST Deploy NUTs [name: ${repo.name}]`, () => { const toDeploy = path.normalize(repo.deploy.sourcepath[0].toDeploy); it(`should checkonly deploy ${toDeploy}`, async () => { await testkit.deploy({ - args: `--sourcepath ${toDeploy} --checkonly --ignoreerrors`, + args: `--sourcepath ${toDeploy} -c -o`, }); await testkit.expect.filesToNotBeDeployed(repo.deploy.sourcepath[0].toVerify); }); @@ -158,7 +158,7 @@ context(`MPD REST Deploy NUTs [name: ${repo.name}]`, () => { const classes = path.join('foo-bar', 'app', 'classes'); const checkOnly = (await testkit.deploy({ - args: `--sourcepath ${classes} --testlevel RunAllTestsInOrg --checkonly --ignoreerrors --wait 0`, + args: `-p ${classes} --testlevel RunAllTestsInOrg --checkonly --ignoreerrors --wait 0`, })) as { result: DeployCommandResult }; // quick deploy won't work unless the checkonly has finished successfully diff --git a/test/nuts/mdapi.nut.ts b/test/nuts/mdapi.nut.ts index 07e513c8e..1bd011bd3 100644 --- a/test/nuts/mdapi.nut.ts +++ b/test/nuts/mdapi.nut.ts @@ -455,7 +455,7 @@ describe('mdapi NUTs', () => { }); it('should deploy validated Id', () => { execCmd( - `force:mdapi:deploy --wait -1 --validateddeployrequestid ${deployCommandResponse.id} --ignorewarnings --ignoreerrors`, + `force:mdapi:deploy --wait -1 --validateddeployrequestid ${deployCommandResponse.id} --ignorewarnings -o`, { ensureExitCode: 0, } diff --git a/test/nuts/trackingCommands/deployRetrieveDelete.nut.ts b/test/nuts/trackingCommands/deployRetrieveDelete.nut.ts index 08bde6c9c..59646c020 100644 --- a/test/nuts/trackingCommands/deployRetrieveDelete.nut.ts +++ b/test/nuts/trackingCommands/deployRetrieveDelete.nut.ts @@ -91,4 +91,37 @@ describe('-t flag for deploy, retrieve, and delete', () => { ).to.have.length(0); }); }); + + describe('short character flag validation', () => { + it("won't confuse -o/-u", () => { + execCmd(`force:source:deploy -p force-app,my-app,foo-bar/app -o --json`, { + ensureExitCode: 0, + }); + + execCmd( + `force:source:deploy -p force-app,my-app,foo-bar/app -o -u ${session.orgs.get('default').username} --json`, + { + ensureExitCode: 0, + } + ); + + execCmd( + `force:source:deploy -p force-app,my-app,foo-bar/app -o --targetusername ${ + session.orgs.get('default').username + } --json`, + { + ensureExitCode: 0, + } + ); + + execCmd( + `force:source:deploy -p force-app,my-app,foo-bar/app -o --target-org ${ + session.orgs.get('default').username + } --json`, + { + ensureExitCode: 0, + } + ); + }); + }); });