fix(downloads): Replace stripped extensions, remember folder

This commit is contained in:
Ben Gotow 2016-03-03 18:00:37 -08:00
parent 4cae9a97a3
commit fa002b82a5
2 changed files with 65 additions and 26 deletions

View file

@ -247,8 +247,8 @@ describe "FileDownloadStore", ->
describe "_fetchAndSave", ->
beforeEach ->
@savePath = "/Users/imaginary/.nylas/Downloads/b.png"
spyOn(NylasEnv, 'showSaveDialog').andCallFake (options, callback) => callback(@savePath)
@userSelectedPath = "/Users/imaginary/.nylas/Downloads/b.png"
spyOn(NylasEnv, 'showSaveDialog').andCallFake (options, callback) => callback(@userSelectedPath)
it "should open a save dialog and prompt the user to choose a download path", ->
spyOn(FileDownloadStore, '_runDownload').andCallFake =>
@ -257,27 +257,6 @@ describe "FileDownloadStore", ->
expect(NylasEnv.showSaveDialog).toHaveBeenCalled()
expect(FileDownloadStore._runDownload).toHaveBeenCalledWith(@testfile)
it "should copy the file to the download path after it's been downloaded and open it after the stream has ended", ->
download = {targetPath: @savePath}
onEndEventCallback = null
streamStub =
pipe: ->
on: (eventName, eventCallback) =>
onEndEventCallback = eventCallback
spyOn(FileDownloadStore, '_runDownload').andCallFake =>
Promise.resolve(download)
spyOn(fs, 'createReadStream').andReturn(streamStub)
spyOn(fs, 'createWriteStream')
FileDownloadStore._fetchAndSave(@testfile)
advanceClock(1)
expect(fs.createReadStream).toHaveBeenCalledWith(download.targetPath)
expect(shell.showItemInFolder).not.toHaveBeenCalled()
onEndEventCallback()
advanceClock(1)
expect(shell.showItemInFolder).toHaveBeenCalledWith(download.targetPath)
it "should open an error if the download fails", ->
spyOn(FileDownloadStore, '_presentError')
spyOn(FileDownloadStore, '_runDownload').andCallFake =>
@ -286,6 +265,49 @@ describe "FileDownloadStore", ->
advanceClock(1)
expect(FileDownloadStore._presentError).toHaveBeenCalled()
describe "when the user confirms a path", ->
beforeEach ->
@download = {targetPath: 'bla'}
@onEndEventCallback = null
streamStub =
pipe: ->
on: (eventName, eventCallback) =>
@onEndEventCallback = eventCallback
spyOn(FileDownloadStore, '_runDownload').andCallFake =>
Promise.resolve(@download)
spyOn(fs, 'createReadStream').andReturn(streamStub)
spyOn(fs, 'createWriteStream')
it "should copy the file to the download path after it's been downloaded and open it after the stream has ended", ->
FileDownloadStore._fetchAndSave(@testfile)
advanceClock(1)
expect(fs.createReadStream).toHaveBeenCalledWith(@download.targetPath)
expect(shell.showItemInFolder).not.toHaveBeenCalled()
@onEndEventCallback()
advanceClock(1)
expect(shell.showItemInFolder).toHaveBeenCalledWith(@userSelectedPath)
it "should update the NylasEnv.savedState.lastDownloadDirectory", ->
NylasEnv.savedState.lastDownloadDirectory = null
@userSelectedPath = "/Users/imaginary/.nylas/Another Random Folder/file.jpg"
FileDownloadStore._fetchAndSave(@testfile)
advanceClock(1)
expect(NylasEnv.savedState.lastDownloadDirectory).toEqual('/Users/imaginary/.nylas/Another Random Folder')
describe "file extensions", ->
it "should allow the user to save the file with a different extension", ->
@userSelectedPath = "/Users/imaginary/.nylas/Downloads/b-changed.tiff"
FileDownloadStore._fetchAndSave(@testfile)
advanceClock(1)
expect(fs.createWriteStream).toHaveBeenCalledWith(@userSelectedPath)
it "should restore the extension if the user removed it entirely, because it's usually an accident", ->
@userSelectedPath = "/Users/imaginary/.nylas/Downloads/b-changed"
FileDownloadStore._fetchAndSave(@testfile)
advanceClock(1)
expect(fs.createWriteStream).toHaveBeenCalledWith("#{@userSelectedPath}.png")
describe "_abortFetchFile", ->
beforeEach ->
@download =

View file

@ -210,8 +210,19 @@ FileDownloadStore = Reflux.createStore
@_presentError(file)
_fetchAndSave: (file) ->
NylasEnv.showSaveDialog {defaultPath: @_defaultSavePath(file)}, (savePath) =>
defaultPath = @_defaultSavePath(file)
defaultExtension = path.extname(defaultPath)
NylasEnv.showSaveDialog {defaultPath: defaultPath}, (savePath) =>
return unless savePath
NylasEnv.savedState.lastDownloadDirectory = path.dirname(savePath)
saveExtension = path.extname(savePath)
didLoseExtension = defaultExtension isnt '' and saveExtension is ''
if didLoseExtension
savePath = savePath + defaultExtension
defaultPath = NylasEnv.savedState.lastDownloadDirectory
@_runDownload(file).then (download) ->
stream = fs.createReadStream(download.targetPath)
stream.pipe(fs.createWriteStream(savePath))
@ -236,13 +247,19 @@ FileDownloadStore = Reflux.createStore
_defaultSavePath: (file) ->
if process.platform is 'win32'
home = process.env.USERPROFILE
else home = process.env.HOME
else
home = process.env.HOME
downloadDir = path.join(home, 'Downloads')
if not fs.existsSync(downloadDir)
downloadDir = os.tmpdir()
path.join(downloadDir, file.displayName())
if NylasEnv.savedState.lastDownloadDirectory
if fs.existsSync(NylasEnv.savedState.lastDownloadDirectory)
downloadDir = NylasEnv.savedState.lastDownloadDirectory
filesafeName = file.displayName().replace(RegExpUtils.illegalPathCharactersRegexp(), '-')
path.join(downloadDir, filesafeName)
_presentError: (file) ->
dialog = require('remote').require('dialog')