Skip to content

Commit

Permalink
fix: custom field was not polling correctly (logic error on del__c)
Browse files Browse the repository at this point in the history
  • Loading branch information
mshanemc committed Jun 21, 2022
1 parent 6e71f03 commit 1ff2341
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 28 deletions.
59 changes: 31 additions & 28 deletions src/shared/expectedSourceMembers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,57 +9,60 @@ import { ComponentStatus } from '@salesforce/source-deploy-retrieve';
import { getMetadataKeyFromFileResponse } from './metadataKeys';
import { RemoteSyncInput } from './types';

const typesToNoPollFor = [
'CustomObject',
'EmailFolder',
'EmailTemplateFolder',
'StandardValueSet',
'Portal',
'StandardValueSetTranslation',
'SharingRules',
'SharingCriteriaRule',
'GlobalValueSetTranslation',
'AssignmentRules',
];

const isEncodedTypeWithPercentSign = (type: string, filePath?: string): boolean =>
['Layout', 'Profile', 'HomePageComponent', 'HomePageLayout'].includes(type) && Boolean(filePath?.includes('%'));

// aura xml aren't tracked as SourceMembers
const isSpecialAuraXml = (filePath?: string): boolean =>
Boolean(
filePath &&
(filePath.endsWith('.cmp-meta.xml') ||
filePath.endsWith('.tokens-meta.xml') ||
filePath.endsWith('.evt-meta.xml') ||
filePath.endsWith('.app-meta.xml') ||
filePath.endsWith('.intf-meta.xml'))
);

export const calculateExpectedSourceMembers = (expectedMembers: RemoteSyncInput[]): Map<string, RemoteSyncInput> => {
const outstandingSourceMembers = new Map<string, RemoteSyncInput>();

expectedMembers
.filter(
// eslint-disable-next-line complexity
(fileResponse) =>
// unchanged files will never be in the sourceMembers. Not really sure why SDR returns them.
fileResponse.state !== ComponentStatus.Unchanged &&
// if a listView is the only change inside an object, the object won't have a sourceMember change. We won't wait for those to be found
// we don't know which email folder type might be there, so don't require either
// Portal doesn't support source tracking, according to the coverage report
![
'CustomObject',
'EmailFolder',
'EmailTemplateFolder',
'StandardValueSet',
'Portal',
'StandardValueSetTranslation',
'SharingRules',
'SharingCriteriaRule',
'GlobalValueSetTranslation',
'AssignmentRules',
].includes(fileResponse.type) &&
!typesToNoPollFor.includes(fileResponse.type) &&
// don't wait for standard fields on standard objects
!(fileResponse.type === 'CustomField' && !fileResponse.filePath?.includes('__c')) &&
// deleted fields
!(fileResponse.type === 'CustomField' && !fileResponse.filePath?.includes('_del__c')) &&
!(fileResponse.type === 'CustomField' && fileResponse.filePath?.includes('_del__c')) &&
// built-in report type ReportType__screen_flows_prebuilt_crt
!(fileResponse.type === 'ReportType' && fileResponse.filePath?.includes('screen_flows_prebuilt_crt')) &&
// they're settings to mdapi, and FooSettings in sourceMembers
!fileResponse.type.includes('Settings') &&
// mdapi encodes these, sourceMembers don't have encoding
!(
(fileResponse.type === 'Layout' ||
fileResponse.type === 'BusinessProcess' ||
fileResponse.type === 'Profile' ||
fileResponse.type === 'HomePageComponent' ||
fileResponse.type === 'HomePageLayout') &&
fileResponse.filePath?.includes('%')
) &&
!isEncodedTypeWithPercentSign(fileResponse.type, fileResponse.filePath) &&
// namespaced labels and CMDT don't resolve correctly
!(['CustomLabels', 'CustomMetadata'].includes(fileResponse.type) && fileResponse.filePath?.includes('__')) &&
// don't wait on workflow children
!fileResponse.type.startsWith('Workflow') &&
// aura xml aren't tracked as SourceMembers
!fileResponse.filePath?.endsWith('.cmp-meta.xml') &&
!fileResponse.filePath?.endsWith('.tokens-meta.xml') &&
!fileResponse.filePath?.endsWith('.evt-meta.xml') &&
!fileResponse.filePath?.endsWith('.app-meta.xml') &&
!fileResponse.filePath?.endsWith('.intf-meta.xml')
!isSpecialAuraXml(fileResponse.filePath)
)
.map((member) => {
getMetadataKeyFromFileResponse(member)
Expand Down
100 changes: 100 additions & 0 deletions test/unit/expectedSourceMembers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2020, 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 { ComponentStatus } from '@salesforce/source-deploy-retrieve';
import { expect } from 'chai';
import { calculateExpectedSourceMembers } from '../../src/shared/expectedSourceMembers';
import { getMetadataKeyFromFileResponse } from '../../src/shared/metadataKeys';

describe('expectedSourceMembers', () => {
it('filters out standard fields and deleted fields on standardObjects but returns custom fields on same object ', () => {
const input = [
{
type: 'CustomField',
fullName: 'Account.Name',
filePath: 'src/objects/Account/fields/Name.field-meta.xml',
state: ComponentStatus.Created,
},
{
type: 'CustomField',
fullName: 'Account.Deleted_del__c',
filePath: 'src/objects/Account/fields/Deleted_del__c.field-meta.xml',
state: ComponentStatus.Created,
},
{
type: 'CustomField',
fullName: 'Account.Foo__c',
filePath: 'src/objects/Account/fields/Foo__c.field-meta.xml',
state: ComponentStatus.Created,
},
];
const result = calculateExpectedSourceMembers(input);
expect(result.size).to.equal(1);
// fields return object, field for their keys
expect(result.get(getMetadataKeyFromFileResponse(input[2]).find((f) => f.startsWith('CustomField')))).to.deep.equal(
input[2]
);
});

it('omits aura xml types', () => {
const input = [
{
type: 'AuraDefinitionBundle',
fullName: 'foo',
state: ComponentStatus.Created,
filePath: 'src/aura/foo/foo.cmp-meta.xml',
},
];
const result = calculateExpectedSourceMembers(input);
expect(result.size).to.equal(0);
});

it('omits Layout only if it contains a %', () => {
const input = [
{
type: 'Layout',
fullName: 'Account.OKLayout',
filePath: 'src/layouts/Account-OKLayout.layout-meta.xml',
state: ComponentStatus.Created,
},
{
type: 'Layout',
fullName: 'Account.Whate%ver',
filePath: 'src/layouts/Account-Whate%ver.layout-meta.xml',
state: ComponentStatus.Created,
},
];
const result = calculateExpectedSourceMembers(input);
expect(result.size).to.equal(1);
expect(result.get(getMetadataKeyFromFileResponse(input[0])[0])).to.deep.equal(input[0]);
});

it('omits namespaced custom labels', () => {
const input = [
{
type: 'CustomLabels',
fullName: 'ns__Test1',
filePath: 'src/labels/ns__Account-OKLayout.labels-meta.xml',
state: ComponentStatus.Created,
},
];
const result = calculateExpectedSourceMembers(input);
expect(result.size).to.equal(0);
});

it('omits standard profile', () => {
const input = [
{
type: 'Profile',
fullName: 'Standard',
filePath: 'src/profiles/Standard.profile-meta.xml',
state: ComponentStatus.Created,
},
];
const result = calculateExpectedSourceMembers(input);
expect(result.size).to.equal(0);
});
});

0 comments on commit 1ff2341

Please sign in to comment.