const test = require('tap').test; const fs = require('fs'); const path = require('path'); const DOMParser = require('xmldom').DOMParser; const fixupSvgString = require('../src/fixup-svg-string'); // The browser DOMParser throws on errors by default, replicate that here // by customizing the error callback to throw (defaults to logging) const domParser = new DOMParser({ errorHandler: { error: e => { throw new Error(e); } } }); test('fixupSvgString should make parsing fixtures not throw', t => { const filePath = path.resolve(__dirname, './fixtures/hearts.svg'); const svgString = fs.readFileSync(filePath) .toString(); const fixed = fixupSvgString(svgString); // Make sure undefineds aren't being written into the file t.equal(fixed.indexOf('undefined'), -1); t.notThrow(() => { domParser.parseFromString(fixed, 'text/xml'); }); t.end(); }); test('fixupSvgString should correct namespace declarations bound to reserved namespace names', t => { const filePath = path.resolve(__dirname, './fixtures/reserved-namespace.svg'); const svgString = fs.readFileSync(filePath) .toString(); const fixed = fixupSvgString(svgString); // Make sure undefineds aren't being written into the file t.equal(fixed.indexOf('undefined'), -1); t.notThrow(() => { domParser.parseFromString(fixed, 'text/xml'); }); t.end(); }); test('fixupSvgString shouldn\'t correct non-attributes', t => { const dontFix = fixupSvgString('<text>xmlns:test="http://www/w3.org/XML/1998/namespace" is not an xmlns attribute</text>'); t.notEqual(dontFix.indexOf('http://www/w3.org/XML/1998/namespace'), -1); t.end(); }); test('fixupSvgString should strip `svg:` prefix from tag names', t => { const filePath = path.resolve(__dirname, './fixtures/svg-tag-prefixes.svg'); const svgString = fs.readFileSync(filePath) .toString(); const fixed = fixupSvgString(svgString); const checkPrefixes = element => { t.notEqual(element.prefix, 'svg'); // JSDOM doesn't have element.children, only element.childNodes if (element.childNodes) { // JSDOM's childNodes is not iterable, so for...of cannot be used here for (let i = 0; i < element.childNodes.length; i++) { const child = element.childNodes[i]; if (child.nodeType === 1 /* Node.ELEMENT_NODE */) checkPrefixes(child); } } }; // Make sure undefineds aren't being written into the file t.equal(fixed.indexOf('undefined'), -1); t.notThrow(() => { domParser.parseFromString(fixed, 'text/xml'); }); checkPrefixes(domParser.parseFromString(fixed, 'text/xml')); t.end(); }); test('fixupSvgString should empty script tags', t => { const filePath = path.resolve(__dirname, './fixtures/script.svg'); const svgString = fs.readFileSync(filePath) .toString(); const fixed = fixupSvgString(svgString); // Script tag should remain but have no contents. t.equals(fixed.indexOf('<script></script>'), 207); // The contents of the script tag (e.g. the alert) are no longer there. t.equals(fixed.indexOf('stuff inside'), -1); t.end(); }); test('fixupSvgString should empty script tags in onload', t => { const filePath = path.resolve(__dirname, './fixtures/onload-script.svg'); const svgString = fs.readFileSync(filePath) .toString(); const fixed = fixupSvgString(svgString); // Script tag should remain but have no contents. t.equals(fixed.indexOf('<script></script>'), 792); t.end(); }); test('fixupSvgString strips contents of metadata', t => { const filePath = path.resolve(__dirname, './fixtures/metadata-body.svg'); const svgString = fs.readFileSync(filePath) .toString(); const fixed = fixupSvgString(svgString); // Metadata tag should still exist, it'll just be empty. t.equals(fixed.indexOf('<metadata></metadata>'), 207); // The contents of the metadata tag are gone. t.equals(fixed.indexOf('stuff inside'), -1); t.end(); }); test('fixupSvgString strips contents of metadata in onload', t => { const filePath = path.resolve(__dirname, './fixtures/metadata-onload.svg'); const svgString = fs.readFileSync(filePath) .toString(); const fixed = fixupSvgString(svgString); // Metadata tag should still exist, it'll just be empty. t.equals(fixed.indexOf('<metadata></metadata>'), 800); t.end(); }); test('fixupSvgString should correct invalid mime type', t => { const filePath = path.resolve(__dirname, './fixtures/invalid-cloud.svg'); const svgString = fs.readFileSync(filePath, 'utf8'); const fixed = fixupSvgString(svgString); // Make sure we replace an invalid mime type from Photoshop exported SVGs t.notEqual(svgString.indexOf('img/png'), -1); t.equal(fixed.indexOf('img/png'), -1); t.notThrow(() => { domParser.parseFromString(fixed, 'text/xml'); }); t.end(); }); test('fixupSvgString shouldn\'t correct non-image tags', t => { const dontFix = fixupSvgString('<text>data:img/png is not a mime type</text>'); t.notEqual(dontFix.indexOf('img/png'), -1); t.end(); });