# 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 ContenteditableComponent = require "../lib/contenteditable-component", describe "ContenteditableComponent", -> beforeEach -> @onChange = jasmine.createSpy('onChange') html = 'Test HTML' @component = ReactTestUtils.renderIntoDocument( ) @editableNode = React.findDOMNode(ReactTestUtils.findRenderedDOMComponentWithAttr(@component, 'contentEditable')) describe "render", -> it 'should render into the document', -> expect(ReactTestUtils.isCompositeComponentWithType @component, ContenteditableComponent).toBe true it "should include a content-editable div", -> expect(@editableNode).toBeDefined() describe "when the html is changed", -> beforeEach -> @changedHtmlWithoutQuote = 'Changed NEW 1 HTML
' @performEdit = (newHTML, component = @component) => @editableNode.innerHTML = newHTML ReactTestUtils.Simulate.input(@editableNode, {target: {value: newHTML}}) it "should fire `props.onChange`", -> @performEdit('Test New HTML') expect(@onChange).toHaveBeenCalled() # One day we may make this more efficient. For now we aggressively # re-render because of the manual cursor positioning. it "should fire if the html is the same", -> expect(@onChange.callCount).toBe(0) @performEdit(@changedHtmlWithoutQuote) expect(@onChange.callCount).toBe(1) @performEdit(@changedHtmlWithoutQuote) expect(@onChange.callCount).toBe(2) describe "pasting behavior", -> tests = [ { in: "" sanitizedAsHTML: "" sanitizedAsPlain: "" }, { in: "Hello World" sanitizedAsHTML: "Hello World" sanitizedAsPlain: "Hello World" }, { in: " Hello World" # Should collapse to 1 space when rendered sanitizedAsHTML: " Hello World" # Preserving 2 spaces sanitizedAsPlain: "  Hello  World" }, { in: " Hello World" sanitizedAsHTML: " Hello World" # Preserving 3 spaces sanitizedAsPlain: "   Hello   World" }, { in: " Hello World" sanitizedAsHTML: " Hello World" # Preserving 4 spaces sanitizedAsPlain: "    Hello    World" }, { in: "Hello\nWorld" sanitizedAsHTML: "Hello
World" # Convert newline to br sanitizedAsPlain: "Hello
World" }, { in: "Hello\rWorld" sanitizedAsHTML: "Hello
World" # Convert carriage return to br sanitizedAsPlain: "Hello
World" }, { in: "Hello\n\n\nWorld" # Never have more than 2 br's in a row sanitizedAsHTML: "Hello

World" # Convert multiple newlines to same number of brs sanitizedAsPlain: "Hello


World" }, { in: " Foo Bar
Baz
" # Strip bad tags sanitizedAsHTML: " Foo Bar Baz
" # HTML encode tags for literal display sanitizedAsPlain: "<style>Yo</style> Foo Bar <div>Baz</div>" } { in: " Yo < script>Boo! < / script >" # Strip non white-list tags and encode malformed ones. sanitizedAsHTML: " Yo < script>Boo! < / script >" # HTML encode tags for literal display sanitizedAsPlain: "<script>Bah</script> Yo < script>Boo! < / script >" } ] it "sanitizes plain text properly", -> for test in tests expect(@component._sanitizeInput(test.in, "text/plain")).toBe test.sanitizedAsPlain it "sanitizes html text properly", -> for test in tests expect(@component._sanitizeInput(test.in, "text/html")).toBe test.sanitizedAsHTML