Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/dot-notation */
import { ComponentType, type ComponentDef } from '@defra/forms-model'
import Boom from '@hapi/boom'
import { type ValidationErrorItem, type ValidationResult } from 'joi'

import {
Expand Down Expand Up @@ -195,6 +196,89 @@ describe('FileUploadPageController', () => {
)
})

it('initiates new upload when getUploadStatus throws a 404 error', async () => {
const state = {
upload: {
[controller.path]: {
upload: {
uploadId: 'some-id',
uploadUrl: 'some-url',
statusUrl: 'some-status-url'
},
files: []
}
}
} as unknown as FormSubmissionState

const notFoundError = Boom.notFound('Upload not found')

jest
.spyOn(uploadService, 'getUploadStatus')
.mockRejectedValue(notFoundError)

const testController = controller as TestableFileUploadPageController
const initiateSpy = jest.spyOn(
testController,
'initiateAndStoreNewUpload'
)
initiateSpy.mockResolvedValue(state as never)

const result = await controller['checkUploadStatus'](request, state, 1)

expect(initiateSpy).toHaveBeenCalledWith(request, state)
expect(result).toBe(state)
})

it('re-throws non-404 Boom errors from getUploadStatus', async () => {
const state = {
upload: {
[controller.path]: {
upload: {
uploadId: 'some-id',
uploadUrl: 'some-url',
statusUrl: 'some-status-url'
},
files: []
}
}
} as unknown as FormSubmissionState

const serverError = Boom.internal('Server error')

jest
.spyOn(uploadService, 'getUploadStatus')
.mockRejectedValue(serverError)

await expect(
controller['checkUploadStatus'](request, state, 1)
).rejects.toThrow('Server error')
})

it('re-throws non-Boom errors from getUploadStatus', async () => {
const state = {
upload: {
[controller.path]: {
upload: {
uploadId: 'some-id',
uploadUrl: 'some-url',
statusUrl: 'some-status-url'
},
files: []
}
}
} as unknown as FormSubmissionState

const networkError = new Error('Network failure')

jest
.spyOn(uploadService, 'getUploadStatus')
.mockRejectedValue(networkError)

await expect(
controller['checkUploadStatus'](request, state, 1)
).rejects.toThrow('Network failure')
})

it('handles pending upload with backoff and retries', async () => {
const state = {
upload: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,22 @@ export class FileUploadPageController extends QuestionPageController {
}

const uploadId = upload.uploadId
const statusResponse = await getUploadStatus(uploadId)

let statusResponse

try {
statusResponse = await getUploadStatus(uploadId)
} catch (err) {
// if the user loads a file upload page and queries the cached upload, after the upload has
// expired in CDP, we will get a 404 from the getUploadStatus endpoint.
// In this case we want to initiate a new upload and return that state, so the form
// doesn't blow up for the end user.
if (Boom.isBoom(err) && err.output.statusCode === 404) {
Comment thread
alexluckett marked this conversation as resolved.
Outdated
return this.initiateAndStoreNewUpload(request, state)
}
throw err
}

if (!statusResponse) {
throw Boom.badRequest(
`Unexpected empty response from getUploadStatus for ${uploadId}`
Expand Down
Loading