From b8f938090f492fa70172aee2af4ad328c70f4c8f Mon Sep 17 00:00:00 2001 From: mshanemc Date: Fri, 5 Feb 2021 16:40:11 -0600 Subject: [PATCH 1/8] fix: user:create matches smoke test json --- src/commands/force/user/create.ts | 30 +++++-- test/commands/user/create.test.ts | 141 ++++++++++++++++-------------- 2 files changed, 100 insertions(+), 71 deletions(-) diff --git a/src/commands/force/user/create.ts b/src/commands/force/user/create.ts index 02aedc00..f377a5f9 100644 --- a/src/commands/force/user/create.ts +++ b/src/commands/force/user/create.ts @@ -36,6 +36,13 @@ interface FailureMsg { message: string; } +const permsetsStringToArray = (fieldsPermsets: string | string[]): string[] => { + if (!fieldsPermsets) return []; + return isArray(fieldsPermsets) + ? fieldsPermsets + : fieldsPermsets.split(',').map((item) => item.replace("'", '').trim()); +}; + export class UserCreateCommand extends SfdxCommand { public static readonly description = messages.getMessage('description'); public static readonly examples = messages.getMessage('examples').split(os.EOL); @@ -61,7 +68,7 @@ export class UserCreateCommand extends SfdxCommand { private authInfo: AuthInfo; /** - * removes fields that cause errors in salesforce api's within sfdx-core's createUser method + * removes fields that cause errors in salesforce APIs within sfdx-core's createUser method * * @param fields a list of combined fields from varargs and the config file * @private @@ -76,7 +83,7 @@ export class UserCreateCommand extends SfdxCommand { return copy as UserFields; } - public async run(): Promise { + public async run(): Promise { this.logger = await Logger.child(this.constructor.name); const defaultUserFields: DefaultUserFields = await DefaultUserFields.create({ templateUser: this.org.getUsername(), @@ -98,9 +105,7 @@ export class UserCreateCommand extends SfdxCommand { try { // permsets can be passed from cli args or file we need to create an array of permset names either way it's passed // it will either be a comma separated string, or an array, force it into an array - const permsetArray: string[] = isArray(fields.permsets) - ? fields.permsets - : fields.permsets.trim().split(','); + const permsetArray = permsetsStringToArray(fields.permsets); await this.user.assignPermissionSets(this.authInfo.getFields().userId, permsetArray); this.successes.push({ @@ -147,7 +152,12 @@ export class UserCreateCommand extends SfdxCommand { this.print(fields); - return Object.assign({ orgId: this.org.getOrgId() }, fields); + const { permsets, ...fieldsWithoutPermsets } = fields; + return { + orgId: this.org.getOrgId(), + permissionSetAssignments: permsetsStringToArray(permsets), + fields: { ...fieldsWithoutPermsets }, + }; } private async catchCreateUser(respBody: Error, fields: UserFields): Promise { @@ -202,7 +212,7 @@ export class UserCreateCommand extends SfdxCommand { defaultFields.profileId = response.records[0].Id; } - // the file schema is camelCase and boolean while the cli arg is no capitialization and a string + // the file schema is camelCase and boolean while the cli arg is no capitalization and a string // we will add logic to capture camelcase in varargs just in case if ( defaultFields['generatepassword'] === 'true' || @@ -258,3 +268,9 @@ export class UserCreateCommand extends SfdxCommand { } export default UserCreateCommand; + +interface UserCreateOutput { + orgId: string; + permissionSetAssignments: string[]; + fields: UserFields; +} diff --git a/test/commands/user/create.test.ts b/test/commands/user/create.test.ts index 9e79357f..26f6a86d 100644 --- a/test/commands/user/create.test.ts +++ b/test/commands/user/create.test.ts @@ -48,7 +48,6 @@ describe('force:user:create', () => { lastName: 'User', timeZoneSidKey: 'America/Los_Angeles', }); - expect(res).to.deep.equal({ alias: 'testAlias', email: 'defaultusername@test.com', @@ -84,6 +83,8 @@ describe('force:user:create', () => { }); stubMethod($$.SANDBOX, Aliases, 'fetch').resolves('testAlias'); stubMethod($$.SANDBOX, User, 'create').callsFake(() => User.prototype); + + stubMethod($$.SANDBOX, User.prototype, 'assignPermissionSets').resolves(); stubMethod($$.SANDBOX, Org.prototype, 'getUsername').returns(username); stubMethod($$.SANDBOX, Org.prototype, 'getOrgId').returns('abc123'); authInfoStub = stubMethod($$.SANDBOX, AuthInfo.prototype, 'save').resolves(); @@ -124,21 +125,23 @@ describe('force:user:create', () => { ]) .it('will handle a merge multiple permsets and profileNames from args and file (permsets from args)', (ctx) => { const expected = { - alias: 'testAlias', - email: 'defaultusername@test.com', - emailEncodingKey: 'UTF-8', - id: '0052D0000043PawWWR', - languageLocaleKey: 'en_US', - lastName: 'User', - localeSidKey: 'en_US', orgId: 'abc123', - generatepassword: 'true', - generatePassword: true, - permsets: "'permCLI, permCLI2'", - profileId: '12345678', - profileName: 'profileFromArgs', - timeZoneSidKey: 'America/Los_Angeles', - username: '1605130295132_test-j6asqt5qoprs@example.com', + permissionSetAssignments: ['permCLI', 'permCLI2'], + fields: { + alias: 'testAlias', + email: 'defaultusername@test.com', + emailEncodingKey: 'UTF-8', + id: '0052D0000043PawWWR', + languageLocaleKey: 'en_US', + lastName: 'User', + localeSidKey: 'en_US', + generatepassword: 'true', + generatePassword: true, + profileId: '12345678', + profileName: 'profileFromArgs', + timeZoneSidKey: 'America/Los_Angeles', + username: '1605130295132_test-j6asqt5qoprs@example.com', + }, }; const result = JSON.parse(ctx.stdout).result; expect(result).to.deep.equal(expected); @@ -164,19 +167,21 @@ describe('force:user:create', () => { ]) .it('will handle a merge multiple permsets and profileNames from args and file (permsets from file)', (ctx) => { const expected = { - alias: 'testAlias', - email: 'defaultusername@test.com', - emailEncodingKey: 'UTF-8', - id: '0052D0000043PawWWR', - languageLocaleKey: 'en_US', - lastName: 'User', - localeSidKey: 'en_US', orgId: 'abc123', - permsets: ['perm1', 'perm2'], - profileId: '12345678', - profileName: 'profileFromArgs', - timeZoneSidKey: 'America/Los_Angeles', - username: 'user@cliArgs.com', + permissionSetAssignments: ['perm1', 'perm2'], + fields: { + alias: 'testAlias', + email: 'defaultusername@test.com', + emailEncodingKey: 'UTF-8', + id: '0052D0000043PawWWR', + languageLocaleKey: 'en_US', + lastName: 'User', + localeSidKey: 'en_US', + profileId: '12345678', + profileName: 'profileFromArgs', + timeZoneSidKey: 'America/Los_Angeles', + username: 'user@cliArgs.com', + }, }; const result = JSON.parse(ctx.stdout).result; expect(result).to.deep.equal(expected); @@ -198,17 +203,20 @@ describe('force:user:create', () => { ]) .it('default create creates user exactly from DefaultUserFields', (ctx) => { const expected = { - alias: 'testAlias', - email: username, - emailEncodingKey: 'UTF-8', - id: '0052D0000043PawWWR', - languageLocaleKey: 'en_US', - lastName: 'User', - localeSidKey: 'en_US', orgId: 'abc123', - profileId: '00e2D000000bNexWWR', - timeZoneSidKey: 'America/Los_Angeles', - username: '1605130295132_test-j6asqt5qoprs@example.com', + permissionSetAssignments: [], + fields: { + alias: 'testAlias', + email: username, + emailEncodingKey: 'UTF-8', + id: '0052D0000043PawWWR', + languageLocaleKey: 'en_US', + lastName: 'User', + localeSidKey: 'en_US', + profileId: '00e2D000000bNexWWR', + timeZoneSidKey: 'America/Los_Angeles', + username: '1605130295132_test-j6asqt5qoprs@example.com', + }, }; const result = JSON.parse(ctx.stdout).result; expect(result).to.deep.equal(expected); @@ -235,20 +243,22 @@ describe('force:user:create', () => { // we set generatepassword=false in the varargs, in the definitionfile we have generatepassword=true, so we SHOULD NOT generate a password .it('will merge fields from the cli args, and the definitionfile correctly, preferring cli args', (ctx) => { const expected = { - alias: 'testAlias', - email: 'me@my.org', - emailEncodingKey: 'UTF-8', - id: '0052D0000043PawWWR', - languageLocaleKey: 'en_US', - lastName: 'User', - localeSidKey: 'en_US', orgId: 'abc123', - permsets: ['test1', 'test2'], - profileId: '00e2D000000bNexWWR', - generatePassword: false, - generatepassword: 'false', - timeZoneSidKey: 'America/Los_Angeles', - username: '1605130295132_test-j6asqt5qoprs@example.com', + permissionSetAssignments: ['test1', 'test2'], + fields: { + alias: 'testAlias', + email: 'me@my.org', + emailEncodingKey: 'UTF-8', + id: '0052D0000043PawWWR', + languageLocaleKey: 'en_US', + lastName: 'User', + localeSidKey: 'en_US', + profileId: '00e2D000000bNexWWR', + generatePassword: false, + generatepassword: 'false', + timeZoneSidKey: 'America/Los_Angeles', + username: '1605130295132_test-j6asqt5qoprs@example.com', + }, }; const result = JSON.parse(ctx.stdout).result; expect(result).to.deep.equal(expected); @@ -279,21 +289,24 @@ describe('force:user:create', () => { 'will merge fields from the cli args, and the definitionfile correctly, preferring cli args, cli args > file > default', (ctx) => { const expected = { - alias: 'testAlias', - email: 'me@my.org', - emailEncodingKey: 'UTF-8', - id: '0052D0000043PawWWR', - languageLocaleKey: 'en_US', - lastName: 'User', - localeSidKey: 'en_US', - generatePassword: false, - generatepassword: 'false', - profileName: "'Chatter Free User'", orgId: 'abc123', - // note the new profileId 12345678 -> Chatter Free User from var args - profileId: '12345678', - timeZoneSidKey: 'America/Los_Angeles', - username: '1605130295132_test-j6asqt5qoprs@example.com', + permissionSetAssignments: [], + fields: { + alias: 'testAlias', + email: 'me@my.org', + emailEncodingKey: 'UTF-8', + id: '0052D0000043PawWWR', + languageLocaleKey: 'en_US', + lastName: 'User', + localeSidKey: 'en_US', + generatePassword: false, + generatepassword: 'false', + profileName: "'Chatter Free User'", + // note the new profileId 12345678 -> Chatter Free User from var args + profileId: '12345678', + timeZoneSidKey: 'America/Los_Angeles', + username: '1605130295132_test-j6asqt5qoprs@example.com', + }, }; const result = JSON.parse(ctx.stdout).result; expect(result).to.deep.equal(expected); From 8b3a6f90b15f0330a6b37dbef1fcf81a59eaaa50 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Mon, 8 Feb 2021 09:48:26 -0600 Subject: [PATCH 2/8] fix: more casing issues --- src/commands/force/user/create.ts | 70 +++++++++++----------- test/commands/user/create.test.ts | 97 +++++++++++++++---------------- 2 files changed, 80 insertions(+), 87 deletions(-) diff --git a/src/commands/force/user/create.ts b/src/commands/force/user/create.ts index f377a5f9..7add7827 100644 --- a/src/commands/force/user/create.ts +++ b/src/commands/force/user/create.ts @@ -20,6 +20,7 @@ import { UserFields, } from '@salesforce/core'; import { QueryResult } from 'jsforce'; +import { omit } from '@salesforce/kit'; import { getString, Dictionary, isArray } from '@salesforce/ts-types'; import { flags, FlagsConfig, SfdxCommand } from '@salesforce/command'; @@ -43,6 +44,26 @@ const permsetsStringToArray = (fieldsPermsets: string | string[]): string[] => { : fieldsPermsets.split(',').map((item) => item.replace("'", '').trim()); }; +const lowercaseAllKeys = (input: Record): Record => { + return Object.keys(input).reduce(function (accum, key) { + accum[key.toLowerCase()] = input[key]; + return accum; + }, {}); +}; + +const standardizePasswordToBoolean = (input: unknown): boolean => { + if (typeof input === 'boolean') { + return input; + } + if (input === 'true' || input === 1) { + return true; + } + if (input === 'false' || input === 0) { + return false; + } + return true; +}; + export class UserCreateCommand extends SfdxCommand { public static readonly description = messages.getMessage('description'); public static readonly examples = messages.getMessage('examples').split(os.EOL); @@ -74,13 +95,7 @@ export class UserCreateCommand extends SfdxCommand { * @private */ private static stripInvalidAPIFields(fields: UserFields & Dictionary): UserFields { - const copy = Object.assign({}, fields); - // remove invalid fields for userCreate() - delete copy.permsets; - delete copy.generatepassword; - delete copy.generatePassword; - delete copy.profileName; - return copy as UserFields; + return omit(fields, ['permsets', 'generatepassword', 'generatePassword', 'profileName']); } public async run(): Promise { @@ -156,7 +171,7 @@ export class UserCreateCommand extends SfdxCommand { return { orgId: this.org.getOrgId(), permissionSetAssignments: permsetsStringToArray(permsets), - fields: { ...fieldsWithoutPermsets }, + fields: { ...lowercaseAllKeys(fieldsWithoutPermsets) }, }; } @@ -194,17 +209,22 @@ export class UserCreateCommand extends SfdxCommand { if (this.varargs) { Object.keys(this.varargs).forEach((key) => { - defaultFields[this.lowerFirstLetter(key)] = this.varargs[key]; - if (key.toLowerCase() === 'generatepassword') { - defaultFields['generatePassword'] = this.varargs[key]; + // standardize generatePassword casing + defaultFields['generatePassword'] = standardizePasswordToBoolean(this.varargs[key]); + } else if (key.toLowerCase() === 'profilename') { + // standardize profileName casing + defaultFields['profileName'] = this.varargs[key]; + } else { + // all other varargs are left "as is" + defaultFields[this.lowerFirstLetter(key)] = this.varargs[key]; } }); } // check if "profileName" was passed, this needs to become a profileId before calling User.create if (defaultFields['profileName']) { - const name = (defaultFields['profileName'] || 'Standard User') as string; + const name = (defaultFields['profileName'] ?? 'Standard User') as string; this.logger.debug(`Querying org for profile name [${name}]`); const response: QueryResult<{ Id: string }> = await this.org .getConnection() @@ -212,30 +232,6 @@ export class UserCreateCommand extends SfdxCommand { defaultFields.profileId = response.records[0].Id; } - // the file schema is camelCase and boolean while the cli arg is no capitalization and a string - // we will add logic to capture camelcase in varargs just in case - if ( - defaultFields['generatepassword'] === 'true' || - defaultFields['generatePassword'] === 'true' || - defaultFields['generatePassword'] === true - ) { - // since only one may be set, set both variations, prefer camelCase and boolean for coding - // this will also maintain --json backwards compatibility for the all lower case scenario - defaultFields['generatepassword'] = 'true'; - defaultFields['generatePassword'] = true; - } - // for the false case - if ( - defaultFields['generatepassword'] === 'false' || - defaultFields['generatePassword'] === 'false' || - defaultFields['generatePassword'] === false - ) { - // since only one may be set, set both variations, prefer camelCase and boolean for coding - // this will also maintain --json backwards compatibility for the all lower case scenario - defaultFields['generatepassword'] = 'false'; - defaultFields['generatePassword'] = false; - } - return defaultFields; } @@ -272,5 +268,5 @@ export default UserCreateCommand; interface UserCreateOutput { orgId: string; permissionSetAssignments: string[]; - fields: UserFields; + fields: Record; } diff --git a/test/commands/user/create.test.ts b/test/commands/user/create.test.ts index 26f6a86d..c3c6cc31 100644 --- a/test/commands/user/create.test.ts +++ b/test/commands/user/create.test.ts @@ -8,7 +8,7 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ import { $$, expect, test } from '@salesforce/command/lib/test'; -import { Aliases, AuthInfo, Connection, DefaultUserFields, fs, Logger, Org, User } from '@salesforce/core'; +import { Aliases, AuthInfo, Connection, DefaultUserFields, fs, Logger, Org, User, UserFields } from '@salesforce/core'; import { stubMethod } from '@salesforce/ts-sinon'; import { IConfig } from '@oclif/config'; import UserCreateCommand from '../../../src/commands/force/user/create'; @@ -66,7 +66,7 @@ describe('force:user:create', () => { async function prepareStubs(throws: { license?: boolean; duplicate?: boolean } = {}, readsFile?) { stubMethod($$.SANDBOX, Org.prototype, 'getConnection').callsFake(() => Connection.prototype); stubMethod($$.SANDBOX, DefaultUserFields, 'create').resolves({ - getFields: () => { + getFields: (): UserFields => { return { id: '0052D0000043PawWWR', username: '1605130295132_test-j6asqt5qoprs@example.com', @@ -109,7 +109,7 @@ describe('force:user:create', () => { test .do(async () => { stubMethod($$.SANDBOX, User.prototype, 'assignPassword').resolves(); - await prepareStubs({}, { profileName: 'profileFromFile', permsets: ['perm1', 'perm2'] }); + await prepareStubs({}, { profilename: 'profileFromFile', permsets: ['perm1', 'perm2'] }); }) .stdout() .command([ @@ -121,25 +121,24 @@ describe('force:user:create', () => { 'devhub@test.com', "permsets='permCLI, permCLI2'", 'generatepassword=true', - 'profileName=profileFromArgs', + 'profilename=profileFromArgs', ]) - .it('will handle a merge multiple permsets and profileNames from args and file (permsets from args)', (ctx) => { + .it('will handle a merge multiple permsets and profilenames from args and file (permsets from args)', (ctx) => { const expected = { orgId: 'abc123', permissionSetAssignments: ['permCLI', 'permCLI2'], fields: { alias: 'testAlias', email: 'defaultusername@test.com', - emailEncodingKey: 'UTF-8', + emailencodingkey: 'UTF-8', id: '0052D0000043PawWWR', - languageLocaleKey: 'en_US', - lastName: 'User', - localeSidKey: 'en_US', - generatepassword: 'true', - generatePassword: true, - profileId: '12345678', - profileName: 'profileFromArgs', - timeZoneSidKey: 'America/Los_Angeles', + languagelocalekey: 'en_US', + lastname: 'User', + localesidkey: 'en_US', + generatepassword: true, + profileid: '12345678', + profilename: 'profileFromArgs', + timezonesidkey: 'America/Los_Angeles', username: '1605130295132_test-j6asqt5qoprs@example.com', }, }; @@ -162,24 +161,24 @@ describe('force:user:create', () => { 'devhub@test.com', '--definitionfile', 'tempfile.json', - 'profileName=profileFromArgs', + 'profilename=profileFromArgs', 'username=user@cliArgs.com', ]) - .it('will handle a merge multiple permsets and profileNames from args and file (permsets from file)', (ctx) => { + .it('will handle a merge multiple permsets and profilenames from args and file (permsets from file)', (ctx) => { const expected = { orgId: 'abc123', permissionSetAssignments: ['perm1', 'perm2'], fields: { alias: 'testAlias', email: 'defaultusername@test.com', - emailEncodingKey: 'UTF-8', + emailencodingkey: 'UTF-8', id: '0052D0000043PawWWR', - languageLocaleKey: 'en_US', - lastName: 'User', - localeSidKey: 'en_US', - profileId: '12345678', - profileName: 'profileFromArgs', - timeZoneSidKey: 'America/Los_Angeles', + languagelocalekey: 'en_US', + lastname: 'User', + localesidkey: 'en_US', + profileid: '12345678', + profilename: 'profileFromArgs', + timezonesidkey: 'America/Los_Angeles', username: 'user@cliArgs.com', }, }; @@ -208,13 +207,13 @@ describe('force:user:create', () => { fields: { alias: 'testAlias', email: username, - emailEncodingKey: 'UTF-8', + emailencodingkey: 'UTF-8', id: '0052D0000043PawWWR', - languageLocaleKey: 'en_US', - lastName: 'User', - localeSidKey: 'en_US', - profileId: '00e2D000000bNexWWR', - timeZoneSidKey: 'America/Los_Angeles', + languagelocalekey: 'en_US', + lastname: 'User', + localesidkey: 'en_US', + profileid: '00e2D000000bNexWWR', + timezonesidkey: 'America/Los_Angeles', username: '1605130295132_test-j6asqt5qoprs@example.com', }, }; @@ -248,15 +247,14 @@ describe('force:user:create', () => { fields: { alias: 'testAlias', email: 'me@my.org', - emailEncodingKey: 'UTF-8', + emailencodingkey: 'UTF-8', id: '0052D0000043PawWWR', - languageLocaleKey: 'en_US', - lastName: 'User', - localeSidKey: 'en_US', - profileId: '00e2D000000bNexWWR', - generatePassword: false, - generatepassword: 'false', - timeZoneSidKey: 'America/Los_Angeles', + languagelocalekey: 'en_US', + lastname: 'User', + localesidkey: 'en_US', + profileid: '00e2D000000bNexWWR', + generatepassword: false, + timezonesidkey: 'America/Los_Angeles', username: '1605130295132_test-j6asqt5qoprs@example.com', }, }; @@ -267,7 +265,7 @@ describe('force:user:create', () => { test .do(async () => { - await prepareStubs({}, { generatepassword: true, profileName: 'System Administrator' }); + await prepareStubs({}, { generatepassword: true, profilename: 'System Administrator' }); }) .stdout() .command([ @@ -281,10 +279,10 @@ describe('force:user:create', () => { 'devhub@test.com', 'email=me@my.org', 'generatepassword=false', - "profileName='Chatter Free User'", + "profilename='Chatter Free User'", ]) // we set generatepassword=false in the varargs, in the definitionfile we have generatepassword=true, so we SHOULD NOT generate a password - // we should override the profileName with 'Chatter Free User' + // we should override the profilename with 'Chatter Free User' .it( 'will merge fields from the cli args, and the definitionfile correctly, preferring cli args, cli args > file > default', (ctx) => { @@ -294,17 +292,16 @@ describe('force:user:create', () => { fields: { alias: 'testAlias', email: 'me@my.org', - emailEncodingKey: 'UTF-8', + emailencodingkey: 'UTF-8', id: '0052D0000043PawWWR', - languageLocaleKey: 'en_US', - lastName: 'User', - localeSidKey: 'en_US', - generatePassword: false, - generatepassword: 'false', - profileName: "'Chatter Free User'", - // note the new profileId 12345678 -> Chatter Free User from var args - profileId: '12345678', - timeZoneSidKey: 'America/Los_Angeles', + languagelocalekey: 'en_US', + lastname: 'User', + localesidkey: 'en_US', + generatepassword: false, + profilename: "'Chatter Free User'", + // note the new profileid 12345678 -> Chatter Free User from var args + profileid: '12345678', + timezonesidkey: 'America/Los_Angeles', username: '1605130295132_test-j6asqt5qoprs@example.com', }, }; From 6c36392c6ce886a304018b48d4f6309270be0992 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Mon, 8 Feb 2021 13:37:15 -0600 Subject: [PATCH 3/8] refactor: kit.mapKeys --- src/commands/force/user/create.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/commands/force/user/create.ts b/src/commands/force/user/create.ts index 7add7827..af4457b4 100644 --- a/src/commands/force/user/create.ts +++ b/src/commands/force/user/create.ts @@ -20,7 +20,7 @@ import { UserFields, } from '@salesforce/core'; import { QueryResult } from 'jsforce'; -import { omit } from '@salesforce/kit'; +import { omit, mapKeys } from '@salesforce/kit'; import { getString, Dictionary, isArray } from '@salesforce/ts-types'; import { flags, FlagsConfig, SfdxCommand } from '@salesforce/command'; @@ -44,13 +44,6 @@ const permsetsStringToArray = (fieldsPermsets: string | string[]): string[] => { : fieldsPermsets.split(',').map((item) => item.replace("'", '').trim()); }; -const lowercaseAllKeys = (input: Record): Record => { - return Object.keys(input).reduce(function (accum, key) { - accum[key.toLowerCase()] = input[key]; - return accum; - }, {}); -}; - const standardizePasswordToBoolean = (input: unknown): boolean => { if (typeof input === 'boolean') { return input; @@ -171,7 +164,7 @@ export class UserCreateCommand extends SfdxCommand { return { orgId: this.org.getOrgId(), permissionSetAssignments: permsetsStringToArray(permsets), - fields: { ...lowercaseAllKeys(fieldsWithoutPermsets) }, + fields: { ...mapKeys(fieldsWithoutPermsets, (value, key) => key.toLowerCase()) }, }; } From c477a6213add2af8f43d94df381850c1be113747 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Mon, 8 Feb 2021 13:41:32 -0600 Subject: [PATCH 4/8] feat: casing for booleans as string, undefined --- src/commands/force/user/create.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/commands/force/user/create.ts b/src/commands/force/user/create.ts index af4457b4..f85006de 100644 --- a/src/commands/force/user/create.ts +++ b/src/commands/force/user/create.ts @@ -48,11 +48,18 @@ const standardizePasswordToBoolean = (input: unknown): boolean => { if (typeof input === 'boolean') { return input; } - if (input === 'true' || input === 1) { - return true; + if (typeof input === 'string') { + if (input.toLowerCase() === 'true') { + return true; + } + if (input.toLowerCase() === 'false') { + return false; + } } - if (input === 'false' || input === 0) { - return false; + if (typeof input === 'number') { + if (input === 1) { + return false; + } } return true; }; From 892535fcd7e4b675ced62332c6882f527ece3487 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Mon, 8 Feb 2021 13:45:32 -0600 Subject: [PATCH 5/8] fix: handle undefined and empty --- src/commands/force/user/create.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/commands/force/user/create.ts b/src/commands/force/user/create.ts index f85006de..c307f8e5 100644 --- a/src/commands/force/user/create.ts +++ b/src/commands/force/user/create.ts @@ -45,6 +45,9 @@ const permsetsStringToArray = (fieldsPermsets: string | string[]): string[] => { }; const standardizePasswordToBoolean = (input: unknown): boolean => { + if (typeof input === 'undefined') { + return false; + } if (typeof input === 'boolean') { return input; } @@ -52,7 +55,7 @@ const standardizePasswordToBoolean = (input: unknown): boolean => { if (input.toLowerCase() === 'true') { return true; } - if (input.toLowerCase() === 'false') { + if (input.toLowerCase() === 'false' || input === '') { return false; } } From 502a69176b9a9c1e791c84b8eda5a963a1a37ec7 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Mon, 8 Feb 2021 15:19:46 -0600 Subject: [PATCH 6/8] fix: also handle nulls --- src/commands/force/user/create.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/force/user/create.ts b/src/commands/force/user/create.ts index c307f8e5..62db90b6 100644 --- a/src/commands/force/user/create.ts +++ b/src/commands/force/user/create.ts @@ -45,7 +45,7 @@ const permsetsStringToArray = (fieldsPermsets: string | string[]): string[] => { }; const standardizePasswordToBoolean = (input: unknown): boolean => { - if (typeof input === 'undefined') { + if (typeof input === 'undefined' || input === null) { return false; } if (typeof input === 'boolean') { From 33cad20da84ecf318423746e0aede40da6c34f34 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Tue, 9 Feb 2021 08:48:25 -0600 Subject: [PATCH 7/8] refactor: password boolean without numbers --- src/commands/force/user/create.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/commands/force/user/create.ts b/src/commands/force/user/create.ts index 62db90b6..6b9bced1 100644 --- a/src/commands/force/user/create.ts +++ b/src/commands/force/user/create.ts @@ -59,12 +59,7 @@ const standardizePasswordToBoolean = (input: unknown): boolean => { return false; } } - if (typeof input === 'number') { - if (input === 1) { - return false; - } - } - return true; + return false; }; export class UserCreateCommand extends SfdxCommand { From 4d17aadf87f9f4d08961a4c5e675a700d670c416 Mon Sep 17 00:00:00 2001 From: mshanemc Date: Tue, 9 Feb 2021 09:34:07 -0600 Subject: [PATCH 8/8] refactor: return true or default false --- src/commands/force/user/create.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/commands/force/user/create.ts b/src/commands/force/user/create.ts index 6b9bced1..577f9bcf 100644 --- a/src/commands/force/user/create.ts +++ b/src/commands/force/user/create.ts @@ -45,9 +45,6 @@ const permsetsStringToArray = (fieldsPermsets: string | string[]): string[] => { }; const standardizePasswordToBoolean = (input: unknown): boolean => { - if (typeof input === 'undefined' || input === null) { - return false; - } if (typeof input === 'boolean') { return input; } @@ -55,9 +52,6 @@ const standardizePasswordToBoolean = (input: unknown): boolean => { if (input.toLowerCase() === 'true') { return true; } - if (input.toLowerCase() === 'false' || input === '') { - return false; - } } return false; };