From e854f30484a0efcef8f33ffe702ea0fa1c51edc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Legan=C3=A9s-Combarro=20=27piranna?= Date: Wed, 19 Oct 2022 16:43:10 +0400 Subject: [PATCH 1/2] Allow `string` data on `Upload` constructor --- lib/browser/fileReader.js | 8 +++++++- lib/node/fileReader.js | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/browser/fileReader.js b/lib/browser/fileReader.js index cc10a9271..aa14b8de3 100644 --- a/lib/browser/fileReader.js +++ b/lib/browser/fileReader.js @@ -6,6 +6,10 @@ import StreamSource from './sources/StreamSource.js' export default class FileReader { openFile (input, chunkSize) { + if (typeof input === 'string') { + input = new Blob(input.split('')) + } + // In React Native, when user selects a file, instead of a File or Blob, // you usually get a file object {} with a uri property that contains // a local path to the file. We use XMLHttpRequest to fetch @@ -35,6 +39,8 @@ export default class FileReader { return Promise.resolve(new StreamSource(input, chunkSize)) } - return Promise.reject(new Error('source object may only be an instance of File, Blob, or Reader in this environment')) + return Promise.reject(new Error( + 'source object may only be an instance of string, File, Blob, or Reader in this environment', + )) } } diff --git a/lib/node/fileReader.js b/lib/node/fileReader.js index a0757d8cc..29cbb3896 100644 --- a/lib/node/fileReader.js +++ b/lib/node/fileReader.js @@ -7,6 +7,10 @@ import StreamSource from './sources/StreamSource.js' export default class FileReader { openFile (input, chunkSize) { + if (typeof input === 'string') { + input = Buffer.from(input) + } + if (Buffer.isBuffer(input)) { return Promise.resolve(new BufferSource(input)) } @@ -23,6 +27,8 @@ export default class FileReader { return Promise.resolve(new StreamSource(input)) } - return Promise.reject(new Error('source object may only be an instance of Buffer or Readable in this environment')) + return Promise.reject(new Error( + 'source object may only be an instance of string, Buffer or Readable in this environment', + )) } } From 828f8f99527a87af210fa1f27d8be299a1c5355e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Legan=C3=A9s-Combarro=20=27piranna?= Date: Wed, 19 Oct 2022 17:38:11 +0400 Subject: [PATCH 2/2] Remove now useless `getBlob()` tests helper function --- lib/upload.js | 2 +- test/spec/helpers/utils.js | 15 -------- test/spec/test-common.js | 58 +++++++++++++++--------------- test/spec/test-end-to-end.js | 5 ++- test/spec/test-parallel-uploads.js | 18 +++++----- test/spec/test-terminate.js | 6 ++-- 6 files changed, 44 insertions(+), 60 deletions(-) diff --git a/lib/upload.js b/lib/upload.js index 25ff92f05..4d778f0b1 100644 --- a/lib/upload.js +++ b/lib/upload.js @@ -159,7 +159,7 @@ class BaseUpload { start () { const { file } = this - if (!file) { + if (file == null) { this._emitError(new Error('tus: no file or stream to upload provided')) return } diff --git a/test/spec/helpers/utils.js b/test/spec/helpers/utils.js index 5b07a0d0a..1804b3052 100644 --- a/test/spec/helpers/utils.js +++ b/test/spec/helpers/utils.js @@ -2,20 +2,6 @@ 'use strict' -const isBrowser = typeof window !== 'undefined' -const isNode = !isBrowser - -/** - * Obtain a platform specific buffer object, which can be - * handled by tus-js-client. - */ -function getBlob (str) { - if (isNode) { - return Buffer.from(str) - } - return new Blob(str.split('')) -} - /** * Create a promise and obtain the resolve/reject functions * outside of the Promise callback. @@ -174,5 +160,4 @@ module.exports = { TestHttpStack, waitableFunction, wait, - getBlob, } diff --git a/test/spec/test-common.js b/test/spec/test-common.js index 1de4305f0..097c0daad 100644 --- a/test/spec/test-common.js +++ b/test/spec/test-common.js @@ -1,6 +1,6 @@ 'use strict' -const { TestHttpStack, waitableFunction, wait, getBlob } = require('./helpers/utils') +const { TestHttpStack, waitableFunction, wait } = require('./helpers/utils') const tus = require('../..') // Uncomment to enable debug log from tus-js-client @@ -20,14 +20,14 @@ describe('tus', () => { }) it('should throw if no endpoint and upload URL is provided', () => { - const file = getBlob('hello world') + const file = 'hello world' const upload = new tus.Upload(file) expect(upload.start.bind(upload)).toThrowError('tus: neither an endpoint or an upload URL is provided') }) it('should upload a file', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, endpoint : 'https://tus.io/uploads', @@ -92,7 +92,7 @@ describe('tus', () => { it('should create an upload if resuming fails', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, endpoint : 'http://tus.io/uploads', @@ -123,7 +123,7 @@ describe('tus', () => { it('should create an upload using the creation-with-data extension', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/uploads', @@ -166,7 +166,7 @@ describe('tus', () => { it('should create an upload with partial data and continue', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/uploads', @@ -231,7 +231,7 @@ describe('tus', () => { it("should add the request's body and ID to errors", async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/uploads', @@ -265,7 +265,7 @@ describe('tus', () => { it('should invoke the request and response callbacks', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, uploadUrl: 'http://tus.io/uploads/foo', @@ -306,7 +306,7 @@ describe('tus', () => { it('should throw an error if resuming fails and no endpoint is provided', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, uploadUrl: 'http://tus.io/uploads/resuming', @@ -331,7 +331,7 @@ describe('tus', () => { it('should resolve relative URLs', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, endpoint : 'http://tus.io:1080/files/', @@ -367,7 +367,7 @@ describe('tus', () => { it('should upload a file in chunks', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, endpoint : 'http://tus.io/uploads', @@ -435,7 +435,7 @@ describe('tus', () => { it('should add the original request to errors', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/uploads', @@ -468,7 +468,7 @@ describe('tus', () => { it('should only create an upload for empty files', async () => { const testStack = new TestHttpStack() - const file = getBlob('') + const file = '' const options = { httpStack: testStack, endpoint : 'http://tus.io/uploads', @@ -497,7 +497,7 @@ describe('tus', () => { it('should not resume a finished upload', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, endpoint : 'http://tus.io/uploads', @@ -531,7 +531,7 @@ describe('tus', () => { it('should resume an upload from a specified url', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, endpoint : 'http://tus.io/uploads', @@ -583,7 +583,7 @@ describe('tus', () => { it('should resume a previously started upload', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, endpoint : 'http://tus.io/uploads', @@ -649,7 +649,7 @@ describe('tus', () => { it('should override the PATCH method', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/uploads', @@ -690,7 +690,7 @@ describe('tus', () => { it('should emit an error if an upload is locked', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/uploads', @@ -716,7 +716,7 @@ describe('tus', () => { it('should emit an error if no Location header is presented', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/uploads', @@ -742,7 +742,7 @@ describe('tus', () => { }) it('should throw if retryDelays is not an array', () => { - const file = getBlob('hello world') + const file = 'hello world' const upload = new tus.Upload(file, { endpoint : 'http://endpoint/', retryDelays: 44, @@ -754,7 +754,7 @@ describe('tus', () => { // response has the code 500 Internal Error, 423 Locked or 409 Conflict. it('should retry the upload', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/files/', @@ -843,7 +843,7 @@ describe('tus', () => { // return value of onShouldRetry is true. it('should retry the upload when onShouldRetry specified and returns true', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/files/', @@ -942,7 +942,7 @@ describe('tus', () => { // return value of onShouldRetry is false. it('should not retry the upload when callback specified and returns false', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/files/', @@ -973,7 +973,7 @@ describe('tus', () => { }) it('should not retry if the error has not been caused by a request', async () => { - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : new TestHttpStack(), endpoint : 'http://tus.io/files/', @@ -1001,7 +1001,7 @@ describe('tus', () => { it('should stop retrying after all delays have been used', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/files/', @@ -1041,7 +1041,7 @@ describe('tus', () => { it('should stop retrying when the abort function is called', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/files/', @@ -1076,7 +1076,7 @@ describe('tus', () => { it('should stop upload when the abort function is called during a callback', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, endpoint : 'http://tus.io/files/', @@ -1124,7 +1124,7 @@ describe('tus', () => { it('should stop upload when the abort function is called during the POST request', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, endpoint : 'http://tus.io/files/', @@ -1160,7 +1160,7 @@ describe('tus', () => { it('should reset the attempt counter if an upload proceeds', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/files/', diff --git a/test/spec/test-end-to-end.js b/test/spec/test-end-to-end.js index e5500089f..cb8a85aa3 100644 --- a/test/spec/test-end-to-end.js +++ b/test/spec/test-end-to-end.js @@ -1,7 +1,6 @@ 'use strict' const axios = require('axios') -const { getBlob } = require('./helpers/utils') const tus = require('../..') // Test timeout for end-to-end tests when uploading to real server. @@ -11,7 +10,7 @@ describe('tus', () => { describe('end-to-end', () => { it('should upload to a real tus server', async () => { return new Promise((resolve, reject) => { - const file = getBlob('hello world') + const file = 'hello world' const options = { endpoint: 'https://tusd.tusdemo.net/files/', metadata: { @@ -44,7 +43,7 @@ describe('tus', () => { it('should upload to a real tus server with creation-with-upload', async () => { return new Promise((resolve, reject) => { - const file = getBlob('hello world') + const file = 'hello world' const options = { endpoint: 'https://tusd.tusdemo.net/files/', metadata: { diff --git a/test/spec/test-parallel-uploads.js b/test/spec/test-parallel-uploads.js index 1002693f0..b169cc638 100644 --- a/test/spec/test-parallel-uploads.js +++ b/test/spec/test-parallel-uploads.js @@ -1,12 +1,12 @@ 'use strict' -const { TestHttpStack, waitableFunction, wait, getBlob } = require('./helpers/utils') +const { TestHttpStack, waitableFunction, wait } = require('./helpers/utils') const tus = require('../..') describe('tus', () => { describe('parallel uploading', () => { it('should throw if incompatible options are used', () => { - const file = getBlob('hello world') + const file = 'hello world' const upload = new tus.Upload(file, { endpoint : 'https://tus.io/uploads', parallelUploads: 2, @@ -16,7 +16,7 @@ describe('tus', () => { }) it('should throw if `parallelUploadBoundaries` is passed without `parallelUploads`', () => { - const file = getBlob('hello world') + const file = 'hello world' const upload = new tus.Upload(file, { endpoint : 'https://tus.io/uploads', parallelUploadBoundaries: [{ start: 0, end: 2 }], @@ -25,7 +25,7 @@ describe('tus', () => { }) it('should throw if `parallelUploadBoundaries` is not the same length as the value of `parallelUploads`', () => { - const file = getBlob('hello world') + const file = 'hello world' const upload = new tus.Upload(file, { endpoint : 'https://tus.io/uploads', parallelUploads : 3, @@ -57,7 +57,7 @@ describe('tus', () => { spyOn(testUrlStorage, 'removeUpload').and.callThrough() spyOn(testUrlStorage, 'addUpload').and.callThrough() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, urlStorage : testUrlStorage, @@ -203,7 +203,7 @@ describe('tus', () => { const testStack = new TestHttpStack() const parallelUploadBoundaries = [{ start: 0, end: 1 }, { start: 1, end: 11 }] - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, parallelUploads: 2, @@ -310,7 +310,7 @@ describe('tus', () => { it('should emit error from a partial upload', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, parallelUploads: 2, @@ -339,7 +339,7 @@ describe('tus', () => { it('should resume the partial uploads', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, // The client should resume the parallel uploads, even if it is not @@ -432,7 +432,7 @@ describe('tus', () => { it('should abort all partial uploads and resume from them', async () => { const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, parallelUploads: 2, diff --git a/test/spec/test-terminate.js b/test/spec/test-terminate.js index f257ae087..b29621dd8 100644 --- a/test/spec/test-terminate.js +++ b/test/spec/test-terminate.js @@ -1,6 +1,6 @@ 'use strict' -const { TestHttpStack, getBlob } = require('./helpers/utils') +const { TestHttpStack } = require('./helpers/utils') const tus = require('../..') describe('tus', () => { @@ -8,7 +8,7 @@ describe('tus', () => { it('should terminate upload when abort is called with true', async () => { let abortPromise const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack: testStack, endpoint : 'http://tus.io/files/', @@ -60,7 +60,7 @@ describe('tus', () => { it('should retry terminate when an error is returned on first try', async () => { let abortPromise const testStack = new TestHttpStack() - const file = getBlob('hello world') + const file = 'hello world' const options = { httpStack : testStack, endpoint : 'http://tus.io/files/',