xmldataprocessor.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /* bender-tags: browser-only */
  6. /* globals window */
  7. import XmlDataProcessor from '/ckeditor5/engine/dataprocessor/xmldataprocessor.js';
  8. import xssTemplates from '/tests/engine/dataprocessor/_utils/xsstemplates.js';
  9. import ViewDocumentFragment from '/ckeditor5/engine/view/documentfragment.js';
  10. import { stringify, parse } from '/ckeditor5/engine/dev-utils/view.js';
  11. describe( 'XmlDataProcessor', () => {
  12. let dataProcessor;
  13. beforeEach( () => {
  14. dataProcessor = new XmlDataProcessor();
  15. } );
  16. describe( 'toView', () => {
  17. it( 'should return empty DocumentFragment when empty string is passed', () => {
  18. const fragment = dataProcessor.toView( '' );
  19. expect( fragment ).to.be.an.instanceOf( ViewDocumentFragment );
  20. expect( fragment.childCount ).to.equal( 0 );
  21. } );
  22. it( 'should convert XML to DocumentFragment with single text node', () => {
  23. const fragment = dataProcessor.toView( 'foo bar' );
  24. expect( stringify( fragment ) ).to.equal( 'foo bar' );
  25. } );
  26. it( 'should convert HTML to DocumentFragment with multiple child nodes', () => {
  27. const fragment = dataProcessor.toView( '<p>foo</p><p>bar</p>' );
  28. expect( stringify( fragment ) ).to.equal( '<p>foo</p><p>bar</p>' );
  29. } );
  30. it( 'should not add any additional nodes', () => {
  31. const fragment = dataProcessor.toView( 'foo <b>bar</b> text' );
  32. expect( stringify( fragment ) ).to.equal( 'foo <b>bar</b> text' );
  33. } );
  34. it( 'should allow to use registered namespaces', () => {
  35. dataProcessor = new XmlDataProcessor( {
  36. namespaces: [ 'foo', 'bar' ]
  37. } );
  38. const fragment = dataProcessor.toView( '<foo:a><bar:b></bar:b></foo:a><bar:b><foo:a></foo:a></bar:b>' );
  39. expect( stringify( fragment ) ).to.equal( '<foo:a><bar:b></bar:b></foo:a><bar:b><foo:a></foo:a></bar:b>' );
  40. } );
  41. it( 'should throw an error when use not registered namespaces', () => {
  42. expect( () => {
  43. dataProcessor.toView( '<foo:a></foo:a>' );
  44. } ).to.throw( Error, /Parse error/ );
  45. } );
  46. it( 'should thrown an error when markup is invalid', () => {
  47. expect( () => {
  48. dataProcessor.toView( '<b>missing closing tag' );
  49. } ).to.throw( Error, /Parse error/ );
  50. } );
  51. // Test against XSS attacks.
  52. for ( let name in xssTemplates ) {
  53. const input = xssTemplates[ name ].replace( /%xss%/g, 'testXss()' );
  54. it( 'should prevent XSS attacks: ' + name, ( done ) => {
  55. window.testXss = sinon.spy();
  56. dataProcessor.toView( input );
  57. window.setTimeout( () => {
  58. sinon.assert.notCalled( window.testXss );
  59. done();
  60. }, 10 );
  61. } );
  62. }
  63. } );
  64. describe( 'toData', () => {
  65. it( 'should return empty string when empty DocumentFragment is passed', () => {
  66. const fragment = new ViewDocumentFragment();
  67. expect( dataProcessor.toData( fragment ) ).to.equal( '' );
  68. } );
  69. it( 'should return text if document fragment with single text node is passed', () => {
  70. const fragment = new ViewDocumentFragment();
  71. fragment.appendChildren( parse( 'foo bar' ) );
  72. expect( dataProcessor.toData( fragment ) ).to.equal( 'foo bar' );
  73. } );
  74. it( 'should convert HTML to DocumentFragment with multiple child nodes', () => {
  75. const fragment = parse( '<p>foo</p><p>bar</p>' );
  76. expect( dataProcessor.toData( fragment ) ).to.equal( '<p>foo</p><p>bar</p>' );
  77. } );
  78. } );
  79. } );