From ddbd36fe2efd44dacff1a64ec9ac4fcd2f6a3bc6 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Tue, 26 Jan 2016 15:44:40 -0800 Subject: [PATCH] A few other changes --- spec/tasks/file-upload-task-spec.coffee | 256 ----------------------- src/flux/stores/file-upload-store.coffee | 1 - src/flux/tasks/destroy-draft.coffee | 4 +- src/flux/tasks/send-draft.coffee | 4 +- src/flux/tasks/syncback-draft.coffee | 2 - src/global/nylas-exports.coffee | 1 - 6 files changed, 3 insertions(+), 265 deletions(-) delete mode 100644 spec/tasks/file-upload-task-spec.coffee diff --git a/spec/tasks/file-upload-task-spec.coffee b/spec/tasks/file-upload-task-spec.coffee deleted file mode 100644 index 209e176d5..000000000 --- a/spec/tasks/file-upload-task-spec.coffee +++ /dev/null @@ -1,256 +0,0 @@ -proxyquire = require 'proxyquire' -_ = require 'underscore' -NylasAPI = require '../../src/flux/nylas-api' -File = require '../../src/flux/models/file' -Task = require '../../src/flux/tasks/task' -Message = require '../../src/flux/models/message' -Actions = require '../../src/flux/actions' - -DatabaseStore = require "../../src/flux/stores/database-store" -AccountStore = require "../../src/flux/stores/account-store" -DraftStore = require "../../src/flux/stores/draft-store" - -{APIError, - OfflineError, - TimeoutError} = require '../../src/flux/errors' - -FileUploadTask = proxyquire "../../src/flux/tasks/file-upload-task", - fs: - statSync: -> {size: 1234} - createReadStream: -> "Read Stream" - "@noCallThru": true - -test_file_paths = [ - "/fake/file.txt", - "/fake/file.jpg" -] - -noop = -> - -messageClientId = "local-id_1234" - -testResponse = '[ - { - "content_type": "image/jpeg", - "filename": "TestFilename.jpg", - "id": "nylas_id_123", - "account_id": "ns-id", - "object": "file", - "size": 19013 - } -]' -equivalentFile = (new File).fromJSON(JSON.parse(testResponse)[0]) - -DATE = 1433963615918 - -describe "FileUploadTask", -> - beforeEach -> - spyOn(Date, "now").andReturn DATE - - @uploadData = - startDate: DATE - messageClientId: messageClientId - filePath: test_file_paths[0] - fileSize: 1234 - fileName: "file.txt" - bytesUploaded: 0 - - @task = new FileUploadTask(test_file_paths[0], messageClientId) - @draft = new Message(accountId: "account-id-of-draft", files: @testFiles) - - @req = jasmine.createSpyObj('req', ['abort']) - @simulateRequestSuccessImmediately = false - @simulateRequestSuccess = null - @simulateRequestFailure = null - - spyOn(NylasAPI, 'makeRequest').andCallFake (reqParams) => - new Promise (resolve, reject) => - reqParams.started?(@req) - @simulateRequestSuccess = (data) => - reqParams.success?(data) - resolve(data) - @simulateRequestFailure = (err) => - reqParams.error?(err) - reject(err) - if @simulateRequestSuccessImmediately - @simulateRequestSuccess(testResponse) - - @testFiles = [] - @changes = [] - spyOn(DatabaseStore, 'run').andCallFake (query) => - Promise.resolve(@draft) - spyOn(DraftStore, "sessionForClientId").andCallFake => - Promise.resolve( - draft: => @draft - changes: - add: ({files}) => @changes = @changes.concat(files) - commit: -> Promise.resolve() - ) - - it "rejects if not initialized with a path name", (done) -> - waitsForPromise -> - (new FileUploadTask).performLocal().catch (err) -> - expect(err instanceof Error).toBe true - - it "rejects if not initialized with a messageClientId", -> - waitsForPromise -> - (new FileUploadTask(test_file_paths[0])).performLocal().catch (err) -> - expect(err instanceof Error).toBe true - - it 'initializes the upload start', -> - task = new FileUploadTask(test_file_paths[0], messageClientId) - expect(task._startDate).toBe DATE - - it "notifies when the task locally starts", -> - spyOn(Actions, "uploadStateChanged") - - waitsForPromise => - @task.performLocal().then => - data = _.extend @uploadData, state: "pending", bytesUploaded: 0 - dataReceived = Actions.uploadStateChanged.calls[0].args[0] - expect(_.isMatch(dataReceived, data)).toBe(true) - - describe "when the remote API request fails with an API Error", -> - beforeEach -> - @taskExitStatus = null - @runWithError = (simulatedError) => - runs -> - @task.performRemote().then (status) => - @taskExitStatus = status - - waitsFor -> - @simulateRequestFailure - runs -> - spyOn(@task, "_getBytesUploaded").andReturn(0) - spyOn(Actions, "uploadStateChanged") - @simulateRequestFailure(simulatedError) - waitsFor -> - Actions.uploadStateChanged.callCount > 0 - advanceClock(100) - - describe "if the error is permanent", -> - beforeEach -> - @apiError = new APIError(statusCode: 400) - @runWithError(@apiError) - - it "should broadcast `failed` if the error is permanent", -> - runs -> - data = _.extend(@uploadData, {state: "failed", bytesUploaded: 0}) - dataReceived = Actions.uploadStateChanged.calls[0].args[0] - expect(_.isMatch(dataReceived, data)).toBe(true) - - it "should report Failed with the APIError", -> - runs => - expect(@taskExitStatus).toEqual([Task.Status.Failed, @apiError]) - - describe "if the error is temporary", -> - beforeEach -> - @runWithError(new APIError(statusCode: NylasAPI.SampleTemporaryErrorCode)) - - it "should resolve with `retry`", -> - runs -> - expect(@taskExitStatus).toBe(Task.Status.Retry) - - describe "if the request was cancelled", -> - beforeEach -> - @runWithError(new APIError(statusCode: NylasAPI.CancelledErrorCode)) - - it "should broadcast `aborted` if the upload was cancelled", -> - runs -> - data = _.extend(@uploadData, {state: "aborted", bytesUploaded: 0}) - dataReceived = Actions.uploadStateChanged.calls[0].args[0] - expect(_.isMatch(dataReceived, data)).toBe(true) - - it "should resolve with Task.Status.Failed", -> - runs -> - expect(@taskExitStatus).toBe(Task.Status.Failed) - - describe "when the remote API request succeeds", -> - beforeEach -> - @simulateRequestSuccessImmediately = true - spyOn(Actions, "uploadStateChanged") - - it "notifies when the task starts remote", -> - waitsForPromise => - @task.performLocal().then => - data = _.extend @uploadData, state: "pending", bytesUploaded: 0 - dataReceived = Actions.uploadStateChanged.calls[0].args[0] - expect(_.isMatch(dataReceived, data)).toBe(true) - - it "should start an API request", -> - waitsForPromise => @task.performRemote().then -> - options = NylasAPI.makeRequest.mostRecentCall.args[0] - expect(options.path).toBe("/files") - expect(options.method).toBe('POST') - expect(options.formData.file.value).toBe("Read Stream") - - it "should use the accountID of the draft", -> - waitsForPromise => @task.performRemote().then -> - options = NylasAPI.makeRequest.mostRecentCall.args[0] - expect(options.accountId).toBe("account-id-of-draft") - - it "attaches the file to the draft", -> - waitsForPromise => @task.performRemote().then => - delete @changes[0].clientId - delete equivalentFile.clientId - expect(@changes).toEqual [equivalentFile] - - describe "file upload notifications", -> - it "correctly fires the fileUploaded action", -> - spyOn(@task, "_getBytesUploaded").andReturn(1000) - spyOn(Actions, "fileUploaded") - @task.performRemote() - advanceClock() - @simulateRequestSuccess() - advanceClock() - Actions.fileUploaded.calls.length > 0 - - uploadDataExpected = _.extend {}, @uploadData, - state: "completed" - bytesUploaded: 1000 - - [{file, uploadData}] = Actions.fileUploaded.calls[0].args - delete file.clientId - delete equivalentFile.clientId - expect(file).toEqual(equivalentFile) - expect(_.isMatch(uploadData, uploadDataExpected)).toBe(true) - - describe "when attaching a lot of files", -> - it "attaches them all to the draft", -> - t1 = new FileUploadTask("1.a", messageClientId) - t2 = new FileUploadTask("2.b", messageClientId) - t3 = new FileUploadTask("3.c", messageClientId) - t4 = new FileUploadTask("4.d", messageClientId) - - @simulateRequestSuccessImmediately = true - waitsForPromise => Promise.all([ - t1.performRemote() - t2.performRemote() - t3.performRemote() - t4.performRemote() - ]).then => - expect(@changes.length).toBe 4 - - describe "cancel", -> - it "should not do anything if the request has finished", -> - runs => - @task.performRemote() - waitsFor => - @simulateRequestSuccess - runs => - @simulateRequestSuccess(testResponse) - waitsFor => - @task.req is null - runs => - @task.cancel() - expect(@req.abort).not.toHaveBeenCalled() - - it "should cancel the request if it's in flight", -> - spyOn(Actions, "uploadStateChanged") - - @task.performRemote() - advanceClock() - @task.cancel() - advanceClock() - - expect(@req.abort).toHaveBeenCalled() diff --git a/src/flux/stores/file-upload-store.coffee b/src/flux/stores/file-upload-store.coffee index 40d9fd5c2..83d645d5f 100644 --- a/src/flux/stores/file-upload-store.coffee +++ b/src/flux/stores/file-upload-store.coffee @@ -4,7 +4,6 @@ path = require 'path' mkdirp = require 'mkdirp' NylasStore = require 'nylas-store' Actions = require '../actions' -FileUploadTask = require '../tasks/file-upload-task' ### TODO: This store uses a combination of Actions and it's own internal structures diff --git a/src/flux/tasks/destroy-draft.coffee b/src/flux/tasks/destroy-draft.coffee index 6987c7245..211dd82a1 100644 --- a/src/flux/tasks/destroy-draft.coffee +++ b/src/flux/tasks/destroy-draft.coffee @@ -7,7 +7,6 @@ NylasAPI = require '../nylas-api' SyncbackDraftTask = require './syncback-draft' SendDraftTask = require './send-draft' -FileUploadTask = require './file-upload-task' module.exports = class DestroyDraftTask extends Task @@ -17,8 +16,7 @@ class DestroyDraftTask extends Task if @draftClientId (other instanceof DestroyDraftTask and other.draftClientId is @draftClientId) or (other instanceof SyncbackDraftTask and other.draftClientId is @draftClientId) or - (other instanceof SendDraftTask and other.draftClientId is @draftClientId) or - (other instanceof FileUploadTask and other.messageClientId is @draftClientId) + (other instanceof SendDraftTask and other.draftClientId is @draftClientId) else if @draftId (other instanceof DestroyDraftTask and other.draftClientId is @draftClientId) else diff --git a/src/flux/tasks/send-draft.coffee b/src/flux/tasks/send-draft.coffee index 90caed3ef..4ca32e973 100644 --- a/src/flux/tasks/send-draft.coffee +++ b/src/flux/tasks/send-draft.coffee @@ -12,7 +12,7 @@ DatabaseStore = require '../stores/database-store' class MultiRequestProgressMonitor - constructor: => + constructor: -> @_requests = {} @_expected = {} @@ -72,7 +72,7 @@ class SendDraftTask extends Task started: (req) => @_progress.add(filepath, req) timeout: 20 * 60 * 1000 - .finally: => + .finally => @_progress.remove(filepath) .then (file) => @draft.files.push(file) diff --git a/src/flux/tasks/syncback-draft.coffee b/src/flux/tasks/syncback-draft.coffee index f281b1147..e38db928a 100644 --- a/src/flux/tasks/syncback-draft.coffee +++ b/src/flux/tasks/syncback-draft.coffee @@ -11,8 +11,6 @@ Task = require './task' Message = require '../models/message' Account = require '../models/account' -FileUploadTask = require './file-upload-task' - # MutateDraftTask module.exports = diff --git a/src/global/nylas-exports.coffee b/src/global/nylas-exports.coffee index 60574f477..99381b28d 100644 --- a/src/global/nylas-exports.coffee +++ b/src/global/nylas-exports.coffee @@ -94,7 +94,6 @@ class NylasExports # we know how to deserialized saved or IPC-sent tasks. @require "EventRSVPTask", 'flux/tasks/event-rsvp' @require "SendDraftTask", 'flux/tasks/send-draft' - @require "FileUploadTask", 'flux/tasks/file-upload-task' @require "DestroyDraftTask", 'flux/tasks/destroy-draft' @require "ChangeMailTask", 'flux/tasks/change-mail-task' @require "ChangeLabelsTask", 'flux/tasks/change-labels-task'