fix(thread-list-participants): Add a new failing test case + fix to the thread list participants

I had to make this less functional so that the token generation function could modify data in the output as it was created. Bust :(
This commit is contained in:
Ben Gotow 2015-09-22 18:56:15 -07:00
parent 7b391ec4f0
commit ff2b225d91
3 changed files with 66 additions and 57 deletions

View file

@ -1,6 +1,6 @@
_ = require 'underscore' _ = require 'underscore'
React = require "react" React = require "react"
{MailViewFilter, ComponentRegistry, WorkspaceStore} = require "nylas-exports" {ComponentRegistry, WorkspaceStore} = require "nylas-exports"
{DownButton, UpButton, ThreadBulkArchiveButton, ThreadBulkStarButton, ThreadBulkToggleUnreadButton} = require "./thread-buttons" {DownButton, UpButton, ThreadBulkArchiveButton, ThreadBulkStarButton, ThreadBulkToggleUnreadButton} = require "./thread-buttons"
{DraftDeleteButton} = require "./draft-buttons" {DraftDeleteButton} = require "./draft-buttons"

View file

@ -1,4 +1,5 @@
React = require 'react' React = require 'react'
{Utils} = require 'nylas-exports'
_ = require 'underscore' _ = require 'underscore'
class ThreadListParticipants extends React.Component class ThreadListParticipants extends React.Component
@ -12,12 +13,12 @@ class ThreadListParticipants extends React.Component
true true
render: => render: =>
items = @getParticipants() items = @getTokens()
<div className="participants"> <div className="participants">
{@getSpans(items)} {@renderSpans(items)}
</div> </div>
getSpans: (items) => renderSpans: (items) =>
spans = [] spans = []
accumulated = null accumulated = null
accumulatedUnread = false accumulatedUnread = false
@ -59,50 +60,47 @@ class ThreadListParticipants extends React.Component
return spans return spans
getParticipants: => getTokensFromMetadata: =>
makeMetadataFilterer = (toOrFrom) -> messages = @props.thread.metadata
(msg, i, msgs) -> tokens = []
isFirstMsg = i is 0
if msg.draft field = 'from'
false if (messages.every (message) -> message.isFromMe())
else if isFirstMsg field = 'to'
true
else # check adjacent email uniqueness for message, idx in messages
last = msgs[i - 1][toOrFrom][0] if message.draft
curr = msgs[i][toOrFrom][0] continue
if last and curr
isUniqueEmail = last.email.toLowerCase() isnt curr.email.toLowerCase() for contact in message[field]
isUniqueName = last.name isnt curr.name if tokens.length is 0
isUniqueEmail or isUniqueName tokens.push({ contact: contact, unread: message.unread })
else else
return false lastToken = tokens[tokens.length - 1]
lastContact = lastToken.contact
makeMetadataMapper = (toOrFrom) -> sameEmail = Utils.emailIsEquivalent(lastContact.email, contact.email)
(msg) -> sameName = lastContact.name is contact.name
msg[toOrFrom].map (contact) -> if sameEmail and sameName
{ contact: contact, unread: msg.unread } lastToken.unread ||= message.unread
if @props.thread.metadata
shouldOnlyShowRecipients = @props.thread.metadata.every (msg) ->
msg.from[0]?.isMe()
input = @props.thread.metadata
toOrFrom = if shouldOnlyShowRecipients then "to" else "from"
filterer = makeMetadataFilterer toOrFrom
mapper = makeMetadataMapper toOrFrom
else else
input = @props.thread.participants tokens.push({ contact: contact, unread: message.unread })
return [] unless input and input instanceof Array
filterer = (contact) -> not contact.isMe()
mapper = (contact) -> { contact: contact, unread: false }
list = _.chain(input) tokens
.filter(filterer)
.map(mapper) getTokensFromParticipants: =>
.reduce(((prevContacts, next) -> prevContacts.concat(next)), []) contacts = @props.thread.participants ? []
.value() contacts = contacts.filter (contact) -> not contact.isMe()
contacts.map (contact) -> { contact: contact, unread: false }
getTokens: =>
if @props.thread.metadata instanceof Array
list = @getTokensFromMetadata()
else
list = @getTokensFromParticipants()
# If no participants, we should at least add current user as sole participant # If no participants, we should at least add current user as sole participant
if list.length is 0 and @props.thread.participants.length > 0 if list.length is 0 and @props.thread.participants?.length > 0
list.push({ contact: @props.thread.participants[0], unread: false }) list.push({ contact: @props.thread.participants[0], unread: false })
# We only ever want to show three. Ben...Kevin... Marty # We only ever want to show three. Ben...Kevin... Marty

View file

@ -25,7 +25,7 @@ describe "ThreadListParticipants", ->
unread = ReactTestUtils.scryRenderedDOMComponentsWithClass(@participants, 'unread-true') unread = ReactTestUtils.scryRenderedDOMComponentsWithClass(@participants, 'unread-true')
expect(unread.length).toBe(1) expect(unread.length).toBe(1)
describe "getParticipants", -> describe "getTokens", ->
beforeEach -> beforeEach ->
@ben = new Contact(email: 'ben@nylas.com', name: 'ben') @ben = new Contact(email: 'ben@nylas.com', name: 'ben')
@evan = new Contact(email: 'evan@nylas.com', name: 'evan') @evan = new Contact(email: 'evan@nylas.com', name: 'evan')
@ -105,6 +105,17 @@ describe "ThreadListParticipants", ->
{spacer: true}, {spacer: true},
{contact: @michael, unread: true}, {contact: @michael, unread: true},
{contact: @kavya, unread: true}] {contact: @kavya, unread: true}]
},{
name: 'ends with two emails from the same person, second one is unread'
in: [
new Message(unread: false, from: [@ben]),
new Message(unread: false, from: [@evan]),
new Message(unread: false, from: [@kavya]),
new Message(unread: true, from: [@kavya]),
]
out: [{contact: @ben, unread: false},
{contact: @evan, unread: false},
{contact: @kavya, unread: true}]
},{ },{
name: 'three unread responses to long thread' name: 'three unread responses to long thread'
in: [ in: [
@ -162,13 +173,13 @@ describe "ThreadListParticipants", ->
<ThreadListParticipants thread={thread}/> <ThreadListParticipants thread={thread}/>
) )
expect(participants.getParticipants()).toEqual(scenario.out) expect(participants.getTokens()).toEqual(scenario.out)
# Slightly misuse jasmine to get the output we want to show # Slightly misuse jasmine to get the output we want to show
if (!_.isEqual(participants.getParticipants(), scenario.out)) if (!_.isEqual(participants.getTokens(), scenario.out))
expect(scenario.name).toBe('correct') expect(scenario.name).toBe('correct')
describe "when getParticipants() called and current user is only sender", -> describe "when getTokens() called and current user is only sender", ->
beforeEach -> beforeEach ->
@me = AccountStore.current().me() @me = AccountStore.current().me()
@ben = new Contact(email: 'ben@nylas.com', name: 'ben') @ben = new Contact(email: 'ben@nylas.com', name: 'ben')
@ -177,19 +188,19 @@ describe "ThreadListParticipants", ->
@michael = new Contact(email: 'michael@nylas.com', name: 'michael') @michael = new Contact(email: 'michael@nylas.com', name: 'michael')
@kavya = new Contact(email: 'kavya@nylas.com', name: 'kavya') @kavya = new Contact(email: 'kavya@nylas.com', name: 'kavya')
getParticipants = (threadMetadata) -> getTokens = (threadMetadata) ->
thread = new Thread() thread = new Thread()
thread.metadata = threadMetadata thread.metadata = threadMetadata
participants = ReactTestUtils.renderIntoDocument( participants = ReactTestUtils.renderIntoDocument(
<ThreadListParticipants thread={thread}/> <ThreadListParticipants thread={thread}/>
) )
participants.getParticipants() participants.getTokens()
it "shows only recipients for emails sent from me to different recipients", -> it "shows only recipients for emails sent from me to different recipients", ->
input = [new Message(unread: false, from: [@me], to: [@ben]) input = [new Message(unread: false, from: [@me], to: [@ben])
new Message(unread: false, from: [@me], to: [@evan]) new Message(unread: false, from: [@me], to: [@evan])
new Message(unread: false, from: [@me], to: [@ben])] new Message(unread: false, from: [@me], to: [@ben])]
actualOut = getParticipants input actualOut = getTokens(input)
expectedOut = [{contact: @ben, unread: false} expectedOut = [{contact: @ben, unread: false}
{contact: @evan, unread: false} {contact: @evan, unread: false}
{contact: @ben, unread: false}] {contact: @ben, unread: false}]
@ -198,7 +209,7 @@ describe "ThreadListParticipants", ->
it "is case insensitive", -> it "is case insensitive", ->
input = [new Message(unread: false, from: [@me], to: [@evan]) input = [new Message(unread: false, from: [@me], to: [@evan])
new Message(unread: false, from: [@me], to: [@evanCapitalized])] new Message(unread: false, from: [@me], to: [@evanCapitalized])]
actualOut = getParticipants input actualOut = getTokens(input)
expectedOut = [{contact: @evan, unread: false}] expectedOut = [{contact: @evan, unread: false}]
expect(actualOut).toEqual expectedOut expect(actualOut).toEqual expectedOut
@ -207,7 +218,7 @@ describe "ThreadListParticipants", ->
new Message(unread: false, from: [@me], to: [@evan]) new Message(unread: false, from: [@me], to: [@evan])
new Message(unread: false, from: [@me], to: [@michael]) new Message(unread: false, from: [@me], to: [@michael])
new Message(unread: false, from: [@me], to: [@kavya])] new Message(unread: false, from: [@me], to: [@kavya])]
actualOut = getParticipants input actualOut = getTokens(input)
expectedOut = [{contact: @ben, unread: false} expectedOut = [{contact: @ben, unread: false}
{spacer: true} {spacer: true}
{contact: @michael, unread: false} {contact: @michael, unread: false}
@ -216,7 +227,7 @@ describe "ThreadListParticipants", ->
it "shows correct recipients even if only one email", -> it "shows correct recipients even if only one email", ->
input = [new Message(unread: false, from: [@me], to: [@ben, @evan, @michael, @kavya])] input = [new Message(unread: false, from: [@me], to: [@ben, @evan, @michael, @kavya])]
actualOut = getParticipants input actualOut = getTokens(input)
expectedOut = [{contact: @ben, unread: false} expectedOut = [{contact: @ben, unread: false}
{spacer: true} {spacer: true}
{contact: @michael, unread: false} {contact: @michael, unread: false}
@ -228,13 +239,13 @@ describe "ThreadListParticipants", ->
new Message(unread: false, from: [@me], to: [@evan]) new Message(unread: false, from: [@me], to: [@evan])
new Message(unread: false, from: [@me], to: [@evan]) new Message(unread: false, from: [@me], to: [@evan])
new Message(unread: false, from: [@me], to: [@evan])] new Message(unread: false, from: [@me], to: [@evan])]
actualOut = getParticipants input actualOut = getTokens(input)
expectedOut = [{contact: @evan, unread: false}] expectedOut = [{contact: @evan, unread: false}]
expect(actualOut).toEqual expectedOut expect(actualOut).toEqual expectedOut
it "shows only the recipient for one sent email", -> it "shows only the recipient for one sent email", ->
input = [new Message(unread: false, from: [@me], to: [@evan])] input = [new Message(unread: false, from: [@me], to: [@evan])]
actualOut = getParticipants input actualOut = getTokens(input)
expectedOut = [{contact: @evan, unread: false}] expectedOut = [{contact: @evan, unread: false}]
expect(actualOut).toEqual expectedOut expect(actualOut).toEqual expectedOut
@ -243,7 +254,7 @@ describe "ThreadListParticipants", ->
new Message(unread: false, from: [@me], to: [@ben]) new Message(unread: false, from: [@me], to: [@ben])
new Message(unread: true, from: [@me], to: [@kavya]) new Message(unread: true, from: [@me], to: [@kavya])
new Message(unread: true, from: [@me], to: [@michael])] new Message(unread: true, from: [@me], to: [@michael])]
actualOut = getParticipants input actualOut = getTokens(input)
expectedOut = [{contact: @evan, unread: false}, expectedOut = [{contact: @evan, unread: false},
{spacer: true}, {spacer: true},
{contact: @kavya, unread: true}, {contact: @kavya, unread: true},
@ -285,8 +296,8 @@ describe "ThreadListParticipants", ->
<ThreadListParticipants thread={thread}/> <ThreadListParticipants thread={thread}/>
) )
expect(participants.getParticipants()).toEqual(scenario.out) expect(participants.getTokens()).toEqual(scenario.out)
# Slightly misuse jasmine to get the output we want to show # Slightly misuse jasmine to get the output we want to show
if (!_.isEqual(participants.getParticipants(), scenario.out)) if (!_.isEqual(participants.getTokens(), scenario.out))
expect(scenario.name).toBe('correct') expect(scenario.name).toBe('correct')