Mailspring/spec/tasks/syncback-draft-files-task-spec.es6

136 lines
4.6 KiB
JavaScript

import fs from 'fs';
import {
DatabaseStore,
DatabaseTransaction,
Message,
Contact,
SyncbackDraftFilesTask,
NylasAPIRequest,
} from 'nylas-exports';
const DBt = DatabaseTransaction.prototype;
describe('SyncbackDraftFilesTask', function syncbackDraftFilesTask() {
describe("with uploads", () => {
beforeEach(() => {
this.uploads = [
{targetPath: '/test-file-1.png', size: 100},
{targetPath: '/test-file-2.png', size: 100},
];
this.draft = new Message({
version: 1,
clientId: 'client-id',
accountId: TEST_ACCOUNT_ID,
from: [new Contact({email: TEST_ACCOUNT_EMAIL})],
subject: 'New Draft',
draft: true,
body: 'hello world',
uploads: [].concat(this.uploads),
});
this.task = new SyncbackDraftFilesTask(this.draft.clientId);
this.resolves = [];
this.resolveAll = () => {
for (const resolve of this.resolves) {
resolve();
}
this.resolves = []
advanceClock()
};
spyOn(DBt, 'persistModel');
spyOn(fs, 'createReadStream').andReturn("stub");
spyOn(NylasAPIRequest.prototype, 'run').andCallFake((options) => {
let response = this.response;
if (options.path === '/files') {
response = JSON.stringify([{
id: '1234',
account_id: TEST_ACCOUNT_ID,
filename: options.formData.file.options.filename,
}]);
}
return new Promise((resolve) => {
this.resolves.push(() => {
if (options.success) { options.success(response) }
resolve(response);
});
});
});
spyOn(DatabaseStore, 'run').andCallFake(() => Promise.resolve(this.draft))
});
it("should begin file uploads and not resolve until they complete", () => {
const taskPromise = this.task.performRemote();
advanceClock();
// uploads should be queued, but not the send
expect(NylasAPIRequest.prototype.run.callCount).toEqual(2);
expect(NylasAPIRequest.prototype.run.calls[0].args[0].formData).toEqual({file: {value: 'stub', options: { filename: 'test-file-1.png' } } });
expect(NylasAPIRequest.prototype.run.calls[1].args[0].formData).toEqual({file: {value: 'stub', options: { filename: 'test-file-2.png' } } });
// finish all uploads
expect(taskPromise.isFulfilled()).toBe(false);
this.resolveAll();
expect(taskPromise.isFulfilled()).toBe(true);
});
it("should update the draft, removing uploads and adding files", () => {
this.task.performRemote();
advanceClock();
this.resolveAll();
advanceClock();
expect(DBt.persistModel).toHaveBeenCalled();
const draft = DBt.persistModel.mostRecentCall.args[0];
expect(draft.files.length).toBe(2);
expect(draft.uploads.length).toBe(0);
});
it("should not upload inline attachments which were removed from the draft body", () => {
this.uploads = [
{targetPath: '/test-file-1.png', size: 100, inline: true, id: 'aaa'},
{targetPath: '/test-file-2.png', size: 100, inline: true, id: 'bbb'},
];
this.draft = new Message({
version: 1,
clientId: 'client-id',
accountId: TEST_ACCOUNT_ID,
from: [new Contact({email: TEST_ACCOUNT_EMAIL})],
subject: 'New Draft',
draft: true,
body: 'This is my response<br><br><img src="cid:bbb"><br>I cut out aaa! What a bummer.',
uploads: [].concat(this.uploads),
});
this.task.performRemote();
advanceClock();
// Only upload `bbb` should be sent, upload `aaa` should be deleted
// because it was not present in the draft body.
expect(NylasAPIRequest.prototype.run.callCount).toEqual(1);
expect(NylasAPIRequest.prototype.run.calls[0].args[0].formData).toEqual({file: {value: 'stub', options: { filename: 'test-file-2.png' } } });
this.resolveAll();
advanceClock();
expect(DBt.persistModel).toHaveBeenCalled();
const draft = DBt.persistModel.mostRecentCall.args[0];
expect(draft.files.length).toBe(1);
// the upload should still be removed
expect(draft.uploads.length).toBe(0);
})
it("should not interfere with other uploads added to the draft during task execution", () => {
this.task.performRemote();
advanceClock();
this.draft.uploads.push({targetPath: '/test-file-3.png', size: 100});
this.resolveAll();
advanceClock();
expect(DBt.persistModel).toHaveBeenCalled();
const draft = DBt.persistModel.mostRecentCall.args[0];
expect(draft.files.length).toBe(2);
expect(draft.uploads.length).toBe(1);
});
});
});