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
194 changes: 192 additions & 2 deletions src/server/plugins/engine/outputFormatters/adapter/v1.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { type FormMetadata } from '@defra/forms-model'
import {
type FormMetadata,
type SubmitResponsePayload
} from '@defra/forms-model'

import { FileUploadField } from '~/src/server/plugins/engine/components/FileUploadField.js'
import { type Field } from '~/src/server/plugins/engine/components/helpers/components.js'
Expand Down Expand Up @@ -26,7 +29,7 @@ const submitResponse = {
files: {
main: '00000000-0000-0000-0000-000000000000',
repeaters: {
pizza: '11111111-1111-1111-1111-111111111111'
exampleRepeat: '11111111-1111-1111-1111-111111111111'
}
}
}
Expand Down Expand Up @@ -258,15 +261,26 @@ describe('Adapter v1 formatter', () => {
exampleFile1: [
{
fileId: '123-456-789',
fileName: 'foobar.txt',
userDownloadLink: 'https://forms-designer/file-download/123-456-789'
},
{
fileId: '456-789-123',
fileName: 'bazbuzz.txt',
userDownloadLink: 'https://forms-designer/file-download/456-789-123'
}
]
}
})

expect(parsedBody.result).toEqual({
files: {
main: '00000000-0000-0000-0000-000000000000',
repeaters: {
exampleRepeat: '11111111-1111-1111-1111-111111111111'
}
}
})
})

