Skip to content

Commit 2723bd8

Browse files
committed
Includes new and removed custom fields.
1 parent ceea88d commit 2723bd8

File tree

5 files changed

+124
-99
lines changed

5 files changed

+124
-99
lines changed

src/core/changelog/__test__/generating-change-log.spec.ts

Lines changed: 99 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { UnparsedApexBundle, UnparsedCustomObjectBundle } from '../../shared/types';
1+
import {
2+
UnparsedApexBundle,
3+
UnparsedCustomFieldBundle,
4+
UnparsedCustomObjectBundle,
5+
UnparsedSourceBundle,
6+
} from '../../shared/types';
27
import { ChangeLogPageData, generateChangeLog } from '../generate-change-log';
38
import { assertEither } from '../../test-helpers/assert-either';
49
import { isSkip } from '../../shared/utils';
@@ -27,31 +32,31 @@ function customObjectGenerator(
2732
</CustomObject>`;
2833
}
2934

30-
// export const customField = `
31-
// <?xml version="1.0" encoding="UTF-8"?>
32-
// <CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
33-
// <fullName>PhotoUrl__c</fullName>
34-
// <externalId>false</externalId>
35-
// <label>PhotoUrl</label>
36-
// <required>false</required>
37-
// <trackFeedHistory>false</trackFeedHistory>
38-
// <type>Url</type>
39-
// <description>A URL that points to a photo</description>
40-
// </CustomField>`;
41-
//
42-
// function unparsedFieldBundleFromRawString(meta: {
43-
// rawContent: string;
44-
// filePath: string;
45-
// parentName: string;
46-
// }): UnparsedCustomFieldBundle {
47-
// return {
48-
// type: 'customfield',
49-
// name: 'TestField__c',
50-
// filePath: meta.filePath,
51-
// content: meta.rawContent,
52-
// parentName: meta.parentName,
53-
// };
54-
// }
35+
export const customField = `
36+
<?xml version="1.0" encoding="UTF-8"?>
37+
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
38+
<fullName>PhotoUrl__c</fullName>
39+
<externalId>false</externalId>
40+
<label>PhotoUrl</label>
41+
<required>false</required>
42+
<trackFeedHistory>false</trackFeedHistory>
43+
<type>Url</type>
44+
<description>A URL that points to a photo</description>
45+
</CustomField>`;
46+
47+
function unparsedFieldBundleFromRawString(meta: {
48+
rawContent: string;
49+
filePath: string;
50+
parentName: string;
51+
}): UnparsedCustomFieldBundle {
52+
return {
53+
type: 'customfield',
54+
name: 'TestField__c',
55+
filePath: meta.filePath,
56+
content: meta.rawContent,
57+
parentName: meta.parentName,
58+
};
59+
}
5560

5661
describe('when generating a changelog', () => {
5762
it('should not skip when skipIfNoChanges, even if there are no changes', async () => {
@@ -366,32 +371,72 @@ describe('when generating a changelog', () => {
366371
});
367372
});
368373

369-
// describe('that includes modifications to custom fields', () => {
370-
// it('should include a section for new or modified custom fields', async () => {
371-
// const oldObjectSource = customObjectGenerator();
372-
// const newObjectSource = customObjectGenerator();
373-
//
374-
// const oldBundle: UnparsedSourceBundle[] = [
375-
// { type: 'customobject', name: 'MyTestObject', content: oldObjectSource, filePath: 'MyTestObject.object' },
376-
// ];
377-
// const newBundle: UnparsedSourceBundle[] = [
378-
// { type: 'customobject', name: 'MyTestObject', content: newObjectSource, filePath: 'MyTestObject.object' },
379-
// unparsedFieldBundleFromRawString({
380-
// rawContent: customField,
381-
// filePath: 'MyTestObject__c.field-meta.xml',
382-
// parentName: 'MyTestObject',
383-
// }),
384-
// ];
385-
//
386-
// const result = await generateChangeLog(oldBundle, newBundle, config)();
387-
//
388-
// assertEither(result, (data) =>
389-
// expect((data as ChangeLogPageData).content).toContain('## New or Modified Fields in Existing Objects'),
390-
// );
391-
// });
392-
//
393-
// // TODO: should list new custom fields
394-
// // TODO: Should list removed custom fields
395-
// // TODO: Should mention custom field label modification
396-
// });
374+
describe('that includes modifications to custom fields', () => {
375+
it('should include a section for new or removed custom fields', async () => {
376+
const oldObjectSource = customObjectGenerator();
377+
const newObjectSource = customObjectGenerator();
378+
379+
const oldBundle: UnparsedSourceBundle[] = [
380+
{ type: 'customobject', name: 'MyTestObject', content: oldObjectSource, filePath: 'MyTestObject.object' },
381+
];
382+
const newBundle: UnparsedSourceBundle[] = [
383+
{ type: 'customobject', name: 'MyTestObject', content: newObjectSource, filePath: 'MyTestObject.object' },
384+
unparsedFieldBundleFromRawString({
385+
rawContent: customField,
386+
filePath: 'MyTestObject__c.field-meta.xml',
387+
parentName: 'MyTestObject',
388+
}),
389+
];
390+
391+
const result = await generateChangeLog(oldBundle, newBundle, config)();
392+
393+
assertEither(result, (data) =>
394+
expect((data as ChangeLogPageData).content).toContain('## New or Removed Fields in Existing Objects'),
395+
);
396+
});
397+
398+
it('should include new custom field names', async () => {
399+
const oldObjectSource = customObjectGenerator();
400+
const newObjectSource = customObjectGenerator();
401+
402+
const oldBundle: UnparsedSourceBundle[] = [
403+
{ type: 'customobject', name: 'MyTestObject', content: oldObjectSource, filePath: 'MyTestObject.object' },
404+
];
405+
const newBundle: UnparsedSourceBundle[] = [
406+
{ type: 'customobject', name: 'MyTestObject', content: newObjectSource, filePath: 'MyTestObject.object' },
407+
unparsedFieldBundleFromRawString({
408+
rawContent: customField,
409+
filePath: 'MyTestObject__c.field-meta.xml',
410+
parentName: 'MyTestObject',
411+
}),
412+
];
413+
414+
const result = await generateChangeLog(oldBundle, newBundle, config)();
415+
416+
assertEither(result, (data) => expect((data as ChangeLogPageData).content).toContain('New Field: TestField__c'));
417+
});
418+
419+
it('should include removed custom field names', async () => {
420+
const oldObjectSource = customObjectGenerator();
421+
const newObjectSource = customObjectGenerator();
422+
423+
const oldBundle: UnparsedSourceBundle[] = [
424+
{ type: 'customobject', name: 'MyTestObject', content: oldObjectSource, filePath: 'MyTestObject.object' },
425+
unparsedFieldBundleFromRawString({
426+
rawContent: customField,
427+
filePath: 'MyTestObject__c.field-meta.xml',
428+
parentName: 'MyTestObject',
429+
}),
430+
];
431+
const newBundle: UnparsedSourceBundle[] = [
432+
{ type: 'customobject', name: 'MyTestObject', content: newObjectSource, filePath: 'MyTestObject.object' },
433+
];
434+
435+
const result = await generateChangeLog(oldBundle, newBundle, config)();
436+
437+
assertEither(result, (data) =>
438+
expect((data as ChangeLogPageData).content).toContain('Removed Field: TestField__c'),
439+
);
440+
});
441+
});
397442
});

src/core/changelog/__test__/processing-changelog.spec.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -160,30 +160,6 @@ describe('when generating a changelog', () => {
160160
expect(changeLog.removedCustomObjects).toEqual([oldObject.name]);
161161
});
162162

163-
it('lists changed custom object labels', () => {
164-
const oldObject = new CustomObjectMetadataBuilder().withLabel('OldLabel').build();
165-
const newObject = new CustomObjectMetadataBuilder().withLabel('NewLabel').build();
166-
const oldVersion = { types: [oldObject] };
167-
const newVersion = { types: [newObject] };
168-
169-
const changeLog = processChangelog(oldVersion, newVersion);
170-
171-
// TODO: The changelog should display the old label and the new label
172-
// TODO: Same deal with fields
173-
174-
expect(changeLog.customObjectModifications).toEqual([
175-
{
176-
typeName: oldObject.name,
177-
modifications: [
178-
{
179-
__typename: 'CustomObjectLabelChanged',
180-
name: newObject.name,
181-
},
182-
],
183-
},
184-
]);
185-
});
186-
187163
it('lists all new fields of a custom object', () => {
188164
const oldObject = new CustomObjectMetadataBuilder().build();
189165
const newField = new CustomFieldMetadataBuilder().build();

src/core/changelog/process-changelog.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ type ModificationTypes =
1717
| 'NewProperty'
1818
| 'RemovedProperty'
1919
| 'NewField'
20-
| 'RemovedField'
21-
| 'CustomObjectLabelChanged';
20+
| 'RemovedField';
2221

2322
export type MemberModificationType = {
2423
__typename: ModificationTypes;
@@ -101,23 +100,11 @@ function getNewOrModifiedApexMembers(oldVersion: VersionManifest, newVersion: Ve
101100
function getCustomObjectModifications(oldVersion: VersionManifest, newVersion: VersionManifest): NewOrModifiedMember[] {
102101
return pipe(
103102
getCustomObjectsInBothVersions(oldVersion, newVersion),
104-
(customObjectsInBoth) => [
105-
...getModifiedCustomObjectLabels(customObjectsInBoth),
106-
...getNewOrRemovedCustomFields(customObjectsInBoth),
107-
],
103+
(customObjectsInBoth) => getNewOrRemovedCustomFields(customObjectsInBoth),
108104
(customObjectModifications) => customObjectModifications.filter((member) => member.modifications.length > 0),
109105
);
110106
}
111107

112-
function getModifiedCustomObjectLabels(typesInBoth: TypeInBoth<CustomObjectMetadata>[]): NewOrModifiedMember[] {
113-
return typesInBoth
114-
.filter(({ oldType, newType }) => oldType.label?.toLowerCase() !== newType.label?.toLowerCase())
115-
.map(({ newType }) => ({
116-
typeName: newType.name,
117-
modifications: [{ __typename: 'CustomObjectLabelChanged', name: newType.name }],
118-
}));
119-
}
120-
121108
function getNewOrRemovedCustomFields(typesInBoth: TypeInBoth<CustomObjectMetadata>[]): NewOrModifiedMember[] {
122109
return typesInBoth.map(({ oldType, newType }) => {
123110
const oldCustomObject = oldType;

src/core/changelog/renderable-changelog.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,7 @@ export type RenderableChangelog = {
4141
newOrModifiedMembers: NewOrModifiedMembersSection | null;
4242
newCustomObjects: NewTypeSection<'customobject'> | null;
4343
removedCustomObjects: RemovedTypeSection | null;
44-
// todo: changed custom objects
45-
// TODO: new fields
46-
// TODO: removed fields
47-
// TODO: changed fields
44+
newOrRemovedCustomFields: NewOrModifiedMembersSection | null;
4845
};
4946

5047
export function convertToRenderableChangelog(
@@ -122,6 +119,14 @@ export function convertToRenderableChangelog(
122119
types: changelog.removedCustomObjects,
123120
}
124121
: null,
122+
newOrRemovedCustomFields:
123+
changelog.customObjectModifications.length > 0
124+
? {
125+
heading: 'New or Removed Fields in Existing Objects',
126+
description: 'These custom fields have been added or removed.',
127+
modifications: changelog.customObjectModifications.map(toRenderableModification),
128+
}
129+
: null,
125130
};
126131
}
127132

@@ -166,7 +171,5 @@ function toRenderableModificationDescription(memberModificationType: MemberModif
166171
return `New Type: ${memberModificationType.name}`;
167172
case 'RemovedType':
168173
return `Removed Type: ${memberModificationType.name}`;
169-
case 'CustomObjectLabelChanged':
170-
return `Label Changed to ${memberModificationType.name}`;
171174
}
172175
}

src/core/changelog/templates/changelog-template.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,20 @@ export const changelogTemplate = `
7777
{{#each newOrModifiedMembers.modifications}}
7878
### {{this.typeName}}
7979
80+
{{#each this.modifications}}
81+
- {{this}}
82+
{{/each}}
83+
{{/each}}
84+
{{/if}}
85+
86+
{{#if newOrRemovedCustomFields}}
87+
## {{newOrRemovedCustomFields.heading}}
88+
89+
{{newOrRemovedCustomFields.description}}
90+
91+
{{#each newOrRemovedCustomFields.modifications}}
92+
### {{this.typeName}}
93+
8094
{{#each this.modifications}}
8195
- {{this}}
8296
{{/each}}

0 commit comments

Comments
 (0)