Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict upload status changes #956

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
} from 'components/data-management/SamplesTableCells';
import UploadStatus, { messageForStatus } from 'utils/upload/UploadStatus';
import { makeStore } from 'redux/store';
import mockAPI, { generateDefaultMockAPIResponses } from '__test__/test-utils/mockAPI';
import mockAPI, { generateDefaultMockAPIResponses, statusResponse } from '__test__/test-utils/mockAPI';
import { loadSamples, updateSampleFileUpload } from 'redux/actions/samples';

import fake from '__test__/test-utils/constants';
Expand All @@ -40,6 +40,7 @@ jest.mock('swr', () => () => ({

const experimentId = `${fake.EXPERIMENT_ID}-0`;
const sampleId = `${fake.SAMPLE_ID}-0`;
const sampleFileId = `${fake.SAMPLE_FILE_ID}`;

enableFetchMocks();

Expand All @@ -50,7 +51,10 @@ describe('UploadCell', () => {

beforeEach(async () => {
fetchMock.mockClear();
fetchMock.mockIf(/.*/, mockAPI(generateDefaultMockAPIResponses(experimentId)));
fetchMock.mockIf(/.*/, mockAPI({
[`experiments/${experimentId}/sampleFiles/${sampleFileId}$`]: () => statusResponse(200, 'OK'),
...generateDefaultMockAPIResponses(experimentId),
}));

storeState = makeStore();

Expand All @@ -73,7 +77,7 @@ describe('UploadCell', () => {

await storeState.dispatch(
updateSampleFileUpload(
experimentId, sampleId, 'features10x', UploadStatus.UPLOADING, percentUploaded,
experimentId, sampleId, sampleFileId, 'features10x', UploadStatus.UPLOADING, percentUploaded,
),
);

Expand Down
1 change: 1 addition & 0 deletions src/__test__/test-utils/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default {
EXPERIMENT_NAME: 'Test Experiment',
PROJECT_ID: 'test24b6-8600-test-mock-63822d2fmock',
SAMPLE_ID: 'test9188-d682-test-mock-cb6d644cmock',
SAMPLE_FILE_ID: 'test4321-1234-test-mock-sampfilemock',
API_ENDPOINT: /^http?:\/\/localhost:3000.*$/,
S3_ENDPOINT: 'http://mock.s3.amazonaws.com',
// pragma: allowlist secret
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ exports[`processUpload Should not upload files if there are errors beginning the
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/features10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploadError"}",
"headers": {
Expand All @@ -83,7 +83,7 @@ exports[`processUpload Should not upload files if there are errors beginning the
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/barcodes10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploadError"}",
"headers": {
Expand All @@ -93,7 +93,7 @@ exports[`processUpload Should not upload files if there are errors beginning the
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/matrix10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploadError"}",
"headers": {
Expand Down Expand Up @@ -193,7 +193,7 @@ exports[`processUpload Updates redux correctly when there are file upload errors
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/features10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploadError"}",
"headers": {
Expand All @@ -203,7 +203,7 @@ exports[`processUpload Updates redux correctly when there are file upload errors
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/barcodes10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploadError"}",
"headers": {
Expand All @@ -213,7 +213,7 @@ exports[`processUpload Updates redux correctly when there are file upload errors
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/matrix10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploadError"}",
"headers": {
Expand Down Expand Up @@ -363,7 +363,7 @@ exports[`processUpload Uploads and updates redux correctly when there are no err
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/features10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploaded"}",
"headers": {
Expand All @@ -373,7 +373,7 @@ exports[`processUpload Uploads and updates redux correctly when there are no err
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/barcodes10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploaded"}",
"headers": {
Expand All @@ -383,7 +383,7 @@ exports[`processUpload Uploads and updates redux correctly when there are no err
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/matrix10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploaded"}",
"headers": {
Expand Down Expand Up @@ -533,7 +533,7 @@ exports[`processUpload Uploads and updates redux correctly when there are no err
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/features10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploaded"}",
"headers": {
Expand All @@ -543,7 +543,7 @@ exports[`processUpload Uploads and updates redux correctly when there are no err
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/barcodes10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploaded"}",
"headers": {
Expand All @@ -553,7 +553,7 @@ exports[`processUpload Uploads and updates redux correctly when there are no err
},
],
[
"http://localhost:3000/v2/experiments/project-uuid/samples/mockSampleId/sampleFiles/matrix10x",
"http://localhost:3000/v2/experiments/project-uuid/sampleFiles/mockSampleFileId",
{
"body": "{"uploadStatus":"uploaded"}",
"headers": {
Expand Down
6 changes: 6 additions & 0 deletions src/__test__/utils/upload/process10XUpload.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,16 @@ const mockProcessUploadCalls = () => {
result = { status: 200, body: JSON.stringify({ WT13: sampleId }) };
}

// Create sample file
if (new RegExp(`/v2/experiments/${mockExperimentId}/samples/.*/sampleFiles/.*`).test(url)) {
result = { status: 200, body: JSON.stringify({}) };
}

// Update sample file status
if (new RegExp(`/v2/experiments/${mockExperimentId}/sampleFiles/.*`).test(url)) {
result = { status: 200, body: JSON.stringify({}) };
}

if (url.endsWith(`/v2/experiments/${mockExperimentId}/sampleFiles/${sampleFileId}/beginUpload`)) {
result = { status: 200, body: JSON.stringify(mockUploadUrlParams) };
}
Expand Down
8 changes: 6 additions & 2 deletions src/redux/actions/samples/createSampleFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ const createSampleFile = (
) => async (dispatch) => {
const updatedAt = dayjs().toISOString();

const sampleFileId = uuidv4();

try {
const url = `/v2/experiments/${experimentId}/samples/${sampleId}/sampleFiles/${type}`;
const body = {
sampleFileId: uuidv4(),
sampleFileId,
size: fileForApiV1.size,
};

Expand Down Expand Up @@ -52,7 +54,9 @@ const createSampleFile = (

return body.sampleFileId;
} catch (e) {
dispatch(updateSampleFileUpload(experimentId, sampleId, type, UploadStatus.UPLOAD_ERROR));
dispatch(updateSampleFileUpload(
experimentId, sampleId, sampleFileId, type, UploadStatus.UPLOAD_ERROR,
));

throw e;
}
Expand Down
4 changes: 2 additions & 2 deletions src/redux/actions/samples/updateSampleFileUpload.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import UploadStatus from 'utils/upload/UploadStatus';
import fileNameForApiV1 from 'utils/upload/fileNameForApiV1';

const updateSampleFileUpload = (
experimentId, sampleId, type, uploadStatus, uploadProgress,
experimentId, sampleId, sampleFileId, type, uploadStatus, uploadProgress,
) => async (dispatch) => {
const updatedAt = dayjs().toISOString();

// Don't send an api update whenever the progress bar is updated, only for uploadStatus changes
// TODO: move progress to not even be a part of redux, manage it in a different way
if (uploadStatus !== UploadStatus.UPLOADING) {
const url = `/v2/experiments/${experimentId}/samples/${sampleId}/sampleFiles/${type}`;
const url = `/v2/experiments/${experimentId}/sampleFiles/${sampleFileId}`;
const body = { uploadStatus };

try {
Expand Down
10 changes: 6 additions & 4 deletions src/utils/upload/processUpload.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const createAndUploadSampleFile = async (file, experimentId, sampleId, dispatch,
try {
file.fileObject = await loadAndCompressIfNecessary(file, () => {
dispatch(updateSampleFileUpload(
experimentId, sampleId, fileType, UploadStatus.COMPRESSING,
experimentId, sampleId, sampleFileId, fileType, UploadStatus.COMPRESSING,
));
});

Expand All @@ -99,7 +99,9 @@ const createAndUploadSampleFile = async (file, experimentId, sampleId, dispatch,
? UploadStatus.FILE_READ_ABORTED
: UploadStatus.FILE_READ_ERROR;

dispatch(updateSampleFileUpload(experimentId, sampleId, fileType, fileErrorStatus));
dispatch(updateSampleFileUpload(
experimentId, sampleId, sampleFileId, fileType, fileErrorStatus,
));
return;
}
}
Expand All @@ -114,15 +116,15 @@ const createAndUploadSampleFile = async (file, experimentId, sampleId, dispatch,

const updateSampleFileUploadProgress = (status, percentProgress = 0) => dispatch(
updateSampleFileUpload(
experimentId, sampleId, fileType, status, percentProgress,
experimentId, sampleId, sampleFileId, fileType, status, percentProgress,
),
);

const uploadUrlParams = { signedUrls, uploadId, fileId: sampleFileId };
await prepareAndUploadFileToS3(file, uploadUrlParams, 'sample', updateSampleFileUploadProgress, abortController);
} catch (e) {
dispatch(updateSampleFileUpload(
experimentId, sampleId, fileType, UploadStatus.UPLOAD_ERROR,
experimentId, sampleId, sampleFileId, fileType, UploadStatus.UPLOAD_ERROR,
));
}
};
Expand Down
Loading