mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-01-31 04:19:15 +08:00
149b389508
* Switch to using Typescript instead of Babel * Switch all es6 / jsx file extensions to ts / tsx * Convert Utils to a TS module from module.exports style module * Move everything from module.exports to typescript exports * Define .d.ts files for mailspring-exports and component kit… Yes it seems this is the best option :( * Load up on those @types * Synthesize TS types from PropTypes for standard components * Add types to Model classes and move constructor constants to instance vars * 9800 => 7700 TS errors * 7700 => 5600 TS errors * 5600 => 5330 TS errors * 5330 => 4866 TS errors * 4866 => 4426 TS errors * 4426 => 2411 TS errors * 2411 > 1598 TS errors * 1598 > 769 TS errors * 769 > 129 TS errors * 129 > 22 TS errors * Fix runtime errors * More runtime error fixes * Remove support for custom .es6 file extension * Remove a few odd remaining references to Nylas * Don’t ship Typescript support in the compiled app for now * Fix issues in compiled app - module resolution in TS is case sensitive? * README updates * Fix a few more TS errors * Make “No Signature” option clickable + selectable * Remove flicker when saving file and reloading keymaps * Fix mail rule item height in preferences * Fix missing spacing in thread sharing popover * Fix scrollbar ticks being nested incorrectly * Add Japanese as a manually reviewed language * Prevent the thread list from “sticking” * Re-use Sheet when switching root tabs, prevent sidebar from resetting * Ensure specs run * Update package configuration to avoid shpping types * Turn eslint back on - we will opt-in to the TS rules one by one
491 lines
11 KiB
TypeScript
491 lines
11 KiB
TypeScript
import * as Utils from '../../src/flux/models/utils';
|
|
import { Message } from '../../src/flux/models/message';
|
|
import { Contact } from '../../src/flux/models/contact';
|
|
|
|
const evan = new Contact({
|
|
name: 'Evan Morikawa',
|
|
email: 'evan@mailspring.com',
|
|
});
|
|
const ben = new Contact({
|
|
name: 'Ben Gotow',
|
|
email: 'ben@mailspring.com',
|
|
});
|
|
const team = new Contact({
|
|
name: 'Mailspring Team',
|
|
email: 'team@mailspring.com',
|
|
});
|
|
const edgehill = new Contact({
|
|
name: 'Edgehill',
|
|
email: 'edgehill@mailspring.com',
|
|
});
|
|
const noEmail = new Contact({
|
|
name: 'Edgehill',
|
|
email: null,
|
|
});
|
|
const me = new Contact({
|
|
name: TEST_ACCOUNT_NAME,
|
|
email: TEST_ACCOUNT_EMAIL,
|
|
});
|
|
const almost_me = new Contact({
|
|
name: TEST_ACCOUNT_NAME,
|
|
email: 'tester+12345@mailspring.com',
|
|
});
|
|
|
|
describe('Message', function() {
|
|
describe('detecting empty bodies', function() {
|
|
const cases = [
|
|
{
|
|
itMsg: "has plain br's and a signature",
|
|
body: `\
|
|
<div class="contenteditable no-open-link-events" contenteditable="true" spellcheck="false"><br><br><signature>Sent from <a href="https://getmailspring.com/?ref=client">Mailspring</a>, the extensible, open source mail client.</signature></div>\
|
|
`,
|
|
isEmpty: true,
|
|
},
|
|
{
|
|
itMsg: 'is an empty string',
|
|
body: '',
|
|
isEmpty: true,
|
|
},
|
|
{
|
|
itMsg: 'has plain text',
|
|
body: 'Hi',
|
|
isEmpty: false,
|
|
},
|
|
{
|
|
itMsg: 'is null',
|
|
body: null,
|
|
isEmpty: true,
|
|
},
|
|
{
|
|
itMsg: 'has empty tags',
|
|
body: `\
|
|
<div class="contenteditable no-open-link-events" contenteditable="true" spellcheck="false"><br><div><p> </p></div>\n\n\n\n<br><signature>Sent from <a href="https://getmailspring.com/?ref=client">Mailspring</a>, the extensible, open source mail client.</signature></div>\
|
|
`,
|
|
isEmpty: true,
|
|
},
|
|
{
|
|
itMsg: 'has nested characters',
|
|
body: `\
|
|
<div class="contenteditable no-open-link-events" contenteditable="true" spellcheck="false"><br><div><p> 1</p></div>\n\n\n\n<br><signature>Sent from <a href="https://getmailspring.com/?ref=client">Mailspring</a>, the extensible, open source mail client.</signature></div>\
|
|
`,
|
|
isEmpty: false,
|
|
},
|
|
{
|
|
itMsg: 'has just a signature',
|
|
body: '<signature>Yo</signature>',
|
|
isEmpty: true,
|
|
},
|
|
{
|
|
itMsg: 'has content after a signature',
|
|
body: '<signature>Yo</signature>Yo',
|
|
isEmpty: false,
|
|
},
|
|
];
|
|
cases.forEach(({ itMsg, body, isEmpty }) =>
|
|
it(itMsg, function() {
|
|
const msg = new Message({ body, pristine: false, draft: true });
|
|
expect(msg.hasEmptyBody()).toBe(isEmpty);
|
|
})
|
|
);
|
|
});
|
|
|
|
it('correctly aggregates participants', function() {
|
|
const m1 = new Message({
|
|
to: [],
|
|
cc: null,
|
|
from: [],
|
|
});
|
|
expect(m1.participants().length).toBe(0);
|
|
|
|
const m2 = new Message({
|
|
to: [evan],
|
|
cc: [],
|
|
bcc: [],
|
|
from: [ben],
|
|
});
|
|
expect(m2.participants().length).toBe(2);
|
|
|
|
const m3 = new Message({
|
|
to: [evan],
|
|
cc: [evan],
|
|
bcc: [evan],
|
|
from: [evan],
|
|
});
|
|
expect(m3.participants().length).toBe(1);
|
|
|
|
const m4 = new Message({
|
|
to: [evan],
|
|
cc: [ben, team, noEmail],
|
|
bcc: [team],
|
|
from: [team],
|
|
});
|
|
// because contact 4 has no email
|
|
expect(m4.participants().length).toBe(3);
|
|
|
|
const m5 = new Message({
|
|
to: [evan],
|
|
cc: [],
|
|
bcc: [team],
|
|
from: [ben],
|
|
});
|
|
// because we exclude bccs
|
|
expect(m5.participants().length).toBe(2);
|
|
});
|
|
|
|
describe('participant replies', function() {
|
|
const cases = [
|
|
// Basic cases
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [me],
|
|
cc: [],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [me],
|
|
cc: [ben],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [ben],
|
|
cc: [me],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [me],
|
|
cc: [ben, team, evan],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [ben, team],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [me, ben, evan, ben, ben, evan],
|
|
cc: [],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [me, ben],
|
|
cc: [team, edgehill],
|
|
bcc: [evan, me, ben],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [ben, team, edgehill],
|
|
},
|
|
},
|
|
|
|
// From me (replying to a message I just sent)
|
|
{
|
|
msg: new Message({
|
|
from: [me],
|
|
to: [me],
|
|
cc: [],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [me],
|
|
cc: [],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [me],
|
|
to: [ben],
|
|
cc: [],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [ben],
|
|
cc: [],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [me],
|
|
to: [ben, team, ben],
|
|
cc: [edgehill],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [ben, team],
|
|
cc: [edgehill],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [me],
|
|
to: [ben, team, ben],
|
|
cc: [edgehill],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [ben, team],
|
|
cc: [edgehill],
|
|
},
|
|
},
|
|
// From me in cases my similar alias is used
|
|
{
|
|
msg: new Message({
|
|
from: [me],
|
|
to: [almost_me],
|
|
cc: [ben],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [almost_me],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [me],
|
|
to: [me, almost_me, me],
|
|
cc: [ben, almost_me, me, me, ben, ben],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [me],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [almost_me],
|
|
to: [me],
|
|
cc: [ben],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [me],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [almost_me],
|
|
to: [almost_me],
|
|
cc: [ben],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [almost_me],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
|
|
// Cases when I'm on email lists
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [team],
|
|
cc: [],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [team],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [team],
|
|
cc: [ben, edgehill],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [team, ben, edgehill],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [team],
|
|
cc: [me],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [team],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [team, me],
|
|
cc: [ben],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [team, ben],
|
|
},
|
|
},
|
|
|
|
// Cases when I'm bcc'd
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [],
|
|
cc: [],
|
|
bcc: [me],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [ben],
|
|
cc: [],
|
|
bcc: [me],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [ben],
|
|
cc: [team, edgehill],
|
|
bcc: [me],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [ben, team, edgehill],
|
|
},
|
|
},
|
|
|
|
// Cases my similar alias is used
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [almost_me],
|
|
cc: [],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [ben],
|
|
cc: [almost_me],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [ben],
|
|
cc: [],
|
|
bcc: [almost_me],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
|
|
// Case when a replyTo is specified
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [ben, me],
|
|
replyTo: [team],
|
|
cc: [],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [team],
|
|
cc: [ben],
|
|
},
|
|
},
|
|
|
|
// Case when a replyTo is specified and it's me. (replyTo will not be honored)
|
|
{
|
|
msg: new Message({
|
|
from: [evan],
|
|
to: [ben, team],
|
|
replyTo: [me],
|
|
cc: [],
|
|
bcc: [],
|
|
}),
|
|
expected: {
|
|
to: [evan],
|
|
cc: [ben, team],
|
|
},
|
|
},
|
|
];
|
|
|
|
const itString = (prefix, msg) =>
|
|
`${prefix} from: ${msg.from.map(c => c.email).join(', ')} | to: ${msg.to
|
|
.map(c => c.email)
|
|
.join(', ')} | cc: ${msg.cc.map(c => c.email).join(', ')} | bcc: ${msg.bcc
|
|
.map(c => c.email)
|
|
.join(', ')} | replyTo: ${msg.replyTo.map(c => c.email).join(', ')}`;
|
|
|
|
it('thinks me and almost_me are equivalent', function() {
|
|
expect(Utils.emailIsEquivalent(me.email, almost_me.email)).toBe(true);
|
|
expect(Utils.emailIsEquivalent(ben.email, me.email)).toBe(false);
|
|
});
|
|
|
|
cases.forEach(function({ msg, expected }) {
|
|
it(itString('Reply All:', msg), () =>
|
|
expect(msg.participantsForReplyAll()).toEqual(expected)
|
|
);
|
|
|
|
it(itString('Reply:', msg), function() {
|
|
const { to, cc } = msg.participantsForReply();
|
|
expect(to).toEqual(expected.to);
|
|
expect(cc).toEqual([]);
|
|
});
|
|
});
|
|
});
|
|
});
|