import {EditorState, ContentState, SelectionState} from 'draft-js'; import * as Highlights from '../../helpers/highlights'; import reducer from '../suggestions'; function getInitialEditorState(startOffset = 2, endOffset = 2) { const content = ContentState.createFromText('test'); const editorState = EditorState.createWithContent(content); const selection = editorState.getSelection().merge({ anchorOffset: startOffset, focusOffset: endOffset, }) as SelectionState; return EditorState.acceptSelection(editorState, selection); } function getEditorStateWithDeleteSuggestion(author, date, startOffset, endOffset, action = 'backspace') { const result = reducer({ editorState: getInitialEditorState(startOffset, endOffset), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: action, data: { date: date, author: author, }, }, }); const {editorState} = result; return editorState; } describe('editor3.reducers.suggestion.CREATE_DELETE_SUGGESTION', () => { it('should suggest a character delete by using backspace key', () => { const date = new Date(); const result = reducer({ editorState: getInitialEditorState(), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'backspace', data: { date: date, author: 'author_id', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(1); expect(selection.getEndOffset()).toEqual(1); for (let i = 0; i < 4; i++) { if (i === 1) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-1']); } else { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } } expect(Highlights.getHighlightData(editorState, 'DELETE_SUGGESTION-1')).toEqual({ date: date, author: 'author_id', type: 'DELETE_SUGGESTION', }); }); it('should suggest a character delete by using delete key', () => { const date = new Date(); const result = reducer({ editorState: getInitialEditorState(), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'delete', data: { date: date, author: 'author_id', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(3); expect(selection.getEndOffset()).toEqual(3); for (let i = 0; i < 4; i++) { if (i === 2) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-1']); } else { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } } expect(Highlights.getHighlightData(editorState, 'DELETE_SUGGESTION-1')).toEqual({ date: date, author: 'author_id', type: 'DELETE_SUGGESTION', }); }); it('should not add suggestion when backspace a character at beginning of the paragraph', () => { const date = new Date(); const result = reducer({ editorState: getInitialEditorState(0, 0), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'backspace', data: { date: date, author: 'author_id', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(0); expect(selection.getEndOffset()).toEqual(0); for (let i = 0; i < 4; i++) { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } }); it('should not add suggestion when delete a character at the end of the paragraph', () => { const date = new Date(); const result = reducer({ editorState: getInitialEditorState(4, 4), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'delete', data: { date: date, author: 'author_id', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(4); expect(selection.getEndOffset()).toEqual(4); for (let i = 0; i < 4; i++) { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } }); it('should add new suggestion when backspace a selected text', () => { const date = new Date(); const result = reducer({ editorState: getInitialEditorState(1, 3), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'backspace', data: { date: date, author: 'author_id', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(1); expect(selection.getEndOffset()).toEqual(1); for (let i = 0; i < 4; i++) { if (i > 0 && i < 3) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-1']); } else { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } } expect(Highlights.getHighlightData(editorState, 'DELETE_SUGGESTION-1')).toEqual({ date: date, author: 'author_id', type: 'DELETE_SUGGESTION', }); }); it('should add new suggestion when delete a selected text', () => { const date = new Date(); const result = reducer({ editorState: getInitialEditorState(1, 3), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'delete', data: { date: date, author: 'author_id', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(3); expect(selection.getEndOffset()).toEqual(3); for (let i = 0; i < 4; i++) { if (i > 0 && i < 3) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-1']); } else { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } } expect(Highlights.getHighlightData(editorState, 'DELETE_SUGGESTION-1')).toEqual({ date: date, author: 'author_id', type: 'DELETE_SUGGESTION', }); }); it('should extend old suggestion when backspace before an existing suggestion with the same author', () => { const date = new Date(); const result = reducer({ editorState: getEditorStateWithDeleteSuggestion('author_id', date, 1, 3), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'backspace', data: { date: date, author: 'author_id', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(0); expect(selection.getEndOffset()).toEqual(0); for (let i = 0; i < 4; i++) { if (i !== 3) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-1']); } else { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } } expect(Highlights.getHighlightData(editorState, 'DELETE_SUGGESTION-1')).toEqual({ date: date, author: 'author_id', type: 'DELETE_SUGGESTION', }); }); it('should extend suggestion when delete with the same author after an existing delete suggestion', () => { const date = new Date(); const result = reducer({ editorState: getEditorStateWithDeleteSuggestion('author_id', date, 1, 3, 'delete'), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'delete', data: { date: date, author: 'author_id', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(4); expect(selection.getEndOffset()).toEqual(4); for (let i = 0; i < 4; i++) { if (i !== 0) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-1']); } else { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } } expect(Highlights.getHighlightData(editorState, 'DELETE_SUGGESTION-1')).toEqual({ date: date, author: 'author_id', type: 'DELETE_SUGGESTION', }); }); it('should add new suggestion when backspace with different author before an existing delete suggestion', () => { const date = new Date(); const result = reducer({ editorState: getEditorStateWithDeleteSuggestion('author_id1', date, 1, 3), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'backspace', data: { date: date, author: 'author_id2', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(0); expect(selection.getEndOffset()).toEqual(0); for (let i = 0; i < 4; i++) { if (i === 0) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-2']); } else if (i < 3) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-1']); } else { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } } expect(Highlights.getHighlightData(editorState, 'DELETE_SUGGESTION-2')).toEqual({ date: date, author: 'author_id2', type: 'DELETE_SUGGESTION', }); }); it('should add a new suggestion when delete with different author after an existing delete suggestion', () => { const date = new Date(); const result = reducer({ editorState: getEditorStateWithDeleteSuggestion('author_id1', date, 1, 3, 'delete'), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'delete', data: { date: date, author: 'author_id2', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(4); expect(selection.getEndOffset()).toEqual(4); for (let i = 0; i < 4; i++) { if (i === 0) { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } else if (i < 3) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-1']); } else { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-2']); } } expect(Highlights.getHighlightData(editorState, 'DELETE_SUGGESTION-2')).toEqual({ date: date, author: 'author_id2', type: 'DELETE_SUGGESTION', }); }); it('should extend suggestion when backspace with the same author after an existing delete suggestion', () => { const date = new Date(); const result = reducer({ editorState: getEditorStateWithDeleteSuggestion('author_id', date, 1, 3, 'delete'), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'backspace', data: { date: date, author: 'author_id', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(2); expect(selection.getEndOffset()).toEqual(2); for (let i = 0; i < 4; i++) { if (i > 0 && i < 3) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-1']); } else { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } } }); it('should extend old suggestion when delete with the same author before an existing delete suggestion', () => { const date = new Date(); const result = reducer({ editorState: getEditorStateWithDeleteSuggestion('author_id', date, 1, 3), suggestingMode: true, onChangeValue: () => ({}), }, { type: 'CREATE_DELETE_SUGGESTION', payload: { action: 'delete', data: { date: date, author: 'author_id', }, }, }); const {editorState} = result; const selection = editorState.getSelection(); const block = editorState.getCurrentContent().getFirstBlock(); expect(editorState.getCurrentContent().getPlainText()).toEqual('test'); expect(selection.getStartOffset()).toEqual(2); expect(selection.getEndOffset()).toEqual(2); for (let i = 0; i < 4; i++) { if (i > 0 && i < 3) { expect(block.getInlineStyleAt(i).toJS()).toEqual(['DELETE_SUGGESTION-1']); } else { expect(block.getInlineStyleAt(i).toJS()).toEqual([]); } } }); });