From df92c79689404b07ffd175df1243e82df85d356e Mon Sep 17 00:00:00 2001 From: tombch Date: Thu, 20 Aug 2026 12:47:26 +0200 Subject: [PATCH 1/6] Fix applyFileMappings for compressed files --- .../Submission/FormOrUploadWrapper.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/website/src/components/Submission/FormOrUploadWrapper.tsx b/website/src/components/Submission/FormOrUploadWrapper.tsx index 129006d517..6eb96807f9 100644 --- a/website/src/components/Submission/FormOrUploadWrapper.tsx +++ b/website/src/components/Submission/FormOrUploadWrapper.tsx @@ -138,14 +138,21 @@ export const FormOrUploadWrapper: FC = ({ }; } case 'bulk': { - let mFile = metadataFile?.inner(); - if (metadataFile !== undefined && columnMapping !== null) { - mFile = await columnMapping.applyTo(metadataFile); - } - if (mFile === undefined) { + if (metadataFile === undefined) { return { type: 'error', errorMessage: 'Please specify a metadata file.' }; } + let mFile: File; + if (columnMapping !== null) { + mFile = await columnMapping.applyTo(metadataFile); + } else if (extraFilesEnabled) { + // Ensure the metadata file is decompressed so that any file mappings + // can be applied correctly + mFile = new File([await metadataFile.text()], 'metadata.tsv'); + } else { + mFile = metadataFile.inner(); + } + const sFile = sequenceFile?.inner(); if (enableConsensusSequences && sFile === undefined) { return { type: 'error', errorMessage: 'Please specify a sequences file.' }; From b4023da76f97db5732e9355c6453c8e530501c37 Mon Sep 17 00:00:00 2001 From: tombch Date: Thu, 20 Aug 2026 14:09:28 +0200 Subject: [PATCH 2/6] Integration test for compressed file --- .../tests/pages/submission.page.ts | 10 ++++--- .../tests/specs/features/file-sharing.spec.ts | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/integration-tests/tests/pages/submission.page.ts b/integration-tests/tests/pages/submission.page.ts index dc14418a21..69b76882ea 100644 --- a/integration-tests/tests/pages/submission.page.ts +++ b/integration-tests/tests/pages/submission.page.ts @@ -1,4 +1,5 @@ import { Page } from '@playwright/test'; +import { gzipSync } from 'zlib'; import { ReviewPage } from './review.page'; import Papa from 'papaparse'; import { NavigationPage } from './navigation.page'; @@ -179,17 +180,18 @@ export class BulkSubmissionPage extends SubmissionPage { * Content is provided as list(s) of strings, and will be formatted into a TSV file. * @param headers The header row cells in the TSV file. The column headers need to be valid input field names. * @param rows A list of rows. For each row, a value for each column must be given. + * @param gzipped Whether to gzip the TSV and upload it as `metadata.tsv.gz`. */ - async uploadMetadataFile(headers: string[], rows: (string | number)[][]) { + async uploadMetadataFile(headers: string[], rows: (string | number)[][], gzipped = false) { const tsvContent = Papa.unparse([headers, ...rows], { delimiter: '\t', newline: '\n', }); await this.page.getByTestId('metadata_file').setInputFiles({ - name: 'metadata.tsv', - mimeType: 'text/plain', - buffer: Buffer.from(tsvContent), + name: gzipped ? 'metadata.tsv.gz' : 'metadata.tsv', + mimeType: gzipped ? 'application/gzip' : 'text/plain', + buffer: gzipped ? gzipSync(Buffer.from(tsvContent)) : Buffer.from(tsvContent), }); } diff --git a/integration-tests/tests/specs/features/file-sharing.spec.ts b/integration-tests/tests/specs/features/file-sharing.spec.ts index 3510d3991f..2ec25e899e 100644 --- a/integration-tests/tests/specs/features/file-sharing.spec.ts +++ b/integration-tests/tests/specs/features/file-sharing.spec.ts @@ -170,6 +170,35 @@ test('bulk submit 2 seqs with 1 & 2 FASTQ files respectively', async ({ await searchPage.checkFileContentInModal('cell', COUNTRY_2, FILES_DOUBLE); }); +test('bulk submit 1 seq with files declared in a compressed metadata file', async ({ + page, + groupId, + tmpDir, +}) => { + test.setTimeout(240_000); + void groupId; + const submissionPage = new BulkSubmissionPage(page); + const isGzipped = true; + await submissionPage.navigateToSubmissionPage(ORGANISM_NAME); + await submissionPage.uploadMetadataFile( + [...METADATA_HEADERS, RAW_READS_FILES_HEADER], + [ + [ + ID_1, + COUNTRY_1, + '2022-12-02', + SEQUENCING_INSTRUMENT, + filesColumnCell(Object.keys(FILES_SINGLE), ID_1), + ], + ], + isGzipped, + ); + await submissionPage.uploadSequencesFile({ [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE }); + await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_SINGLE }, tmpDir); + const reviewPage = await submissionPage.submitAndWaitForProcessingDone(180_000); + await reviewPage.checkFilesInReviewDialog(FILES_SINGLE); +}); + test('bulk submit 1 seq: discarding and reading a FASTQ file', async ({ page, groupId, From 3b450b1f4a45f4a129349fd2f7ce00ab754f09ce Mon Sep 17 00:00:00 2001 From: tombch Date: Thu, 20 Aug 2026 14:14:34 +0200 Subject: [PATCH 3/6] Add error handling --- .../Submission/FormOrUploadWrapper.tsx | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/website/src/components/Submission/FormOrUploadWrapper.tsx b/website/src/components/Submission/FormOrUploadWrapper.tsx index 6eb96807f9..cbfc2e395f 100644 --- a/website/src/components/Submission/FormOrUploadWrapper.tsx +++ b/website/src/components/Submission/FormOrUploadWrapper.tsx @@ -143,14 +143,23 @@ export const FormOrUploadWrapper: FC = ({ } let mFile: File; - if (columnMapping !== null) { - mFile = await columnMapping.applyTo(metadataFile); - } else if (extraFilesEnabled) { - // Ensure the metadata file is decompressed so that any file mappings - // can be applied correctly - mFile = new File([await metadataFile.text()], 'metadata.tsv'); - } else { - mFile = metadataFile.inner(); + try { + if (columnMapping !== null) { + mFile = await columnMapping.applyTo(metadataFile); + } else if (extraFilesEnabled) { + // Ensure the metadata file is decompressed so that any file mappings + // can be applied correctly + mFile = new File([await metadataFile.text()], 'metadata.tsv'); + } else { + mFile = metadataFile.inner(); + } + } catch (error) { + return { + type: 'error', + errorMessage: `Could not read ${metadataFile.handle().name}: ${ + error instanceof Error ? error.message : String(error) + }`, + }; } const sFile = sequenceFile?.inner(); From 496ff56f6b2f2c398fefeb4e1ec333718119b3e2 Mon Sep 17 00:00:00 2001 From: tombch Date: Wed, 26 Aug 2026 16:36:20 +0200 Subject: [PATCH 4/6] Parameterise less time-consuming submission with file tests to also test compressed metadata --- .../tests/pages/submission.page.ts | 10 +- .../tests/specs/features/file-sharing.spec.ts | 215 ++++++++---------- 2 files changed, 103 insertions(+), 122 deletions(-) diff --git a/integration-tests/tests/pages/submission.page.ts b/integration-tests/tests/pages/submission.page.ts index 69b76882ea..47530ea5a2 100644 --- a/integration-tests/tests/pages/submission.page.ts +++ b/integration-tests/tests/pages/submission.page.ts @@ -180,18 +180,18 @@ export class BulkSubmissionPage extends SubmissionPage { * Content is provided as list(s) of strings, and will be formatted into a TSV file. * @param headers The header row cells in the TSV file. The column headers need to be valid input field names. * @param rows A list of rows. For each row, a value for each column must be given. - * @param gzipped Whether to gzip the TSV and upload it as `metadata.tsv.gz`. + * @param compressFile Whether to compress the TSV (with GZIP) and upload it as `metadata.tsv.gz`. */ - async uploadMetadataFile(headers: string[], rows: (string | number)[][], gzipped = false) { + async uploadMetadataFile(headers: string[], rows: (string | number)[][], compressFile = false) { const tsvContent = Papa.unparse([headers, ...rows], { delimiter: '\t', newline: '\n', }); await this.page.getByTestId('metadata_file').setInputFiles({ - name: gzipped ? 'metadata.tsv.gz' : 'metadata.tsv', - mimeType: gzipped ? 'application/gzip' : 'text/plain', - buffer: gzipped ? gzipSync(Buffer.from(tsvContent)) : Buffer.from(tsvContent), + name: compressFile ? 'metadata.tsv.gz' : 'metadata.tsv', + mimeType: compressFile ? 'application/gzip' : 'text/plain', + buffer: compressFile ? gzipSync(Buffer.from(tsvContent)) : Buffer.from(tsvContent), }); } diff --git a/integration-tests/tests/specs/features/file-sharing.spec.ts b/integration-tests/tests/specs/features/file-sharing.spec.ts index 2ec25e899e..10324c59c0 100644 --- a/integration-tests/tests/specs/features/file-sharing.spec.ts +++ b/integration-tests/tests/specs/features/file-sharing.spec.ts @@ -170,64 +170,40 @@ test('bulk submit 2 seqs with 1 & 2 FASTQ files respectively', async ({ await searchPage.checkFileContentInModal('cell', COUNTRY_2, FILES_DOUBLE); }); -test('bulk submit 1 seq with files declared in a compressed metadata file', async ({ - page, - groupId, - tmpDir, -}) => { - test.setTimeout(240_000); - void groupId; - const submissionPage = new BulkSubmissionPage(page); - const isGzipped = true; - await submissionPage.navigateToSubmissionPage(ORGANISM_NAME); - await submissionPage.uploadMetadataFile( - [...METADATA_HEADERS, RAW_READS_FILES_HEADER], - [ - [ - ID_1, - COUNTRY_1, - '2022-12-02', - SEQUENCING_INSTRUMENT, - filesColumnCell(Object.keys(FILES_SINGLE), ID_1), - ], - ], - isGzipped, - ); - await submissionPage.uploadSequencesFile({ [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE }); - await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_SINGLE }, tmpDir); - const reviewPage = await submissionPage.submitAndWaitForProcessingDone(180_000); - await reviewPage.checkFilesInReviewDialog(FILES_SINGLE); -}); - -test('bulk submit 1 seq: discarding and reading a FASTQ file', async ({ - page, - groupId, - tmpDir, -}) => { - test.setTimeout(240_000); - void groupId; - const submissionPage = new BulkSubmissionPage(page); - await submissionPage.navigateToSubmissionPage(ORGANISM_NAME); - await submissionPage.uploadMetadataFile( - [...METADATA_HEADERS, RAW_READS_FILES_HEADER], - [ - [ - ID_1, - COUNTRY_1, - '2023-01-01', - SEQUENCING_INSTRUMENT, - filesColumnCell(Object.keys(FILES_DOUBLE), ID_1), - ], - ], +[ + { compressFile: false, description: '' }, + { compressFile: true, description: ' with compressed metadata file' }, +].forEach(({ compressFile, description }) => { + test( + 'bulk submit 1 seq: discarding and reading a FASTQ file' + description, + async ({ page, groupId, tmpDir }) => { + test.setTimeout(240_000); + void groupId; + const submissionPage = new BulkSubmissionPage(page); + await submissionPage.navigateToSubmissionPage(ORGANISM_NAME); + await submissionPage.uploadMetadataFile( + [...METADATA_HEADERS, RAW_READS_FILES_HEADER], + [ + [ + ID_1, + COUNTRY_1, + '2023-01-01', + SEQUENCING_INSTRUMENT, + filesColumnCell(Object.keys(FILES_DOUBLE), ID_1), + ], + ], + compressFile, + ); + await submissionPage.uploadSequencesFile({ [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE }); + await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_SINGLE }, tmpDir); + await submissionPage.discardFiles(RAW_READS); + await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_DOUBLE }, tmpDir); + const reviewPage = await submissionPage.submitAndWaitForProcessingDone(180_000); + await reviewPage.checkFilesInReviewDialog(FILES_DOUBLE, Object.keys(FILES_SINGLE)); + const searchPage = await reviewPage.releaseAndGoToReleasedSequences(); + await searchPage.checkFileContentInModal('cell', COUNTRY_1, FILES_DOUBLE); + }, ); - await submissionPage.uploadSequencesFile({ [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE }); - await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_SINGLE }, tmpDir); - await submissionPage.discardFiles(RAW_READS); - await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_DOUBLE }, tmpDir); - const reviewPage = await submissionPage.submitAndWaitForProcessingDone(180_000); - await reviewPage.checkFilesInReviewDialog(FILES_DOUBLE, Object.keys(FILES_SINGLE)); - const searchPage = await reviewPage.releaseAndGoToReleasedSequences(); - await searchPage.checkFileContentInModal('cell', COUNTRY_1, FILES_DOUBLE); }); test('bulk submit 1 seq with a 35 MB FASTQ file', async ({ page, groupId, tmpDir }) => { @@ -266,67 +242,72 @@ test('bulk submit 1 seq with a 35 MB FASTQ file', async ({ page, groupId, tmpDir await searchPage.checkFileContentInModal('cell', COUNTRY_1, LARGE_FILE); }); -test('bulk submit blocks a submission with errors in file linkage or parsing', async ({ - page, - groupId, - tmpDir, -}) => { - test.setTimeout(180_000); - void groupId; - - const [file1Name, file2Name] = Object.keys(FILES_DOUBLE); - const file1 = { [file1Name]: FILES_DOUBLE[file1Name] }; - const reusedFileId = '123e4567-e89b-12d3-a456-426614174000'; - - const linkageErrors = [ - { - metadataFileEntries: 'a::b::c', - uploadedFiles: undefined, - error: 'Failed to parse file entry', - }, - { - metadataFileEntries: filesColumnCell(Object.keys(FILES_DOUBLE), ID_1), - uploadedFiles: { [ID_1]: file1 }, - error: `referenced in metadata but not uploaded: ${ID_1}/${file2Name}`, +[ + { compressFile: false, description: '' }, + { compressFile: true, description: ' with compressed metadata file' }, +].forEach(({ compressFile, description }) => { + test( + 'bulk submit blocks a submission with errors in file linkage or parsing' + description, + async ({ page, groupId, tmpDir }) => { + test.setTimeout(180_000); + void groupId; + + const [file1Name, file2Name] = Object.keys(FILES_DOUBLE); + const file1 = { [file1Name]: FILES_DOUBLE[file1Name] }; + const reusedFileId = '123e4567-e89b-12d3-a456-426614174000'; + + const linkageErrors = [ + { + metadataFileEntries: 'a::b::c', + uploadedFiles: undefined, + error: 'Failed to parse file entry', + }, + { + metadataFileEntries: filesColumnCell(Object.keys(FILES_DOUBLE), ID_1), + uploadedFiles: { [ID_1]: file1 }, + error: `referenced in metadata but not uploaded: ${ID_1}/${file2Name}`, + }, + { + metadataFileEntries: filesColumnCell(Object.keys(file1), ID_1), + uploadedFiles: { [ID_1]: FILES_DOUBLE }, + error: `uploaded but not referenced in metadata: ${ID_1}/${file2Name}`, + }, + { + // Uploaded without a submission ID subfolder, so the uploaded file's path matches + // the name of a metadata entry which already references an existing file + metadataFileEntries: `${file1Name}:${reusedFileId}`, + uploadedFiles: file1, + error: `uploaded but the metadata still references an existing file for them: ${file1Name}`, + }, + ]; + + const submissionPage = new BulkSubmissionPage(page); + for (const { metadataFileEntries, uploadedFiles, error } of linkageErrors) { + await submissionPage.navigateToSubmissionPage(ORGANISM_NAME); + await submissionPage.acceptTerms(); + await submissionPage.uploadMetadataFile( + [...METADATA_HEADERS, RAW_READS_FILES_HEADER], + [[ID_1, COUNTRY_1, '2023-01-01', SEQUENCING_INSTRUMENT, metadataFileEntries]], + compressFile, + ); + await submissionPage.uploadSequencesFile({ + [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE, + }); + if (uploadedFiles !== undefined) + await submissionPage.uploadExternalFiles(RAW_READS, uploadedFiles, tmpDir); + + await submissionPage.clickSubmit(); + + // Multiple toasts can be shown at the same time + // For example, the parse error appears on metadata file load, as well as on handle submit + await expect(page.getByText(error).first()).toBeVisible(); + // A blocked submission returns before the data use terms dialog is shown + await expect( + page.getByRole('button', { name: 'Continue under Open terms' }), + ).toHaveCount(0); + } }, - { - metadataFileEntries: filesColumnCell(Object.keys(file1), ID_1), - uploadedFiles: { [ID_1]: FILES_DOUBLE }, - error: `uploaded but not referenced in metadata: ${ID_1}/${file2Name}`, - }, - { - // Uploaded without a submission ID subfolder, so the uploaded file's path matches - // the name of a metadata entry which already references an existing file - metadataFileEntries: `${file1Name}:${reusedFileId}`, - uploadedFiles: file1, - error: `uploaded but the metadata still references an existing file for them: ${file1Name}`, - }, - ]; - - const submissionPage = new BulkSubmissionPage(page); - for (const { metadataFileEntries, uploadedFiles, error } of linkageErrors) { - await submissionPage.navigateToSubmissionPage(ORGANISM_NAME); - await submissionPage.acceptTerms(); - await submissionPage.uploadMetadataFile( - [...METADATA_HEADERS, RAW_READS_FILES_HEADER], - [[ID_1, COUNTRY_1, '2023-01-01', SEQUENCING_INSTRUMENT, metadataFileEntries]], - ); - await submissionPage.uploadSequencesFile({ - [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE, - }); - if (uploadedFiles !== undefined) - await submissionPage.uploadExternalFiles(RAW_READS, uploadedFiles, tmpDir); - - await submissionPage.clickSubmit(); - - // Multiple toasts can be shown at the same time - // For example, the parse error appears on metadata file load, as well as on handle submit - await expect(page.getByText(error).first()).toBeVisible(); - // A blocked submission returns before the data use terms dialog is shown - await expect(page.getByRole('button', { name: 'Continue under Open terms' })).toHaveCount( - 0, - ); - } + ); }); const REVISION_METADATA_HEADERS = [ From 1b7feed744e5cc1e3c419a4d998afc08ca411ff1 Mon Sep 17 00:00:00 2001 From: tombch Date: Wed, 26 Aug 2026 16:41:47 +0200 Subject: [PATCH 5/6] update wording --- .../tests/specs/features/file-sharing.spec.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/integration-tests/tests/specs/features/file-sharing.spec.ts b/integration-tests/tests/specs/features/file-sharing.spec.ts index 10324c59c0..a4ef6750c7 100644 --- a/integration-tests/tests/specs/features/file-sharing.spec.ts +++ b/integration-tests/tests/specs/features/file-sharing.spec.ts @@ -37,6 +37,12 @@ const FILES_DOUBLE: Record = { 'file2.fastq': EBOLA_SUDAN_SMALL_FASTQ(2), }; +// For parameterised tests over compressed/uncompressed metadata +const METADATA_COMPRESSION_CASES = [ + { compressMetadata: false, description: '' }, + { compressMetadata: true, description: ' with compressed metadata file' }, +]; + // File cells can be formatted either as a list of file names, // Or file names with file paths under a subfolder const filesColumnCell = (fileNames: string[], subfolder?: string) => @@ -170,10 +176,7 @@ test('bulk submit 2 seqs with 1 & 2 FASTQ files respectively', async ({ await searchPage.checkFileContentInModal('cell', COUNTRY_2, FILES_DOUBLE); }); -[ - { compressFile: false, description: '' }, - { compressFile: true, description: ' with compressed metadata file' }, -].forEach(({ compressFile, description }) => { +METADATA_COMPRESSION_CASES.forEach(({ compressMetadata, description }) => { test( 'bulk submit 1 seq: discarding and reading a FASTQ file' + description, async ({ page, groupId, tmpDir }) => { @@ -192,7 +195,7 @@ test('bulk submit 2 seqs with 1 & 2 FASTQ files respectively', async ({ filesColumnCell(Object.keys(FILES_DOUBLE), ID_1), ], ], - compressFile, + compressMetadata, ); await submissionPage.uploadSequencesFile({ [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE }); await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_SINGLE }, tmpDir); @@ -242,10 +245,7 @@ test('bulk submit 1 seq with a 35 MB FASTQ file', async ({ page, groupId, tmpDir await searchPage.checkFileContentInModal('cell', COUNTRY_1, LARGE_FILE); }); -[ - { compressFile: false, description: '' }, - { compressFile: true, description: ' with compressed metadata file' }, -].forEach(({ compressFile, description }) => { +METADATA_COMPRESSION_CASES.forEach(({ compressMetadata, description }) => { test( 'bulk submit blocks a submission with errors in file linkage or parsing' + description, async ({ page, groupId, tmpDir }) => { @@ -288,7 +288,7 @@ test('bulk submit 1 seq with a 35 MB FASTQ file', async ({ page, groupId, tmpDir await submissionPage.uploadMetadataFile( [...METADATA_HEADERS, RAW_READS_FILES_HEADER], [[ID_1, COUNTRY_1, '2023-01-01', SEQUENCING_INSTRUMENT, metadataFileEntries]], - compressFile, + compressMetadata, ); await submissionPage.uploadSequencesFile({ [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE, From be3c3cbdfd6aa91563429565c8f8ed05db83eeec Mon Sep 17 00:00:00 2001 From: tombch Date: Wed, 26 Aug 2026 16:46:21 +0200 Subject: [PATCH 6/6] Parameterise different test --- .../tests/specs/features/file-sharing.spec.ts | 104 +++++++++--------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/integration-tests/tests/specs/features/file-sharing.spec.ts b/integration-tests/tests/specs/features/file-sharing.spec.ts index a4ef6750c7..7ba6efc67a 100644 --- a/integration-tests/tests/specs/features/file-sharing.spec.ts +++ b/integration-tests/tests/specs/features/file-sharing.spec.ts @@ -133,52 +133,9 @@ test('reject FASTQ raw_reads file with human host reads with a deacon validation await reviewPage.expectNoValidSequencesToApprove(); }); -test('bulk submit 2 seqs with 1 & 2 FASTQ files respectively', async ({ - page, - groupId, - tmpDir, -}) => { - test.setTimeout(240_000); - void groupId; - const submissionPage = new BulkSubmissionPage(page); - await submissionPage.navigateToSubmissionPage(ORGANISM_NAME); - await submissionPage.uploadMetadataFile( - [...METADATA_HEADERS, RAW_READS_FILES_HEADER], - [ - [ - ID_1, - COUNTRY_1, - '2022-12-02', - SEQUENCING_INSTRUMENT, - filesColumnCell(Object.keys(FILES_SINGLE), ID_1), - ], - [ - ID_2, - COUNTRY_2, - '2022-12-13', - SEQUENCING_INSTRUMENT, - filesColumnCell(Object.keys(FILES_DOUBLE), ID_2), - ], - ], - ); - await submissionPage.uploadSequencesFile({ - [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE, - [ID_2]: EBOLA_SUDAN_SHORT_SEQUENCE, - }); - await submissionPage.uploadExternalFiles( - RAW_READS, - { [ID_1]: FILES_SINGLE, [ID_2]: FILES_DOUBLE }, - tmpDir, - ); - const reviewPage = await submissionPage.submitAndWaitForProcessingDone(180_000); - const searchPage = await reviewPage.releaseAndGoToReleasedSequences(); - await searchPage.checkFileContentInModal('cell', COUNTRY_1, FILES_SINGLE); - await searchPage.checkFileContentInModal('cell', COUNTRY_2, FILES_DOUBLE); -}); - METADATA_COMPRESSION_CASES.forEach(({ compressMetadata, description }) => { test( - 'bulk submit 1 seq: discarding and reading a FASTQ file' + description, + 'bulk submit 2 seqs with 1 & 2 FASTQ files respectively' + description, async ({ page, groupId, tmpDir }) => { test.setTimeout(240_000); void groupId; @@ -190,25 +147,68 @@ METADATA_COMPRESSION_CASES.forEach(({ compressMetadata, description }) => { [ ID_1, COUNTRY_1, - '2023-01-01', + '2022-12-02', SEQUENCING_INSTRUMENT, - filesColumnCell(Object.keys(FILES_DOUBLE), ID_1), + filesColumnCell(Object.keys(FILES_SINGLE), ID_1), + ], + [ + ID_2, + COUNTRY_2, + '2022-12-13', + SEQUENCING_INSTRUMENT, + filesColumnCell(Object.keys(FILES_DOUBLE), ID_2), ], ], compressMetadata, ); - await submissionPage.uploadSequencesFile({ [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE }); - await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_SINGLE }, tmpDir); - await submissionPage.discardFiles(RAW_READS); - await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_DOUBLE }, tmpDir); + await submissionPage.uploadSequencesFile({ + [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE, + [ID_2]: EBOLA_SUDAN_SHORT_SEQUENCE, + }); + await submissionPage.uploadExternalFiles( + RAW_READS, + { [ID_1]: FILES_SINGLE, [ID_2]: FILES_DOUBLE }, + tmpDir, + ); const reviewPage = await submissionPage.submitAndWaitForProcessingDone(180_000); - await reviewPage.checkFilesInReviewDialog(FILES_DOUBLE, Object.keys(FILES_SINGLE)); const searchPage = await reviewPage.releaseAndGoToReleasedSequences(); - await searchPage.checkFileContentInModal('cell', COUNTRY_1, FILES_DOUBLE); + await searchPage.checkFileContentInModal('cell', COUNTRY_1, FILES_SINGLE); + await searchPage.checkFileContentInModal('cell', COUNTRY_2, FILES_DOUBLE); }, ); }); +test('bulk submit 1 seq: discarding and reading a FASTQ file', async ({ + page, + groupId, + tmpDir, +}) => { + test.setTimeout(240_000); + void groupId; + const submissionPage = new BulkSubmissionPage(page); + await submissionPage.navigateToSubmissionPage(ORGANISM_NAME); + await submissionPage.uploadMetadataFile( + [...METADATA_HEADERS, RAW_READS_FILES_HEADER], + [ + [ + ID_1, + COUNTRY_1, + '2023-01-01', + SEQUENCING_INSTRUMENT, + filesColumnCell(Object.keys(FILES_DOUBLE), ID_1), + ], + ], + ); + await submissionPage.uploadSequencesFile({ [ID_1]: EBOLA_SUDAN_SHORT_SEQUENCE }); + await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_SINGLE }, tmpDir); + await submissionPage.discardFiles(RAW_READS); + await submissionPage.uploadExternalFiles(RAW_READS, { [ID_1]: FILES_DOUBLE }, tmpDir); + const reviewPage = await submissionPage.submitAndWaitForProcessingDone(180_000); + await reviewPage.checkFilesInReviewDialog(FILES_DOUBLE, Object.keys(FILES_SINGLE)); + const searchPage = await reviewPage.releaseAndGoToReleasedSequences(); + await searchPage.checkFileContentInModal('cell', COUNTRY_1, FILES_DOUBLE); +}); + test('bulk submit 1 seq with a 35 MB FASTQ file', async ({ page, groupId, tmpDir }) => { test.setTimeout(400_000); void groupId;