Skip to content

Commit

Permalink
Provide last response to onSuccess callback (#689)
Browse files Browse the repository at this point in the history
* Pass response to onSuccess callback

* Change onSucess callback to object, add tests.

* Update test/spec/test-common.js

Co-authored-by: Marius <[email protected]>

* Update docs/api.md

Co-authored-by: Marius <[email protected]>

* Update docs/api.md

Co-authored-by: Marius <[email protected]>

* Update lib/upload.js

---------

Co-authored-by: Marius <[email protected]>
  • Loading branch information
netdown and Acconut authored Jul 31, 2024
1 parent f929e55 commit 2387d07
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 7 deletions.
10 changes: 10 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ _Default value:_ `null`

An optional function called when the upload finished successfully.

The argument will be an object with information about the completed upload. Its `lastResponse` property contains lastly received [`HttpResponse`](#httpstack), which can be used to retrieve additional data from the server. Be aware that this is usually a response to a `PATCH` request, but it might also be a response for a `POST` request (if `uploadDataDuringCreation` is enabled or an empty file is uploaded) or `HEAD` request (if an already completed upload is resumed).

```js
onSuccess: function (payload) {
const { lastResponse } = payload
// Server can include details in the Upload-Info header, for example.
console.log("Important information", lastResponse.getHeader('Upload-Info'))
}
```

#### onError

_Default value:_ `null`
Expand Down
13 changes: 7 additions & 6 deletions lib/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ class BaseUpload {
this.url = resolveUrl(this.options.endpoint, location)
log(`Created upload at ${this.url}`)

this._emitSuccess()
this._emitSuccess(res)
})
.catch((err) => {
this._emitError(err)
Expand Down Expand Up @@ -519,17 +519,18 @@ class BaseUpload {
/**
* Publishes notification if the upload has been successfully completed.
*
* @param {object} lastResponse Last HTTP response.
* @api private
*/
_emitSuccess() {
_emitSuccess(lastResponse) {
if (this.options.removeFingerprintOnSuccess) {
// Remove stored fingerprint and corresponding endpoint. This causes
// new uploads of the same file to be treated as a different file.
this._removeFromUrlStorage()
}

if (typeof this.options.onSuccess === 'function') {
this.options.onSuccess()
this.options.onSuccess({ lastResponse })
}
}

Expand Down Expand Up @@ -622,7 +623,7 @@ class BaseUpload {

if (this._size === 0) {
// Nothing to upload and file was successfully created
this._emitSuccess()
this._emitSuccess(res)
this._source.close()
return
}
Expand Down Expand Up @@ -713,7 +714,7 @@ class BaseUpload {
// data to the server
if (offset === length) {
this._emitProgress(length, length)
this._emitSuccess()
this._emitSuccess(res)
return
}

Expand Down Expand Up @@ -858,7 +859,7 @@ class BaseUpload {

if (offset === this._size) {
// Yay, finally done :)
this._emitSuccess()
this._emitSuccess(res)
this._source.close()
return
}
Expand Down
1 change: 1 addition & 0 deletions test/spec/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class TestResponse {

module.exports = {
TestHttpStack,
TestResponse,
waitableFunction,
wait,
getBlob,
Expand Down
29 changes: 28 additions & 1 deletion test/spec/test-common.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { TestHttpStack, waitableFunction, wait, getBlob } = require('./helpers/utils')
const { TestHttpStack, waitableFunction, wait, getBlob, TestResponse } = require('./helpers/utils')
const tus = require('../..')

// Uncomment to enable debug log from tus-js-client
Expand Down Expand Up @@ -308,6 +308,33 @@ describe('tus', () => {
expect(options.onAfterResponse).toHaveBeenCalled()
})

it('should invoke the onSuccess callback with event payload', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const options = {
httpStack: testStack,
uploadUrl: 'http://tus.io/uploads/foo',
onSuccess: waitableFunction('onSuccess'),
}

const upload = new tus.Upload(file, options)
upload.start()

const req = await testStack.nextRequest()
req.respondWith({
status: 204,
responseHeaders: {
'Upload-Offset': 11,
'Upload-Length': 11,
'Custom-Header': 'hello',
},
})

const { lastResponse } = await options.onSuccess.toBeCalled
expect(lastResponse).toBeInstanceOf(TestResponse)
expect(lastResponse.getHeader('Custom-Header')).toBe('hello')
})

it('should throw an error if resuming fails and no endpoint is provided', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
Expand Down

0 comments on commit 2387d07

Please sign in to comment.