Skip to content

Commit

Permalink
fix: test class
Browse files Browse the repository at this point in the history
  • Loading branch information
PreziosiRaffaele committed Jan 28, 2024
1 parent 1eaed63 commit e361f03
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 67 deletions.
8 changes: 5 additions & 3 deletions src/PermissionSetUpdater.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable class-methods-use-this */
import path from 'node:path';
import { promises as fsPromises } from 'node:fs';
import { XMLParser, XMLBuilder } from 'fast-xml-parser';

Expand Down Expand Up @@ -27,13 +28,14 @@ export class PermissionSetUpdater {
}

public async updatePermissionSet(
directoryPath: string,
permissionSet: string,
fieldsPermissionSelected: { [key: string]: string },
objectSelected: string
): Promise<void> {
const completeFilePath = `./force-app/main/default/permissionsets/${permissionSet}`;
const permissionSetXml = await this.fs.readFile(completeFilePath, 'utf8');
const permissionSetParsedJSON = this.parser.parse(permissionSetXml) as PermissionSet;
const completeFilePath: string = path.resolve(directoryPath, 'permissionsets', permissionSet);
const permissionSetXml: string = await this.fs.readFile(completeFilePath, 'utf8');
const permissionSetParsedJSON: PermissionSet = this.parser.parse(permissionSetXml) as PermissionSet;

for (const field in fieldsPermissionSelected) {
if (Object.prototype.hasOwnProperty.call(fieldsPermissionSelected, field)) {
Expand Down
64 changes: 46 additions & 18 deletions src/commands/perms/field/new.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable class-methods-use-this */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import path from 'node:path';
import { promises as fsPromises } from 'node:fs';
import { SfCommand } from '@salesforce/sf-plugins-core';
import { Messages } from '@salesforce/core';
Expand All @@ -10,52 +10,75 @@ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('sf-perms', 'perms.field.new');

export type PermsFieldNewResult = {
isSucces: boolean;
isSuccess: boolean;
errorMessage?: string;
};

export default class PermsFieldNew extends SfCommand<PermsFieldNewResult> {
public static readonly summary = messages.getMessage('summary');
public static readonly description = messages.getMessage('description');
public static readonly examples = messages.getMessages('examples');

public static readonly flags = {};

// eslint-disable-next-line class-methods-use-this
public static fs = fsPromises;
public static prompts = prompts;

public async run(): Promise<PermsFieldNewResult> {
const result: PermsFieldNewResult = {
isSucces: true,
isSuccess: true,
};

const directoryPath: string = path.resolve(process.cwd(), 'test', 'force-app', 'main', 'default');

try {
const { permissionSetsSelected, objectSelected } = await this.selectPermissionSetsAndObject();
const selectedFields = await this.selectFields(objectSelected);
await this.checkDirectory(directoryPath);
const { permissionSetsSelected, objectSelected } = await this.selectPermissionSetsAndObject(directoryPath);
const selectedFields = await this.selectFields(objectSelected, directoryPath);
const fieldsPermissionSelected = await this.selectFieldsPermissions(selectedFields);
const permissionSetUpdater = new PermissionSetUpdater(fsPromises);
const permissionSetUpdater = new PermissionSetUpdater(PermsFieldNew.fs);
await Promise.all(
permissionSetsSelected.map((permissionSet) =>
permissionSetUpdater.updatePermissionSet(permissionSet, fieldsPermissionSelected, objectSelected)
permissionSetUpdater.updatePermissionSet(
directoryPath,
permissionSet,
fieldsPermissionSelected,
objectSelected
)
)
);
this.log(`Permission Sets ${permissionSetsSelected.join(', ')} updated successfully!`);
} catch (err) {
result.isSucces = false;
result.isSuccess = false;
result.errorMessage = (err as Error).message;
}

return result;
}

private async selectFields(objectSelected: string): Promise<string[]> {
const fields: string[] = await fsPromises.readdir(`./force-app/main/default/objects/${objectSelected}/fields`);
private async checkDirectory(directoryPath: string): Promise<void> {
try {
await PermsFieldNew.fs.access(directoryPath);
} catch (err) {
throw new Error(`Directory ${directoryPath} not found`);
}
const files = await PermsFieldNew.fs.readdir(directoryPath);
if (files.length === 0) {
throw new Error(`Directory ${directoryPath} is empty`);
}
}

private async selectFields(objectSelected: string, directoryPath: string): Promise<string[]> {
const pathToFields: string = path.resolve(directoryPath, 'objects', objectSelected, 'fields');
await this.checkDirectory(pathToFields);
const fields: string[] = await PermsFieldNew.fs.readdir(pathToFields);

const fieldChoises: prompts.Choice[] = fields.map((file) => ({
title: file.split('.')[0],
value: file.split('.')[0],
}));

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unused-vars
const selectedFields = await prompts({
const selectedFields = await PermsFieldNew.prompts({
type: 'multiselect',
name: 'Fields',
message: 'Select Fields',
Expand All @@ -67,13 +90,18 @@ export default class PermsFieldNew extends SfCommand<PermsFieldNewResult> {
return selectedFields.Fields;
}

private async selectPermissionSetsAndObject(): Promise<{
private async selectPermissionSetsAndObject(directoryPath: string): Promise<{
permissionSetsSelected: string[];
objectSelected: string;
}> {
const pathToPermissionSets: string = path.resolve(directoryPath, 'permissionsets');
await this.checkDirectory(pathToPermissionSets);
const pathToObjects: string = path.resolve(directoryPath, 'objects');
await this.checkDirectory(pathToObjects);

const [permissionsets, objects]: [string[], string[]] = await Promise.all([
fsPromises.readdir('./force-app/main/default/permissionsets'),
fsPromises.readdir('./force-app/main/default/objects'),
PermsFieldNew.fs.readdir(pathToPermissionSets),
PermsFieldNew.fs.readdir(pathToObjects),
]);

const permissionSetChoises: prompts.Choice[] = permissionsets.map((file) => ({
Expand All @@ -87,7 +115,7 @@ export default class PermsFieldNew extends SfCommand<PermsFieldNewResult> {
}));

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unused-vars
const { permissionSetsSelected, objectSelected } = await prompts([
const { permissionSetsSelected, objectSelected } = await PermsFieldNew.prompts([
{
type: 'multiselect',
name: 'permissionSetsSelected',
Expand Down Expand Up @@ -131,7 +159,7 @@ export default class PermsFieldNew extends SfCommand<PermsFieldNewResult> {
}));

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
const fieldsPermissionSelected = await prompts(fieldsPermissionPrompts);
const fieldsPermissionSelected = await PermsFieldNew.prompts(fieldsPermissionPrompts);

// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return fieldsPermissionSelected;
Expand Down
21 changes: 0 additions & 21 deletions test/commands/perms/field/new.nut.ts

This file was deleted.

102 changes: 77 additions & 25 deletions test/commands/perms/field/new.test.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,92 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import fs from 'node:fs';
import path from 'node:path';
import { XMLParser } from 'fast-xml-parser';
import { TestContext } from '@salesforce/core/lib/testSetup.js';
import { expect } from 'chai';
import { stubSfCommandUx } from '@salesforce/sf-plugins-core';
import PermsFieldNew from '../../../../src/commands/perms/field/new.js';
import PermsFieldNew, { PermsFieldNewResult } from '../../../../src/commands/perms/field/new.js';

const pathToPermissionSet = path.resolve('', 'test', 'force-app', 'main', 'default', 'permissionsets');

describe('perms field new', () => {
const $$ = new TestContext();
let sfCommandStubs: ReturnType<typeof stubSfCommandUx>;

beforeEach(() => {
sfCommandStubs = stubSfCommandUx($$.SANDBOX);
fs.copyFileSync(
path.resolve(pathToPermissionSet, 'FirstPermissionSet.permissionset-meta.xml'),
path.resolve(pathToPermissionSet, 'FirstPermissionSetBackup.permissionset-meta.xml')
);
});

afterEach(() => {
$$.restore();
fs.copyFileSync(
path.resolve(pathToPermissionSet, 'FirstPermissionSetBackup.permissionset-meta.xml'),
path.resolve(pathToPermissionSet, 'FirstPermissionSet.permissionset-meta.xml')
);
fs.unlinkSync(path.resolve(pathToPermissionSet, 'FirstPermissionSetBackup.permissionset-meta.xml'));
});

it('runs hello', async () => {
await PermsFieldNew.run([]);
const output = sfCommandStubs.log
.getCalls()
.flatMap((c) => c.args)
.join('\n');
expect(output).to.include('hello world');
});

it('runs hello with --json and no provided name', async () => {
const result = await PermsFieldNew.run([]);
expect(result.path).to.equal('/Users/raffaele.preziosi/VsCode/sf-perms/src/commands/perms/field/new.ts');
});

it('runs hello world --name Astro', async () => {
await PermsFieldNew.run(['--name', 'Astro']);
const output = sfCommandStubs.log
.getCalls()
.flatMap((c) => c.args)
.join('\n');
expect(output).to.include('hello Astro');
it('add new field permission', async () => {
let callCount = 0;
$$.SANDBOX.stub(PermsFieldNew, 'prompts').callsFake(() => {
callCount++;
switch (callCount) {
case 1:
return Promise.resolve({
permissionSetsSelected: ['FirstPermissionSet.permissionset-meta.xml'],
objectSelected: 'Account',
});
case 2:
return Promise.resolve({
Fields: ['Address__c', 'AddressString__c'],
});
case 3:
return Promise.resolve({
// eslint-disable-next-line camelcase
Address__c: 'read',
// eslint-disable-next-line camelcase
AddressString__c: 'read_edit',
});
default:
return Promise.resolve({});
}
});
const result: PermsFieldNewResult = await PermsFieldNew.run([]);
expect(result).to.have.property('isSuccess', true);
// check field permissions are added in the file
const permissionSetXml = fs.readFileSync(
path.resolve(pathToPermissionSet, 'FirstPermissionSet.permissionset-meta.xml'),
'utf8'
);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const permissionSetParsedJSON = new XMLParser({ ignoreAttributes: false }).parse(permissionSetXml);
expect(permissionSetParsedJSON).to.have.property('PermissionSet');
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
expect(permissionSetParsedJSON.PermissionSet).to.have.property('fieldPermissions');
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
expect(permissionSetParsedJSON.PermissionSet.fieldPermissions).to.be.an('array');
expect(permissionSetParsedJSON.PermissionSet.fieldPermissions).to.have.lengthOf(2);
expect(
permissionSetParsedJSON.PermissionSet.fieldPermissions.find(
(fp: { field: string }) => fp.field === 'Account.Address__c'
)
).to.have.property('editable', false);
expect(
permissionSetParsedJSON.PermissionSet.fieldPermissions.find(
(fp: { field: string }) => fp.field === 'Account.Address__c'
)
).to.have.property('readable', true);
expect(
permissionSetParsedJSON.PermissionSet.fieldPermissions.find(
(fp: { field: string }) => fp.field === 'Account.AddressString__c'
)
).to.have.property('editable', true);
expect(
permissionSetParsedJSON.PermissionSet.fieldPermissions.find(
(fp: { field: string }) => fp.field === 'Account.AddressString__c'
)
).to.have.property('readable', true);
});
});
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
<description></description>
<hasActivationRequired>false</hasActivationRequired>
<label>First Permission Set</label>
</PermissionSet>

0 comments on commit e361f03

Please sign in to comment.