import React from 'react'; import {mount} from 'enzyme'; import * as defaultSpellcheckers from '../spellchecker/default-spellcheckers'; import {Provider} from 'react-redux'; import {createStore} from 'redux'; import {EditorState, ContentState} from 'draft-js'; import editorReducers from 'core/editor3/reducers'; import {Editor3} from '..'; import {noop} from 'lodash'; import {ISpellchecker} from '../spellchecker/interfaces'; const editorStateInitial = EditorState.createWithContent(ContentState.createFromText('This speling is not correkt.')); const testSpellchecker: ISpellchecker = { check: () => Promise.resolve([ { startOffset: 5, text: 'speling', suggestions: [{text: 'spelling'}], type: 'spelling', }, { startOffset: 20, text: 'correkt', suggestions: [{text: 'correct'}, {text: 'incorrect'}], type: 'spelling', }, ]), actions: { testAction: { label: 'test action', perform: (warning) => Promise.resolve(), }, testAction2: { label: 'test action 2', perform: (warning) => Promise.resolve(), }, }, }; describe('editor3.spellchecker', () => { it('displays spellchecking errors in the editor', (done) => { spyOn(defaultSpellcheckers, 'getSpellchecker').and.returnValue(testSpellchecker); const initialState = { editorState: editorStateInitial, spellchecking: { enabled: true, language: 'en', inProgress: false, warningsByBlock: {}, }, }; const wrapper = mount( , ); // waiting for the spellchecker to load setTimeout(() => { wrapper.update(); const warningsInDom = wrapper.find('[data-test-id="spellchecker-warning"]'); expect(warningsInDom.length).toBe(2); expect(warningsInDom.at(0).text()).toBe('speling'); expect(warningsInDom.at(1).text()).toBe('correkt'); expect(wrapper.text().indexOf('speling')).toBe(5); expect(wrapper.text().indexOf('correkt')).toBe(20); wrapper.unmount(); done(); }, 1000); }); it('doesn\'t display the errors if the spellchecker is off', (done) => { spyOn(defaultSpellcheckers, 'getSpellchecker').and.returnValue(testSpellchecker); const initialState = { editorState: editorStateInitial, spellchecking: { enabled: false, language: 'en', inProgress: false, warningsByBlock: {}, }, }; const wrapper = mount( , ); // waiting for the spellchecker to load // the spellchecker is intentionally asynchronous to allow the editor to load faster setTimeout(() => { wrapper.update(); const warningsInDom = wrapper.find('[data-test-id="spellchecker-warning"]'); expect(warningsInDom.length).toBe(0); wrapper.unmount(); done(); }, 1000); }); it('displays suggestions and actions', (done) => { spyOn(defaultSpellcheckers, 'getSpellchecker').and.returnValue(testSpellchecker); const initialState = { editorState: editorStateInitial, spellchecking: { enabled: true, language: 'en', inProgress: false, warningsByBlock: {}, }, }; const wrapper = mount( , ); // waiting for the spellchecker to load // the spellchecker is intentionally asynchronous to allow the editor to load faster setTimeout(() => { wrapper.update(); wrapper.find('[data-test-id="spellchecker-warning"]') .at(1) .simulate('contextmenu'); const suggestions = Array.from(document.querySelectorAll('[data-test-id="spellchecker-menu--suggestion"]')) .map((el) => el.textContent); expect(suggestions[0]).toBe('correct'); expect(suggestions[1]).toBe('incorrect'); const actions = Array.from(document.querySelectorAll('[data-test-id="spellchecker-menu--action"]')) .map((el) => el.textContent); expect(actions[0]).toBe('test action'); expect(actions[1]).toBe('test action 2'); wrapper.unmount(); done(); }, 1000); }); it('can apply spellchecker suggestion', (done) => { spyOn(defaultSpellcheckers, 'getSpellchecker').and.returnValue(testSpellchecker); const initialState = { editorState: editorStateInitial, spellchecking: { enabled: true, language: 'en', inProgress: false, warningsByBlock: {}, }, onChangeValue: noop, }; const wrapper = mount( , ); // waiting for the spellchecker to load // the spellchecker is intentionally asynchronous to allow the editor to load faster setTimeout(() => { wrapper.update(); wrapper.find('[data-test-id="spellchecker-warning"]') .at(1) .simulate('contextmenu'); expect(document.querySelectorAll('[data-test-id="spellchecker-menu--suggestion"]').length).toBe(2); expect(wrapper.text()).toBe('This speling is not correkt.'); const suggestion: HTMLButtonElement = document.querySelector('[data-test-id="spellchecker-menu--suggestion"]'); const event = new MouseEvent('mousedown'); event.initEvent('mousedown', true, true); suggestion.dispatchEvent(event); wrapper.update(); expect(wrapper.text()).toBe('This speling is not correct.'); // the word "correkt" was replaced to "correct" ^ wrapper.unmount(); done(); }, 1000); }); it('works around around jasmine\'s buggy behaviour', (done) => { // it looks like jasmine is starting one test before previous has finished // & destroying spies sooner the test finishes(at least in case of an async test) // I don't see how this could have an any effect otherwise. spyOn(defaultSpellcheckers, 'getSpellchecker').and.returnValue(testSpellchecker); setTimeout(done, 1000); }); });