8
0

xmldataprocessor.js 3.5 KB

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