add more test coverage and refactor checking if a contact is the current user. fixes T3360.

Summary: @evan -- would love to get your opinion on this approach!

Test Plan: add new tests

Reviewers: evan

Reviewed By: evan

Subscribers: evan

Maniphest Tasks: T3360

Differential Revision: https://phab.nylas.com/D1904
This commit is contained in:
dillon 2015-08-18 10:18:30 -07:00
parent 920e7575fa
commit 07996da960
8 changed files with 63 additions and 20 deletions

View file

@ -2,8 +2,6 @@ React = require "react"
_ = require "underscore"
ContactChip = require './ContactChip'
{NamespaceStore} = require "nylas-exports"
# Parameters
# clickable (optional) - is this currently clickable?
# thread (optional) - thread context for sorting
@ -25,12 +23,11 @@ class Participants extends React.Component
</span>
getParticipants: =>
myEmail = NamespaceStore.current().emailAddress
list = @props.participants
# Remove 'Me' if there is more than one participant
if list.length > 1
list = _.reject list, (p) -> p.email is myEmail
list = _.reject list, (contact) -> contact.isMe()
list.forEach (p) ->
p.id = p.name+p.email

View file

@ -24,8 +24,7 @@ class ThreadListIcon extends React.Component
msgs = @_nonDraftMessages()
last = msgs[msgs.length - 1]
myEmail = NamespaceStore.current()?.emailAddress
if msgs.length > 1 and last.from[0]?.email is myEmail
if msgs.length > 1 and last.from[0].isMe()
if Utils.isForwardedMessage(last)
return 'thread-icon-forwarded'
else

View file

@ -1,6 +1,5 @@
React = require 'react'
_ = require 'underscore'
{NamespaceStore} = require 'nylas-exports'
class ThreadListParticipants extends React.Component
@displayName: 'ThreadListParticipants'
@ -69,7 +68,7 @@ class ThreadListParticipants extends React.Component
else # check adjacent email uniqueness
last = msgs[i - 1][toOrFrom][0]
curr = msgs[i][toOrFrom][0]
isUniqueEmail = last.email isnt curr.email
isUniqueEmail = last.email.toLowerCase() isnt curr.email.toLowerCase()
isUniqueName = last.name isnt curr.name
isUniqueEmail or isUniqueName
@ -80,8 +79,7 @@ class ThreadListParticipants extends React.Component
if @props.thread.metadata
shouldOnlyShowRecipients = @props.thread.metadata.every (msg) ->
sender = msg.from[0]
sender.email is NamespaceStore.current().emailAddress
msg.from[0]?.isMe()
input = @props.thread.metadata
toOrFrom = if shouldOnlyShowRecipients then "to" else "from"
filterer = makeMetadataFilterer toOrFrom
@ -89,8 +87,7 @@ class ThreadListParticipants extends React.Component
else
input = @props.thread.participants
return [] unless input and input instanceof Array
currentUserEmail = NamespaceStore.current().emailAddress
filterer = (msg) -> msg.email isnt currentUserEmail
filterer = (contact) -> not contact.isMe()
mapper = (contact) -> { contact: contact, unread: false }
list = _.chain(input)

View file

