       @dialog = remote.dialog
       spyOn(remote, "getCurrentWindow")
       spyOn(@dialog, "showMessageBox")
-      spyOn(Actions, "sendDraft")
+      spyOn(Actions, "sendDraft").andCallThrough()
 
     it "shows an error if there are no recipients", ->
-      useDraft.call @, subject: "no recipients"
-      makeComposer.call(@)
-      status = @composer._isValidDraft()
-      expect(status).toBe false
-      expect(@dialog.showMessageBox).toHaveBeenCalled()
-      dialogArgs = @dialog.showMessageBox.mostRecentCall.args[1]
-      expect(dialogArgs.detail).toEqual("You need to provide one or more recipients before sending the message.")
-      expect(dialogArgs.buttons).toEqual ['Edit Message', 'Cancel']
+      sessionSetupComplete = false
+      useDraft.call(@, subject: "no recipients").then( =>
+        sessionSetupComplete = true
+      )
+      waitsFor(( => sessionSetupComplete), "The session's draft needs to be set", 500)
+      runs( =>
+        makeComposer.call(@)
+        status = @composer._isValidDraft()
+        expect(status).toBe false
+        expect(@dialog.showMessageBox).toHaveBeenCalled()
+        dialogArgs = @dialog.showMessageBox.mostRecentCall.args[1]
+        expect(dialogArgs.detail).toEqual("You need to provide one or more recipients before sending the message.")
+        expect(dialogArgs.buttons).toEqual ['Edit Message', 'Cancel']
+      )
 
     it "shows an error if a recipient is invalid", ->
-      useDraft.call @,
+      sessionSetupComplete = false
+      useDraft.call(@,
         subject: 'hello world!'
-        to: [new Contact(email: 'lol', name: 'lol')]
-      makeComposer.call(@)
-      status = @composer._isValidDraft()
-      expect(status).toBe false
-      expect(@dialog.showMessageBox).toHaveBeenCalled()
-      dialogArgs = @dialog.showMessageBox.mostRecentCall.args[1]
-      expect(dialogArgs.detail).toEqual("lol is not a valid email address - please remove or edit it before sending.")
-      expect(dialogArgs.buttons).toEqual ['Edit Message', 'Cancel']
+        to: [new Contact(email: 'lol', name: 'lol')])
+      .then( =>
+        sessionSetupComplete = true
+      )
+      waitsFor(( => sessionSetupComplete), "The session's draft needs to be set", 500)
+      runs( =>
+        makeComposer.call(@)
+        status = @composer._isValidDraft()
+        expect(status).toBe false
+        expect(@dialog.showMessageBox).toHaveBeenCalled()
+        dialogArgs = @dialog.showMessageBox.mostRecentCall.args[1]
+        expect(dialogArgs.detail).toEqual("lol is not a valid email address - please remove or edit it before sending.")
+        expect(dialogArgs.buttons).toEqual ['Edit Message', 'Cancel']
+      )
 
     describe "empty body warning", ->
       it "warns if the body of the email is still the pristine body", ->
         pristineBody = "<br><br>"
-
-        useDraft.call @,
+        sessionSetupComplete = false
+        useDraft.call(@,
           to: [u1]
           subject: "Hello World"
-          body: pristineBody
-        makeComposer.call(@)
-
-        spyOn(@session, 'draftPristineBody').andCallFake -> pristineBody
-
+          body: pristineBody)
+        .then( =>
+          sessionSetupComplete = true
+        )
+        waitsFor(( => sessionSetupComplete), "The session's draft needs to be set", 500)
+
+        runs( =>
+          makeComposer.call(@)
+          spyOn(@session, 'draftPristineBody').andCallFake -> pristineBody
+
+          status = @composer._isValidDraft()
+          expect(status).toBe false
+          expect(@dialog.showMessageBox).toHaveBeenCalled()
+          dialogArgs = @dialog.showMessageBox.mostRecentCall.args[1]
+          expect(dialogArgs.buttons).toEqual ['Send Anyway', 'Cancel']
+        )
+
+      it "does not warn if the body of the email is all quoted text, but the email is a forward", ->
+        sessionSetupComplete = false
+        useDraft.call(@,
+          to: [u1]
+          subject: "Fwd: Hello World"
+          body: "<br><br><blockquote class='gmail_quote'>This is my quoted text!</blockquote>")
+        .then( =>
+          sessionSetupComplete = true
+        )
+        waitsFor(( => sessionSetupComplete), "The session's draft needs to be set", 500)
+        runs( =>
+          makeComposer.call(@)
+          status = @composer._isValidDraft()
+          expect(status).toBe true
+        )
+
+      it "does not warn if the user has attached a file", ->
+        sessionSetupComplete = false
+        useDraft.call(@,
+          to: [u1]
+          subject: "Hello World"
+          body: ""
+          files: [f1])
+        .then( =>
+          sessionSetupComplete = true
+        )
+        waitsFor(( => sessionSetupComplete), "The session's draft needs to be set", 500)
+
+        runs( =>
+          makeComposer.call(@)
+          status = @composer._isValidDraft()
+          expect(status).toBe true
+          expect(@dialog.showMessageBox).not.toHaveBeenCalled()
+        )
+
+    it "shows a warning if there's no subject", ->
+      sessionSetupComplete = false
+      useDraft.call(@, to: [u1], subject: "").then( =>
+        sessionSetupComplete = true
+      )
+      waitsFor(( => sessionSetupComplete), "The session's draft needs to be set", 500)
+      runs( =>
+        makeComposer.call(@)
         status = @composer._isValidDraft()
         expect(status).toBe false
         expect(@dialog.showMessageBox).toHaveBeenCalled()
         dialogArgs = @dialog.showMessageBox.mostRecentCall.args[1]
         expect(dialogArgs.buttons).toEqual ['Send Anyway', 'Cancel']
-
-      it "does not warn if the body of the email is all quoted text, but the email is a forward", ->
-        useDraft.call @,
-          to: [u1]
-          subject: "Fwd: Hello World"
-          body: "<br><br><blockquote class='gmail_quote'>This is my quoted text!</blockquote>"
-        makeComposer.call(@)
-        status = @composer._isValidDraft()
-        expect(status).toBe true
-
-      it "does not warn if the user has attached a file", ->
-        useDraft.call @,
-          to: [u1]
-          subject: "Hello World"
-          body: ""
-          files: [f1]
+      )
+
+    it "doesn't show a warning if requirements are satisfied", ->
+      sessionSetupComplete = false
+      useFullDraft.apply(@).then( =>
+        sessionSetupComplete = true
+      )
+      waitsFor(( => sessionSetupComplete), "The session's draft needs to be set", 500)
+      runs( =>
         makeComposer.call(@)
         status = @composer._isValidDraft()
         expect(status).toBe true
         expect(@dialog.showMessageBox).not.toHaveBeenCalled()
-
-    it "shows a warning if there's no subject", ->
-      useDraft.call @, to: [u1], subject: ""
-      makeComposer.call(@)
-      status = @composer._isValidDraft()
-      expect(status).toBe false
-      expect(@dialog.showMessageBox).toHaveBeenCalled()
-      dialogArgs = @dialog.showMessageBox.mostRecentCall.args[1]
-      expect(dialogArgs.buttons).toEqual ['Send Anyway', 'Cancel']
-
-    it "doesn't show a warning if requirements are satisfied", ->
-      useFullDraft.apply(@); makeComposer.call(@)
-      status = @composer._isValidDraft()
-      expect(status).toBe true
-      expect(@dialog.showMessageBox).not.toHaveBeenCalled()
+      )
 
     describe "Checking for attachments", ->
       warn = (body) ->
