Mailspring/packages/client-app/spec/components/clipboard-service-spec.coffee

126 lines
4.5 KiB
CoffeeScript

ClipboardService = require('../../src/components/contenteditable/clipboard-service').default
{InlineStyleTransformer, SanitizeTransformer} = require 'nylas-exports'
fs = require 'fs'
describe "ClipboardService", ->
beforeEach ->
@onFilePaste = jasmine.createSpy('onFilePaste')
@setInnerState = jasmine.createSpy('setInnerState')
@clipboardService = new ClipboardService
data: {props: {@onFilePaste}}
methods: {@setInnerState}
spyOn(document, 'execCommand')
describe "when both html and plain text parts are present", ->
beforeEach ->
@mockEvent =
preventDefault: jasmine.createSpy('preventDefault')
clipboardData:
getData: (mimetype) ->
return '<strong>This is text</strong>' if mimetype is 'text/html'
return 'This is plain text' if mimetype is 'text/plain'
return null
items: [{
kind: 'string'
type: 'text/html'
getAsString: -> '<strong>This is text</strong>'
},{
kind: 'string'
type: 'text/plain'
getAsString: -> 'This is plain text'
}]
it "should choose to insert the HTML representation", ->
spyOn(@clipboardService, '_sanitizeHTMLInput').andCallFake (input) =>
Promise.resolve(input)
runs ->
@clipboardService.onPaste(@mockEvent)
waitsFor ->
document.execCommand.callCount > 0
runs ->
[command, a, html] = document.execCommand.mostRecentCall.args
expect(command).toEqual('insertHTML')
expect(html).toEqual('<strong>This is text</strong>')
describe "when only plain text is present", ->
beforeEach ->
@mockEvent =
preventDefault: jasmine.createSpy('preventDefault')
clipboardData:
getData: (mimetype) ->
return 'This is plain text\nAnother line Hello World' if mimetype is 'text/plain'
return null
items: [{
kind: 'string'
type: 'text/plain'
getAsString: -> 'This is plain text\nAnother line Hello World'
}]
it "should convert the plain text to HTML and call insertHTML", ->
runs ->
@clipboardService.onPaste(@mockEvent)
waitsFor ->
document.execCommand.callCount > 0
runs ->
[command, a, html] = document.execCommand.mostRecentCall.args
expect(command).toEqual('insertHTML')
expect(html).toEqual('This is plain text<br/>Another line &nbsp;Hello &nbsp;World')
describe "HTML sanitization", ->
beforeEach ->
spyOn(InlineStyleTransformer, 'run').andCallThrough()
spyOn(SanitizeTransformer, 'run').andCallThrough()
it "should inline CSS styles and run the standard permissive HTML sanitizer", ->
input = "HTML HERE"
waitsForPromise =>
@clipboardService._sanitizeHTMLInput(input)
.then =>
expect(InlineStyleTransformer.run).toHaveBeenCalledWith(input)
expect(SanitizeTransformer.run).toHaveBeenCalledWith(input, SanitizeTransformer.Preset.Permissive)
it "should replace two or more <br/>s in a row", ->
tests = [{
in: "Hello\n\n\nWorld"
out: "Hello<br/><br/>World"
},{
in: "Hello<br/><br/><br/><br/>World"
out: "Hello<br/><br/>World"
}]
for test in tests
waitsForPromise =>
@clipboardService._sanitizeHTMLInput(test.in).then (out) ->
expect(out).toBe(test.out)
it "should remove all leading and trailing <br/>s from the text", ->
tests = [{
in: "<br/><br/>Hello<br/>World"
out: "Hello<br/>World"
},{
in: "<br/><br/>Hello<br/><br/><br/><br/>"
out: "Hello"
}]
for test in tests
waitsForPromise =>
@clipboardService._sanitizeHTMLInput(test.in).then (out) ->
expect(out).toBe(test.out)
# Unfortunately, it doesn't seem we can do real IPC (to `juice` in the main process)
# so these tests are non-functional.
xdescribe "real-world examples", ->
it "should produce the correct output", ->
scenarios = []
fixtures = path.resolve('./spec/fixtures/paste')
for filename in fs.readdirSync(fixtures)
if filename[-8..-1] is '-in.html'
scenarios.push
in: fs.readFileSync(path.join(fixtures, filename)).toString()
out: fs.readFileSync(path.join(fixtures, "#{filename[0..-9]}-out.html")).toString()
scenarios.forEach (scenario) =>
@clipboardService._sanitizeHTMLInput(scenario.in).then (out) ->
expect(out).toBe(scenario.out)