mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-11 18:32:20 +08:00
97e9637068
Summary: - `from` participants now have their own line - `to` participants in collapsed mode merge `to`, `cc`, `bcc` as in gmail, and start in separate line from `from` - number of `to` participants in collapsed mode is limited, and also overflows with an ellipsis with css in case its too long - /some/ cleanup - Unsuccessfully tried to update the css for the message item header to convert to a flexbox. Wrapping the `from` address when the text is too long is still a TODO - Fixes #1113 Test Plan: - Manual Reviewers: bengotow, evan Reviewed By: evan Differential Revision: https://phab.nylas.com/D2507
219 lines
7.4 KiB
CoffeeScript
219 lines
7.4 KiB
CoffeeScript
proxyquire = require 'proxyquire'
|
|
React = require "react/addons"
|
|
ReactTestUtils = React.addons.TestUtils
|
|
|
|
{Contact,
|
|
Message,
|
|
File,
|
|
Thread,
|
|
Utils,
|
|
QuotedHTMLTransformer,
|
|
FileDownloadStore,
|
|
MessageBodyProcessor} = require "nylas-exports"
|
|
|
|
MessageItemBody = React.createClass({render: -> <div></div>})
|
|
|
|
{InjectedComponent} = require 'nylas-component-kit'
|
|
|
|
file = new File
|
|
id: 'file_1_id'
|
|
filename: 'a.png'
|
|
contentType: 'image/png'
|
|
size: 10
|
|
file_not_downloaded = new File
|
|
id: 'file_2_id'
|
|
filename: 'b.png'
|
|
contentType: 'image/png'
|
|
size: 10
|
|
file_inline = new File
|
|
id: 'file_inline_id'
|
|
filename: 'c.png'
|
|
contentId: 'file_inline_id'
|
|
contentType: 'image/png'
|
|
size: 10
|
|
file_inline_downloading = new File
|
|
id: 'file_inline_downloading_id'
|
|
filename: 'd.png'
|
|
contentId: 'file_inline_downloading_id'
|
|
contentType: 'image/png'
|
|
size: 10
|
|
file_inline_not_downloaded = new File
|
|
id: 'file_inline_not_downloaded_id'
|
|
filename: 'e.png'
|
|
contentId: 'file_inline_not_downloaded_id'
|
|
contentType: 'image/png'
|
|
size: 10
|
|
file_cid_but_not_referenced = new File
|
|
id: 'file_cid_but_not_referenced'
|
|
filename: 'f.png'
|
|
contentId: 'file_cid_but_not_referenced'
|
|
contentType: 'image/png'
|
|
size: 10
|
|
file_cid_but_not_referenced_or_image = new File
|
|
id: 'file_cid_but_not_referenced_or_image'
|
|
filename: 'ansible notes.txt'
|
|
contentId: 'file_cid_but_not_referenced_or_image'
|
|
contentType: 'text/plain'
|
|
size: 300
|
|
file_without_filename = new File
|
|
id: 'file_without_filename'
|
|
contentType: 'image/png'
|
|
size: 10
|
|
|
|
download =
|
|
fileId: 'file_1_id'
|
|
download_inline =
|
|
fileId: 'file_inline_downloading_id'
|
|
|
|
user_1 = new Contact
|
|
name: "User One"
|
|
email: "user1@nylas.com"
|
|
user_2 = new Contact
|
|
name: "User Two"
|
|
email: "user2@nylas.com"
|
|
user_3 = new Contact
|
|
name: "User Three"
|
|
email: "user3@nylas.com"
|
|
user_4 = new Contact
|
|
name: "User Four"
|
|
email: "user4@nylas.com"
|
|
user_5 = new Contact
|
|
name: "User Five"
|
|
email: "user5@nylas.com"
|
|
|
|
|
|
MessageItem = proxyquire '../lib/message-item',
|
|
'./message-item-body': MessageItemBody
|
|
|
|
MessageTimestamp = require '../lib/message-timestamp'
|
|
|
|
|
|
describe "MessageItem", ->
|
|
beforeEach ->
|
|
spyOn(FileDownloadStore, 'pathForFile').andCallFake (f) ->
|
|
return '/fake/path.png' if f.id is file.id
|
|
return '/fake/path-inline.png' if f.id is file_inline.id
|
|
return '/fake/path-downloading.png' if f.id is file_inline_downloading.id
|
|
return null
|
|
spyOn(FileDownloadStore, 'downloadDataForFiles').andCallFake (ids) ->
|
|
return {'file_1_id': download, 'file_inline_downloading_id': download_inline}
|
|
|
|
spyOn(MessageBodyProcessor, 'addToCache').andCallFake ->
|
|
|
|
@message = new Message
|
|
id: "111"
|
|
from: [user_1]
|
|
to: [user_2]
|
|
cc: [user_3, user_4]
|
|
bcc: null
|
|
body: "Body One"
|
|
date: new Date(1415814587)
|
|
draft: false
|
|
files: []
|
|
unread: false
|
|
snippet: "snippet one..."
|
|
subject: "Subject One"
|
|
threadId: "thread_12345"
|
|
accountId: TEST_ACCOUNT_ID
|
|
|
|
@thread = new Thread
|
|
id: 'thread-111'
|
|
accountId: TEST_ACCOUNT_ID
|
|
|
|
@threadParticipants = [user_1, user_2, user_3, user_4]
|
|
|
|
# Generate the test component. Should be called after @message is configured
|
|
# for the test, since MessageItem assumes attributes of the message will not
|
|
# change after getInitialState runs.
|
|
@createComponent = ({collapsed} = {}) =>
|
|
collapsed ?= false
|
|
@component = ReactTestUtils.renderIntoDocument(
|
|
<MessageItem key={@message.id}
|
|
message={@message}
|
|
thread={@thread}
|
|
collapsed={collapsed} />
|
|
)
|
|
|
|
# TODO: We currently don't support collapsed messages
|
|
# describe "when collapsed", ->
|
|
# beforeEach ->
|
|
# @createComponent({collapsed: true})
|
|
#
|
|
# it "should not render the EmailFrame", ->
|
|
# expect( -> ReactTestUtils.findRenderedComponentWithType(@component, EmailFrameStub)).toThrow()
|
|
#
|
|
# it "should have the `collapsed` class", ->
|
|
# expect(React.findDOMNode(@component).className.indexOf('collapsed') >= 0).toBe(true)
|
|
|
|
describe "when displaying detailed headers", ->
|
|
beforeEach ->
|
|
@createComponent({collapsed: false})
|
|
@component.setState detailedHeaders: true
|
|
|
|
it "correctly sets the participant states", ->
|
|
participants = ReactTestUtils.scryRenderedDOMComponentsWithClass(@component, "expanded-participants")
|
|
expect(participants.length).toBe 2
|
|
expect(-> ReactTestUtils.findRenderedDOMComponentWithClass(@component, "collapsed-participants")).toThrow()
|
|
|
|
it "correctly sets the timestamp", ->
|
|
ts = ReactTestUtils.findRenderedComponentWithType(@component, MessageTimestamp)
|
|
expect(ts.props.isDetailed).toBe true
|
|
|
|
describe "when not collapsed", ->
|
|
beforeEach ->
|
|
@createComponent({collapsed: false})
|
|
|
|
it "should render the MessageItemBody", ->
|
|
frame = ReactTestUtils.findRenderedComponentWithType(@component, MessageItemBody)
|
|
expect(frame).toBeDefined()
|
|
|
|
it "should not have the `collapsed` class", ->
|
|
expect(React.findDOMNode(@component).className.indexOf('collapsed') >= 0).toBe(false)
|
|
|
|
describe "when the message contains attachments", ->
|
|
beforeEach ->
|
|
@message.files = [
|
|
file,
|
|
file_not_downloaded,
|
|
file_cid_but_not_referenced,
|
|
file_cid_but_not_referenced_or_image,
|
|
|
|
file_inline,
|
|
file_inline_downloading,
|
|
file_inline_not_downloaded,
|
|
file_without_filename
|
|
]
|
|
@message.body = """
|
|
<img alt=\"A\" src=\"cid:#{file_inline.contentId}\"/>
|
|
<img alt=\"B\" src=\"cid:#{file_inline_downloading.contentId}\"/>
|
|
<img alt=\"C\" src=\"cid:#{file_inline_not_downloaded.contentId}\"/>
|
|
<img src=\"cid:missing-attachment\"/>
|
|
"""
|
|
@createComponent()
|
|
|
|
it "should include the attachments area", ->
|
|
attachments = ReactTestUtils.findRenderedDOMComponentWithClass(@component, 'attachments-area')
|
|
expect(attachments).toBeDefined()
|
|
|
|
it "should render the registered an injected component for each attachment", ->
|
|
attachments = ReactTestUtils.scryRenderedComponentsWithTypeAndProps(@component, InjectedComponent, matching: {role: 'Attachment'})
|
|
expect(attachments[0].props.exposedProps.file).toBe(file)
|
|
|
|
it "should list attachments that are not mentioned in the body via cid", ->
|
|
attachments = ReactTestUtils.scryRenderedComponentsWithTypeAndProps(@component, InjectedComponent, matching: {role: 'Attachment'})
|
|
expect(attachments.length).toEqual(5)
|
|
expect(attachments[0].props.exposedProps.file).toBe(file)
|
|
expect(attachments[1].props.exposedProps.file).toBe(file_not_downloaded)
|
|
expect(attachments[2].props.exposedProps.file).toBe(file_cid_but_not_referenced)
|
|
expect(attachments[3].props.exposedProps.file).toBe(file_cid_but_not_referenced_or_image)
|
|
|
|
it "should provide file download state to each InjectedComponent", ->
|
|
attachments = ReactTestUtils.scryRenderedComponentsWithTypeAndProps(@component, InjectedComponent, matching: {role: 'Attachment'})
|
|
expect(attachments[0].props.exposedProps.download).toBe(download)
|
|
expect(attachments[1].props.exposedProps.download).toBe(undefined)
|
|
|
|
it "should still list attachments when the message has no body", ->
|
|
@message.body = ""
|
|
@createComponent()
|
|
attachments = ReactTestUtils.scryRenderedComponentsWithTypeAndProps(@component, InjectedComponent, matching: {role: 'Attachment'})
|
|
expect(attachments.length).toEqual(8)
|