mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-03-11 15:34:27 +08:00
fix(drafts): Use the appropriate account and alias
This commit is contained in:
parent
f846447f12
commit
394d85cecf
5 changed files with 154 additions and 6 deletions
|
@ -5,7 +5,9 @@
|
|||
"$n": false,
|
||||
"waitsForPromise": false,
|
||||
"advanceClock": false,
|
||||
"TEST_ACCOUNT_ID": false
|
||||
"TEST_ACCOUNT_ID": false,
|
||||
"TEST_ACCOUNT_NAME": false,
|
||||
"TEST_ACCOUNT_ALIAS_EMAIL": false
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
|
|
|
@ -110,6 +110,7 @@ window.TEST_ACCOUNT_ID = "test-account-server-id"
|
|||
window.TEST_ACCOUNT_EMAIL = "tester@nylas.com"
|
||||
window.TEST_ACCOUNT_NAME = "Nylas Test"
|
||||
window.TEST_PLUGIN_ID = "test-plugin-id-123"
|
||||
window.TEST_ACCOUNT_ALIAS_EMAIL = "tester+alternative@nylas.com"
|
||||
|
||||
beforeEach ->
|
||||
NylasEnv.testOrganizationUnit = null
|
||||
|
@ -161,7 +162,6 @@ beforeEach ->
|
|||
spyOn(NylasEnv.menu, 'sendToBrowserProcess')
|
||||
|
||||
# Log in a fake user, and ensure that accountForId, etc. work
|
||||
AccountStore._index = 0
|
||||
AccountStore._accounts = [
|
||||
new Account({
|
||||
provider: "gmail"
|
||||
|
@ -169,7 +169,23 @@ beforeEach ->
|
|||
emailAddress: TEST_ACCOUNT_EMAIL
|
||||
organizationUnit: NylasEnv.testOrganizationUnit || 'label'
|
||||
clientId: TEST_ACCOUNT_CLIENT_ID
|
||||
serverId: TEST_ACCOUNT_ID
|
||||
serverId: TEST_ACCOUNT_ID,
|
||||
aliases: [
|
||||
"#{TEST_ACCOUNT_NAME} Alternate <#{TEST_ACCOUNT_ALIAS_EMAIL}>"
|
||||
]
|
||||
}),
|
||||
new Account({
|
||||
provider: "gmail"
|
||||
name: 'Second'
|
||||
emailAddress: 'second@gmail.com'
|
||||
organizationUnit: NylasEnv.testOrganizationUnit || 'label'
|
||||
clientId: 'second-test-account-id'
|
||||
serverId: 'second-test-account-id'
|
||||
aliases: [
|
||||
'Second Support <second@gmail.com>'
|
||||
'Second Alternate <second+alternate@gmail.com>'
|
||||
'Second <second+third@gmail.com>'
|
||||
]
|
||||
})
|
||||
]
|
||||
|
||||
|
|
|
@ -148,6 +148,57 @@ describe("DraftFactory", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("should set the accountId and from address based on the message", () => {
|
||||
waitsForPromise(() => {
|
||||
const secondAccount = AccountStore.accounts()[1];
|
||||
fakeMessage1.to = [
|
||||
new Contact({email: secondAccount.emailAddress}),
|
||||
new Contact({email: 'evan@nylas.com'}),
|
||||
]
|
||||
fakeMessage1.accountId = secondAccount.id
|
||||
fakeThread.accountId = secondAccount.id
|
||||
|
||||
return DraftFactory.createDraftForReply({thread: fakeThread, message: fakeMessage1, type: 'reply'}).then((draft) => {
|
||||
expect(draft.accountId).toEqual(secondAccount.id);
|
||||
expect(draft.from[0].email).toEqual(secondAccount.defaultMe().email);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the email is TO an alias", () => {
|
||||
it("should use the alias as the from address", () => {
|
||||
waitsForPromise(() => {
|
||||
fakeMessage1.to = [
|
||||
new Contact({email: TEST_ACCOUNT_ALIAS_EMAIL}),
|
||||
new Contact({email: 'evan@nylas.com'}),
|
||||
]
|
||||
|
||||
return DraftFactory.createDraftForReply({thread: fakeThread, message: fakeMessage1, type: 'reply'}).then((draft) => {
|
||||
expect(draft.accountId).toEqual(TEST_ACCOUNT_ID);
|
||||
expect(draft.from[0].email).toEqual(TEST_ACCOUNT_ALIAS_EMAIL);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the email is CC'd to an alias", () => {
|
||||
it("should use the alias as the from address", () => {
|
||||
waitsForPromise(() => {
|
||||
fakeMessage1.to = [
|
||||
new Contact({email: 'juan@nylas.com'}),
|
||||
]
|
||||
fakeMessage1.cc = [
|
||||
new Contact({email: TEST_ACCOUNT_ALIAS_EMAIL}),
|
||||
new Contact({email: 'evan@nylas.com'}),
|
||||
]
|
||||
|
||||
return DraftFactory.createDraftForReply({thread: fakeThread, message: fakeMessage1, type: 'reply'}).then((draft) => {
|
||||
expect(draft.accountId).toEqual(TEST_ACCOUNT_ID);
|
||||
expect(draft.from[0].email).toEqual(TEST_ACCOUNT_ALIAS_EMAIL);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
it("should sanitize the HTML", () => {
|
||||
waitsForPromise(() => {
|
||||
return DraftFactory.createDraftForReply({thread: fakeThread, message: fakeMessage1, type: 'reply'}).then(() => {
|
||||
|
@ -455,6 +506,53 @@ describe("DraftFactory", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("_fromContactForReply", () => {
|
||||
it("should work correctly in a range of test cases", () => {
|
||||
// Note: These specs are based on the second account hard-coded in SpecHelper
|
||||
account = AccountStore.accounts()[1];
|
||||
const cases = [
|
||||
{
|
||||
to: [new Contact({name: 'Ben', email: 'ben@nylas.com'})], // user is not present, must have been BCC'd
|
||||
cc: [],
|
||||
expected: account.defaultMe(),
|
||||
},
|
||||
{
|
||||
to: [new Contact({name: 'Second Support', email: 'second@gmail.com'})], // only name identifies alias
|
||||
cc: [],
|
||||
expected: new Contact({name: 'Second Support', email: 'second@gmail.com'}),
|
||||
},
|
||||
{
|
||||
to: [new Contact({name: 'Second Wrong!', email: 'second+alternate@gmail.com'})], // only email identifies alias, name wrong
|
||||
cc: [],
|
||||
expected: new Contact({name: 'Second Alternate', email: 'second+alternate@gmail.com'}),
|
||||
},
|
||||
{
|
||||
to: [new Contact({name: 'Second Alternate', email: 'second+alternate@gmail.com'})], // exact alias match
|
||||
cc: [],
|
||||
expected: new Contact({name: 'Second Alternate', email: 'second+alternate@gmail.com'}),
|
||||
},
|
||||
{
|
||||
to: [new Contact({email: 'second+third@gmail.com'})], // exact alias match, name not present
|
||||
cc: [],
|
||||
expected: new Contact({name: 'Second', email: 'second+third@gmail.com'}),
|
||||
},
|
||||
{
|
||||
to: [new Contact({email: 'ben@nylas.com'})],
|
||||
cc: [new Contact({email: 'second+third@gmail.com'})], // exact alias match, but in CC
|
||||
expected: new Contact({name: 'Second', email: 'second+third@gmail.com'}),
|
||||
},
|
||||
]
|
||||
cases.forEach(({to, cc, expected}) => {
|
||||
const contact = DraftFactory._fromContactForReply(new Message({
|
||||
accountId: account.id,
|
||||
to: to,
|
||||
cc: cc,
|
||||
}));
|
||||
expect(contact.name).toEqual(expected.name);
|
||||
expect(contact.email).toEqual(expected.email);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("_prepareBodyForQuoting", () => {
|
||||
it("should transform inline styles and sanitize unsafe html", () => {
|
||||
|
|
|
@ -55,18 +55,21 @@ describe "FocusedPerspectiveStore", ->
|
|||
expect(current).toEqual saved
|
||||
|
||||
describe "_onCategoryStoreChanged", ->
|
||||
it "should set the current category to Inbox when it is unset", ->
|
||||
it "should set the current category to unified inbox when it is unset", ->
|
||||
FocusedPerspectiveStore._perspective = null
|
||||
FocusedPerspectiveStore._onCategoryStoreChanged()
|
||||
expect(FocusedPerspectiveStore.current()).not.toBe(null)
|
||||
expect(FocusedPerspectiveStore.current().categories()).toEqual([@inboxCategory])
|
||||
|
||||
# same because the stub above returns @inboxCategory for both accounts
|
||||
expect(FocusedPerspectiveStore.current().categories()).toEqual([@inboxCategory, @inboxCategory])
|
||||
|
||||
it "should set the current category to Inbox when the current category no longer exists in the CategoryStore", ->
|
||||
otherAccountInbox = @inboxCategory.clone()
|
||||
otherAccountInbox.serverId = 'other-id'
|
||||
FocusedPerspectiveStore._perspective = MailboxPerspective.forCategory(otherAccountInbox)
|
||||
FocusedPerspectiveStore._onCategoryStoreChanged()
|
||||
expect(FocusedPerspectiveStore.current().categories()).toEqual([@inboxCategory])
|
||||
# same because the stub above returns @inboxCategory for both accounts
|
||||
expect(FocusedPerspectiveStore.current().categories()).toEqual([@inboxCategory, @inboxCategory])
|
||||
|
||||
describe "_onFocusPerspective", ->
|
||||
it "should focus the category and trigger", ->
|
||||
|
|
|
@ -106,7 +106,9 @@ class DraftFactory
|
|||
subject: subjectWithPrefix(message.subject, 'Re:')
|
||||
to: to,
|
||||
cc: cc,
|
||||
from: [@_fromContactForReply(message)],
|
||||
threadId: thread.id,
|
||||
accountId: message.accountId
|
||||
replyToMessageId: message.id,
|
||||
body: """
|
||||
<br><br><div class="gmail_quote">
|
||||
|
@ -133,7 +135,9 @@ class DraftFactory
|
|||
@createDraft(
|
||||
subject: subjectWithPrefix(message.subject, 'Fwd:')
|
||||
files: [].concat(message.files),
|
||||
from: [@_fromContactForReply(message)],
|
||||
threadId: thread.id,
|
||||
accountId: message.accountId,
|
||||
body: """
|
||||
<br><br><div class="gmail_quote">
|
||||
---------- Forwarded message ---------
|
||||
|
@ -219,6 +223,31 @@ class DraftFactory
|
|||
InlineStyleTransformer.run(body).then (body) =>
|
||||
SanitizeTransformer.run(body, SanitizeTransformer.Preset.UnsafeOnly)
|
||||
|
||||
_fromContactForReply: (message) =>
|
||||
account = AccountStore.accountForId(message.accountId)
|
||||
defaultMe = account.defaultMe()
|
||||
result = defaultMe
|
||||
|
||||
for aliasString in account.aliases
|
||||
alias = account.meUsingAlias(aliasString)
|
||||
for recipient in [].concat(message.to, message.cc)
|
||||
emailIsNotDefault = alias.email isnt defaultMe.email
|
||||
emailsMatch = recipient.email is alias.email
|
||||
nameIsNotDefault = alias.name isnt defaultMe.name
|
||||
namesMatch = recipient.name is alias.name
|
||||
|
||||
# No better match is possible
|
||||
if emailsMatch and emailIsNotDefault and namesMatch and nameIsNotDefault
|
||||
return alias
|
||||
|
||||
# A better match is possible. eg: the user may have two aliases with the same
|
||||
# email but different phrases, and we'll get an exact match on the other one.
|
||||
# Continue iterating and wait to see.
|
||||
if (emailsMatch and emailIsNotDefault) or (namesMatch and nameIsNotDefault)
|
||||
result = alias
|
||||
|
||||
return result
|
||||
|
||||
_accountForNewDraft: =>
|
||||
defAccountId = NylasEnv.config.get('core.sending.defaultAccountIdForSend')
|
||||
account = AccountStore.accountForId(defAccountId)
|
||||
|
|
Loading…
Reference in a new issue