diff --git a/src/Presets.md b/src/Presets.md index 4b61f8ac7..9e3a53cab 100644 --- a/src/Presets.md +++ b/src/Presets.md @@ -20,7 +20,7 @@ source format Each child of PermissionSet that is a repeated xml element (ex: ClassAccesses) is saved as a separate file Simple fields (ex: `description`, `userLicense`) remain in the top-level `myPS.permissionset-meta.xml` -FieldPermissions for all objects are in the same folder (they're not in sub-folders by object). This is intentional--I wanted subfolders but couldn't get it to work well. +FieldPermissions for all objects are in the same folder (they're not in sub-folders by object). This is intentional ## `decomposePermissionSetBeta2` @@ -52,7 +52,7 @@ source format Simple fields (ex: `description`, `userLicense`) remain in the top-level `PO_Manager.permissionset-meta.xml` -FieldPermissions for all objects are in the same folder (they're not in sub-folders by object). This is intentional--I wanted subfolders but couldn't get it to work well. +FieldPermissions for all objects are in the same folder (they're not in sub-folders by object). This is intentional ## `decomposeSharingRulesBeta` diff --git a/src/convert/convertContext/decomposedPermissionSetFinalizer.ts b/src/convert/convertContext/decomposedPermissionSetFinalizer.ts index 7205e855f..386549664 100644 --- a/src/convert/convertContext/decomposedPermissionSetFinalizer.ts +++ b/src/convert/convertContext/decomposedPermissionSetFinalizer.ts @@ -15,13 +15,13 @@ import { ConvertTransactionFinalizer } from './transactionFinalizer'; type PermissionSetState = { /* - * Incoming child xml (CustomLabel) keyed by label fullname + * Incoming child xml (children of PS) keyed by label name */ permissionSetChildByPath: Map; }; /** - * Merges child components that share the same parent in the conversion pipeline + * Merges child components that share the same object in the conversion pipeline * into a single file. * * Inserts unclaimed child components into the parent that belongs to the default package @@ -66,15 +66,12 @@ export class DecomposedPermissionSetFinalizer extends ConvertTransactionFinalize /** Return a json object that's built up from the mergeMap children */ const generateXml = (children: Map): JsonMap => ({ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - ['PermissionSet']: { + PermissionSet: { [XML_NS_KEY]: XML_NS_URL, - // for CustomLabels, that's `labels` - ...Object.assign({}, ...children.values()), - // labels: Array.from(children.values()).filter(customLabelHasFullName).sort(sortLabelsByFullName), + ...Object.assign( + {}, + // sort the children by fullName + ...Object.values(Array.from(children.values()).sort((a, b) => ((a.fullName ?? '') > (b.fullName ?? '') ? -1 : 1))) + ), }, }); - -// type CustomLabelWithFullName = PermissionSet & { fullName: string }; -// -// const sortLabelsByFullName = (a: CustomLabelWithFullName, b: CustomLabelWithFullName): number => -// a.fullName.localeCompare(b.fullName); diff --git a/src/convert/transformers/decomposedMetadataTransformer.ts b/src/convert/transformers/decomposedMetadataTransformer.ts index 27eb82e62..2bfcf7685 100644 --- a/src/convert/transformers/decomposedMetadataTransformer.ts +++ b/src/convert/transformers/decomposedMetadataTransformer.ts @@ -186,7 +186,7 @@ const getChildWriteInfos = return []; }; -const getWriteInfosFromMerge = +export const getWriteInfosFromMerge = (mergeWith: SourceComponent) => (stateSetter: StateSetter) => (parentXmlObject: XmlObj) => @@ -208,7 +208,7 @@ const getWriteInfosFromMerge = return []; }; -const getWriteInfosWithoutMerge = +export const getWriteInfosWithoutMerge = (defaultDirectory: string | undefined) => (parentXmlObject: XmlObj) => (component: SourceComponent): WriteInfo[] => { @@ -233,7 +233,7 @@ const getWriteInfosWithoutMerge = * * @param state */ -const setDecomposedState = +export const setDecomposedState = (state: DecompositionState) => (forComponent: MetadataComponent, props: Partial>): void => { const key = getKey(forComponent); @@ -272,13 +272,13 @@ const getDefaultOutput = (component: MetadataComponent): SourcePath => { }; /** use the given xmlElementName name if it exists, otherwise use see if one matches the directories */ -const tagToChildTypeId = ({ tagKey, type }: { tagKey: string; type: MetadataType }): string | undefined => +export const tagToChildTypeId = ({ tagKey, type }: { tagKey: string; type: MetadataType }): string | undefined => Object.values(type.children?.types ?? {}).find((c) => c.xmlElementName === tagKey)?.id ?? type.children?.directories?.[tagKey]; -const hasChildTypeId = (cm: ComposedMetadata): cm is Required => !!cm.childTypeId; +export const hasChildTypeId = (cm: ComposedMetadata): cm is Required => !!cm.childTypeId; -const addChildType = (cm: Required): ComposedMetadataWithChildType => { +export const addChildType = (cm: Required): ComposedMetadataWithChildType => { const childType = cm.parentType.children?.types[cm.childTypeId]; if (childType) { return { ...cm, childType }; @@ -286,10 +286,10 @@ const addChildType = (cm: Required): ComposedMetadataWithChild throw messages.createError('error_missing_child_type_definition', [cm.parentType.name, cm.childTypeId]); }; -type ComposedMetadata = { tagKey: string; tagValue: AnyJson; parentType: MetadataType; childTypeId?: string }; -type ComposedMetadataWithChildType = ComposedMetadata & { childType: MetadataType }; +export type ComposedMetadata = { tagKey: string; tagValue: AnyJson; parentType: MetadataType; childTypeId?: string }; +export type ComposedMetadataWithChildType = ComposedMetadata & { childType: MetadataType }; -type InfoContainer = { +export type InfoContainer = { entryName: string; childComponent: MetadataComponent; /** the parsed xml */ @@ -318,7 +318,7 @@ const toInfoContainer = }; }; -const forceIgnoreAllowsComponent = +export const forceIgnoreAllowsComponent = (forceIgnore: ForceIgnore) => (ic: InfoContainer): boolean => forceIgnore.accepts(getDefaultOutput(ic.childComponent)); @@ -341,5 +341,5 @@ const buildParentXml = }, }); -const getOutputFile = (component: SourceComponent, mergeWith?: SourceComponent): string => +export const getOutputFile = (component: SourceComponent, mergeWith?: SourceComponent): string => mergeWith?.xml ?? getDefaultOutput(component); diff --git a/src/convert/transformers/decomposedPermissionSetTransformer.ts b/src/convert/transformers/decomposedPermissionSetTransformer.ts index a5231d8ff..46dab5875 100644 --- a/src/convert/transformers/decomposedPermissionSetTransformer.ts +++ b/src/convert/transformers/decomposedPermissionSetTransformer.ts @@ -6,13 +6,11 @@ */ import { dirname, join } from 'node:path'; -import fs from 'node:fs'; import { AnyJson, ensureString, JsonMap } from '@salesforce/ts-types'; import { Messages } from '@salesforce/core'; import type { PermissionSet } from '@jsforce/jsforce-node/lib/api/metadata/schema'; import { calculateRelativePath } from '../../utils/path'; -import { ForceIgnore } from '../../resolve/forceIgnore'; -import { objectHasSomeRealValues, unwrapAndOmitNS } from '../../utils/decomposed'; +import { unwrapAndOmitNS } from '../../utils/decomposed'; import type { MetadataComponent } from '../../resolve/types'; import { type MetadataType } from '../../registry/types'; import { SourceComponent } from '../../resolve/sourceComponent'; @@ -21,8 +19,20 @@ import type { ToSourceFormatInput, WriteInfo, XmlObj } from '../types'; import { META_XML_SUFFIX, XML_NS_KEY, XML_NS_URL } from '../../common/constants'; import type { SourcePath } from '../../common/types'; import { ComponentSet } from '../../collections/componentSet'; -import type { DecompositionState, DecompositionStateValue } from '../convertContext/decompositionFinalizer'; +import type { DecompositionStateValue } from '../convertContext/decompositionFinalizer'; import { BaseMetadataTransformer } from './baseMetadataTransformer'; +import { + addChildType, + ComposedMetadata, + forceIgnoreAllowsComponent, + getOutputFile, + getWriteInfosFromMerge, + getWriteInfosWithoutMerge, + hasChildTypeId, + InfoContainer, + setDecomposedState, + tagToChildTypeId, +} from './decomposedMetadataTransformer'; type StateSetter = (forComponent: MetadataComponent, props: Partial>) => void; @@ -41,8 +51,8 @@ export class DecomposedPermissionSetTransformer extends BaseMetadataTransformer // TODO: this feels wrong, I'm not sure why the parent (.permissionset) isn't here child.getChildren() returns children new SourceComponent({ // because the children have the same name as the parent - name: children[0].name, - xml: children[0].xml!.replace(/(\w+\.\w+-meta\.xml)/gm, `${children[0].name}.permissionset-meta.xml`), + name: children[0]?.name, + xml: children[0]?.xml!.replace(/(\w+\.\w+-meta\.xml)/gm, `${children[0].name}.permissionset-meta.xml`), type: this.context.decomposedPermissionSet.permissionSetType, }), ].map((c) => { @@ -84,9 +94,11 @@ export class DecomposedPermissionSetTransformer extends BaseMetadataTransformer const writeInfosForChildren = getAndCombineChildWriteInfos( [ - // children whose type don't have a directory assigned will be written to the top level, separate them into individual WriteInfo[][] + // children whose type don't have a directory assigned will be written to the top level, separate them into individual WriteInfo[] with only one entry + // a [WriteInfo] with one entry, will result in one file ...preparedMetadata.filter((c) => !c.childComponent.type.directoryName).map((c) => [c]), // children whose type have a directory name will be grouped accordingly, bundle these together as a WriteInfo[][] with length > 1 + // a [WriteInfo, WriteInfo, ...] will be combined into a [WriteInfo] with combined contents preparedMetadata.filter((c) => c.childComponent.type.directoryName), ], stateSetter, @@ -116,66 +128,6 @@ export class DecomposedPermissionSetTransformer extends BaseMetadataTransformer const hasXml = (c: SourceComponent): c is SourceComponent & { xml: string } => typeof c.xml === 'string'; -const getWriteInfosFromMerge = - (mergeWith: SourceComponent) => - (stateSetter: StateSetter) => - (parentXmlObject: XmlObj) => - (parentComponent: SourceComponent): WriteInfo[] => { - const writeInfo = { source: new JsToXml(parentXmlObject), output: getOutputFile(parentComponent, mergeWith) }; - const parentHasRealValues = objectHasSomeRealValues(parentComponent.type)(parentXmlObject); - - if (mergeWith?.xml) { - // mark the component as found - stateSetter(parentComponent, { foundMerge: true }); - return objectHasSomeRealValues(parentComponent.type)(mergeWith.parseXmlSync()) && !parentHasRealValues - ? [] // the target file has values but this process doesn't, so we don't want to overwrite it - : [writeInfo]; - } - if (objectHasSomeRealValues(parentComponent.type)(parentXmlObject)) { - // set the state but don't return any writeInfo to avoid writing "empty" (ns-only) parent files - stateSetter(parentComponent, { writeInfo }); - } - return []; - }; - -const getWriteInfosWithoutMerge = - (defaultDirectory: string | undefined) => - (parentXmlObject: XmlObj) => - (component: SourceComponent): WriteInfo[] => { - const output = join(defaultDirectory ?? '', getOutputFile(component)); - // if the parent would be empty - // and it exists - // and every child is addressable - // don't overwrite the existing parent - if ( - !objectHasSomeRealValues(component.type)(parentXmlObject) && - fs.existsSync(output) && - Object.values(component.type.children ?? {}).every((child) => !child.isAddressable) - ) { - return []; - } else { - return [{ source: new JsToXml(parentXmlObject), output }]; - } - }; - -/** - * Helper for setting the decomposed transaction state - * - * @param state - */ -const setDecomposedState = - (state: DecompositionState) => - (forComponent: MetadataComponent, props: Partial>): void => { - const key = getKey(forComponent); - state.set(key, { - // origin gets set the first time - ...(state.get(key) ?? { origin: forComponent.parent ?? forComponent }), - ...(props ?? {}), - }); - }; - -const getKey = (component: MetadataComponent): string => `${component.type.name}#${component.fullName}`; - /** for a component, parse the xml and create an json object with contents, child typeId, etc */ const getComposedMetadataEntries = async (component: SourceComponent): Promise => // composedMetadata might be undefined if you call toSourceFormat() from a non-source-backed Component @@ -201,40 +153,13 @@ const getDefaultOutput = (component: MetadataComponent): SourcePath => { return join(calculateRelativePath('source')({ self: parent?.type ?? type })(fullName)(baseName), output); }; -/** use the given xmlElementName name if it exists, otherwise use see if one matches the directories */ -const tagToChildTypeId = ({ tagKey, type }: { tagKey: string; type: MetadataType }): string | undefined => - Object.values(type.children?.types ?? {}).find((c) => c.xmlElementName === tagKey)?.id ?? - type.children?.directories?.[tagKey]; - -const hasChildTypeId = (cm: ComposedMetadata): cm is Required => !!cm.childTypeId; - -const addChildType = (cm: Required): ComposedMetadataWithChildType => { - const childType = cm.parentType.children?.types[cm.childTypeId]; - if (childType) { - return { ...cm, childType }; - } - throw messages.createError('error_missing_child_type_definition', [cm.parentType.name, cm.childTypeId]); -}; - -type ComposedMetadata = { tagKey: string; tagValue: AnyJson; parentType: MetadataType; childTypeId?: string }; -type ComposedMetadataWithChildType = ComposedMetadata & { childType: MetadataType }; - -type InfoContainer = { - entryName: string; - childComponent: MetadataComponent; - /** the parsed xml */ - value: JsonMap; - parentComponent: SourceComponent; - mergeWith?: SourceComponent; -}; - const getAndCombineChildWriteInfos = ( containers: InfoContainer[][], stateSetter: StateSetter, childrenOfMergeComponent: ComponentSet ): WriteInfo[] => { // aggregator write info, will be returned at the end - const agg: WriteInfo[] = []; + const writeInfos: WriteInfo[] = []; containers.forEach((c) => { // we have multiple InfoContainers, build a map of output file => file content // this is how we'll combine multiple children into one file @@ -266,7 +191,7 @@ const getAndCombineChildWriteInfos = ( // if there's nothing to merge with, push write operation now to default location const childInfo = info[0].childComponent; if (!info[0].mergeWith) { - agg.push({ source, output: getDefaultOutput(childInfo) }); + writeInfos.push({ source, output: getDefaultOutput(childInfo) }); return; } // if the merge parent has a child that can be merged with, push write @@ -277,14 +202,14 @@ const getAndCombineChildWriteInfos = ( throw messages.createError('error_parsing_xml', [childInfo.fullName, childInfo.type.name]); } stateSetter(childInfo, { foundMerge: true }); - agg.push({ source, output: mergeChild.xml }); + writeInfos.push({ source, output: mergeChild.xml }); return; } // If we have a parent and the child is unaddressable without the parent, keep them // together on the file system, meaning a new child will not be written to the default dir. if (childInfo.type.unaddressableWithoutParent && typeof info[0].mergeWith?.xml === 'string') { // get output path from parent - agg.push({ + writeInfos.push({ source, output: join( dirname(info[0].mergeWith.xml), @@ -300,7 +225,7 @@ const getAndCombineChildWriteInfos = ( return []; }); }); - return agg; + return writeInfos; }; /** returns a data structure with lots of context information in it */ @@ -324,11 +249,3 @@ const toInfoContainer = mergeWith, }; }; - -const forceIgnoreAllowsComponent = - (forceIgnore: ForceIgnore) => - (ic: InfoContainer): boolean => - forceIgnore.accepts(getDefaultOutput(ic.childComponent)); - -const getOutputFile = (component: SourceComponent, mergeWith?: SourceComponent): string => - mergeWith?.xml ?? getDefaultOutput(component); diff --git a/test/convert/transformers/decompoedPermissionSetTransformer.test.ts b/test/convert/transformers/decompoedPermissionSetTransformer.test.ts new file mode 100644 index 000000000..ceee84680 --- /dev/null +++ b/test/convert/transformers/decompoedPermissionSetTransformer.test.ts @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023, salesforce.com, inc. + * All rights reserved. + * Licensed under the BSD 3-Clause license. + * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +import { join } from 'node:path'; +import { expect } from 'chai'; +import { ComponentSet } from '../../../src/collections/componentSet'; +import { RegistryAccess } from '../../../src/registry/registryAccess'; +import { getEffectiveRegistry } from '../../../src/registry/variants'; +import { presetMap } from '../../../src/registry/presets/presetMap'; +import { DecomposedPermissionSetTransformer } from '../../../src/convert/transformers/decomposedPermissionSetTransformer'; +import { + MD_FORMAT_PS, + ONLY_PS_PARENT, + SOURCE_FORMAT_PS, +} from '../../mock/type-constants/decomposedPermissionSetConstant'; + +describe('DecomposedPermissionSetTransformer', () => { + const regAcc = new RegistryAccess(getEffectiveRegistry({ presets: [presetMap.get('decomposePermissionSetBeta2')!] })); + + describe('toSourceFormat', () => { + describe('WriteInfo output (where the file will write to)', () => { + it('multiple children combined, and some written to individual files', async () => { + const component = MD_FORMAT_PS; + const xf = new DecomposedPermissionSetTransformer(regAcc); + const result = await xf.toSourceFormat({ component }); + expect(result).to.have.length(5); + result.map((l) => { + expect(l.output).to.include(join('main', 'default', 'permissionsets')); + }); + expect(result[0].output).to.match(/myPS.classAccess-meta.xml$/); + expect(result[1].output).to.match(/myPS.userPermission-meta.xml$/); + expect(result[2].output).to.match(/objectSettings[\\/]Account.objectSettings-meta.xml$/); + expect(result[3].output).to.match(/objectSettings[\\/]Broker__c.objectSettings-meta.xml$/); + expect(result[4].output).to.match(/myPS.permissionset-meta.xml$/); + }); + it('merge component in defaultDir', async () => { + const component = MD_FORMAT_PS; + const xf = new DecomposedPermissionSetTransformer(regAcc); + const result = await xf.toSourceFormat({ + component, + mergeSet: new ComponentSet([ONLY_PS_PARENT], regAcc), + }); + expect(result).to.have.length(5); + expect(result[4].output).to.equal(ONLY_PS_PARENT.xml!); + }); + }); + }); + + describe('toMetadataFormat', () => { + it('decomposed PS 2 combined to md-format', async () => { + const component = SOURCE_FORMAT_PS; + const xf = new DecomposedPermissionSetTransformer(regAcc); + const result = await xf.toMetadataFormat(component); + expect(result).to.deep.equal([]); + expect(xf.context.decomposedPermissionSet.permissionSetType).to.equal(regAcc.getTypeByName('PermissionSet')); + }); + }); +}); diff --git a/test/mock/type-constants/decomposedPermissionSetConstant.ts b/test/mock/type-constants/decomposedPermissionSetConstant.ts new file mode 100644 index 000000000..0f6903906 --- /dev/null +++ b/test/mock/type-constants/decomposedPermissionSetConstant.ts @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2023, salesforce.com, inc. + * All rights reserved. + * Licensed under the BSD 3-Clause license. + * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +import { join } from 'node:path'; +import { SourceComponent, VirtualTreeContainer, presetMap, RegistryAccess } from '../../../src'; +import { getEffectiveRegistry } from '../../../src/registry/variants'; + +// Constants for a matching content file type +const regAcc = new RegistryAccess(getEffectiveRegistry({ presets: [presetMap.get('decomposePermissionSetBeta2')!] })); + +const permissionSet = regAcc.getTypeByName('PermissionSet'); + +const MDAPI_XML_NAME = 'myPS.permissionset'; +const SOURCE_XML_NAME = 'myPS.permissionset-meta.xml'; + +export const MD_FORMAT_PS = new SourceComponent( + { + name: 'myPS', + type: permissionSet, + xml: join('permissionsets', MDAPI_XML_NAME), + }, + new VirtualTreeContainer([ + { + dirPath: 'permissionsets', + children: [ + { + name: MDAPI_XML_NAME, + data: Buffer.from(` + + + FileUtilities + true + + + FileUtilitiesTest + true + + + GeocodingService + true + + + GeocodingServiceTest + true + + + PagedResult + true + + + PropertyController + true + + + SampleDataController + true + + + TestPropertyController + true + + + TestSampleDataController + true + + + true + CanApproveFeedPost + + + true + PrivacyDataAccess + + + true + RunFlow + + + true + ViewRoles + + + true + ViewSetup + + + false + false + false + true + false + Account + true + + + true + false + true + true + false + AppAnalyticsQueryRequest + false + + + false + false + false + true + false + Asset + true + + + false + false + false + true + false + AssetAction + true + + + true + false + false + true + false + Broker__c + false + + + true + Broker__c.Broker_Id__c + true + + + true + Broker__c.Email__c + true + + + true + Broker__c.Mobile_Phone__c + true + + + true + Broker__c.Phone__c + true + + + false + Broker__c.Picture_IMG__c + true + + + true + Broker__c.Picture__c + true + + + true + Broker__c.Title__c + true + + + Broker__c + Visible + + + standard-AssetAction + Visible + + decomposed desc adfadf + false + + Analytics Cloud Integration User + +`), + }, + ], + }, + ]) +); + +export const SOURCE_FORMAT_PS = new SourceComponent( + { + name: 'myPS', + type: permissionSet, + content: join('main', 'default', 'permissionsets', 'myPS', SOURCE_XML_NAME), + }, + new VirtualTreeContainer([ + { + dirPath: join('main', 'default', 'permissionsets', 'myPS'), + children: [ + { + name: 'myPS.classAccess-meta.xml', + data: Buffer.from(` + + + FileUtilities + true + + + FileUtilitiesTest + true + + + GeocodingService + true + + + GeocodingServiceTest + true + + + PagedResult + true + + + PropertyController + true + + + SampleDataController + true + + + TestPropertyController + true + + + TestSampleDataController + true + + +`), + }, + { + name: 'myPS.permissionset-meta.xml', + data: Buffer.from(` + + decomposed desc adfadf + false + + Analytics Cloud Integration User +`), + }, + ], + }, + { + dirPath: join('main', 'default', 'permissionsets', 'myPS', 'objectSettings'), + children: [ + { + name: 'Account.objectSettings-meta.xml', + data: Buffer.from(` + + + false + false + false + true + false + Account + true + + + true + false + true + true + false + AppAnalyticsQueryRequest + false + + + false + false + false + true + false + Asset + true + + + false + false + false + true + false + AssetAction + true + + + true + false + false + true + false + Broker__c + false + + +`), + }, + { + name: 'Broker__c.objectSettings-meta.xml', + data: Buffer.from(` + + + true + Broker__c.Broker_Id__c + true + + + true + Broker__c.Email__c + true + + + true + Broker__c.Mobile_Phone__c + true + + + true + Broker__c.Phone__c + true + + + false + Broker__c.Picture_IMG__c + true + + + true + Broker__c.Picture__c + true + + + true + Broker__c.Title__c + true + + + Broker__c + Visible + + + standard-AssetAction + Visible + + +`), + }, + ], + }, + ]) +); +export const ONLY_PS_PARENT = new SourceComponent( + { + name: 'myPS', + type: permissionSet, + xml: join('main', 'default', 'permissionsets', 'myPS', `${MDAPI_XML_NAME}-meta.xml`), + }, + new VirtualTreeContainer([ + { + dirPath: 'permissionsets', + children: [ + { + name: MDAPI_XML_NAME, + data: Buffer.from(` + + decomposed desc adfadf + false + + Analytics Cloud Integration User +`), + }, + ], + }, + ]) +); + +// export const THREE_CUSTOM_LABELS_CMP = new SourceComponent( +// { +// name: 'CustomLabels', +// type: permissionSet, +// xml: join('labels', MDAPI_XML_NAME), +// }, +// new VirtualTreeContainer([ +// { +// dirPath: 'permissionSet', +// children: [ +// { +// name: MDAPI_XML_NAME, +// data: Buffer.from(` +// +// +// DeleteMe +// en_US +// true +// DeleteMe +// Test +// +// +// KeepMe1 +// en_US +// true +// KeepMe1 +// Test +// +// +// KeepMe2 +// en_US +// true +// KeepMe2 +// Test +// +// `), +// }, +// ], +// }, +// ]) +// ); +// +// const ONLY_LABEL_CONTENTS = ` +// +// OnlyLabel +// en_US +// true +// OnlyLabel +// OnlyLabel +// `; +// +// export const ONLY_LABEL_CMP_IN_DEFAULT_DIR_CMP = new SourceComponent( +// { +// name: 'OnlyLabel', +// type: customLabelType, +// xml: join('main', 'default', 'labels', 'OnlyLabel.label-meta.xml'), +// }, +// new VirtualTreeContainer([ +// { +// dirPath: join('main', 'default', 'labels'), +// children: [ +// { +// name: 'OnlyLabel.label-meta.xml', +// data: Buffer.from(ONLY_LABEL_CONTENTS), +// }, +// ], +// }, +// ]) +// ); +// +// export const ONLY_LABEL_CMP_IN_ANOTHER_DIR_CMP = new SourceComponent( +// { +// name: 'OnlyLabel', +// type: customLabelType, +// xml: join('other', 'dir', 'labels', 'OnlyLabel.label-meta.xml'), +// }, +// new VirtualTreeContainer([ +// { +// dirPath: join('other', 'dir', 'labels'), +// children: [ +// { +// name: 'OnlyLabel.label-meta.xml', +// data: Buffer.from(ONLY_LABEL_CONTENTS), +// }, +// ], +// }, +// ]) +// ); +// +// export const ONLY_LABEL_NO_DIR_CMP = new SourceComponent( +// { +// name: 'OnlyLabel', +// type: customLabelType, +// xml: 'OnlyLabel.label-meta.xml', +// }, +// new VirtualTreeContainer([ +// { +// dirPath: '', +// children: [ +// { +// name: 'OnlyLabel.label-meta.xml', +// data: Buffer.from(ONLY_LABEL_CONTENTS), +// }, +// ], +// }, +// ]) +// ); +// +// export const OTHER_LABEL_CMP = new SourceComponent( +// { +// name: 'OtherLabel', +// type: customLabelType, +// xml: join('labels', 'OtherLabel.label-meta.xml'), +// }, +// new VirtualTreeContainer([ +// { +// dirPath: 'permissionSet', +// children: [ +// { +// name: 'OtherLabel.label-meta.xml', +// data: Buffer.from(` +// +// OtherLabel +// en_US +// true +// OtherLabel +// OtherLabel +// `), +// }, +// ], +// }, +// ]) +// ); diff --git a/test/mock/type-constants/index.ts b/test/mock/type-constants/index.ts index 32342e47f..038d8aa52 100644 --- a/test/mock/type-constants/index.ts +++ b/test/mock/type-constants/index.ts @@ -18,6 +18,7 @@ import * as nonDecomposed from './customlabelsConstant'; import * as nestedTypes from './territoryConstant'; import * as lwcBundle from './lwcBundleConstant'; import * as digitalExperienceBundle from './digitalExperienceBundleConstants'; +import * as decomposedPermissionSet from './decomposedPermissionSetConstant'; export { xmlInFolder, @@ -34,4 +35,5 @@ export { lwcBundle, digitalExperienceBundle, experiencePropertyTypeContentSingleFile, + decomposedPermissionSet, };