Procházet zdrojové kódy

Add missing tests for CKFinderCommand and handle errors.

Maciej Gołaszewski před 7 roky
rodič
revize
c5e28709de

+ 19 - 7
packages/ckeditor5-ckfinder/src/ckfindercommand.js

@@ -10,6 +10,7 @@
  */
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
+import Notification from '@ckeditor/ckeditor5-ui/src/notification/notification';
 
 import { findOptimalInsertionPosition } from '@ckeditor/ckeditor5-widget/src/utils';
 
@@ -42,25 +43,36 @@ export default class CKFinderCommand extends Command {
 			height: 500,
 			// required:
 			chooseFiles: true,
-			connectorPath: 'https://cksource.com/weuy2g4ryt278ywiue/core/connector/php/connector.php',
+			// connectorPath: 'https://cksource.com/weuy2g4ryt278ywiue/core/connector/php/connector.php',
+			connectorPath: '/build/core/connector/php/connector.php',
 			onInit: finder => {
 				finder.on( 'files:choose', evt => {
 					for ( const file of evt.data.files.toArray() ) {
+
 						// Use CKFinder file isImage() to insert only image-type files.
 						if ( file.isImage() ) {
 							const url = file.get( 'url' );
 
-							if ( !url ) {
-								finder.request( 'file:getUrl', { file } ).then( url => insertImage( editor.model, url ) );
-							} else {
-								insertImage( editor.model, url );
-							}
+							insertImage( editor.model, url ? url : finder.request( 'file:getProxyUrl', { file } ) );
 						}
 					}
 				} );
 
 				finder.on( 'file:choose:resizedImage', evt => {
-					insertImage( editor.model, evt.data.resizedUrl );
+					const resizedUrl = evt.data.resizedUrl;
+
+					if ( !resizedUrl ) {
+						const notification = editor.plugins.get( Notification );
+						const t = editor.locale.t;
+
+						notification.showWarning( t( 'Could not obtain resized image URL. Try different image or folder.' ), {
+							title: t( 'Selecting resized image failed' ),
+							namespace: 'ckfinder'
+						} );
+					}
+
+					// show warning - no resizedUrl returned...
+					insertImage( editor.model, resizedUrl );
 				} );
 			}
 		} );

+ 9 - 0
packages/ckeditor5-ckfinder/src/ckfinderediting.js

@@ -8,6 +8,8 @@
  */
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import Notification from '@ckeditor/ckeditor5-ui/src/notification/notification';
+
 import CKFinderCommand from './ckfindercommand';
 
 /**
@@ -23,6 +25,13 @@ export default class CKFinderEditing extends Plugin {
 		return 'CKFinderEditing';
 	}
 
+	/**
+	 * @inheritDoc
+	 */
+	static get requires() {
+		return [ Notification ];
+	}
+
 	/**
 	 * @inheritDoc
 	 */

+ 80 - 24
packages/ckeditor5-ckfinder/tests/ckfindercommand.js

