Files
Accordion/tests/validate-project.js
T

65 lines
4.2 KiB
JavaScript

'use strict';
var fs = require('fs');
var path = require('path');
var root = path.resolve(__dirname, '..');
var passed = 0;
function read(file) { return fs.readFileSync(path.join(root, file), 'utf8'); }
function json(file) { return JSON.parse(read(file)); }
function assert(condition, message) { if (!condition) { throw new Error(message); } passed++; }
var packageJson = json('package.json');
var solution = json('config/package-solution.json').solution;
var config = json('config/config.json');
var manifest = json('src/webparts/accordion/AccordionWebPart.manifest.json');
var webPart = read('src/webparts/accordion/AccordionWebPart.ts');
var component = read('src/webparts/accordion/components/Accordion.tsx');
var sanitizer = read('src/webparts/accordion/AccordionHtmlSanitizer.ts');
var styles = read('src/webparts/accordion/components/Accordion.module.scss');
assert(packageJson.version === '1.1.2', 'Package version must be 1.1.2.');
assert(solution.version === '1.1.2.0', 'Solution version must be 1.1.2.0.');
assert(solution.includeClientSideAssets === true, 'Client-side assets must be included.');
assert(solution.skipFeatureDeployment === true, 'Solution must support central deployment.');
assert(packageJson.name === 'accordion-web-part' && solution.name === 'accordion-web-part' &&
solution.title === 'accordion-web-part', 'Accordion package naming is inconsistent.');
assert(json('config/package-solution.json').paths.zippedPackage === 'solution/accordion-web-part.sppkg',
'Accordion package file name is inconsistent.');
assert(manifest.componentType === 'WebPart', 'Component must be a web part.');
assert(!!config.bundles['accordion-web-part'], 'Accordion bundle is missing.');
assert(webPart.indexOf("PropertyPaneDropdown('listId'") >= 0, 'Dynamic list selection is missing.');
assert(webPart.indexOf("PropertyPaneDropdown('contentField'") >= 0, 'Dynamic content field selection is missing.');
assert(webPart.indexOf("PropertyPaneDropdown('categoryField'") >= 0, 'Category field selection is missing.');
assert(webPart.indexOf("PropertyPaneDropdown('selectedCategory'") >= 0, 'Category value filter is missing.');
assert(read('src/webparts/accordion/AccordionDataService.ts').indexOf('getCategoryValues') >= 0,
'Dynamic category values are missing.');
var dataService = read('src/webparts/accordion/AccordionDataService.ts');
var categoryValues = read('src/webparts/accordion/AccordionCategoryValues.ts');
assert(dataService.indexOf("'TaxonomyFieldType'") >= 0 &&
dataService.indexOf("'TaxonomyFieldTypeMulti'") >= 0 &&
dataService.indexOf('getAccordionCategoryValues') >= 0 &&
categoryValues.indexOf('entry.Label') >= 0 && categoryValues.indexOf("candidate.indexOf(';#')") >= 0,
'Managed Metadata category support is missing.');
assert(dataService.indexOf('FieldValuesAsText/') >= 0 &&
dataService.indexOf('itemCategoryValues') >= 0 && categoryValues.indexOf('splitPlainSemicolon') >= 0,
'Managed Metadata labels must be resolved instead of displaying WSS IDs.');
assert(dataService.indexOf("getbytitle('TaxonomyHiddenList')") >= 0 &&
dataService.indexOf('loadTaxonomyLabels') >= 0 &&
categoryValues.indexOf('replaceAccordionCategoryIds') >= 0,
'Numeric WSS IDs must be resolved through the site collection TaxonomyHiddenList.');
assert(component.indexOf('items[i].categories') >= 0 && component.indexOf('nameIndex') >= 0,
'Multi-value category grouping is missing.');
assert(component.indexOf("aria-expanded={open}") >= 0 && component.indexOf("role='region'") >= 0,
'Accessible accordion semantics are missing.');
assert(component.indexOf('sanitizeAccordionHtml(item.content)') >= 0, 'Rich text is not sanitized before rendering.');
var allowedTags = sanitizer.substring(sanitizer.indexOf('const AllowedTags'), sanitizer.indexOf('const DropContentTags'));
assert(allowedTags.indexOf("'script'") < 0 && allowedTags.indexOf("'img'") < 0 &&
sanitizer.indexOf("'script'") >= 0,
'Unsafe rich-text elements must be removed rather than allow-listed.');
['neutralPrimary', 'neutralLight', 'neutralLighter', 'themePrimary', 'white'].forEach(function (slot) {
assert(styles.indexOf('[theme: ' + slot + ', default:') >= 0, 'SharePoint theme slot is missing: ' + slot);
});
console.log('Accordion project validation passed:', passed);