UNPKG

nebulab-dropbox

Version:
1,116 lines (1,013 loc) 84.3 kB
buildBlob = (fragments, mimeType) -> try return new Blob fragments, mimeType catch blobError builder = new WebKitBlobBuilder builder.append fragment for fragment in fragments return builder.getBlob mimeType buildClientTests = (clientKeys) -> # Creates the global client. setupClient = (test, done) -> # Should only be used for fixture teardown. test.__client = new Dropbox.Client clientKeys done() # Creates the test directory. setupDirectory = (test, done) -> # True if running on node.js test.node_js = module? and module?.exports? and require? # All test data should go here. test.testFolder = '/js tests.' + Math.random().toString(36) test.__client.mkdir test.testFolder, (error, stat) -> if error isnt null console.error error throw new Error("Unexpected setup error"); done() # Creates the binary image file in the test directory. setupImageFile = (test, done) -> test.imageFile = "#{test.testFolder}/test-binary-image.png" test.imageFileBytes = testImageBytes setupImageFileUsingArrayBuffer test, (success) -> if success return done() setupImageFileUsingBlob test, (success) -> if success return done() setupImageFileUsingString test, done # Standard-compliant browsers write via XHR#send(ArrayBufferView). setupImageFileUsingArrayBuffer = (test, done) -> if Uint8Array? view = new Uint8Array test.imageFileBytes.length for i in [0...test.imageFileBytes.length] view[i] = test.imageFileBytes[i] buffer = view.buffer test.__client.writeFile test.imageFile, buffer, (error, stat) -> if error return done(false) # Some browsers will send the '[object Uint8Array]' string instead of # the ArrayBufferView. if stat.size is buffer.byteLength test.imageFileTag = stat.versionTag done true else done false else done false # Fallback to XHR#send(Blob). setupImageFileUsingBlob = (test, done) -> if Blob? view = new Uint8Array test.imageFileBytes.length for i in [0...test.imageFileBytes.length] view[i] = test.imageFileBytes[i] buffer = view.buffer blob = buildBlob [buffer], type: 'image/png' test.__client.writeFile test.imageFile, blob, (error, stat) -> if error return done(false) if stat.size is blob.size test.imageFileTag = stat.versionTag done true else done false else done false # Last resort: send a string that will get crushed by encoding errors. setupImageFileUsingString = (test, done) -> stringChars = for i in [0...test.imageFileBytes.length] String.fromCharCode(test.imageFileBytes[i]) test.__client.writeFile(test.imageFile, stringChars.join(''), { binary: true }, (error, stat) -> if error isnt null console.error error throw new Error("Unexpected setup error"); test.imageFileTag = stat.versionTag done() ) # Creates the plaintext file in the test directory. setupTextFile = (test, done) -> test.textFile = "#{test.testFolder}/test-file.txt" test.textFileData = "Plaintext test file #{Math.random().toString(36)}.\n" test.__client.writeFile(test.textFile, test.textFileData, (error, stat) -> if error isnt null console.error error throw new Error("Unexpected setup error"); test.textFileTag = stat.versionTag done() ) # Global (expensive) fixtures. before (done) -> setupClient @, => setupDirectory @, => setupImageFile @, => setupTextFile @, -> done() # Teardown for global fixtures. after (done) -> @__client.remove @testFolder, (error, stat) => throw new Error(error) if error done() # Per-test (cheap) fixtures. beforeEach -> @client = new Dropbox.Client clientKeys describe '#getAccountInfo', -> it 'returns reasonable information', (done) -> @client.getAccountInfo (error, accountInfo, rawAccountInfo) -> expect(error).to.equal null expect(accountInfo).to.be.instanceOf Dropbox.AccountInfo expect(accountInfo.uid).to.equal clientKeys.uid expect(rawAccountInfo).not.to.be.instanceOf Dropbox.AccountInfo expect(rawAccountInfo).to.have.property 'uid' done() describe 'with httpCache', -> beforeEach -> @xhr = null @client.onXhr.addListener (xhr) => @xhr = xhr it 'uses Authorization headers', (done) -> @client.getAccountInfo httpCache: true, (error, accountInfo, rawAccountInfo) => if Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers expect(@xhr.url).to.contain 'access_token' else expect(@xhr.headers).to.have.key 'Authorization' expect(error).to.equal null expect(accountInfo).to.be.instanceOf Dropbox.AccountInfo expect(accountInfo.uid).to.equal clientKeys.uid expect(rawAccountInfo).not.to.be.instanceOf Dropbox.AccountInfo expect(rawAccountInfo).to.have.property 'uid' done() describe '#mkdir', -> afterEach (done) -> return done() unless @newFolder @client.remove @newFolder, (error, stat) -> done() it 'creates a folder in the test folder', (done) -> @newFolder = "#{@testFolder}/test'folder" @client.mkdir @newFolder, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFolder expect(stat.isFolder).to.equal true @client.stat @newFolder, (error, stat) => expect(error).to.equal null expect(stat.isFolder).to.equal true done() describe '#readFile', -> beforeEach -> @newFile = null afterEach (done) -> return done() unless @newFile @client.remove @newFile, (error, stat) -> done() it 'reads a text file', (done) -> @client.readFile @textFile, (error, data, stat) => expect(error).to.equal null expect(data).to.equal @textFileData unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat # TODO(pwnall): enable after API contents server bug is fixed #if clientKeys.key is testFullDropboxKeys.key # expect(stat.inAppFolder).to.equal false #else # expect(stat.inAppFolder).to.equal true expect(stat.path).to.equal @textFile expect(stat.isFile).to.equal true done() it 'reads the beginning of a text file', (done) -> return done() if Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. @client.readFile @textFile, start: 0, length: 10, (error, data, stat, rangeInfo) => expect(error).to.equal null expect(data).to.equal @textFileData.substring(0, 10) expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @textFile expect(stat.isFile).to.equal true expect(rangeInfo).to.be.instanceOf Dropbox.Http.RangeInfo expect(rangeInfo.start).to.equal 0 expect(rangeInfo.end).to.equal 9 expect(rangeInfo.size).to.equal @textFileData.length done() it 'reads the middle of a text file', (done) -> return done() if Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. @client.readFile @textFile, start: 8, length: 10, (error, data, stat, rangeInfo) => expect(error).to.equal null expect(data).to.equal @textFileData.substring(8, 18) expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @textFile expect(stat.isFile).to.equal true expect(rangeInfo).to.be.instanceOf Dropbox.Http.RangeInfo expect(rangeInfo.start).to.equal 8 expect(rangeInfo.end).to.equal 17 expect(rangeInfo.size).to.equal @textFileData.length done() it 'reads the end of a text file via the start: option', (done) -> return done() if Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. @client.readFile @textFile, start: 10, (error, data, stat, rangeInfo) => expect(error).to.equal null expect(data).to.equal @textFileData.substring(10) expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @textFile expect(stat.isFile).to.equal true expect(rangeInfo).to.be.instanceOf Dropbox.Http.RangeInfo expect(rangeInfo.start).to.equal 10 expect(rangeInfo.end).to.equal @textFileData.length - 1 expect(rangeInfo.size).to.equal @textFileData.length done() it 'reads the end of a text file via the length: option', (done) -> return done() if Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. @client.readFile @textFile, length: 10, (error, data, stat, rangeInfo) => expect(error).to.equal null expect(data).to. equal @textFileData.substring(@textFileData.length - 10) expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @textFile expect(stat.isFile).to.equal true expect(rangeInfo).to.be.instanceOf Dropbox.Http.RangeInfo expect(rangeInfo.start).to.equal @textFileData.length - 10 expect(rangeInfo.end).to.equal @textFileData.length - 1 expect(rangeInfo.size).to.equal @textFileData.length done() it 'reads a binary file into a string', (done) -> @client.readFile @imageFile, binary: true, (error, data, stat) => expect(error).to.equal null bytes = (data.charCodeAt i for i in [0...data.length]) expect(bytes).to.deep.equal @imageFileBytes unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @imageFile expect(stat.isFile).to.equal true done() it 'reads a JSON file into a string', (done) -> jsonString = '{"answer":42,"autoParse":false}' @newFile = "#{@testFolder}/json test file.json" @client.writeFile @newFile, jsonString, (error, stat) => expect(error).to.equal null @client.readFile @newFile, (error, data, stat) => expect(error).to.equal null expect(data).to.equal jsonString unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true done() it 'reads a binary file into a Blob', (done) -> return done() unless Blob? @client.readFile @imageFile, blob: true, (error, blob, stat) => expect(error).to.equal null expect(blob).to.be.instanceOf Blob unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @imageFile expect(stat.isFile).to.equal true onBufferAvailable = (buffer) => view = new Uint8Array buffer bytes = (view[i] for i in [0...buffer.byteLength]) expect(bytes).to.deep.equal @imageFileBytes done() if typeof FileReaderSync isnt 'undefined' # Firefox WebWorkers don't have FileReader. reader = new FileReaderSync buffer = reader.readAsArrayBuffer blob onBufferAvailable buffer else reader = new FileReader reader.onloadend = -> return unless reader.readyState == FileReader.DONE onBufferAvailable reader.result reader.readAsArrayBuffer blob it 'reads a binary file into an ArrayBuffer', (done) -> return done() unless ArrayBuffer? @client.readFile @imageFile, arrayBuffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf ArrayBuffer expect(buffer.byteLength).to.equal @imageFileBytes.length unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @imageFile expect(stat.isFile).to.equal true view = new Uint8Array buffer bytes = (view[i] for i in [0...buffer.byteLength]) expect(bytes).to.deep.equal @imageFileBytes done() it 'reads a binary file into a node.js Buffer', (done) -> return done() unless Buffer? @client.readFile @imageFile, buffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf Buffer expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @imageFile expect(stat.isFile).to.equal true bytes = (buffer.readUInt8(i) for i in [0...buffer.length]) expect(bytes).to.deep.equal @imageFileBytes done() it 'reports non-existing files correctly', (done) -> @client.readFile @textFile + '-not-found', (error, text, stat) => expect(text).not.to.be.ok expect(stat).not.to.be.ok expect(error).to.be.instanceOf Dropbox.ApiError unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do error codes. expect(error.status).to.equal Dropbox.ApiError.NOT_FOUND expect(error.url).to.contain '-not-found' done() describe 'with an onXhr listener', -> beforeEach -> @listenerXhr = null @callbackCalled = false it 'calls the listener with a Dropbox.Util.Xhr argument', (done) -> @client.onXhr.addListener (xhr) => expect(xhr).to.be.instanceOf Dropbox.Util.Xhr @listenerXhr = xhr true @client.readFile @textFile, (error, data, stat) => expect(error).to.equal null expect(data).to.equal @textFileData done() it 'calls the listener before firing the XHR', (done) -> @client.onXhr.addListener (xhr) => unless Dropbox.Util.Xhr.ieXdr # IE's XHR doesn't have readyState expect(xhr.xhr.readyState).to.equal 1 expect(@callbackCalled).to.equal false @listenerXhr = xhr true @client.readFile @textFile, (error, data, stat) => @callbackCalled = true expect(@listenerXhr).to.be.instanceOf Dropbox.Util.Xhr expect(error).to.equal null expect(data).to.equal @textFileData done() it 'does not send the XHR if the listener cancels the event', (done) -> @client.onXhr.addListener (xhr) => expect(@callbackCalled).to.equal false @listenerXhr = xhr # NOTE: if the client calls send(), a DOM error will fail the test xhr.send() false @client.readFile @textFile, (error, data, stat) => @callbackCalled = true expect(@listenerXhr).to.be.instanceOf Dropbox.Util.Xhr done() describe 'with httpCache', -> beforeEach -> @xhr = null @client.onXhr.addListener (xhr) => @xhr = xhr it 'reads a text file using Authorization headers', (done) -> @client.readFile @textFile, httpCache: true, (error, data, stat) => if Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers expect(@xhr.url).to.contain 'access_token' else expect(@xhr.headers).to.have.key 'Authorization' expect(error).to.equal null expect(data).to.equal @textFileData unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @textFile expect(stat.isFile).to.equal true done() describe '#writeFile', -> beforeEach -> @newFile = null afterEach (done) -> return done() unless @newFile @client.remove @newFile, (error, stat) -> done() it 'writes a new text file', (done) -> @newFile = "#{@testFolder}/another text file.txt" @newFileData = "Another plaintext file #{Math.random().toString(36)}." @client.writeFile @newFile, @newFileData, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true # TODO(pwnall): enable after API contents server bug is fixed #if clientKeys.key is testFullDropboxKeys.key # expect(stat.inAppFolder).to.equal false #else # expect(stat.inAppFolder).to.equal true @client.readFile @newFile, (error, data, stat) => expect(error).to.equal null expect(data).to.equal @newFileData unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true done() it 'writes a new empty file', (done) -> @newFile = "#{@testFolder}/another text file.txt" @newFileData = '' @client.writeFile @newFile, @newFileData, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true @client.readFile @newFile, (error, data, stat) => expect(error).to.equal null expect(data).to.equal @newFileData unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true done() it 'writes a new text file with ~ - and _ in the name', (done) -> @newFile = "#{@testFolder}/oauth~sig-test_file.txt" @newFileData = "A file whose name checks for OAuth signatures on ~-_" @client.writeFile @newFile, @newFileData, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true @client.readFile @newFile, (error, data, stat) => expect(error).to.equal null expect(data).to.equal @newFileData unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true done() it 'writes a Blob to a binary file', (done) -> return done() unless Blob? and ArrayBuffer? @newFile = "#{@testFolder}/test image from blob.png" newBuffer = new ArrayBuffer @imageFileBytes.length newBytes = new Uint8Array newBuffer for i in [0...@imageFileBytes.length] newBytes[i] = @imageFileBytes[i] @newBlob = buildBlob [newBytes], type: 'image/png' if @newBlob.size isnt newBuffer.byteLength @newBlob = buildBlob [newBuffer], type: 'image/png' @client.writeFile @newFile, @newBlob, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true expect(stat.size).to.equal @newBlob.size @client.readFile @newFile, arrayBuffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf ArrayBuffer expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true view = new Uint8Array buffer bytes = (view[i] for i in [0...buffer.byteLength]) expect(bytes).to.deep.equal @imageFileBytes done() it 'writes a File to a binary file', (done) -> return done() unless File? and Blob? and ArrayBuffer? @newFile = "#{@testFolder}/test image from file.png" newBuffer = new ArrayBuffer @imageFileBytes.length newBytes = new Uint8Array newBuffer for i in [0...@imageFileBytes.length] newBytes[i] = @imageFileBytes[i] # Called when we have a File wrapping newBlob. actualTestCase = (file) => @newFileObject = file @client.writeFile @newFile, @newFileObject, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true expect(stat.size).to.equal @newFileObject.size @client.readFile @newFile, arrayBuffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf ArrayBuffer expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true view = new Uint8Array buffer bytes = (view[i] for i in [0...buffer.byteLength]) expect(bytes).to.deep.equal @imageFileBytes done() try file = new File [newBuffer], 'test image file.png', type: 'image/png' actualTestCase file catch noFileConstructorError newBlob = buildBlob [newBytes], type: 'image/png' return done() if typeof webkitRequestFileSystem is 'undefined' webkitRequestFileSystem window.TEMPORARY, 1024 * 1024, (fileSystem) -> # NOTE: the File name is different from the uploaded file name, to # catch bugs such as http://crbug.com/165095 fileSystem.root.getFile 'test image file.png', create: true, exclusive: false, (fileEntry) -> fileEntry.createWriter (fileWriter) -> fileWriter.onwriteend = -> fileEntry.file (file) -> actualTestCase file fileWriter.write newBlob it 'writes an ArrayBuffer to a binary file', (done) -> return done() unless ArrayBuffer? @newFile = "#{@testFolder}/test image from arraybuffer.png" @newBuffer = new ArrayBuffer @imageFileBytes.length newBytes = new Uint8Array @newBuffer for i in [0...@imageFileBytes.length] newBytes[i] = @imageFileBytes[i] @client.writeFile @newFile, @newBuffer, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true expect(stat.size).to.equal @newBuffer.byteLength @client.readFile @newFile, arrayBuffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf ArrayBuffer expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true view = new Uint8Array buffer bytes = (view[i] for i in [0...buffer.byteLength]) expect(bytes).to.deep.equal @imageFileBytes done() it 'writes an ArrayBufferView to a binary file', (done) -> return done() unless ArrayBuffer? @newFile = "#{@testFolder}/test image from arraybufferview.png" @newBytes = new Uint8Array @imageFileBytes.length for i in [0...@imageFileBytes.length] @newBytes[i] = @imageFileBytes[i] @client.writeFile @newFile, @newBytes, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true expect(stat.size).to.equal @newBytes.byteLength @client.readFile @newFile, arrayBuffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf ArrayBuffer expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true view = new Uint8Array buffer bytes = (view[i] for i in [0...buffer.byteLength]) expect(bytes).to.deep.equal @imageFileBytes done() it 'writes a node.js Buffer to a binary file', (done) -> return done() unless Buffer? @newFile = "#{@testFolder}/test image from node buffer.png" @newBuffer = new Buffer @imageFileBytes.length for i in [0...@imageFileBytes.length] @newBuffer.writeUInt8 @imageFileBytes[i], i @client.writeFile @newFile, @newBuffer, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true expect(stat.size).to.equal @newBuffer.length @client.readFile @newFile, buffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf Buffer expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true bytes = (buffer.readUInt8(i) for i in [0...buffer.length]) expect(bytes).to.deep.equal @imageFileBytes done() describe '#resumableUploadStep + #resumableUploadFinish', -> beforeEach -> if ArrayBuffer? # IE9 and below doesn't have ArrayBuffer @length1 = Math.ceil @imageFileBytes.length / 3 @length2 = @imageFileBytes.length - @length1 @arrayBuffer1 = new ArrayBuffer @length1 @buffer1 = new Buffer @length1 if Buffer? @view1 = new Uint8Array @arrayBuffer1 for i in [0...@length1] @view1[i] = @imageFileBytes[i] if @buffer1 @buffer1.writeUInt8 @imageFileBytes[i], i @arrayBuffer2 = new ArrayBuffer @length2 @buffer2 = new Buffer @length2 if Buffer? @view2 = new Uint8Array @arrayBuffer2 for i in [0...@length2] @view2[i] = @imageFileBytes[@length1 + i] if @buffer2 @buffer2.writeUInt8 @imageFileBytes[@length1 + i], i if Blob? # node.js and IE9 and below don't have Blob @blob1 = buildBlob [@view1], type: 'image/png' if @blob1.size isnt @arrayBuffer1.byteLength @blob1 = buildBlob [@arrayBuffer1], type: 'image/png' @blob2 = buildBlob [@view2], type: 'image/png' if @blob2.size isnt @arrayBuffer2.byteLength @blob2 = buildBlob [@arrayBuffer2], type: 'image/png' afterEach (done) -> @timeout 30 * 1000 # This sequence is slow on the current API server. return done() unless @newFile @client.remove @newFile, (error, stat) -> done() it 'writes a text file in two stages', (done) -> @timeout 20 * 1000 # This sequence is slow on the current API server. @newFile = "#{@testFolder}/test resumable upload.txt" line1 = "This is the first fragment\n" line2 = "This is the second fragment\n" @client.resumableUploadStep line1, null, (error, cursor1) => expect(error).to.equal null expect(cursor1).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor1.offset).to.equal line1.length @client.resumableUploadStep line2, cursor1, (error, cursor2) => expect(error).to.equal null expect(cursor2).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor2.offset).to.equal line1.length + line2.length expect(cursor2.tag).to.equal cursor1.tag @client.resumableUploadFinish @newFile, cursor2, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true # TODO(pwnall): enable after API contents server bug is fixed #if clientKeys.key is testFullDropboxKeys.key # expect(stat.inAppFolder).to.equal false #else # expect(stat.inAppFolder).to.equal true @client.readFile @newFile, (error, data, stat) => expect(error).to.equal null expect(data).to.equal line1 + line2 unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true # TODO(pwnall): enable after API contents server bug is fixed #if clientKeys.key is testFullDropboxKeys.key # expect(stat.inAppFolder).to.equal false #else # expect(stat.inAppFolder).to.equal true done() it 'writes a binary file using two ArrayBuffers', (done) -> return done() unless @arrayBuffer1 @timeout 20 * 1000 # This sequence is slow on the current API server. @newFile = "#{@testFolder}/test resumable arraybuffer upload.png" @client.resumableUploadStep @arrayBuffer1, null, (error, cursor1) => expect(error).to.equal null expect(cursor1).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor1.offset).to.equal @length1 @client.resumableUploadStep @arrayBuffer2, cursor1, (error, cursor2) => expect(error).to.equal null expect(cursor2).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor2.offset).to.equal @length1 + @length2 expect(cursor2.tag).to.equal cursor1.tag @client.resumableUploadFinish @newFile, cursor2, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true @client.readFile @newFile, arrayBuffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf ArrayBuffer expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true view = new Uint8Array buffer bytes = (view[i] for i in [0...buffer.byteLength]) expect(bytes).to.deep.equal @imageFileBytes done() it 'writes a binary file using two ArrayBufferViews', (done) -> return done() unless @view1 @timeout 20 * 1000 # This sequence is slow on the current API server. @newFile = "#{@testFolder}/test resumable arraybuffer upload.png" @client.resumableUploadStep @arrayBuffer1, null, (error, cursor1) => expect(error).to.equal null expect(cursor1).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor1.offset).to.equal @length1 @client.resumableUploadStep @arrayBuffer2, cursor1, (error, cursor2) => expect(error).to.equal null expect(cursor2).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor2.offset).to.equal @length1 + @length2 expect(cursor2.tag).to.equal cursor1.tag @client.resumableUploadFinish @newFile, cursor2, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true @client.readFile @newFile, arrayBuffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf ArrayBuffer expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true view = new Uint8Array buffer bytes = (view[i] for i in [0...buffer.byteLength]) expect(bytes).to.deep.equal @imageFileBytes done() it 'writes a binary file using two node.js Buffers', (done) -> return done() unless @buffer1 @timeout 30 * 1000 # This sequence is slow on the current API server. @newFile = "#{@testFolder}/test resumable node buffer upload.png" @client.resumableUploadStep @buffer1, null, (error, cursor1) => expect(error).to.equal null expect(cursor1).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor1.offset).to.equal @length1 @client.resumableUploadStep @buffer2, cursor1, (error, cursor2) => expect(error).to.equal null expect(cursor2).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor2.offset).to.equal @length1 + @length2 expect(cursor2.tag).to.equal cursor1.tag @client.resumableUploadFinish @newFile, cursor2, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true @client.readFile @newFile, buffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf Buffer expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true bytes = (buffer.readUInt8(i) for i in [0...buffer.length]) expect(bytes).to.deep.equal @imageFileBytes done() it 'writes a binary file using two Blobs', (done) -> return done() unless @blob1 @timeout 20 * 1000 # This sequence is slow on the current API server. @newFile = "#{@testFolder}/test resumable blob upload.png" @client.resumableUploadStep @blob1, null, (error, cursor1) => expect(error).to.equal null expect(cursor1).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor1.offset).to.equal @length1 @client.resumableUploadStep @blob2, cursor1, (error, cursor2) => expect(error).to.equal null expect(cursor2).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor2.offset).to.equal @length1 + @length2 expect(cursor2.tag).to.equal cursor1.tag @client.resumableUploadFinish @newFile, cursor2, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true @client.readFile @newFile, arrayBuffer: true, (error, buffer, stat) => expect(error).to.equal null expect(buffer).to.be.instanceOf ArrayBuffer expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true view = new Uint8Array buffer bytes = (view[i] for i in [0...buffer.byteLength]) expect(bytes).to.deep.equal @imageFileBytes done() it 'recovers from out-of-sync correctly', (done) -> # IE's XDR doesn't return anything on errors, so we can't do recovery. return done() if Dropbox.Util.Xhr.ieXdr @timeout 20 * 1000 # This sequence is slow on the current API server. @newFile = "#{@testFolder}/test resumable upload out of sync.txt" line1 = "This is the first fragment\n" line2 = "This is the second fragment\n" @client.resumableUploadStep line1, null, (error, cursor1) => expect(error).to.equal null expect(cursor1).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor1.offset).to.equal line1.length cursor1.offset += 10 @client.resumableUploadStep line2, cursor1, (error, cursor2) => expect(error).to.equal null expect(cursor2).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor2.offset).to.equal line1.length expect(cursor2.tag).to.equal cursor1.tag @client.resumableUploadStep line2, cursor2, (error, cursor3) => expect(error).to.equal null expect(cursor3).to.be.instanceOf Dropbox.Http.UploadCursor expect(cursor3.offset).to.equal line1.length + line2.length expect(cursor3.tag).to.equal cursor1.tag @client.resumableUploadFinish @newFile, cursor3, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true @client.readFile @newFile, (error, data, stat) => expect(error).to.equal null expect(data).to.equal line1 + line2 unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true done() it 'reports errors correctly', (done) -> @newFile = "#{@testFolder}/test resumable upload error.txt" badCursor = new Dropbox.Http.UploadCursor 'trollcursor' badCursor.offset = 42 @client.resumableUploadStep @textFileData, badCursor, (error, cursor) => expect(cursor).to.equal undefined expect(error).to.be.instanceOf Dropbox.ApiError unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do status codes. expect(error.status).to.equal Dropbox.ApiError.NOT_FOUND done() describe '#stat', -> it 'retrieves a Stat for a file', (done) -> @client.stat @textFile, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @textFile expect(stat.isFile).to.equal true expect(stat.versionTag).to.equal @textFileTag expect(stat.size).to.equal @textFileData.length if clientKeys.key is testFullDropboxKeys.key expect(stat.inAppFolder).to.equal false else expect(stat.inAppFolder).to.equal true done() it 'retrieves a Stat for a folder', (done) -> @client.stat @testFolder, (error, stat, entries) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @testFolder expect(stat.isFolder).to.equal true expect(stat.size).to.equal 0 if clientKeys.key is testFullDropboxKeys.key expect(stat.inAppFolder).to.equal false else expect(stat.inAppFolder).to.equal true expect(entries).to.equal undefined done() it 'retrieves a Stat and entries for a folder', (done) -> @client.stat @testFolder, { readDir: true }, (error, stat, entries) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @testFolder expect(stat.isFolder).to.equal true expect(entries).to.be.ok expect(entries).to.have.length 2 expect(entries[0]).to.be.instanceOf Dropbox.File.Stat expect(entries[0].path).not.to.equal @testFolder expect(entries[0].path).to.have.string @testFolder done() it 'fails cleanly for a non-existing path', (done) -> listenerError = null @client.onError.addListener (error) -> listenerError = error @client.stat @testFolder + '/should_404.txt', (error, stat, entries) => expect(stat).to.equal undefined expect(entries).to.equal.null expect(error).to.be.instanceOf Dropbox.ApiError expect(listenerError).to.equal error unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do status codes. expect(error).to.have.property 'status' expect(error.status).to.equal Dropbox.ApiError.NOT_FOUND done() describe 'with httpCache', -> beforeEach -> @xhr = null @client.onXhr.addListener (xhr) => @xhr = xhr it 'retrieves a Stat for a file using Authorization headers', (done) -> @client.stat @textFile, httpCache: true, (error, stat) => if Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers expect(@xhr.url).to.contain 'access_token' else expect(@xhr.headers).to.have.key 'Authorization' expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @textFile expect(stat.isFile).to.equal true expect(stat.versionTag).to.equal @textFileTag expect(stat.size).to.equal @textFileData.length if clientKeys.key is testFullDropboxKeys.key expect(stat.inAppFolder).to.equal false else expect(stat.inAppFolder).to.equal true done() describe '#readdir', -> it 'retrieves a Stat and entries for a folder', (done) -> @client.readdir @testFolder, (error, entries, dirStat, entryStats) => expect(error).to.equal null expect(entries).to.be.ok expect(entries).to.have.length 2 expect(entries[0]).to.be.a 'string' expect(entries[0]).not.to.have.string '/' expect(entries[0]).to.match /^(test-binary-image.png)|(test-file.txt)$/ expect(dirStat).to.be.instanceOf Dropbox.File.Stat expect(dirStat.path).to.equal @testFolder expect(dirStat.isFolder).to.equal true if clientKeys.key is testFullDropboxKeys.key expect(dirStat.inAppFolder).to.equal false else expect(dirStat.inAppFolder).to.equal true expect(entryStats).to.be.ok expect(entryStats).to.have.length 2 expect(entryStats[0]).to.be.instanceOf Dropbox.File.Stat expect(entryStats[0].path).not.to.equal @testFolder expect(entryStats[0].path).to.have.string @testFolder done() describe 'with httpCache', -> beforeEach -> @xhr = null @client.onXhr.addListener (xhr) => @xhr = xhr it 'retrieves a folder Stat and entries using Authorization', (done) -> @client.readdir @testFolder, httpCache: true, (error, entries, dir_stat, entry_stats) => if Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers expect(@xhr.url).to.contain 'access_token' else expect(@xhr.headers).to.have.key 'Authorization' expect(error).to.equal null expect(entries).to.be.ok expect(entries).to.have.length 2 expect(entries[0]).to.be.a 'string' expect(entries[0]).not.to.have.string '/' expect(entries[0]).to.match( /^(test-binary-image.png)|(test-file.txt)$/) expect(dir_stat).to.be.instanceOf Dropbox.File.Stat expect(dir_stat.path).to.equal @testFolder expect(dir_stat.isFolder).to.equal true expect(entry_stats).to.be.ok expect(entry_stats).to.have.length 2 expect(entry_stats[0]).to.be.instanceOf Dropbox.File.Stat expect(entry_stats[0].path).not.to.equal @testFolder expect(entry_stats[0].path).to.have.string @testFolder done() describe 'with contentHash', (done) -> beforeEach (done) -> @client.readdir @testFolder, (error, entries, dirStat) => expect(error).to.equal null @contentHash = dirStat.contentHash done() it 'does not retrieve a folder twice if the tag matches', (done) -> @client.readdir @testFolder, contentHash: @contentHash, (error, entries) -> expect(error).to.be.instanceOf Dropbox.ApiError expect(entries).not.to.be.ok unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do status codes expect(error.status).to.equal Dropbox.ApiError.NO_CONTENT done() describe '#history', -> it 'gets a list of revisions', (done) -> @client.history @textFile, (error, versions) => expect(error).to.equal null expect(versions).to.have.length 1 expect(versions[0]).to.be.instanceOf Dropbox.File.Stat expect(versions[0].path).to.equal @textFile expect(versions[0].size).to.equal @textFileData.length expect(versions[0].versionTag).to.equal @textFileTag done() it 'returns 40x if the limit is set to 0', (done) -> listenerError = null @client.onError.addListener (error) -> listenerError = error @client.history @textFile, limit: 0, (error, versions) => expect(error).to.be.instanceOf Dropbox.ApiError expect(listenerError).to.equal error unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do status codes. expect(error.status).to.be.within 400, 499 expect(versions).not.to.be.ok done() describe 'with httpCache', -> beforeEach -> @xhr = null @client.onXhr.addListener (xhr) => @xhr = xhr it 'gets a list of revisions using Authorization headers', (done) -> @client.history @textFile, httpCache: true, (error, versions) => if Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers expect(@xhr.url).to.contain 'access_token' else expect(@xhr.headers).to.have.key 'Authorization' expect(error).to.equal null expect(versions).to.have.length 1 expect(versions[0]).to.be.instanceOf Dropbox.File.Stat expect(versions[0].path).to.equal @textFile expect(versions[0].size).to.equal @textFileData.length expect(versions[0].versionTag).to.equal @textFileTag done() describe '#copy', -> beforeEach -> @newFile = null afterEach (done) -> return done() unless @newFile @client.remove @newFile, (error, stat) -> done() it 'copies a file given by path', (done) -> @newFile = "#{@testFolder}/copy of test-file.txt" @client.copy @textFile, @newFile, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile if clientKeys.key is testFullDropboxKeys.key expect(stat.inAppFolder).to.equal false else expect(stat.inAppFolder).to.equal true @client.readFile @newFile, (error, data, stat) => expect(error).to.equal null expect(data).to.equal @textFileData unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile @client.readFile @textFile, (error, data, stat) => expect(error).to.equal null expect(data).to.equal @textFileData unless Dropbox.Util.Xhr.ieXdr # IE's XDR doesn't do headers. expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @textFile expect(stat.versionTag).to.equal @textFileTag done() describe '#makeCopyReference', -> beforeEach -> @newFile = null afterEach (done) -> return done() unless @newFile @client.remove @newFile, (error, stat) -> done() it 'creates a Dropbox.File.CopyReference that copies the file', (done) -> @newFile = "#{@testFolder}/ref copy of test-file.txt" @client.makeCopyReference @textFile, (error, copyRef) => expect(error).to.equal null expect(copyRef).to.be.instanceOf Dropbox.File.CopyReference @client.copy copyRef, @newFile, (error, stat) => expect(error).to.equal null expect(stat).to.be.instanceOf Dropbox.File.Stat expect(stat.path).to.equal @newFile expect(stat.isFile).to.equal true # TODO(pwnall): enable after API contents server bug is fixed # if clientKeys.key is testFullDropboxKey