Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow empty flag values when updating resources #57

Merged
merged 1 commit into from
Aug 26, 2019
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
7 changes: 4 additions & 3 deletions src/base-commands/twilio-client-command.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const BaseCommand = require('./base-command');
const CliRequestClient = require('../services/cli-http-client');
const { TwilioApiClient } = require('../services/twilio-api');
const { TwilioCliError } = require('../services/error');
const { camelCase } = require('../services/naming-conventions');
const { HELP_ENVIRONMENT_VARIABLES, UNEXPECTED_ERROR } = require('../services/messaging/help-messages');

// 'account-sid' is a special snowflake
Expand Down Expand Up @@ -79,10 +80,9 @@ class TwilioClientCommand extends BaseCommand {

let updatedProperties = null;
Object.keys(this.constructor.PropertyFlags).forEach(propName => {
if (this.flags[propName]) {
if (this.flags[propName] !== undefined) {
updatedProperties = updatedProperties || {};
// Convert kebab-case to camelCase
const paramName = propName.replace(/-([a-z])/g, g => g[1].toUpperCase());
const paramName = camelCase(propName);
updatedProperties[paramName] = this.flags[propName];
}
});
Expand All @@ -97,6 +97,7 @@ class TwilioClientCommand extends BaseCommand {
};

updatedProperties = updatedProperties || this.parseProperties();
this.logger.debug('Updated properties:');
this.logger.debug(updatedProperties);

if (updatedProperties) {
Expand Down
30 changes: 19 additions & 11 deletions test/base-commands/twilio-client-command.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ describe('base-commands', () => {
});
};

setUpTest().it('should not allow construction of the base class', async ctx => {
setUpTest().it('should not allow construction of the base class', ctx => {
expect(() => new TwilioClientCommand([], ctx.fakeConfig)).to.throw('runCommand');
});

setUpTest(['-l', 'debug']).it('should create a client for the active profile', async ctx => {
setUpTest(['-l', 'debug']).it('should create a client for the active profile', ctx => {
expect(ctx.stderr).to.contain('MyFirstProfile');
expect(ctx.testCmd.twilioClient.accountSid).to.equal(constants.FAKE_ACCOUNT_SID);
expect(ctx.testCmd.twilioClient.username).to.equal(constants.FAKE_API_KEY);
Expand All @@ -75,7 +75,7 @@ describe('base-commands', () => {

setUpTest(['-l', 'debug', '--account-sid', 'ACbaccbaccbaccbaccbaccbaccbaccbacc'], { commandClass: AccountSidClientCommand }).it(
'should create a client for the active profile with a different account SID',
async ctx => {
ctx => {
expect(ctx.stderr).to.contain('MyFirstProfile');
expect(ctx.testCmd.twilioClient.accountSid).to.equal('ACbaccbaccbaccbaccbaccbaccbaccbacc');
expect(ctx.testCmd.twilioClient.username).to.equal(constants.FAKE_API_KEY);
Expand All @@ -86,21 +86,21 @@ describe('base-commands', () => {

setUpTest(['-l', 'debug'], { setUpUserConfig: () => 0 })
.exit(1)
.it('should fail for a non-existent active profile', async ctx => {
.it('should fail for a non-existent active profile', ctx => {
expect(ctx.stderr).to.contain('No profile configured');
expect(ctx.stderr).to.contain('To add the profile, run: twilio profiles:add');
expect(ctx.stderr).to.contain('TWILIO_ACCOUNT_SID');
});

setUpTest(['-p', 'alt', '-l', 'debug'])
.exit(1)
.it('should fail for a non-existent profile', async ctx => {
.it('should fail for a non-existent profile', ctx => {
expect(ctx.stderr).to.contain('No profile configured');
expect(ctx.stderr).to.contain('To add the profile, run: twilio profiles:add -p alt');
expect(ctx.stderr).to.contain('TWILIO_ACCOUNT_SID');
});

setUpTest(['-p', 'twilio-cli-unit-testing']).it('should create a client for a non-default profile', async ctx => {
setUpTest(['-p', 'twilio-cli-unit-testing']).it('should create a client for a non-default profile', ctx => {
expect(ctx.testCmd.twilioClient.accountSid).to.equal(constants.FAKE_ACCOUNT_SID);
expect(ctx.testCmd.twilioClient.username).to.equal(constants.FAKE_API_KEY);
expect(ctx.testCmd.twilioClient.password).to.equal(constants.FAKE_API_SECRET + 'twilio-cli-unit-testing');
Expand All @@ -109,7 +109,7 @@ describe('base-commands', () => {

setUpTest(['-p', 'twilio-cli-unit-testing'], { mockSecureStorage: false })
.exit(1)
.it('should handle a secure storage error', async ctx => {
.it('should handle a secure storage error', ctx => {
expect(ctx.stderr).to.contain('Could not get credentials for profile "twilio-cli-unit-testing"');
expect(ctx.stderr).to.contain(
'To reconfigure the profile, run: twilio profiles:add -p twilio-cli-unit-testing'
Expand All @@ -118,17 +118,17 @@ describe('base-commands', () => {

setUpTest([], { commandClass: ThrowingClientCommand })
.exit(1)
.it('should catch unhandled errors', async ctx => {
.it('should catch unhandled errors', ctx => {
expect(ctx.stderr).to.contain('unexpected error');
});

describe('parseProperties', () => {
setUpTest().it('should ignore empty PropertyFlags', async ctx => {
setUpTest().it('should ignore empty PropertyFlags', ctx => {
const updatedProperties = ctx.testCmd.parseProperties();
expect(updatedProperties).to.be.null;
});

setUpTest().it('should ignore empty command flags', async ctx => {
setUpTest().it('should ignore missing command flags', ctx => {
ctx.testCmd.constructor.PropertyFlags = {
'friendly-name': {},
'sms-url': {}
Expand All @@ -138,7 +138,7 @@ describe('base-commands', () => {
expect(updatedProperties).to.be.null;
});

setUpTest().it('should parse options into API resource properties', async ctx => {
setUpTest().it('should parse options into API resource properties', ctx => {
ctx.testCmd.constructor.PropertyFlags = {
'friendly-name': {},
'sms-url': {}
Expand All @@ -152,6 +152,14 @@ describe('base-commands', () => {
expect(updatedProperties.friendlyName).to.equal('Casper');
expect(updatedProperties.smsUrl).to.equal('https://localhost:5000/sms');
});

setUpTest().it('should parse empty command flags', ctx => {
ctx.testCmd.constructor.PropertyFlags = { 'sms-url': {} };
ctx.testCmd.flags = { 'sms-url': '' };

const updatedProperties = ctx.testCmd.parseProperties();
expect(updatedProperties.smsUrl).to.be.empty;
});
});

describe('updateResource', () => {
Expand Down