mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-12-27 02:23:28 +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
240 lines
8.9 KiB
TypeScript
240 lines
8.9 KiB
TypeScript
import {
|
|
AccountStore,
|
|
MailboxPerspective,
|
|
TaskFactory,
|
|
Label,
|
|
CategoryStore,
|
|
} from 'mailspring-exports';
|
|
|
|
describe('MailboxPerspective', function mailboxPerspective() {
|
|
beforeEach(() => {
|
|
this.accountIds = ['a1', 'a2'];
|
|
this.accounts = {
|
|
a1: {
|
|
id: 'a1',
|
|
preferredRemovalDestination: () => ({ displayName: 'archive' }),
|
|
},
|
|
a2: {
|
|
id: 'a2',
|
|
preferredRemovalDestination: () => ({ displayName: 'trash2' }),
|
|
},
|
|
};
|
|
this.perspective = new MailboxPerspective(this.accountIds);
|
|
spyOn(AccountStore, 'accountForId').andCallFake(accId => this.accounts[accId]);
|
|
});
|
|
|
|
describe('isEqual', () => {
|
|
// TODO
|
|
});
|
|
|
|
describe('canArchiveThreads', () => {
|
|
it('returns false if the perspective is archive', () => {
|
|
const accounts = [{ canArchiveThreads: () => true }, { canArchiveThreads: () => true }];
|
|
spyOn(AccountStore, 'accountsForItems').andReturn(accounts);
|
|
spyOn(this.perspective, 'isArchive').andReturn(true);
|
|
expect(this.perspective.canArchiveThreads()).toBe(false);
|
|
});
|
|
|
|
it('returns false if one of the accounts associated with the threads cannot archive', () => {
|
|
const accounts = [{ canArchiveThreads: () => true }, { canArchiveThreads: () => false }];
|
|
spyOn(AccountStore, 'accountsForItems').andReturn(accounts);
|
|
spyOn(this.perspective, 'isArchive').andReturn(false);
|
|
expect(this.perspective.canArchiveThreads()).toBe(false);
|
|
});
|
|
|
|
it('returns true otherwise', () => {
|
|
const accounts = [{ canArchiveThreads: () => true }, { canArchiveThreads: () => true }];
|
|
spyOn(AccountStore, 'accountsForItems').andReturn(accounts);
|
|
spyOn(this.perspective, 'isArchive').andReturn(false);
|
|
expect(this.perspective.canArchiveThreads()).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('canMoveThreadsTo', () => {
|
|
it('returns false if the perspective is the target folder', () => {
|
|
const accounts = [{ id: 'a' }, { id: 'b' }];
|
|
spyOn(AccountStore, 'accountsForItems').andReturn(accounts);
|
|
spyOn(this.perspective, 'categoriesSharedRole').andReturn('trash');
|
|
expect(this.perspective.canMoveThreadsTo([], 'trash')).toBe(false);
|
|
});
|
|
|
|
it('returns false if one of the accounts associated with the threads does not have the folder', () => {
|
|
const accounts = [{ id: 'a' }, { id: 'b' }];
|
|
spyOn(CategoryStore, 'getCategoryByRole').andReturn(null);
|
|
spyOn(AccountStore, 'accountsForItems').andReturn(accounts);
|
|
spyOn(this.perspective, 'categoriesSharedRole').andReturn('inbox');
|
|
expect(this.perspective.canMoveThreadsTo([], 'trash')).toBe(false);
|
|
});
|
|
|
|
it('returns true otherwise', () => {
|
|
const accounts = [{ id: 'a' }, { id: 'b' }];
|
|
const category = { id: 'cat' };
|
|
spyOn(CategoryStore, 'getCategoryByRole').andReturn(category);
|
|
spyOn(AccountStore, 'accountsForItems').andReturn(accounts);
|
|
spyOn(this.perspective, 'categoriesSharedRole').andReturn('inbox');
|
|
expect(this.perspective.canMoveThreadsTo([], 'trash')).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('canReceiveThreadsFromAccountIds', () => {
|
|
it('returns true if the thread account ids are included in the current account ids', () => {
|
|
expect(this.perspective.canReceiveThreadsFromAccountIds(['a1'])).toBe(true);
|
|
});
|
|
|
|
it('returns false otherwise', () => {
|
|
expect(this.perspective.canReceiveThreadsFromAccountIds(['a4'])).toBe(false);
|
|
expect(this.perspective.canReceiveThreadsFromAccountIds([])).toBe(false);
|
|
expect(this.perspective.canReceiveThreadsFromAccountIds()).toBe(false);
|
|
});
|
|
});
|
|
|
|
// todo bg
|
|
xdescribe('tasksForRemovingItems', () => {
|
|
beforeEach(() => {
|
|
this.categories = {
|
|
a1: {
|
|
archive: new Label({ role: 'archive', path: 'archive', accountId: 'a1' }),
|
|
inbox: new Label({ role: 'inbox', path: 'inbox1', accountId: 'a1' }),
|
|
trash: new Label({ role: 'trash', path: 'trash1', accountId: 'a1' }),
|
|
category: new Label({ role: null, path: 'folder1', accountId: 'a1' }),
|
|
},
|
|
a2: {
|
|
archive: new Label({ role: 'all', path: 'all', accountId: 'a2' }),
|
|
inbox: new Label({ role: 'inbox', path: 'inbox2', accountId: 'a2' }),
|
|
trash: new Label({ role: 'trash', path: 'trash2', accountId: 'a2' }),
|
|
category: new Label({ role: null, path: 'label2', accountId: 'a2' }),
|
|
},
|
|
};
|
|
this.threads = [{ accountId: 'a1' }, { accountId: 'a2' }];
|
|
spyOn(TaskFactory, 'tasksForApplyingCategories');
|
|
spyOn(CategoryStore, 'getTrashCategory').andCallFake(accId => {
|
|
return this.categories[accId].trash;
|
|
});
|
|
});
|
|
|
|
function assertMoved(accId) {
|
|
expect(TaskFactory.tasksForApplyingCategories).toHaveBeenCalled();
|
|
const { args } = TaskFactory.tasksForApplyingCategories.calls[0];
|
|
const { categoriesToRemove, categoriesToAdd } = args[0];
|
|
|
|
const assertor = {
|
|
from(originName) {
|
|
expect(categoriesToRemove(accId)[0].displayName).toEqual(originName);
|
|
return assertor;
|
|
},
|
|
to(destinationName) {
|
|
expect(categoriesToAdd(accId)[0].displayName).toEqual(destinationName);
|
|
return assertor;
|
|
},
|
|
};
|
|
return assertor;
|
|
}
|
|
|
|
it('moves to finished category if viewing inbox', () => {
|
|
const perspective = MailboxPerspective.forCategories([
|
|
this.categories.a1.inbox,
|
|
this.categories.a2.inbox,
|
|
]);
|
|
perspective.tasksForRemovingItems(this.threads);
|
|
assertMoved('a1')
|
|
.from('inbox1')
|
|
.to('archive');
|
|
assertMoved('a2')
|
|
.from('inbox2')
|
|
.to('trash2');
|
|
});
|
|
|
|
it('moves to trash if viewing archive', () => {
|
|
const perspective = MailboxPerspective.forCategories([
|
|
this.categories.a1.archive,
|
|
this.categories.a2.archive,
|
|
]);
|
|
perspective.tasksForRemovingItems(this.threads);
|
|
assertMoved('a1')
|
|
.from('archive')
|
|
.to('trash1');
|
|
assertMoved('a2')
|
|
.from('all')
|
|
.to('trash2');
|
|
});
|
|
|
|
it('deletes permanently if viewing trash', () => {
|
|
// TODO
|
|
// Not currently possible
|
|
});
|
|
|
|
it('moves to default finished category if viewing category', () => {
|
|
const perspective = MailboxPerspective.forCategories([
|
|
this.categories.a1.category,
|
|
this.categories.a2.category,
|
|
]);
|
|
perspective.tasksForRemovingItems(this.threads);
|
|
assertMoved('a1')
|
|
.from('folder1')
|
|
.to('archive');
|
|
assertMoved('a2')
|
|
.from('label2')
|
|
.to('trash2');
|
|
});
|
|
|
|
it('unstars if viewing starred', () => {
|
|
spyOn(TaskFactory, 'taskForInvertingStarred').andReturn({ some: 'task' });
|
|
const perspective = MailboxPerspective.forStarred(this.accountIds);
|
|
const tasks = perspective.tasksForRemovingItems(this.threads);
|
|
expect(tasks).toEqual([{ some: 'task' }]);
|
|
});
|
|
|
|
it('does nothing when viewing spam or sent', () => {
|
|
['spam', 'sent'].forEach(invalid => {
|
|
const perspective = MailboxPerspective.forCategories([
|
|
new Label({ role: invalid, accountId: 'a1' }),
|
|
new Label({ role: invalid, accountId: 'a2' }),
|
|
]);
|
|
const tasks = perspective.tasksForRemovingItems(this.threads);
|
|
expect(TaskFactory.tasksForApplyingCategories).not.toHaveBeenCalled();
|
|
expect(tasks).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe('when perspective is category perspective', () => {
|
|
it('does not create tasks if any name in the ruleset is null', () => {
|
|
const perspective = MailboxPerspective.forCategories([this.categories.a1.category]);
|
|
spyOn(perspective, 'categoriesSharedRole').andReturn('all');
|
|
const tasks = perspective.tasksForRemovingItems(this.threads);
|
|
expect(tasks).toEqual([]);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('CategoryMailboxPerspective', () => {
|
|
beforeEach(() => {
|
|
this.categories = [
|
|
new Label({ path: 'c1', accountId: 'a1' }),
|
|
new Label({ path: 'c2', accountId: 'a2' }),
|
|
new Label({ path: 'c3', accountId: 'a2' }),
|
|
];
|
|
this.perspective = MailboxPerspective.forCategories(this.categories);
|
|
});
|
|
|
|
describe('canReceiveThreadsFromAccountIds', () => {
|
|
it('returns true if the thread account ids are included in the current account ids', () => {
|
|
expect(this.perspective.canReceiveThreadsFromAccountIds(['a1'])).toBe(true);
|
|
});
|
|
|
|
it('returns false otherwise', () => {
|
|
expect(this.perspective.canReceiveThreadsFromAccountIds(['a4'])).toBe(false);
|
|
expect(this.perspective.canReceiveThreadsFromAccountIds([])).toBe(false);
|
|
expect(this.perspective.canReceiveThreadsFromAccountIds()).toBe(false);
|
|
});
|
|
|
|
it('returns false if it is a locked category', () => {
|
|
this.perspective._categories.push(new Label({ role: 'sent', path: 'c4', accountId: 'a1' }));
|
|
expect(this.perspective.canReceiveThreadsFromAccountIds(['a2'])).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('receiveThreads', () => {
|
|
// TODO
|
|
});
|
|
});
|
|
});
|