base64uploadadapter.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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, setTimeout */
  6. import Base64UploadAdapter from '../../src/adapters/base64uploadadapter';
  7. import FileRepository from '../../src/filerepository';
  8. import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
  9. import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
  10. import { createNativeFileMock } from '../_utils/mocks';
  11. describe( 'Base64UploadAdapter', () => {
  12. let div, stubs;
  13. testUtils.createSinonSandbox();
  14. beforeEach( () => {
  15. div = window.document.createElement( 'div' );
  16. window.document.body.appendChild( div );
  17. stubs = {
  18. addEventListener( event, callback ) {
  19. stubs[ `on${ event }` ] = callback;
  20. },
  21. readAsDataURL: testUtils.sinon.spy(),
  22. abort: testUtils.sinon.spy(),
  23. result: 'data:image/png;base64'
  24. };
  25. testUtils.sinon.stub( window, 'FileReader' ).callsFake( function FileReader() {
  26. return stubs;
  27. } );
  28. } );
  29. afterEach( () => {
  30. window.document.body.removeChild( div );
  31. } );
  32. it( 'should require the FileRepository plugin', () => {
  33. expect( Base64UploadAdapter.requires ).to.deep.equal( [ FileRepository ] );
  34. } );
  35. it( 'should be named', () => {
  36. expect( Base64UploadAdapter.pluginName ).to.equal( 'Base64UploadAdapter' );
  37. } );
  38. describe( 'init()', () => {
  39. it( 'should set the loader', () => {
  40. return ClassicTestEditor
  41. .create( div, {
  42. plugins: [ Base64UploadAdapter ]
  43. } )
  44. .then( editor => {
  45. expect( editor.plugins.get( FileRepository ).createUploadAdapter ).is.a( 'function' );
  46. return editor.destroy();
  47. } );
  48. } );
  49. } );
  50. describe( 'Adapter', () => {
  51. let editor, fileRepository, adapter;
  52. beforeEach( () => {
  53. return ClassicTestEditor.create( div, {
  54. plugins: [ Base64UploadAdapter ]
  55. } ).then( _editor => {
  56. editor = _editor;
  57. fileRepository = editor.plugins.get( FileRepository );
  58. adapter = fileRepository.createLoader( createNativeFileMock() );
  59. } );
  60. } );
  61. afterEach( () => {
  62. return editor.destroy();
  63. } );
  64. it( 'crateAdapter method should be registered and have upload() and abort() methods', () => {
  65. expect( adapter ).to.not.be.undefined;
  66. expect( adapter.upload ).to.be.a( 'function' );
  67. expect( adapter.abort ).to.be.a( 'function' );
  68. } );
  69. describe( 'upload()', () => {
  70. it( 'returns a promise that resolves an image as a base64 string', () => {
  71. setTimeout( () => {
  72. // FileReader has loaded the file.
  73. stubs.onload();
  74. } );
  75. return adapter.upload()
  76. .then( response => {
  77. expect( response.default ).to.equal( 'data:image/png;base64' );
  78. expect( stubs.readAsDataURL.calledOnce ).to.equal( true );
  79. } );
  80. } );
  81. it( 'returns a promise that rejects if something went wrong', () => {
  82. const uploadError = new Error( 'Something went wrong.' );
  83. setTimeout( () => {
  84. // An error occurred while FileReader was reading the file.
  85. stubs.onerror( uploadError );
  86. } );
  87. return adapter.upload()
  88. .then(
  89. () => {
  90. return new Error( 'Supposed to be rejected.' );
  91. },
  92. err => {
  93. expect( err ).to.equal( uploadError );
  94. expect( stubs.readAsDataURL.calledOnce ).to.equal( true );
  95. }
  96. );
  97. } );
  98. it( 'returns a promise that rejects if FileReader aborted reading a file', () => {
  99. setTimeout( () => {
  100. // FileReader aborted reading the file.
  101. stubs.onabort();
  102. } );
  103. return adapter.upload()
  104. .then(
  105. () => {
  106. return new Error( 'Supposed to be rejected.' );
  107. },
  108. () => {
  109. expect( stubs.readAsDataURL.calledOnce ).to.equal( true );
  110. }
  111. );
  112. } );
  113. } );
  114. describe( 'abort()', () => {
  115. it( 'should not call abort() on the non-existing FileReader uploader (loader#file not resolved)', () => {
  116. const adapter = fileRepository.createLoader( createNativeFileMock() );
  117. expect( () => {
  118. // Catch the upload error to prevent uncaught promise errors
  119. adapter.upload().catch( () => {} );
  120. adapter.abort();
  121. } ).to.not.throw();
  122. expect( stubs.abort.called ).to.equal( false );
  123. } );
  124. it( 'should call abort() on the FileReader uploader (loader#file resolved)', done => {
  125. adapter.upload();
  126. // Wait for the `loader.file` promise.
  127. setTimeout( () => {
  128. adapter.abort();
  129. expect( stubs.abort.called ).to.equal( true );
  130. done();
  131. } );
  132. } );
  133. } );
  134. } );
  135. } );