Skip to content

Commit 87f4fe3

Browse files
iowillhoitjayreeshetzelmshanemc
authored
QA PR for 466 (#487)
* fix: update registry * test: one missing type, test for validating child suffix/dir * test: even more registry validation * chore: lint fixes Co-authored-by: jayree <[email protected]> Co-authored-by: Steve Hetzel <[email protected]> Co-authored-by: mshanemc <[email protected]>
1 parent 15073db commit 87f4fe3

File tree

2 files changed

+153
-78
lines changed

2 files changed

+153
-78
lines changed

src/registry/metadataRegistry.json

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@
6161
}
6262
},
6363
"suffixes": {
64-
"customLabel": "labels"
64+
"labels": "customlabel"
6565
},
6666
"directories": {
67-
"customLabels": "labels"
67+
"labels": "customlabel"
6868
}
6969
},
7070
"strategies": {
@@ -516,6 +516,9 @@
516516
},
517517
"suffixes": {
518518
"formSection": "formsection"
519+
},
520+
"directories": {
521+
"formSections": "formsection"
519522
}
520523
}
521524
},
@@ -676,7 +679,7 @@
676679
"workflowsend": {
677680
"id": "workflowsend",
678681
"name": "WorkflowSend",
679-
"xmlElementName": "sends",
682+
"xmlElementName": "send",
680683
"uniqueIdElement": "fullName",
681684
"directoryName": "workflowSends",
682685
"suffix": "workflowSend"
@@ -709,6 +712,7 @@
709712
},
710713
"directories": {
711714
"workflowFieldUpdates": "workflowfieldupdate",
715+
"workflowKnowledgePublishs": "workflowknowledgepublish",
712716
"workflowTasks": "workflowtask",
713717
"workflowAlerts": "workflowalert",
714718
"workflowSends": "workflowsend",
@@ -1072,6 +1076,7 @@
10721076
"name": "WaveTemplateBundle",
10731077
"directoryName": "waveTemplates",
10741078
"inFolder": false,
1079+
"strictDirectoryName": true,
10751080
"strategies": {
10761081
"adapter": "bundle"
10771082
}
@@ -1242,7 +1247,9 @@
12421247
},
12431248
"directories": {
12441249
"sharingOwnerRules": "sharingownerrule",
1245-
"sharingCriteriaRules": "sharingcriteriarule"
1250+
"sharingCriteriaRules": "sharingcriteriarule",
1251+
"sharingGuestRules": "sharingguestrule",
1252+
"sharingTerritoryRules": "sharingterritoryrule"
12461253
}
12471254
}
12481255
},
@@ -2086,6 +2093,9 @@
20862093
},
20872094
"suffixes": {
20882095
"workSkillRoutingAttribute": "workskillroutingattribute"
2096+
},
2097+
"directories": {
2098+
"workSkillRoutingAttributes": "workskillroutingattribute"
20892099
}
20902100
}
20912101
},
@@ -2610,9 +2620,7 @@
26102620
"suffixes": {
26112621
"ai": "aiapplication",
26122622
"aiapplicationconfig": "aiapplicationconfig",
2613-
"mlprediction": "mlPrediction",
26142623
"mlDataDefinition": "mldatadefinition",
2615-
"sites": "customsite",
26162624
"icon": "icon",
26172625
"businessProcessGroup": "businessprocessgroup",
26182626
"model": "discoveryaimodel",
@@ -2630,7 +2638,6 @@
26302638
"decisionTableDatasetLink": "decisiontabledatasetlink",
26312639
"briefcaseDefinition": "briefcasedefinition",
26322640
"batchProcessJobDefinition": "batchprocessjobdefinition",
2633-
"webstoretemplate": "webstoretemplate",
26342641
"acctMgrTargetSetting": "acctmgrtargetsettings",
26352642
"dataSourceObject": "datasourceobject",
26362643
"externalDataConnector": "externaldataconnector",
@@ -2642,7 +2649,6 @@
26422649
"installedPackage": "installedpackage",
26432650
"labels": "customlabels",
26442651
"navigationMenu": "navigationmenu",
2645-
"resource": "staticresource",
26462652
"scf": "scontrol",
26472653
"crt": "certificate",
26482654
"messageChannel": "lightningmessagechannel",

test/registry/registryValidation.test.ts

Lines changed: 139 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -13,93 +13,162 @@ describe('Registry Validation', () => {
1313
const registry = defaultRegistry as MetadataRegistry;
1414
const typesWithChildren = Object.values(registry.types).filter((type) => type.children);
1515

16-
describe('every child type has an entry in children', () => {
17-
const childMapping = new Map<string, string>();
16+
describe('child types', () => {
17+
describe('child types are configured properly', () => {
18+
typesWithChildren.forEach((type) => {
19+
it(`${type.name} has a valid children configuration`, () => {
20+
expect(type.children).to.have.property('types');
21+
expect(type.children).to.have.property('suffixes');
22+
expect(type.children).to.have.property('directories');
23+
Object.values(type.children.types).forEach((childType) => {
24+
expect(type.children.suffixes[childType.suffix]).to.equal(childType.id);
25+
expect(type.children.directories[childType.directoryName]).to.equal(childType.id);
26+
});
27+
});
28+
});
29+
});
1830

19-
typesWithChildren.map((parentType) =>
20-
Object.values(parentType.children.types).map((childType) => {
21-
childMapping.set(childType.id, parentType.id);
22-
})
23-
);
31+
describe('every child type has an entry in children', () => {
32+
const childMapping = new Map<string, string>();
2433

25-
childMapping.forEach((parentId, childId) => {
26-
it(`has a childType for ${childId} : ${parentId}`, () => {
27-
expect(parentId).to.be.a('string');
28-
expect(childId).to.be.a('string');
29-
expect(registry.childTypes[childId]).to.equal(parentId);
34+
typesWithChildren.map((parentType) =>
35+
Object.values(parentType.children.types).map((childType) => {
36+
childMapping.set(childType.id, parentType.id);
37+
})
38+
);
39+
40+
childMapping.forEach((parentId, childId) => {
41+
it(`has a childType for ${childId} : ${parentId}`, () => {
42+
expect(parentId).to.be.a('string');
43+
expect(childId).to.be.a('string');
44+
expect(registry.childTypes[childId]).to.equal(parentId);
45+
});
46+
});
47+
});
48+
49+
describe('every childTypes top-level property maps to a top-level type that has it in its childTypes', () => {
50+
Object.entries(registry.childTypes).forEach(([childId, parentId]) => {
51+
it(`childTypes member ${childId} matches a parent type ${parentId}`, () => {
52+
expect(registry.types[parentId]).to.have.property('children');
53+
expect(registry.types[parentId].children.types).to.have.property(childId);
54+
});
3055
});
3156
});
3257
});
3358

34-
describe('suffix object is complete', () => {
35-
const knownExceptions = [
36-
'DataSource', // both ExternalDataSource and DataSource use the suffix .dataSource :(
37-
'CustomLabel', // custom label (child of customLabel has suffix labels in types BUT has an entry in suffixes that points to customlabels )
38-
'CustomLabels', // custom label (child of customLabel has suffix labels in types BUT has an entry in suffixes that points to customlabels )
39-
'MatchingRules', // same suffix on MatchingRule and MatchingRules
40-
'MatchingRule', // same suffix on MatchingRule and MatchingRules
41-
// things that use the suffix .settings (!)
42-
'IndustriesManufacturingSettings',
43-
'ObjectHierarchyRelationship',
44-
];
59+
describe('suffixes', () => {
60+
describe('all properties of suffixes match a real parent or child type', () => {
61+
Object.entries(registry.suffixes).forEach(([suffix, typeId]) => {
62+
it(`suffix ${suffix} matches a parent or child type ${typeId}`, () => {
63+
// could be a parent type or a child type
64+
// exclusion for legacy suffixes
65+
if (registry.childTypes[typeId]) {
66+
expect(registry.types[registry.childTypes[typeId]].children.types[typeId].suffix).to.equal(suffix);
67+
} else if (registry.types[typeId].legacySuffix) {
68+
// if there are legacy suffixes, this could be either that or the regular suffix
69+
expect([registry.types[typeId].legacySuffix, registry.types[typeId].suffix]).to.include(suffix);
70+
} else {
71+
expect(registry.types[typeId].suffix).to.equal(suffix);
72+
}
73+
});
74+
});
75+
});
76+
describe('suffix object is complete', () => {
77+
const knownExceptions = [
78+
'DataSource', // both ExternalDataSource and DataSource use the suffix .dataSource :(
79+
'CustomLabel', // custom label (child of customLabel has suffix labels in types BUT has an entry in suffixes that points to customlabels )
80+
'CustomLabels', // custom label (child of customLabel has suffix labels in types BUT has an entry in suffixes that points to customlabels )
81+
'MatchingRules', // same suffix on MatchingRule and MatchingRules
82+
'MatchingRule', // same suffix on MatchingRule and MatchingRules
83+
// things that use the suffix .settings (!)
84+
'IndustriesManufacturingSettings',
85+
'ObjectHierarchyRelationship',
86+
];
4587

46-
const suffixMap = new Map<string, string>();
47-
Object.values(registry.types)
48-
.filter((type) => type.suffix && !type.strictDirectoryName && !knownExceptions.includes(type.name))
49-
.map((type) => {
50-
// mapping for the type's suffix
51-
suffixMap.set(type.suffix, type.id);
52-
if (type.children) {
53-
Object.values(type.children.types).map((childType) => {
54-
// mapping for the child's suffix
55-
suffixMap.set(childType.suffix, childType.id);
56-
});
88+
const suffixMap = new Map<string, string>();
89+
Object.values(registry.types)
90+
.filter((type) => type.suffix && !type.strictDirectoryName && !knownExceptions.includes(type.name))
91+
.map((type) => {
92+
// mapping for the type's suffix
93+
suffixMap.set(type.suffix, type.id);
94+
if (type.children) {
95+
Object.values(type.children.types).map((childType) => {
96+
// mapping for the child's suffix
97+
suffixMap.set(childType.suffix, childType.id);
98+
});
99+
}
100+
});
101+
suffixMap.forEach((typeid, suffix) => {
102+
it(`has a suffix entry for "${suffix}" : "${typeid}"`, () => {
103+
expect(typeid).to.be.a('string');
104+
expect(suffix).to.be.a('string');
105+
expect(registry.suffixes[suffix]).to.equal(typeid);
106+
});
107+
});
108+
});
109+
110+
describe('suffixes must be unique on non-strict types', () => {
111+
const suffixMap = new Map<string, MetadataType[]>();
112+
Object.values(registry.types).map((type) => {
113+
if (type.suffix) {
114+
// some bundle types have no suffix
115+
suffixMap.set(type.suffix, suffixMap.has(type.suffix) ? [...suffixMap.get(type.suffix), type] : [type]);
57116
}
58117
});
59-
suffixMap.forEach((typeid, suffix) => {
60-
it(`has a suffix entry for "${suffix}" : "${typeid}"`, () => {
61-
expect(typeid).to.be.a('string');
62-
expect(suffix).to.be.a('string');
63-
expect(registry.suffixes[suffix]).to.equal(typeid);
118+
suffixMap.forEach((types, suffix) => {
119+
if (types.length > 1) {
120+
// identify when a single suffix is used in multiple metadata types.
121+
// when the happens, there can only be one who is not marked as strictDirectoryName
122+
it(`Suffix "${suffix}" used by types (${types
123+
.map((type) => type.name)
124+
.join(',')}) should have only 1 non-strict directory`, () => {
125+
const nonStrictTypes = types.filter((type) => !type.strictDirectoryName);
126+
expect(nonStrictTypes.length, nonStrictTypes.map((type) => type.name).join(',')).lessThan(2);
127+
});
128+
}
64129
});
65130
});
66131
});
67132

68-
describe('suffixes must be unique on non-strict types', () => {
69-
const suffixMap = new Map<string, MetadataType[]>();
70-
Object.values(registry.types).map((type) => {
71-
if (type.suffix) {
72-
// some bundle types have no suffix
73-
suffixMap.set(type.suffix, suffixMap.has(type.suffix) ? [...suffixMap.get(type.suffix), type] : [type]);
74-
}
75-
});
76-
suffixMap.forEach((types, suffix) => {
77-
if (types.length > 1) {
78-
// identify when a single suffix is used in multiple metadata types.
79-
// when the happens, there can only be one who is not marked as strictDirectoryName
80-
it(`Suffix "${suffix}" used by types (${types
81-
.map((type) => type.name)
82-
.join(',')}) should have only 1 non-strict directory`, () => {
83-
const nonStrictTypes = types.filter((type) => !type.strictDirectoryName);
84-
expect(nonStrictTypes.length, nonStrictTypes.map((type) => type.name).join(',')).lessThan(2);
133+
describe('strictDirectories', () => {
134+
describe('strict types are all in strictDirectoryNames', () => {
135+
const strictTypeMap = new Map<string, string>();
136+
Object.values(registry.types)
137+
.filter((type) => type.strictDirectoryName)
138+
.map((type) => {
139+
// the type's suffix
140+
strictTypeMap.set(type.directoryName, type.id);
85141
});
86-
}
142+
strictTypeMap.forEach((typeid, strictDirectoryName) => {
143+
it(`has a strictDirectoryNames entry for "${strictDirectoryName}" : "${typeid}"`, () => {
144+
expect(typeid).to.be.a('string');
145+
expect(strictDirectoryName).to.be.a('string');
146+
expect(registry.strictDirectoryNames[strictDirectoryName]).to.equal(typeid);
147+
});
148+
});
87149
});
88-
});
89150

90-
describe('strict types are all in strictDirectoryNames', () => {
91-
const strictTypeMap = new Map<string, string>();
92-
Object.values(registry.types)
93-
.filter((type) => type.strictDirectoryName)
94-
.map((type) => {
95-
// the type's suffix
96-
strictTypeMap.set(type.directoryName, type.id);
151+
describe('strictDirectoryNames all map to types with strictDirectoryName and correct directoryName', () => {
152+
Object.entries(registry.strictDirectoryNames).forEach(([dirName, typeId]) => {
153+
it(`directory member ${dirName} matches a parent type ${typeId}`, () => {
154+
expect(registry.types[typeId].directoryName).equal(dirName);
155+
expect(registry.types[typeId].strictDirectoryName).equal(true);
156+
});
97157
});
98-
strictTypeMap.forEach((typeid, strictDirectoryName) => {
99-
it(`has a strictDirectoryNames entry for "${strictDirectoryName}" : "${typeid}"`, () => {
100-
expect(typeid).to.be.a('string');
101-
expect(strictDirectoryName).to.be.a('string');
102-
expect(registry.strictDirectoryNames[strictDirectoryName]).to.equal(typeid);
158+
159+
const strictTypeMap = new Map<string, string>();
160+
Object.values(registry.types)
161+
.filter((type) => type.strictDirectoryName)
162+
.map((type) => {
163+
// the type's suffix
164+
strictTypeMap.set(type.directoryName, type.id);
165+
});
166+
strictTypeMap.forEach((typeid, strictDirectoryName) => {
167+
it(`has a strictDirectoryNames entry for "${strictDirectoryName}" : "${typeid}"`, () => {
168+
expect(typeid).to.be.a('string');
169+
expect(strictDirectoryName).to.be.a('string');
170+
expect(registry.strictDirectoryNames[strictDirectoryName]).to.equal(typeid);
171+
});
103172
});
104173
});
105174
});

0 commit comments

Comments
 (0)