Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 0 additions & 14 deletions tests/unit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ describe( 'CKEditor4 React', () => {
// Increases timeout so that CI can have a chance to capture changes.
const timeout = 5000;
const requestedVersion = process.env.REQUESTED_REACT_VERSION;
const windw = window as any;
const log = windw.console.log;

beforeAll( () => {
// Extends jasmine with custom RTL matchers.
Expand All @@ -30,18 +28,6 @@ describe( 'CKEditor4 React', () => {
}
} );

beforeEach( async () => {
if ( windw.CKEDITOR ) {
// Ensures that all instances of editor are cleaned up.
expect( Object.entries( windw.CKEDITOR.instances ).length ).toEqual( 0 );
}
} );

afterEach( async () => {
// Restores `console.log` in case it was overriden with a spy.
windw.console.log = log;
} );

initCommonTests();
initUseCKEditorTests();
initRegisterEditorEventHandler();
Expand Down
108 changes: 31 additions & 77 deletions tests/unit/registerEditorEventHandler.test.ts
Original file line number Diff line number Diff line change
@@ -1,115 +1,69 @@
import { renderHook } from '@testing-library/react';
import { createDivElement, waitForValueToChange } from './utils';
import { registerEditorEventHandler, useCKEditor } from '../../src';
import { registerEditorEventHandler } from '../../src';

function init() {
describe( 'registerEditorEventHandler', () => {
/**
* Registers an event handler within editor.
*/
const windw = window as any;
const log = windw.console.log;
const spyOnEventOn = jasmine.createSpy( 'editor.on' );
const spyOnRemoveListener = jasmine.createSpy( 'editor.removeListener' );
const createEditor = () => ( { on: spyOnEventOn, removeListener: spyOnRemoveListener } );

afterEach( () => {
spyOnEventOn.calls.reset();
spyOnRemoveListener.calls.reset();
windw.console.log = log;
} );

it( 'registers / unregisters event handler', async () => {
const element = createDivElement();
const onInstanceReady = jasmine.createSpy( 'onInstanceReady' );
const { result } = renderHook( () =>
useCKEditor( {
element
} )
);
await waitForValueToChange( () => !!result.current.editor );
const unregister = registerEditorEventHandler( {
editor: result.current.editor,
editor: createEditor(),
evtName: 'instanceReady',
handler: onInstanceReady
} );
expect(
result.current.editor.hasListeners( 'instanceReady' )
).toBeTrue();
await waitForValueToChange( () => result.current.status === 'ready' );
expect( onInstanceReady ).toHaveBeenCalledTimes( 1 );
expect( spyOnEventOn ).toHaveBeenCalledTimes( 1 );
expect( spyOnEventOn ).toHaveBeenCalledWith( 'instanceReady', onInstanceReady, null, undefined, undefined );
unregister();
expect(
result.current.editor.hasListeners( 'instanceReady' )
).toBeUndefined();
expect( spyOnRemoveListener ).toHaveBeenCalledTimes( 1 );
expect( spyOnRemoveListener ).toHaveBeenCalledWith( 'instanceReady', onInstanceReady );
} );

/**
* With debugging enabled, events are logged to console.
*/
it( 'turns on `debug` mode', async () => {
const windw = window as any;
windw.console.log = jasmine.createSpy( 'windw.console.log' );
const element = createDivElement();
windw.console.log = jasmine.createSpy( 'window.console.log' );
const onInstanceReady = jasmine.createSpy( 'onInstanceReady' );
const { result } = renderHook( () =>
useCKEditor( {
element
} )
);
await waitForValueToChange( () => !!result.current.editor );
registerEditorEventHandler( {
editor: result.current.editor,
editor: createEditor(),
evtName: 'instanceReady',
handler: onInstanceReady,
debug: true
} );
await waitForValueToChange( () => result.current.status === 'ready' );
expect( onInstanceReady ).toHaveBeenCalledTimes( 1 );
expect( spyOnEventOn ).toHaveBeenCalledTimes( 1 );
expect( spyOnEventOn ).toHaveBeenCalledWith( 'instanceReady', jasmine.any( Function ), null, undefined, undefined );
expect( windw.console.log ).toHaveBeenCalled();
} );

/**
* Accepts and passes custom listener data.
*/
it( 'uses listener data', async () => {
const element = createDivElement();
const onInstanceReady = jasmine.createSpy( 'onInstanceReady' );
const { result } = renderHook( () =>
useCKEditor( {
element
} )
);
await waitForValueToChange( () => !!result.current.editor );
registerEditorEventHandler( {
editor: result.current.editor,
editor: createEditor(),
evtName: 'instanceReady',
handler: onInstanceReady,
listenerData: { hello: 'hello' }
listenerData: { foo: 'bar' }
} );
await waitForValueToChange( () => result.current.status === 'ready' );
expect( onInstanceReady ).toHaveBeenCalledWith(
jasmine.objectContaining( {
listenerData: { hello: 'hello' }
} )
);
expect( spyOnEventOn ).toHaveBeenCalledTimes( 1 );
expect( spyOnEventOn ).toHaveBeenCalledWith( 'instanceReady', onInstanceReady, null, { foo: 'bar' }, undefined );
} );

/**
* Sets priority in which handlers are invoked.
*/
it( 'accepts priority', async () => {
const element = createDivElement();
const onInstanceReady1 = jasmine.createSpy( 'onInstanceReady1' );
const onInstanceReady2 = jasmine.createSpy( 'onInstanceReady2' );
const { result } = renderHook( () =>
useCKEditor( {
element
} )
);
await waitForValueToChange( () => !!result.current.editor );
registerEditorEventHandler( {
editor: result.current.editor,
evtName: 'instanceReady',
handler: onInstanceReady1,
priority: 1
} );
const onInstanceReady = jasmine.createSpy( 'onInstanceReady' );
registerEditorEventHandler( {
editor: result.current.editor,
editor: createEditor(),
evtName: 'instanceReady',
handler: onInstanceReady2,
handler: onInstanceReady,
priority: 0
} );
await waitForValueToChange( () => result.current.status === 'ready' );
expect( onInstanceReady2 ).toHaveBeenCalledBefore( onInstanceReady1 );
expect( spyOnEventOn ).toHaveBeenCalledTimes( 1 );
expect( spyOnEventOn ).toHaveBeenCalledWith( 'instanceReady', onInstanceReady, null, undefined, 0 );
} );
} );
}
Expand Down
5 changes: 1 addition & 4 deletions tests/unit/useCKEditor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ function init() {
expect( result.current.editor ).toBeUndefined();
expect( result.current.loading ).toBeTrue();
await waitForValueToChange( () => !!result.current.editor );
expect( result.current.status ).toEqual( 'unloaded' );
expect( result.current.loading ).toBeFalse();
await waitForValueToChange(
() => result.current.status === 'loaded'
Expand Down Expand Up @@ -267,9 +266,7 @@ function init() {
}
} )
);
await waitForValueToChange(
() => result.current.status === 'unloaded'
);
await waitForValueToChange( () => result.current.status === 'loaded' );
expect( onBeforeLoad ).toHaveBeenCalledTimes( 1 );
await waitForValueToChange( () => result.current.status === 'ready' );
expect( onBeforeLoad ).toHaveBeenCalledTimes( 1 );
Expand Down
21 changes: 11 additions & 10 deletions tests/unit/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { getByText, waitFor } from '@testing-library/react';
import * as React from 'react';
import { getByText, render, waitFor } from '@testing-library/react';

/**
* Creates dummy element.
*
* @returns element
*/
export function createDivElement() {
const el = document.createElement( 'div' );
document.body.appendChild( el );
return el;
const ref = React.createRef<HTMLDivElement>();
render( <div ref={ref} /> );
return ref.current;
}

/**
Expand All @@ -20,7 +21,7 @@ export function createDivElement() {
* @param fn predicate
* @returns resolved promise if predicate evaluates to true
*/
export async function waitForValueToChange( fn: () => boolean ) {
export function waitForValueToChange( fn: () => boolean ) {
return waitFor( () => {
if ( !fn() ) {
throw new Error();
Expand All @@ -34,7 +35,7 @@ export async function waitForValueToChange( fn: () => boolean ) {
* @param text editor content to find
* @returns found html element wrapped in promise
*/
export async function findByClassicEditorContent( text: string ) {
export function findByClassicEditorContent( text: string ) {
return waitFor( () => {
const iframe = queryClassicEditorFrame();
if ( !iframe?.contentWindow?.document.body ) {
Expand All @@ -50,7 +51,7 @@ export async function findByClassicEditorContent( text: string ) {
* @param editable indicates if editor is editable
* @returns found html element wrapped in promise
*/
export async function findByClassicEditorEditable( editable: boolean ) {
export function findByClassicEditorEditable( editable: boolean ) {
return waitFor( () => {
const iframe = queryClassicEditorFrame();
const editableEl = iframe?.contentWindow?.document.querySelector(
Expand All @@ -69,7 +70,7 @@ export async function findByClassicEditorEditable( editable: boolean ) {
* @param text editor root element to find
* @returns found html element wrapped in promise
*/
export async function findByEditorName( name: string ) {
export function findByEditorName( name: string ) {
return waitFor( () => {
const contentEl: HTMLElement | null = document.getElementById(
`cke_${ name }`
Expand All @@ -87,7 +88,7 @@ export async function findByEditorName( name: string ) {
* @param editable indicates if editor is editable
* @returns found html element wrapped in promise
*/
export async function findByInlineEditorEditable( editable: boolean ) {
export function findByInlineEditorEditable( editable: boolean ) {
return waitFor( () => {
const editableEl = document.querySelector(
`[contenteditable=${ editable }]`
Expand All @@ -105,7 +106,7 @@ export async function findByInlineEditorEditable( editable: boolean ) {
* @param text editor content to find
* @returns found html element wrapped in promise
*/
export async function findByInlineEditorContent( text: string ) {
export function findByInlineEditorContent( text: string ) {
return waitFor( () => {
const contentEl = queryInlineEditor();
if ( !contentEl ) {
Expand Down