import PropTypes from 'prop-types'; import {Map, OrderedSet, List, Repeat} from 'immutable'; import { EditorState, ContentState, ContentBlock, RichUtils, SelectionState, convertToRaw, CharacterMetadata, genKey, } from 'draft-js'; import insertAtomicBlockWithoutEmptyLines from '../../helpers/insertAtomicBlockWithoutEmptyLines'; /** * @name mockStore * @description Creates a new Redux store mock and returns an object containing * two keys: "store" as the actual store, and "options" as the parameter to be * passed to enzyme's mount command in order to use this store as context. * @param {Object} state The state the store should have when queried. * @returns {Object} The object containing the store and the enzyme mount param. */ export default function mockStore(state = {}) { const store = { subscribe: () => ({}), dispatch: () => ({}), getState: () => state, }; const options = { context: {store}, childContextTypes: { store: PropTypes.object.isRequired, }, }; return {store, options}; } /** * @name stateWithLink * @description Returns a new editorState that has the text "click HERE to open page" * as content, having the uppercased letters marked as an entity of type LINK, containing * the data {link: {href: 'entity-url'}} * @returns {Object} editorState */ export function stateWithLink() { const contentState = ContentState .createFromText('click HERE to open page') .createEntity('LINK', 'MUTABLE', {link: {href: 'entity-url'}}); const entityKey = contentState.getLastCreatedEntityKey(); const blockKey = contentState.getFirstBlock().getKey(); const linkSelection = SelectionState.createEmpty(blockKey).merge({ anchorOffset: 6, focusOffset: 9, }); return RichUtils.toggleLink( EditorState.createWithContent(contentState), linkSelection as SelectionState, entityKey, ); } /** * @description Returns a block containing an image and it's host content state. * @returns {Object} Keys 'block' and 'contentState' */ export function imageBlockAndContent() { return createBlockAndContent('MEDIA', { media: { _type: 'archive', // make sure edit icon is visible renditions: {original: {href: 'image_href'}}, alt_text: 'image_alt_text', headline: 'image_headline', description_text: 'image_description', type: 'picture', }, }); } /** * @description Creates a contentState containing an atomic block with the entity * having the given type and containing the given data. * @param {String} type Entity type * @param {Object} data Entity data * @returns {Object} Keys 'block' and 'contentState' */ export function createBlockAndContent(type, data) { const cs = ContentState.createFromText('here is an image:'); const contentState = cs.createEntity(type, 'MUTABLE', data); const entityKey = contentState.getLastCreatedEntityKey(); const {editorState} = insertAtomicBlockWithoutEmptyLines( EditorState.createWithContent(contentState), entityKey, ' '); const block = editorState.getCurrentContent().getBlocksAsArray()[1]; return {block: block, contentState: editorState.getCurrentContent()}; } /** * @description Creates a contentState containing an atomic block that is an embed. * @returns {Object} Keys 'block' and 'contentState' */ export function embedBlockAndContent() { return createBlockAndContent('EMBED', { data: { html: '