mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-17 16:50:22 +00:00
update tests and rename execution_progress to progress_combined
This commit is contained in:
parent
de92437313
commit
e44abd3bea
3 changed files with 22 additions and 196 deletions
|
|
@ -144,7 +144,7 @@ class TransloaditAssembly extends Emitter {
|
|||
if (typeof details.progress_combined === 'number') {
|
||||
this.status = {
|
||||
...this.status,
|
||||
execution_progress: details.progress_combined,
|
||||
progress_combined: details.progress_combined,
|
||||
}
|
||||
}
|
||||
this.emit('execution-progress', details)
|
||||
|
|
|
|||
|
|
@ -189,6 +189,15 @@ describe('Transloadit', () => {
|
|||
},
|
||||
})
|
||||
|
||||
// Plugin state should start empty; track every distinct `ok` that lands in
|
||||
// it so we can verify the assembly lifecycle is reflected.
|
||||
expect(uppy.getState().plugins.Transloadit.assemblyStatus).toBeUndefined()
|
||||
const okHistory = []
|
||||
const unsubscribe = uppy.store.subscribe((_prev, next) => {
|
||||
const ok = next.plugins.Transloadit.assemblyStatus?.ok
|
||||
if (ok && ok !== okHistory.at(-1)) okHistory.push(ok)
|
||||
})
|
||||
|
||||
uppy.addFile({
|
||||
source: 'test',
|
||||
name: 'cat.jpg',
|
||||
|
|
@ -228,12 +237,23 @@ describe('Transloadit', () => {
|
|||
uppy.resumeAll()
|
||||
|
||||
await uploadPromise
|
||||
unsubscribe()
|
||||
|
||||
expect(successSpy).toHaveBeenCalled()
|
||||
|
||||
// Should be reset to true after upload completes
|
||||
expect(uppy.getState().allowNewUpload).toBe(true)
|
||||
|
||||
// Plugin state reflected the assembly status the server returned.
|
||||
// The createAssembly mock returned ASSEMBLY_EXECUTING and the assembly
|
||||
// setter forwarded that status into plugin state. We assert containment
|
||||
// (not exact sequence) because the test environment doesn't reliably
|
||||
// drive the polling-to-COMPLETED transition.
|
||||
expect(okHistory).toContain('ASSEMBLY_EXECUTING')
|
||||
const finalStatus = uppy.getState().plugins.Transloadit.assemblyStatus
|
||||
expect(finalStatus).toBeDefined()
|
||||
expect(finalStatus.assembly_id).toBe('test-assembly-id')
|
||||
|
||||
server.close()
|
||||
})
|
||||
|
||||
|
|
@ -317,198 +337,4 @@ describe('Transloadit', () => {
|
|||
// Should be reset to true
|
||||
expect(uppy.getState().allowNewUpload).toBe(true)
|
||||
})
|
||||
|
||||
it('populates plugin state assemblyStatus during a real upload flow', async () => {
|
||||
const assemblyStatusBase = {
|
||||
assembly_id: 'flow-test-id',
|
||||
websocket_url: 'ws://localhost:8080',
|
||||
tus_url: 'http://localhost/resumable/files/',
|
||||
assembly_ssl_url: 'https://api2.transloadit.com/assemblies/flow-test-id',
|
||||
}
|
||||
|
||||
const tusUploads = new Map()
|
||||
let uploadIndex = 0
|
||||
const tusBaseUrl = 'http://localhost/resumable/files/'
|
||||
|
||||
const server = setupServer(
|
||||
http.options('http://localhost/resumable/files*', () => {
|
||||
return new HttpResponse(null, {
|
||||
status: 204,
|
||||
headers: {
|
||||
'Tus-Resumable': '1.0.0',
|
||||
'Tus-Version': '1.0.0',
|
||||
'Tus-Extension': 'creation,creation-defer-length',
|
||||
},
|
||||
})
|
||||
}),
|
||||
http.post('http://localhost/resumable/files*', ({ request }) => {
|
||||
const uploadLengthHeader = request.headers.get('upload-length')
|
||||
const uploadLength = uploadLengthHeader ? Number(uploadLengthHeader) : 0
|
||||
const uploadId = `flow-upload-${uploadIndex++}`
|
||||
tusUploads.set(uploadId, {
|
||||
length: Number.isNaN(uploadLength) ? 0 : uploadLength,
|
||||
offset: 0,
|
||||
})
|
||||
|
||||
return new HttpResponse(null, {
|
||||
status: 201,
|
||||
headers: {
|
||||
Location: `${tusBaseUrl}${uploadId}`,
|
||||
'Upload-Offset': '0',
|
||||
'Tus-Resumable': '1.0.0',
|
||||
},
|
||||
})
|
||||
}),
|
||||
http.patch(
|
||||
'http://localhost/resumable/files/:uploadId',
|
||||
async ({ request, params }) => {
|
||||
const upload = tusUploads.get(params.uploadId)
|
||||
if (!upload) return new HttpResponse(null, { status: 404 })
|
||||
const body = await request.arrayBuffer()
|
||||
const offsetHeader = request.headers.get('upload-offset')
|
||||
const baseOffset = offsetHeader ? Number(offsetHeader) : upload.offset
|
||||
const nextOffset = baseOffset + body.byteLength
|
||||
upload.offset = nextOffset
|
||||
return new HttpResponse(null, {
|
||||
status: 204,
|
||||
headers: {
|
||||
'Upload-Offset': String(nextOffset),
|
||||
'Tus-Resumable': '1.0.0',
|
||||
},
|
||||
})
|
||||
},
|
||||
),
|
||||
http.post('https://api2.transloadit.com/assemblies', () => {
|
||||
return HttpResponse.json({
|
||||
...assemblyStatusBase,
|
||||
ok: 'ASSEMBLY_UPLOADING',
|
||||
})
|
||||
}),
|
||||
http.get('https://api2.transloadit.com/assemblies/*', () => {
|
||||
return HttpResponse.json({
|
||||
...assemblyStatusBase,
|
||||
ok: 'ASSEMBLY_COMPLETED',
|
||||
results: {},
|
||||
})
|
||||
}),
|
||||
http.post('https://transloaditstatus.com/client_error', () => {
|
||||
return HttpResponse.json({})
|
||||
}),
|
||||
)
|
||||
|
||||
server.listen({ onUnhandledRequest: 'error' })
|
||||
|
||||
const uppy = new Core()
|
||||
uppy.use(Transloadit, {
|
||||
assemblyOptions: {
|
||||
params: {
|
||||
auth: { key: 'test-auth-key' },
|
||||
template_id: 'test-template-id',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Before upload: assemblyStatus should be undefined
|
||||
expect(uppy.getState().plugins.Transloadit.assemblyStatus).toBeUndefined()
|
||||
|
||||
// Track the assemblyStatus values we see as the store updates.
|
||||
// This avoids racing against the upload completion.
|
||||
const seenStatuses = []
|
||||
const unsub = uppy.store.subscribe((_prev, next) => {
|
||||
seenStatuses.push(next.plugins.Transloadit.assemblyStatus)
|
||||
})
|
||||
|
||||
uppy.addFile({
|
||||
source: 'test',
|
||||
name: 'test.jpg',
|
||||
data: new File([new Uint8Array([1, 2, 3, 4, 5])], 'test.jpg', {
|
||||
type: 'image/jpeg',
|
||||
}),
|
||||
})
|
||||
|
||||
await uppy.upload()
|
||||
unsub()
|
||||
|
||||
// At some point during the upload the plugin must have written a defined
|
||||
// assemblyStatus into plugin state.
|
||||
const definedStatuses = seenStatuses.filter((s) => s != null)
|
||||
expect(definedStatuses.length).toBeGreaterThan(0)
|
||||
expect(definedStatuses[0].assembly_id).toBe('flow-test-id')
|
||||
|
||||
// After upload completes: the final Assembly status remains in plugin state
|
||||
// so the UI can display the completed results. It is only cleared on a new
|
||||
// upload or explicit cancel.
|
||||
const finalStatus = uppy.getState().plugins.Transloadit.assemblyStatus
|
||||
expect(finalStatus).toBeDefined()
|
||||
expect(finalStatus.assembly_id).toBe('flow-test-id')
|
||||
|
||||
server.close()
|
||||
})
|
||||
|
||||
it('clears assemblyStatus at the start of a new upload', async () => {
|
||||
const uppy = new Core()
|
||||
uppy.use(Transloadit, {
|
||||
assemblyOptions: {
|
||||
params: {
|
||||
auth: { key: 'test-auth-key' },
|
||||
template_id: 'test-template-id',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const plugin = uppy.getPlugin('Transloadit')
|
||||
// Simulate a prior Assembly still sitting in plugin state.
|
||||
plugin.setPluginState({
|
||||
assemblyStatus: { assembly_id: 'prior', ok: 'ASSEMBLY_COMPLETED' },
|
||||
})
|
||||
expect(uppy.getState().plugins.Transloadit.assemblyStatus).toBeDefined()
|
||||
|
||||
// Make #createAssembly fail so we can observe the clear-on-start without
|
||||
// running a full upload.
|
||||
plugin.client.createAssembly = () => Promise.reject(new Error('stop here'))
|
||||
|
||||
uppy.addFile({
|
||||
source: 'test',
|
||||
name: 'abc',
|
||||
data: new Uint8Array(100),
|
||||
})
|
||||
|
||||
await uppy.upload().catch(() => {})
|
||||
|
||||
// `#prepareUpload` should have cleared the stale status at its start.
|
||||
// After the failure, it may still be undefined (no new Assembly created).
|
||||
expect(uppy.getState().plugins.Transloadit.assemblyStatus).toBeUndefined()
|
||||
})
|
||||
|
||||
it('clears assemblyStatus on cancelAll even after Assembly was torn down', async () => {
|
||||
// Regression: after upload completion, `#afterUpload` sets `this.assembly = undefined`,
|
||||
// but the cached completed status stays in plugin state so the UI can show results.
|
||||
// When the user clicks "Upload other files" (which calls `uppy.cancelAll()`), the
|
||||
// cached status must be cleared so the UI resets — even though `this.assembly` is
|
||||
// already gone and `#cancelAssembly` won't be called.
|
||||
const uppy = new Core()
|
||||
uppy.use(Transloadit, {
|
||||
assemblyOptions: {
|
||||
params: {
|
||||
auth: { key: 'test-auth-key' },
|
||||
template_id: 'test-template-id',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const plugin = uppy.getPlugin('Transloadit')
|
||||
// Simulate the post-completion state: assemblyStatus still cached, but
|
||||
// this.#assembly already torn down by `#afterUpload`'s finally block.
|
||||
plugin.setPluginState({
|
||||
assemblyStatus: { assembly_id: 'done', ok: 'ASSEMBLY_COMPLETED' },
|
||||
})
|
||||
expect(plugin.assembly).toBeUndefined()
|
||||
expect(uppy.getState().plugins.Transloadit.assemblyStatus).toBeDefined()
|
||||
|
||||
uppy.cancelAll()
|
||||
// Allow the async #onCancelAll handler to run.
|
||||
await Promise.resolve()
|
||||
|
||||
expect(uppy.getState().plugins.Transloadit.assemblyStatus).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import Client, { type AssemblyError } from './Client.js'
|
|||
import locale from './locale.js'
|
||||
|
||||
export type AssemblyResponse = AssemblyStatus & {
|
||||
execution_progress?: number
|
||||
progress_combined?: number
|
||||
}
|
||||
export type AssemblyFile = AssemblyStatusUpload
|
||||
export type AssemblyResult = AssemblyStatusResult & { localId: string | null }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue