Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
31 changes: 18 additions & 13 deletions designer/server/src/routes/admin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,7 @@ async function processForm(metadata, token, archive) {
archive.append(metadataJson, { name: metadataName })

// Then append definitions under {id}/definition_*.json
const definition = await getFormDefinitions(
metadata.id,
!!metadata.draft,
token
)
const definition = await getFormDefinitions(metadata.id, token)
appendFormDefinitionsToArchive(metadata.id, archive, definition)
}

Expand Down Expand Up @@ -322,21 +318,30 @@ function appendManifestToArchive(archive, totalForms, manifestEntities) {
/**
* Retrieve both live and draft form definitions
* @param {string} id - The form metadata ID
* @param { boolean } includeDraft - Whether to include draft definition
* @param {string} token - Auth token
* @returns {Promise<{ liveDefinition: FormDefinition | null, draftDefinition: FormDefinition | null }>}
* @returns {Promise<{ liveDefinition?: FormDefinition , draftDefinition?: FormDefinition }>}
*/
async function getFormDefinitions(id, includeDraft, token) {
async function getFormDefinitions(id, token) {
const [liveDefinition, draftDefinition] = await Promise.all([
forms.getLiveFormDefinition(id, token),
includeDraft
? forms.getDraftFormDefinition(id, token)
: Promise.resolve(null)
forms.getLiveFormDefinition(id, token).catch(ignore404Error),
forms.getDraftFormDefinition(id, token).catch(ignore404Error)
])

return { liveDefinition, draftDefinition }
}

/**
*
* @param {Error & {data?:{statusCode: StatusCodes}}} err
* @returns {undefined | never}
*/
function ignore404Error(err) {
if (err.data?.statusCode === StatusCodes.NOT_FOUND) {
return undefined
}
throw err
}

/**
* Append form definitions using id-based folder paths
* @param {string} id form ID
Expand All @@ -358,5 +363,5 @@ function appendFormDefinitionsToArchive(id, archive, definition) {

/**
* @import { ServerRoute , Request, ResponseToolkit, ResponseObject} from '@hapi/hapi'
* @import { FormMetadata, FormDefinition ,FormMetadataState} from '@defra/forms-model'
* @import { FormMetadata, FormDefinition } from '@defra/forms-model'
*/
92 changes: 88 additions & 4 deletions designer/server/src/routes/admin/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,18 @@ describe('System admin routes', () => {
yield formWithoutDraft
})

const notFoundError = Object.assign(new Error('Not found'), {
data: { statusCode: StatusCodes.NOT_FOUND }
})

jest
.mocked(forms.getLiveFormDefinition)
.mockResolvedValue(testFormDefinitionWithSinglePage)

jest
.mocked(forms.getDraftFormDefinition)
.mockRejectedValueOnce(notFoundError)

const options = {
method: 'post',
url: '/admin/index',
Expand All @@ -383,10 +391,10 @@ describe('System admin routes', () => {

expect(response.statusCode).toBe(StatusCodes.OK)

// Verify only live definition was requested (draft wasn't fetched because metadata.draft is undefined)
// Verify live definition was requested
expect(forms.getLiveFormDefinition).toHaveBeenCalledTimes(1)
// Draft definition should not be called when form.draft is undefined
expect(forms.getDraftFormDefinition).not.toHaveBeenCalled()
// Draft definition is always requested and 404 is ignored
expect(forms.getDraftFormDefinition).toHaveBeenCalledTimes(1)

// Verify audit event published
expect(publishFormsBackupRequestedEvent).toHaveBeenCalledWith(
Expand All @@ -396,7 +404,7 @@ describe('System admin routes', () => {
)
})

test('should throw error if one of the api calls fails', async () => {
test('should throw error if one of the api calls fails (non 404 error)', async () => {
const form1 = Promise.resolve(testFormMetadata)
const form2 = Promise.resolve({
...testFormMetadata,
Expand Down Expand Up @@ -437,6 +445,82 @@ describe('System admin routes', () => {
// Verify definitions were requested
expect(publishFormsBackupRequestedEvent).not.toHaveBeenCalled()
expect(forms.getLiveFormDefinition).toHaveBeenCalledTimes(2)
expect(forms.getDraftFormDefinition).toHaveBeenCalledTimes(2)
})

test('should ignore 404 when fetching live definition', async () => {
const form1 = Promise.resolve(testFormMetadata)

jest.mocked(forms.listAll).mockImplementationOnce(async function* () {
yield await form1
})

const notFoundError = Object.assign(new Error('Not found'), {
data: { statusCode: StatusCodes.NOT_FOUND }
})

jest
.mocked(forms.getLiveFormDefinition)
.mockRejectedValueOnce(notFoundError)

jest
.mocked(forms.getDraftFormDefinition)
.mockResolvedValueOnce(testFormDefinitionWithSinglePage)

const options = {
method: 'post',
url: '/admin/index',
auth,
payload: { action: 'download' }
}

const response = await server.inject(options)

expect(response.statusCode).toBe(StatusCodes.OK)
expect(publishFormsBackupRequestedEvent).toHaveBeenCalledWith(
expect.any(Object),
1,
expect.any(Number)
)
expect(forms.getLiveFormDefinition).toHaveBeenCalledTimes(1)
expect(forms.getDraftFormDefinition).toHaveBeenCalledTimes(1)
})

test('should ignore 404 when fetching draft definition', async () => {
const form1 = Promise.resolve(testFormMetadata)

jest.mocked(forms.listAll).mockImplementationOnce(async function* () {
yield await form1
})

const notFoundError = Object.assign(new Error('Not found'), {
data: { statusCode: StatusCodes.NOT_FOUND }
})

jest
.mocked(forms.getLiveFormDefinition)
.mockResolvedValueOnce(testFormDefinitionWithSinglePage)

jest
.mocked(forms.getDraftFormDefinition)
.mockRejectedValueOnce(notFoundError)

const options = {
method: 'post',
url: '/admin/index',
auth,
payload: { action: 'download' }
}

const response = await server.inject(options)

expect(response.statusCode).toBe(StatusCodes.OK)
expect(publishFormsBackupRequestedEvent).toHaveBeenCalledWith(
expect.any(Object),
1,
expect.any(Number)
)
expect(forms.getLiveFormDefinition).toHaveBeenCalledTimes(1)
expect(forms.getDraftFormDefinition).toHaveBeenCalledTimes(1)
})

Expand Down
Loading