it('should handle preview form status correctly', () => {
Expand Down Expand Up @@ -385,6 +399,14 @@ describe('Adapter v1 formatter', () => {
expect(parsedBody.data.main).toEqual({})
expect(parsedBody.data.repeaters).toEqual({})
expect(parsedBody.data.files).toEqual({})
expect(parsedBody.result).toEqual({
files: {
main: '00000000-0000-0000-0000-000000000000',
repeaters: {
exampleRepeat: '11111111-1111-1111-1111-111111111111'
}
}
})
})

it('should handle different form statuses', () => {
Expand Down Expand Up @@ -503,4 +525,172 @@ describe('Adapter v1 formatter', () => {
expect(parsedBody.meta.formSlug).toBe('')
expect(parsedBody.meta.notificationEmail).toBe('only-email@example.com')
})

it('should include CSV file IDs from submitResponse.result.files', () => {
const formStatus = {
isPreview: false,
state: FormStatus.Live
}

const body = format(context, items, model, submitResponse, formStatus)
const parsedBody = JSON.parse(body) as FormAdapterSubmissionMessagePayload

expect(parsedBody.data.main).toEqual({
exampleField: 'hello world',
exampleField2: 'hello world'
})

expect(parsedBody.data.repeaters.exampleRepeat).toEqual([
{
subItem1_1: 'hello world',
subItem1_2: 'hello world'
},
{
subItem2_1: 'hello world'
}
])

expect(parsedBody.data.files.exampleFile1).toEqual([
{
fileId: '123-456-789',
fileName: 'foobar.txt',
userDownloadLink: 'https://forms-designer/file-download/123-456-789'
},
{
fileId: '456-789-123',
fileName: 'bazbuzz.txt',
userDownloadLink: 'https://forms-designer/file-download/456-789-123'
}
])

expect(parsedBody.result).toEqual({
files: {
main: '00000000-0000-0000-0000-000000000000',
repeaters: {
exampleRepeat: '11111111-1111-1111-1111-111111111111'
}
}
})
})

it('should handle submitResponse without CSV file IDs gracefully', () => {
const submitResponseWithoutFiles = {
message: 'Submit completed',
result: {
files: {
main: '',
repeaters: {}
}
}
}

const formStatus = {
isPreview: false,
state: FormStatus.Live
}

const body = format(
context,
items,
model,
submitResponseWithoutFiles,
formStatus
)
const parsedBody = JSON.parse(body) as FormAdapterSubmissionMessagePayload

expect(parsedBody.data.main).toEqual({
exampleField: 'hello world',
exampleField2: 'hello world'
})

expect(parsedBody.data.repeaters.exampleRepeat).toEqual([
{
subItem1_1: 'hello world',
subItem1_2: 'hello world'
},
{
subItem2_1: 'hello world'
}
])
})

it('should handle submitResponse with only main CSV file ID', () => {
const submitResponseWithMainOnly = {
message: 'Submit completed',
result: {
files: {
main: 'main-only-file-id',
repeaters: {}
}
}
}

const formStatus = {
isPreview: false,
state: FormStatus.Live
}

const body = format(
context,
items,
model,
submitResponseWithMainOnly,
formStatus
)
const parsedBody = JSON.parse(body) as FormAdapterSubmissionMessagePayload

expect(parsedBody.data.main).toEqual({
exampleField: 'hello world',
exampleField2: 'hello world'
})

expect(parsedBody.data.repeaters.exampleRepeat).toEqual([
{
subItem1_1: 'hello world',
subItem1_2: 'hello world'
},
{
subItem2_1: 'hello world'
}
])

expect(parsedBody.result).toEqual({
files: {
main: 'main-only-file-id',
repeaters: {}
}
})
})

it('should handle submitResponse with missing repeaters property', () => {
const submitResponseWithoutRepeaters = {
message: 'Submit completed',
result: {
files: {
main: 'main-only-file-id'
}
}
}

const formStatus = {
isPreview: false,
state: FormStatus.Live
}

const body = format(
context,
items,
model,
submitResponseWithoutRepeaters as unknown as SubmitResponsePayload,
formStatus
)
const parsedBody = JSON.parse(body) as FormAdapterSubmissionMessagePayload

expect(parsedBody.result).toEqual({
files: {
main: 'main-only-file-id',
repeaters: {}
}
})
})
})
50 changes: 38 additions & 12 deletions src/server/plugins/engine/outputFormatters/adapter/v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import { format as machineV2 } from '~/src/server/plugins/engine/outputFormatter
import { FormAdapterSubmissionSchemaVersion } from '~/src/server/plugins/engine/types/enums.js'
import {
type FormAdapterSubmissionMessageData,
type FormAdapterSubmissionMessageMeta,
type FormAdapterSubmissionMessagePayload,
type FormAdapterSubmissionMessageResult,
type FormContext
} from '~/src/server/plugins/engine/types.js'
import { FormStatus } from '~/src/server/routes/types.js'
Expand All @@ -34,20 +36,44 @@ export function format(
data: FormAdapterSubmissionMessageData
}

const csvFiles = extractCsvFiles(submitResponse)

const transformedData = v2DataParsed.data

const meta: FormAdapterSubmissionMessageMeta = {
schemaVersion: FormAdapterSubmissionSchemaVersion.V1,
timestamp: new Date(),
referenceNumber: context.referenceNumber,
formName: model.name,
formId: formMetadata?.id ?? '',
formSlug: formMetadata?.slug ?? '',
Comment on lines +48 to +49
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of scope of the PR but why would these ever be null/undefined?

status: formStatus.isPreview ? FormStatus.Draft : FormStatus.Live,
isPreview: formStatus.isPreview,
notificationEmail: formMetadata?.notificationEmail ?? ''
}
const data: FormAdapterSubmissionMessageData = transformedData

const result: FormAdapterSubmissionMessageResult = {
files: csvFiles
}

const payload: FormAdapterSubmissionMessagePayload = {
meta: {
schemaVersion: FormAdapterSubmissionSchemaVersion.V1,
timestamp: new Date(),
referenceNumber: context.referenceNumber,
formName: model.name,
formId: formMetadata?.id ?? '',
formSlug: formMetadata?.slug ?? '',
status: formStatus.isPreview ? FormStatus.Draft : FormStatus.Live,
isPreview: formStatus.isPreview,
notificationEmail: formMetadata?.notificationEmail ?? ''
},
data: v2DataParsed.data
meta,
data,
result
}

return JSON.stringify(payload)
}

function extractCsvFiles(
submitResponse: SubmitResponsePayload
): FormAdapterSubmissionMessageResult['files'] {
const result =
submitResponse.result as Partial<FormAdapterSubmissionMessageResult>

return {
main: result.files?.main ?? '',
repeaters: result.files?.repeaters ?? {}
}
}
2 changes: 2 additions & 0 deletions src/server/plugins/engine/outputFormatters/machine/v2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,12 @@ describe('getPersonalisation', () => {
exampleFile1: [
{
fileId: '123-456-789',
fileName: 'foobar.txt',
userDownloadLink: 'https://forms-designer/file-download/123-456-789'
},
{
fileId: '456-789-123',
fileName: 'bazbuzz.txt',
userDownloadLink: 'https://forms-designer/file-download/456-789-123'
}
]
Expand Down
Loading
Loading