@@ -11,6 +11,8 @@ import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
 
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import ImageEditing from '@ckeditor/ckeditor5-image/src/image/imageediting';
+import Notification from '@ckeditor/ckeditor5-ui/src/notification/notification';
+import { downcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/downcast-converters';
 
 import CKFinderCommand from '../src/ckfindercommand';
 
@@ -22,7 +24,7 @@ describe( 'CKFinderCommand', () => {
 	beforeEach( () => {
 		return VirtualTestEditor
 			.create( {
-				plugins: [ Paragraph, ImageEditing ]
+				plugins: [ Paragraph, ImageEditing, Notification ]
 			} )
 			.then( newEditor => {
 				editor = newEditor;
@@ -32,6 +34,8 @@ describe( 'CKFinderCommand', () => {
 
 				const schema = model.schema;
 				schema.extend( 'image' );
+
+				setModelData( model, '<paragraph>f[o]o</paragraph>' );
 			} );
 	} );
 
@@ -72,7 +76,6 @@ describe( 'CKFinderCommand', () => {
 		} );
 
 		it( 'should register proper listeners on CKFinder instance', () => {
-			setModelData( model, '<paragraph>f[o]o</paragraph>' );
 
 			command.execute();
 
@@ -81,32 +84,24 @@ describe( 'CKFinderCommand', () => {
 		} );
 
 		it( 'should insert single chosen image as image widget', () => {
-			setModelData( model, '<paragraph>f[o]o</paragraph>' );
 			const url = 'foo/bar.jpg';
 
 			command.execute();
 
-			expect( finderMock ).to.have.property( 'files:choose' );
-			expect( finderMock ).to.have.property( 'file:choose:resizedImage' );
-
-			mockFinderEvent( 'files:choose', [ mockFinderFile( url ) ] );
+			mockFilesChooseEvent( [ mockFinderFile( url ) ] );
 
 			expect( getModelData( model ) )
 				.to.equal( `[<image src="${ url }"></image>]<paragraph>foo</paragraph>` );
 		} );
 
 		it( 'should insert multiple chosen images as image widget', () => {
-			setModelData( model, '<paragraph>f[o]o</paragraph>' );
 			const url1 = 'foo/bar1.jpg';
 			const url2 = 'foo/bar2.jpg';
 			const url3 = 'foo/bar3.jpg';
 
 			command.execute();
 
-			expect( finderMock ).to.have.property( 'files:choose' );
-			expect( finderMock ).to.have.property( 'file:choose:resizedImage' );
-
-			mockFinderEvent( 'files:choose', [ mockFinderFile( url1 ), mockFinderFile( url2 ), mockFinderFile( url3 ) ] );
+			mockFilesChooseEvent( [ mockFinderFile( url1 ), mockFinderFile( url2 ), mockFinderFile( url3 ) ] );
 
 			expect( getModelData( model ) ).to.equal(
 				`<image src="${ url1 }"></image><image src="${ url2 }"></image>[<image src="${ url3 }"></image>]<paragraph>foo</paragraph>`
@@ -114,23 +109,82 @@ describe( 'CKFinderCommand', () => {
 		} );
 
 		it( 'should insert only images from chosen files', () => {
-			setModelData( model, '<paragraph>f[o]o</paragraph>' );
 			const url1 = 'foo/bar1.jpg';
 			const url2 = 'foo/bar2.pdf';
 			const url3 = 'foo/bar3.jpg';
 
 			command.execute();
 
-			expect( finderMock ).to.have.property( 'files:choose' );
-			expect( finderMock ).to.have.property( 'file:choose:resizedImage' );
-
-			mockFinderEvent( 'files:choose', [ mockFinderFile( url1 ), mockFinderFile( url2, false ), mockFinderFile( url3 ) ] );
+			mockFilesChooseEvent( [ mockFinderFile( url1 ), mockFinderFile( url2, false ), mockFinderFile( url3 ) ] );
 
 			expect( getModelData( model ) ).to.equal(
 				`<image src="${ url1 }"></image>[<image src="${ url3 }"></image>]<paragraph>foo</paragraph>`
 			);
 		} );
 
+		it( 'should use CKFinder Proxy for privately hosted files', () => {
+
+			const proxyUrl = 'bar/foo.jpg';
+
+			finderMock.request = () => proxyUrl;
+
+			command.execute();
+
+			mockFilesChooseEvent( [ mockFinderFile( false ) ] );
+
+			expect( getModelData( model ) ).to.equal(
+				`[<image src="${ proxyUrl }"></image>]<paragraph>foo</paragraph>`
+			);
+		} );
+
+		it( 'should insert resized image as image widget', () => {
+			const url = 'foo/bar.jpg';
+
+			command.execute();
+
+			mockFinderEvent( 'file:choose:resizedImage', { resizedUrl: url } );
+
+			expect( getModelData( model ) )
+				.to.equal( `[<image src="${ url }"></image>]<paragraph>foo</paragraph>` );
+		} );
+
+		it( 'should show warning notification if no resized image URL was returned', done => {
+			const notification = editor.plugins.get( Notification );
+
+			notification.on( 'show:warning', ( evt, data ) => {
+				expect( data.message ).to.equal( 'Could not obtain resized image URL. Try different image or folder.' );
+				expect( data.title ).to.equal( 'Selecting resized image failed' );
+				evt.stop();
+
+				done();
+			}, { priority: 'high' } );
+
+			command.execute();
+
+			mockFinderEvent( 'file:choose:resizedImage', { resizedUrl: undefined } );
+
+			expect( getModelData( model ) )
+				.to.equal( '<paragraph>f[o]o</paragraph>' );
+		} );
+
+		it( 'should not insert image nor crash when image could not be inserted', () => {
+			model.schema.register( 'other', {
+				allowIn: '$root',
+				isLimit: true
+			} );
+			model.schema.extend( '$text', { allowIn: 'other' } );
+
+			editor.conversion.for( 'downcast' ).add( downcastElementToElement( { model: 'other', view: 'p' } ) );
+
+			setModelData( model, '<other>[]</other>' );
+
+			command.execute();
+
+			mockFilesChooseEvent( [ mockFinderFile( 'foo/bar.jpg' ) ] );
+
+			expect( getModelData( model ) ).to.equal( '<other>[]</other>' );
+		} );
+
 		function mockFinderFile( url = 'foo/bar.jpg', isImage = true ) {
 			return {
 				isImage: () => isImage,
@@ -138,16 +192,18 @@ describe( 'CKFinderCommand', () => {
 			};
 		}
 
-		function mockFinderEvent( eventName, files ) {
-			const evt = {
-				data: {
-					files: {
-						toArray: () => files
-					}
+		function mockFinderEvent( eventName, data ) {
+			finderMock[ eventName ]( { data } );
+		}
+
+		function mockFilesChooseEvent( files ) {
+			const data = {
+				files: {
+					toArray: () => files
 				}
 			};
 
-			finderMock[ eventName ]( evt );
+			mockFinderEvent( 'files:choose', data );
 		}
 	} );
 } );

+ 6 - 1
packages/ckeditor5-ckfinder/tests/ckfinderediting.js

@@ -3,10 +3,11 @@
  * For licensing, see LICENSE.md.
  */
 
+import Command from '@ckeditor/ckeditor5-core/src/command';
 import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
 import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
+import Notification from '@ckeditor/ckeditor5-ui/src/notification/notification';
 import global from '@ckeditor/ckeditor5-utils/src/dom/global';
-import Command from '@ckeditor/ckeditor5-core/src/command';
 
 import CKFinder from '../src/ckfinder';
 import CKFinderEditing from '../src/ckfinderediting';
@@ -40,6 +41,10 @@ describe( 'CKFinderEditing', () => {
 		expect( editor.plugins.get( CKFinderEditing ) ).to.be.instanceOf( CKFinderEditing );
 	} );
 
+	it( 'should load Notification plugin', () => {
+		expect( editor.plugins.get( Notification ) ).to.instanceOf( Notification );
+	} );
+
 	it( 'should register command', () => {
 		const command = editor.commands.get( 'ckfinder' );
 

+ 2 - 2
packages/ckeditor5-ckfinder/tests/manual/ckfinder.html

@@ -1,5 +1,5 @@
-<script src="https://cksource.com/weuy2g4ryt278ywiue/ckfinder.js"></script>
-<!-- <script src="/build/ckfinder.js"></script> -->
+<!--<script src="https://cksource.com/weuy2g4ryt278ywiue/ckfinder.js"></script>-->
+ <script src="/build/ckfinder.js"></script>
 
 <div id="editor">
 	<h2>CKFinder sample</h2>