Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion packages/b2c-cli/src/commands/code/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,35 @@
reloadCodeVersion,
};

async run(): Promise<DeployResult> {

Check warning on line 57 in packages/b2c-cli/src/commands/code/deploy.ts

View workflow job for this annotation

GitHub Actions / test (22.x)

Async method 'run' has a complexity of 24. Maximum allowed is 20

Check warning on line 57 in packages/b2c-cli/src/commands/code/deploy.ts

View workflow job for this annotation

GitHub Actions / test (24.x)

Async method 'run' has a complexity of 24. Maximum allowed is 20
this.requireWebDavCredentials();
this.requireOAuthCredentials();

const hostname = this.resolvedConfig.values.hostname!;
let version = this.resolvedConfig.values.codeVersion;

// OAuth is only required if:
// 1. No code version specified (need to auto-discover via OCAPI)
// 2. --reload flag is set (need to call OCAPI to reload)
const needsOAuth = !version || this.flags.reload;
if (needsOAuth && !this.hasOAuthCredentials()) {
Comment thread
clavery marked this conversation as resolved.
const reason = version
? t(
'commands.code.deploy.oauthRequiredForReload',
'The --reload flag requires OAuth credentials to reload the code version via OCAPI.',
)
: t(
'commands.code.deploy.oauthRequiredForDiscovery',
'No code version specified. OAuth credentials are required to auto-discover the active code version.',
);
this.error(
t(
'commands.code.deploy.oauthRequired',
'{{reason}}\n\nProvide --code-version to use basic auth only, or configure OAuth credentials.\nSee: https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/configuration.html',
{reason},
),
);
}

// If no code version specified, discover the active one
if (!version) {
this.warn(
Expand Down
11 changes: 10 additions & 1 deletion packages/b2c-cli/src/commands/code/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,20 @@ export default class CodeWatch extends CartridgeCommand<typeof CodeWatch> {

async run(): Promise<void> {
this.requireWebDavCredentials();
this.requireOAuthCredentials();

const hostname = this.resolvedConfig.values.hostname!;
const version = this.resolvedConfig.values.codeVersion;

// OAuth is only required if no code version specified (need to auto-discover via OCAPI)
if (!version && !this.hasOAuthCredentials()) {
this.error(
t(
'commands.code.watch.oauthRequired',
'No code version specified. OAuth credentials are required to auto-discover the active code version.\n\nProvide --code-version to use basic auth only, or configure OAuth credentials.\nSee: https://salesforcecommercecloud.github.io/b2c-developer-tooling/guide/configuration.html',
),
);
}

this.log(t('commands.code.watch.starting', 'Starting watcher for {{path}}', {path: this.cartridgePath}));
this.log(t('commands.code.watch.target', 'Target: {{hostname}}', {hostname}));
if (version) {
Expand Down
50 changes: 48 additions & 2 deletions packages/b2c-cli/test/commands/code/deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('code deploy', () => {
function stubCommon(command: any) {
const instance = {config: {hostname: 'example.com', codeVersion: 'v1'}};
sinon.stub(command, 'requireWebDavCredentials').returns(void 0);
sinon.stub(command, 'requireOAuthCredentials').returns(void 0);
sinon.stub(command, 'hasOAuthCredentials').returns(true);
sinon.stub(command, 'log').returns(void 0);
sinon.stub(command, 'warn').returns(void 0);
sinon.stub(command, 'resolvedConfig').get(() => ({values: {hostname: 'example.com', codeVersion: 'v1'}}));
Expand Down Expand Up @@ -113,11 +113,57 @@ describe('code deploy', () => {
expect(result.reloaded).to.equal(false);
});

it('errors when no code version and no OAuth credentials', async () => {
const command: any = await createCommand({}, {cartridgePath: '.'});

sinon.stub(command, 'requireWebDavCredentials').returns(void 0);
sinon.stub(command, 'hasOAuthCredentials').returns(false);
sinon.stub(command, 'log').returns(void 0);
sinon.stub(command, 'warn').returns(void 0);
sinon.stub(command, 'resolvedConfig').get(() => ({values: {hostname: 'example.com', codeVersion: undefined}}));

const errorStub = sinon.stub(command, 'error').throws(new Error('OAuth required'));

try {
await command.run();
expect.fail('Should have thrown');
} catch {
// expected
}

expect(errorStub.calledOnce).to.equal(true);
const errorMessage = errorStub.firstCall.args[0];
expect(errorMessage).to.include('auto-discover');
});

it('errors when --reload flag set but no OAuth credentials', async () => {
const command: any = await createCommand({reload: true}, {cartridgePath: '.'});

sinon.stub(command, 'requireWebDavCredentials').returns(void 0);
sinon.stub(command, 'hasOAuthCredentials').returns(false);
sinon.stub(command, 'log').returns(void 0);
sinon.stub(command, 'warn').returns(void 0);
sinon.stub(command, 'resolvedConfig').get(() => ({values: {hostname: 'example.com', codeVersion: 'v1'}}));

const errorStub = sinon.stub(command, 'error').throws(new Error('OAuth required'));

try {
await command.run();
expect.fail('Should have thrown');
} catch {
// expected
}

expect(errorStub.calledOnce).to.equal(true);
const errorMessage = errorStub.firstCall.args[0];
expect(errorMessage).to.include('reload');
});

it('uses active code version when resolvedConfig is missing codeVersion', async () => {
const command: any = await createCommand({}, {cartridgePath: '.'});

sinon.stub(command, 'requireWebDavCredentials').returns(void 0);
sinon.stub(command, 'requireOAuthCredentials').returns(void 0);
sinon.stub(command, 'hasOAuthCredentials').returns(true);
sinon.stub(command, 'log').returns(void 0);
sinon.stub(command, 'warn').returns(void 0);

Expand Down
Loading