@ -173,6 +173,7 @@ describe "ThreadListParticipants", ->
@me = NamespaceStore.current().me()
@ben = new Contact(email: 'ben@nylas.com', name: 'ben')
@evan = new Contact(email: 'evan@nylas.com', name: 'evan')
@evanCapitalized = new Contact(email: 'EVAN@nylas.com', name: 'evan')
@michael = new Contact(email: 'michael@nylas.com', name: 'michael')
@kavya = new Contact(email: 'kavya@nylas.com', name: 'kavya')
@ -194,6 +195,13 @@ describe "ThreadListParticipants", ->
{contact: @ben, unread: false}]
expect(actualOut).toEqual expectedOut
it "is case insensitive", ->
input = [new Message(unread: false, from: [@me], to: [@evan])
new Message(unread: false, from: [@me], to: [@evanCapitalized])]
actualOut = getParticipants input
expectedOut = [{contact: @evan, unread: false}]
expect(actualOut).toEqual expectedOut
it "shows only first, spacer, second to last, and last recipients if recipients count > 3", ->
input = [new Message(unread: false, from: [@me], to: [@ben])
new Message(unread: false, from: [@me], to: [@evan])
@ -215,6 +223,33 @@ describe "ThreadListParticipants", ->
{contact: @kavya, unread: false}]
expect(actualOut).toEqual expectedOut
it "shows only one recipient if the sender only sent to one recipient", ->
input = [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
expectedOut = [{contact: @evan, unread: false}]
expect(actualOut).toEqual expectedOut
it "shows only the recipient for one sent email", ->
input = [new Message(unread: false, from: [@me], to: [@evan])]
actualOut = getParticipants input
expectedOut = [{contact: @evan, unread: false}]
expect(actualOut).toEqual expectedOut
it "shows unread email as well", ->
input = [new Message(unread: false, from: [@me], to: [@evan])
new Message(unread: false, from: [@me], to: [@ben])
new Message(unread: true, from: [@me], to: [@kavya])
new Message(unread: true, from: [@me], to: [@michael])]
actualOut = getParticipants input
expectedOut = [{contact: @evan, unread: false},
{spacer: true},
{contact: @kavya, unread: true},
{contact: @michael, unread: true}]
expect(actualOut).toEqual expectedOut
describe "when thread.messages is not available", ->
it "correctly produces items for display in a wide range of scenarios", ->
me = NamespaceStore.current().me()

View file

@ -2,8 +2,7 @@ _ = require 'underscore'
{Thread,
Actions,
CategoryStore,
DatabaseStore,
NamespaceStore} = require 'nylas-exports'
DatabaseStore} = require 'nylas-exports'
module.exports =
@ -63,11 +62,10 @@ module.exports =
incomingThreads = incoming['thread'] ? []
# Filter for new messages that are not sent by the current user
myEmail = NamespaceStore.current().emailAddress
newUnread = _.filter incomingMessages, (msg) =>
isUnread = msg.unread is true
isNew = msg.date?.valueOf() >= @activationTime
isFromMe = msg.from[0]?.email is myEmail
isFromMe = msg.isFromMe()
return isUnread and isNew and not isFromMe
return resolve() if newUnread.length is 0

View file

@ -81,3 +81,14 @@ describe "Contact", ->
expect(c1.displayName()).toBe "You"
expect(c1.displayFirstName()).toBe "You"
expect(c1.displayLastName()).toBe ""
describe "isMe", ->
it "returns true if the contact name matches the namespace email address", ->
c1 = new Contact {email: NamespaceStore.current().emailAddress}
expect(c1.isMe()).toBe(true)
c1 = new Contact {email: 'ben@nylas.com'}
expect(c1.isMe()).toBe(false)
it "is case insensitive", ->
c1 = new Contact {email: NamespaceStore.current().emailAddress.toUpperCase()}
expect(c1.isMe()).toBe(true)

View file

@ -71,20 +71,26 @@ class Contact extends Model
json['name'] ||= json['email']
json
# Public: Returns true if the contact is the current user, false otherwise.
# You should use this method instead of comparing the user's email address to
# the namespace email, since it is case-insensitive and future-proof.
isMe: ->
@email.toLowerCase() is NamespaceStore.current()?.emailAddress.toLowerCase()
# Returns a {String} display name.
# - "You" if the contact is the current user
# - `name` if the contact has a populated name value
# - `email` in all other cases.
displayName: ->
return "You" if @email is NamespaceStore.current()?.emailAddress
return "You" if @isMe()
@_nameParts().join(' ')
displayFirstName: ->
return "You" if @email is NamespaceStore.current()?.emailAddress
return "You" if @isMe()
@firstName()
displayLastName: ->
return "" if @email is NamespaceStore.current()?.emailAddress
return "" if @isMe()
@lastName()
firstName: ->

View file

@ -256,7 +256,7 @@ class Message extends Model
# address. In the future, this method will take into account all of the
# user's email addresses and namespaces.
isFromMe: ->
@from[0].email is NamespaceStore.current().emailAddress
@from[0]?.isMe()
# Public: Returns a plaintext version of the message body using Chromium's
# DOMParser. Use with care.