-        useDraft.call @, subject: "Subject", to: [u1], body: body
-        makeComposer.call(@)
-        status = @composer._isValidDraft()
-        expect(status).toBe false
-        expect(@dialog.showMessageBox).toHaveBeenCalled()
-        dialogArgs = @dialog.showMessageBox.mostRecentCall.args[1]
-        expect(dialogArgs.buttons).toEqual ['Send Anyway', 'Cancel']
+        sessionSetupComplete = false
+        useDraft.call(@, subject: "Subject", to: [u1], body: body).then( =>
+          sessionSetupComplete = true
+        )
+        waitsFor(( => sessionSetupComplete), "The session's draft needs to be set", 500)
+        runs( =>
+          makeComposer.call(@)
+          status = @composer._isValidDraft()
+          expect(status).toBe false
+          expect(@dialog.showMessageBox).toHaveBeenCalled()
+          dialogArgs = @dialog.showMessageBox.mostRecentCall.args[1]
+          expect(dialogArgs.buttons).toEqual ['Send Anyway', 'Cancel']
+        )
 
       noWarn = (body) ->
-        useDraft.call @, subject: "Subject", to: [u1], body: body
-        makeComposer.call(@)
-        status = @composer._isValidDraft()
-        expect(status).toBe true
-        expect(@dialog.showMessageBox).not.toHaveBeenCalled()
+        sessionSetupComplete = false
+        useDraft.call(@, subject: "Subject", to: [u1], body: body).then( =>
+          sessionSetupComplete = true
+        )
+        waitsFor(( => sessionSetupComplete), "The session's draft needs to be set", 500)
+        runs( =>
+          makeComposer.call(@)
+          status = @composer._isValidDraft()
+          expect(status).toBe true
+          expect(@dialog.showMessageBox).not.toHaveBeenCalled()
+        )
 
       it "warns", -> warn.call(@, "Check out the attached file")
       it "warns", -> warn.call(@, "I've added an attachment")

        ReactDOM.findDOMNode(@$composer).dispatchEvent(new CustomEvent('composer:send-message'))
        expect(Actions.sendDraft).toHaveBeenCalledWith(DRAFT_CLIENT_ID, 'send')
        expect(Actions.sendDraft.calls.length).toBe 1
        @isSending = true
        DraftStore.trigger()
        ReactDOM.findDOMNode(@$composer).dispatchEvent(new CustomEvent('composer:send-message'))
        expect(Actions.sendDraft).toHaveBeenCalledWith(DRAFT_CLIENT_ID, 'send')
        expect(Actions.sendDraft.calls.length).toBe 1

  describe "drag and drop", ->
    beforeEach ->
      useDraft.call @,
        to: [u1]
        subject: "Hello World"
        body: ""
        files: [f1]
      makeComposer.call(@)

    describe "_shouldAcceptDrop", ->
      it "should return true if the event is carrying native files", ->

  @draft = new Message _.extend({draft: true, body: ""}, draftAttributes)
  @draft.clientId = DRAFT_CLIENT_ID
  @session = new DraftEditingSession(DRAFT_CLIENT_ID, @draft)
  # spyOn().andCallFake wasn't working properly on ensureCorrectAccount for some reason
  @session.ensureCorrectAccount = => Promise.resolve(@session)
  DraftStore._draftSessions[DRAFT_CLIENT_ID] = @session
  @session._draftPromise

useFullDraft = ->
  useDraft.call @,
