diff --git a/internal_packages/composer/lib/contenteditable-component.cjsx b/internal_packages/composer/lib/contenteditable-component.cjsx index c38f2207f..b10c0d8f8 100644 --- a/internal_packages/composer/lib/contenteditable-component.cjsx +++ b/internal_packages/composer/lib/contenteditable-component.cjsx @@ -6,6 +6,12 @@ FloatingToolbar = require './floating-toolbar.cjsx' module.exports = ContenteditableComponent = React.createClass + propTypes: + html: React.PropTypes.string + style: React.PropTypes.object + tabIndex: React.PropTypes.number + onChange: React.PropTypes.func.isRequired + getInitialState: -> toolbarTop: 0 toolbarMode: "buttons" diff --git a/internal_packages/composer/spec/contenteditable-component-spec.cjsx b/internal_packages/composer/spec/contenteditable-component-spec.cjsx index 37d785b8e..c1c39f272 100644 --- a/internal_packages/composer/spec/contenteditable-component-spec.cjsx +++ b/internal_packages/composer/spec/contenteditable-component-spec.cjsx @@ -1,20 +1,13 @@ +# This tests the basic Contenteditable component. For various modules of +# the contenteditable (such as selection, tooltip, quoting, etc) see the +# related test files. +# _ = require "underscore-plus" React = require "react/addons" - ReactTestUtils = React.addons.TestUtils -ReactTestUtils.scryRenderedDOMComponentsWithAttr = (root, attrName, attrValue) -> - ReactTestUtils.findAllInRenderedTree root, (inst) -> - inst.props[attrName] and (!attrValue or inst.props[attrName] is attrValue) - -ReactTestUtils.findRenderedDOMComponentWithAttr = (root, attrName, attrValue) -> - all = ReactTestUtils.scryRenderedDOMComponentsWithAttr(root, attrName, attrValue) - if all.length is not 1 - throw new Error("Did not find exactly one match for data attribute: #{attrName} with value: #{attrValue}") - all[0] - ContenteditableComponent = require "../lib/contenteditable-component.cjsx", -describe "ContenteditableComponent", -> +fdescribe "ContenteditableComponent", -> beforeEach -> @onChange = jasmine.createSpy('onChange') html = 'Test HTML' @@ -22,11 +15,6 @@ describe "ContenteditableComponent", -> ) - html = 'Test HTML
QUOTE
' - @componentWithQuote = ReactTestUtils.renderIntoDocument( - - ) - describe "render", -> it 'should render into the document', -> expect(ReactTestUtils.isCompositeComponentWithType @component, ContenteditableComponent).toBe true @@ -34,49 +22,12 @@ describe "ContenteditableComponent", -> it "should include a content-editable div", -> expect(ReactTestUtils.findRenderedDOMComponentWithAttr(@component, 'contentEditable')).toBeDefined() - describe "quoted-text-control", -> - it "should be rendered", -> - expect(ReactTestUtils.findRenderedDOMComponentWithClass(@component, 'quoted-text-control')).toBeDefined() - - it "should be visible if the html contains quoted text", -> - @toggle = ReactTestUtils.findRenderedDOMComponentWithClass(@componentWithQuote, 'quoted-text-control') - expect(@toggle.props.className.indexOf('no-quoted-text') >= 0).toBe(false) - - it "should be have `show-quoted-text` if editQuotedText is true", -> - @componentWithQuote.setState(editQuotedText: true) - @toggle = ReactTestUtils.findRenderedDOMComponentWithClass(@componentWithQuote, 'quoted-text-control') - expect(@toggle.props.className.indexOf('show-quoted-text') >= 0).toBe(true) - - it "should not have `show-quoted-text` if editQuotedText is false", -> - @componentWithQuote.setState(editQuotedText: false) - @toggle = ReactTestUtils.findRenderedDOMComponentWithClass(@componentWithQuote, 'quoted-text-control') - expect(@toggle.props.className.indexOf('show-quoted-text') >= 0).toBe(false) - - it "should be hidden otherwise", -> - @toggle = ReactTestUtils.findRenderedDOMComponentWithClass(@component, 'quoted-text-control') - expect(@toggle.props.className.indexOf('no-quoted-text') >= 0).toBe(true) - - describe "when editQuotedText is false", -> - it "should only display HTML up to the beginning of the quoted text", -> - @editDiv = ReactTestUtils.findRenderedDOMComponentWithAttr(@componentWithQuote, 'contentEditable') - expect(@editDiv.getDOMNode().innerHTML.indexOf('gmail_quote') >= 0).toBe(false) - - describe "when editQuotedText is true", -> - it "should display all the HTML", -> - @componentWithQuote.setState(editQuotedText: true) - @editDiv = ReactTestUtils.findRenderedDOMComponentWithAttr(@componentWithQuote, 'contentEditable') - expect(@editDiv.getDOMNode().innerHTML.indexOf('gmail_quote') >= 0).toBe(true) - - describe "editQuotedText", -> - it "should default to false", -> - expect(@component.state.editQuotedText).toBe(false) - describe "when the html is changed", -> beforeEach -> @changedHtmlWithoutQuote = 'Changed NEW 1 HTML
' @changedHtmlWithQuote = 'Changed NEW 1 HTML
QUOTE
' - @performEdit = (newHTML, component = @componentWithQuote) => + @performEdit = (newHTML, component = @component) => editDiv = ReactTestUtils.findRenderedDOMComponentWithAttr(component, 'contentEditable') editDiv.getDOMNode().innerHTML = newHTML ReactTestUtils.Simulate.input(editDiv, {target: {value: newHTML}}) @@ -93,31 +44,3 @@ describe "ContenteditableComponent", -> expect(@onChange.callCount).toBe(1) @performEdit(@changedHtmlWithoutQuote) expect(@onChange.callCount).toBe(2) - - describe "when editQuotedText is true", -> - it "should call `props.onChange` with the entire HTML string", -> - @componentWithQuote.setState(editQuotedText: true) - @performEdit(@changedHtmlWithQuote) - ev = @onChange.mostRecentCall.args[0] - expect(ev.target.value).toEqual(@changedHtmlWithQuote) - - it "should allow the quoted text to be changed", -> - changed = 'Test NEW 1 HTML
QUOTE CHANGED!!!
' - @componentWithQuote.setState(editQuotedText: true) - @performEdit(changed) - ev = @onChange.mostRecentCall.args[0] - expect(ev.target.value).toEqual(changed) - - describe "when editQuotedText is false", -> - it "should call `props.onChange` with the entire HTML string, even though the div being edited only contains some of it", -> - @componentWithQuote.setState(editQuotedText: false) - @performEdit(@changedHtmlWithoutQuote) - ev = @onChange.mostRecentCall.args[0] - expect(ev.target.value).toEqual(@changedHtmlWithQuote) - - it "should work if the component does not contain quoted text", -> - changed = 'Hallooo! NEW 1 HTML HTML HTML
' - @component.setState(editQuotedText: true) - @performEdit(changed, @component) - ev = @onChange.mostRecentCall.args[0] - expect(ev.target.value).toEqual(changed) diff --git a/internal_packages/composer/spec/contenteditable-quoted-text-spec.cjsx b/internal_packages/composer/spec/contenteditable-quoted-text-spec.cjsx new file mode 100644 index 000000000..f23323c0f --- /dev/null +++ b/internal_packages/composer/spec/contenteditable-quoted-text-spec.cjsx @@ -0,0 +1,97 @@ +# This tests just quoted text within a contenteditable. +# +# For a test of the basic component itself see +# contenteditable-component-spec.cjsx +# +_ = require "underscore-plus" +React = require "react/addons" +ReactTestUtils = React.addons.TestUtils +ContenteditableComponent = require "../lib/contenteditable-component.cjsx", + +fdescribe "ContenteditableComponent", -> + beforeEach -> + @onChange = jasmine.createSpy('onChange') + html = 'Test HTML' + @component = ReactTestUtils.renderIntoDocument( + + ) + + html = 'Test HTML
QUOTE
' + @componentWithQuote = ReactTestUtils.renderIntoDocument( + + ) + + describe "quoted-text-control", -> + it "should be rendered", -> + expect(ReactTestUtils.findRenderedDOMComponentWithClass(@component, 'quoted-text-control')).toBeDefined() + + it "should be visible if the html contains quoted text", -> + @toggle = ReactTestUtils.findRenderedDOMComponentWithClass(@componentWithQuote, 'quoted-text-control') + expect(@toggle.props.className.indexOf('no-quoted-text') >= 0).toBe(false) + + it "should be have `show-quoted-text` if editQuotedText is true", -> + @componentWithQuote.setState(editQuotedText: true) + @toggle = ReactTestUtils.findRenderedDOMComponentWithClass(@componentWithQuote, 'quoted-text-control') + expect(@toggle.props.className.indexOf('show-quoted-text') >= 0).toBe(true) + + it "should not have `show-quoted-text` if editQuotedText is false", -> + @componentWithQuote.setState(editQuotedText: false) + @toggle = ReactTestUtils.findRenderedDOMComponentWithClass(@componentWithQuote, 'quoted-text-control') + expect(@toggle.props.className.indexOf('show-quoted-text') >= 0).toBe(false) + + it "should be hidden otherwise", -> + @toggle = ReactTestUtils.findRenderedDOMComponentWithClass(@component, 'quoted-text-control') + expect(@toggle.props.className.indexOf('no-quoted-text') >= 0).toBe(true) + + describe "when editQuotedText is false", -> + it "should only display HTML up to the beginning of the quoted text", -> + @editDiv = ReactTestUtils.findRenderedDOMComponentWithAttr(@componentWithQuote, 'contentEditable') + expect(@editDiv.getDOMNode().innerHTML.indexOf('gmail_quote') >= 0).toBe(false) + + describe "when editQuotedText is true", -> + it "should display all the HTML", -> + @componentWithQuote.setState(editQuotedText: true) + @editDiv = ReactTestUtils.findRenderedDOMComponentWithAttr(@componentWithQuote, 'contentEditable') + expect(@editDiv.getDOMNode().innerHTML.indexOf('gmail_quote') >= 0).toBe(true) + + describe "editQuotedText", -> + it "should default to false", -> + expect(@component.state.editQuotedText).toBe(false) + + describe "when the html is changed", -> + beforeEach -> + @changedHtmlWithoutQuote = 'Changed NEW 1 HTML
' + @changedHtmlWithQuote = 'Changed NEW 1 HTML
QUOTE
' + + @performEdit = (newHTML, component = @componentWithQuote) => + editDiv = ReactTestUtils.findRenderedDOMComponentWithAttr(component, 'contentEditable') + editDiv.getDOMNode().innerHTML = newHTML + ReactTestUtils.Simulate.input(editDiv, {target: {value: newHTML}}) + + describe "when editQuotedText is true", -> + it "should call `props.onChange` with the entire HTML string", -> + @componentWithQuote.setState(editQuotedText: true) + @performEdit(@changedHtmlWithQuote) + ev = @onChange.mostRecentCall.args[0] + expect(ev.target.value).toEqual(@changedHtmlWithQuote) + + it "should allow the quoted text to be changed", -> + changed = 'Test NEW 1 HTML
QUOTE CHANGED!!!
' + @componentWithQuote.setState(editQuotedText: true) + @performEdit(changed) + ev = @onChange.mostRecentCall.args[0] + expect(ev.target.value).toEqual(changed) + + describe "when editQuotedText is false", -> + it "should call `props.onChange` with the entire HTML string, even though the div being edited only contains some of it", -> + @componentWithQuote.setState(editQuotedText: false) + @performEdit(@changedHtmlWithoutQuote) + ev = @onChange.mostRecentCall.args[0] + expect(ev.target.value).toEqual(@changedHtmlWithQuote) + + it "should work if the component does not contain quoted text", -> + changed = 'Hallooo! NEW 1 HTML HTML HTML
' + @component.setState(editQuotedText: true) + @performEdit(changed, @component) + ev = @onChange.mostRecentCall.args[0] + expect(ev.target.value).toEqual(changed)