Arthur Bogaart pushed to branch feature/cmng-psp1 at cms-community / hippo-addon-channel-manager
Commits: 0fe5fc90 by Arthur Bogaart at 2016-02-23T00:33:23+01:00 CHANNELMGR-339 Add unit test for hstCommentsProcessor service - - - - - 4 changed files: - + frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.fixture.html - + frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.invalid.json.fixture.html - frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.js - + frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.spec.js Changes: ===================================== frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.fixture.html ===================================== --- /dev/null +++ b/frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.fixture.html @@ -0,0 +1,33 @@ +<div id="qa-page"> + + <!----> + + <!--[if IE]> + <div id="ie-only1"> + IE-ONLY + </div> + <![endif]--> + + <!-- {Ignore this comment} --> + + <!-- { + "HST-Type":"CONTAINER_COMPONENT", + "name":"Container-1" +} --> +<div id="qa-container1"> + <!-- { + "HST-Type":"CONTAINER_ITEM_COMPONENT", + "name":"Container-1-Item-1" + } --> + <div id="qa-item1"> + <!-- This comment will be ignored --> + <p>Item 1</p> + </div> +</div> + +</div> +<!-- { + "HST-Type":"PAGE-META-DATA", + "name": "Page-1" +} --> +<!-- This comment will be ignored --> ===================================== frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.invalid.json.fixture.html ===================================== --- /dev/null +++ b/frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.invalid.json.fixture.html @@ -0,0 +1,6 @@ +<div id="qa-page"> + <!-- { + "HST-Type":"CONTAINER_COMPONENT" + "name":"Container-1" +} --> +</div> ===================================== frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.js ===================================== --- a/frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.js +++ b/frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.js @@ -26,69 +26,77 @@ export class HstCommentsProcessorService { } run(document, callback) { - // IE doesn't support 'evaluate', see https://developer.mozilla.org/en/docs/Web/API/Document/evaluate#Browser_compatibility + // IE doesn't support 'evaluate', see + // https://developer.mozilla.org/en/docs/Web/API/Document/evaluate#Browser_compatibility if (!!document.evaluate) { - processCommentsWithXPath(document, callback); + this.processCommentsWithXPath(document, callback); } else { - processCommentsWithDomWalking(document, callback); + this.processCommentsWithDomWalking(document, callback); } } -} - -function getCommentData(element) { - if (element.length < 0) { - // Skip conditional comments in IE: reading their 'data' property throws an - // Error "Not enough storage space is available to complete this operation." - // Conditional comments can be recognized by a negative 'length' property. - return null; - } - if (!element.data || element.data.length === 0) { - // no data available - return null; + processCommentsWithXPath(document, callback) { + const query = document.evaluate('//comment()', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + for (let i = 0; i < query.snapshotLength; i++) { + this._processComment(query.snapshotItem(i), callback); + } } - return element.data; -} + processCommentsWithDomWalking(node, callback) { + if (!node || node.nodeType === undefined) { + return; + } -function isHstComment(data) { - return data !== null && data.startsWith(' {') && data.endsWith('} ') && data.includes(HST.TYPE); -} + if (node.nodeType === 8) { + this._processComment(node, callback); + } else { + for (let i = 0; i < node.childNodes.length; i++) { + this.processCommentsWithDomWalking(node.childNodes[i], callback); + } + } + } -function processComment(element, callback) { - const data = getCommentData(element); + _processComment(element, callback) { + const data = this._getCommentData(element); - if (isHstComment(data)) { - try { - const json = JSON.parse(data); - return callback(element, json); - } catch (e) { - log.warn('Error parsing HST comment', e, data); + if (this._isHstComment(data)) { + const json = this._parseJson(data); + if (json !== null) { + try { + callback(element, json); + } catch (e) { + log.warn('Error invoking callback on HST comment', e, json); + } + } } } -} -function isComment(element) { - return element.nodeType === 8; -} + _getCommentData(element) { + if (element.length < 0) { + // Skip conditional comments in IE: reading their 'data' property throws an + // Error "Not enough storage space is available to complete this operation." + // Conditional comments can be recognized by a negative 'length' property. + return null; + } -function processCommentsWithXPath(document, callback) { - const query = document.evaluate('//comment()', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - for (let i = 0; i < query.snapshotLength; i++) { - processComment(query.snapshotItem(i), callback); + if (!element.data || element.data.length === 0) { + // no data available + return null; + } + + return element.data; } -} -function processCommentsWithDomWalking(node, callback) { - if (!node || node.nodeType === undefined) { - return; + _isHstComment(data) { + return data !== null && data.startsWith(' {') && data.endsWith('} ') && data.includes(HST.TYPE); } - if (isComment(node)) { - processComment(node, callback); - } else { - for (let i = 0; i < node.childNodes.length; i++) { - processCommentsWithDomWalking(node.childNodes[i], callback); + _parseJson(data) { + try { + return JSON.parse(data); + } catch (e) { + log.warn('Error parsing HST comment as JSON', e, data); } + return null; } } ===================================== frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.spec.js ===================================== --- /dev/null +++ b/frontend-ng/src/angularjs/channel/hippoIframe/hstCommentsProcessor.service.spec.js @@ -0,0 +1,53 @@ +describe('HstCommentsProcessorService', function () { + 'use strict'; + + var hstCommentsProcessorService; + function NOOP() {} + + beforeEach(function () { + module('hippo-cm.channel.hippoIframe'); + + inject(function (_hstCommentsProcessorService_) { + hstCommentsProcessorService = _hstCommentsProcessorService_; + }); + }); + + // PhantomJS does not support XPath querying through document.evaluate (https://github.com/ariya/phantomjs/issues/10161) + it('should use DOM-walking when XPath querying is not available', function () { + jasmine.getFixtures().load('channel/hippoIframe/hstCommentsProcessor.service.fixture.html'); + spyOn(hstCommentsProcessorService, 'processCommentsWithDomWalking'); + hstCommentsProcessorService.run($j('#jasmine-fixtures')[0], NOOP); + expect(hstCommentsProcessorService.processCommentsWithDomWalking).toHaveBeenCalled(); + }); + + + it('should process comments with DOM-walking', function () { + var gatheredData = []; + jasmine.getFixtures().load('channel/hippoIframe/hstCommentsProcessor.service.fixture.html'); + hstCommentsProcessorService.processCommentsWithDomWalking($j('#jasmine-fixtures')[0], function (element, json) { + gatheredData.push(json); + }); + + expect(gatheredData).toEqual([ + { 'HST-Type': 'CONTAINER_COMPONENT', name: 'Container-1' }, + { 'HST-Type': 'CONTAINER_ITEM_COMPONENT', name: 'Container-1-Item-1' }, + { 'HST-Type': 'PAGE-META-DATA', name: 'Page-1' }, + ]); + }); + + it('should gracefully handle an undefined element when DOM-walking', function () { + expect(hstCommentsProcessorService.processCommentsWithDomWalking).not.toThrow(); + }); + + + it('should not invoke callback when JSON data is invalid', function () { + var observer = { callback: NOOP }; + spyOn(observer, 'callback'); + + jasmine.getFixtures().load('channel/hippoIframe/hstCommentsProcessor.service.invalid.json.fixture.html'); + hstCommentsProcessorService.processCommentsWithDomWalking($j('#jasmine-fixtures')[0], observer.callback); + + expect(observer.callback).not.toHaveBeenCalled(); + }); + +}); View it on GitLab: https://code.onehippo.org/cms-community/hippo-addon-channel-manager/commit/0fe5fc907fc691659e48aad071cf2851804171da
_______________________________________________ Hippocms-svn mailing list Hippocms-svn@lists.onehippo.org https://lists.onehippo.org/mailman/listinfo/hippocms-svn