Skip to content

Commit

Permalink
Fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
cosa65 committed Jun 27, 2022
2 parents 997bf80 + def7de6 commit 1331f8a
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 265 deletions.
32 changes: 20 additions & 12 deletions src/__test__/components/data-management/ProjectDetails.test.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import _ from 'lodash';
import React from 'react';
import '@testing-library/jest-dom';

import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { screen, render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import rootReducer from 'redux/reducers/index';
import { createStore, applyMiddleware } from 'redux';
import _ from 'lodash';
import thunk from 'redux-thunk';

import '@testing-library/jest-dom';
import configureStore from 'redux-mock-store';
import { act } from 'react-dom/test-utils';
import { fireEvent } from '@testing-library/dom';
import rootReducer from 'redux/reducers/index';
import userEvent from '@testing-library/user-event';
import { screen, render, waitFor } from '@testing-library/react';

import * as createMetadataTrack from 'redux/actions/projects/createMetadataTrack';
import initialProjectState, { projectTemplate } from 'redux/reducers/projects/initialState';
import initialSamplesState, { sampleTemplate } from 'redux/reducers/samples/initialState';
Expand All @@ -18,6 +22,7 @@ import { initialExperimentBackendStatus } from 'redux/reducers/backendStatus/ini
import PipelineStatus from 'utils/pipelineStatusValues';
import UploadStatus from 'utils/upload/UploadStatus';
import ProjectDetails from 'components/data-management/ProjectDetails';

import '__test__/test-utils/setupTests';

const mockNavigateTo = jest.fn();
Expand Down Expand Up @@ -227,11 +232,14 @@ describe('ProjectDetails', () => {

it('Creates a metadata column', async () => {
const store = createStore(rootReducer, _.cloneDeep(withDataState), applyMiddleware(thunk));
render(
<Provider store={store}>
<ProjectDetails width={width} height={height} />
</Provider>,
);
await act(async () => {
render(
<Provider store={store}>
<ProjectDetails width={width} height={height} />
</Provider>,
);
});

const addMetadata = screen.getByText('Add metadata');
userEvent.click(addMetadata);
const field = screen.getByRole('textbox');
Expand Down
133 changes: 63 additions & 70 deletions src/__test__/components/data-management/SamplesTable.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ import '@testing-library/jest-dom';
import fetchMock, { enableFetchMocks } from 'jest-fetch-mock';
import reactSortableHoc from 'react-sortable-hoc';

import Storage from '@aws-amplify/storage';

import _ from 'lodash';
import { Provider } from 'react-redux';

import mockAPI, { generateDefaultMockAPIResponses, statusResponse } from '__test__/test-utils/mockAPI';
import { experiments, samples } from '__test__/test-utils/mockData';
import mockAPI, { generateDefaultMockAPIResponses, promiseResponse, statusResponse } from '__test__/test-utils/mockAPI';
import { experiments, responseData, samples } from '__test__/test-utils/mockData';

import SamplesTable from 'components/data-management/SamplesTable';
import { makeStore } from 'redux/store';
Expand All @@ -21,12 +19,13 @@ import thunk from 'redux-thunk';
import createTestComponentFactory from '__test__/test-utils/testComponentFactory';

import { loadProjects, setActiveProject } from 'redux/actions/projects';
import downloadFromUrl from 'utils/data-management/downloadFromUrl';

import loadEnvironment from 'redux/actions/networkResources/loadEnvironment';
import { loadExperiments } from 'redux/actions/experiments';
import { loadSamples } from 'redux/actions/samples';

import mockDemoExperiments from '__test__/test-utils/mockData/mockDemoExperiments.json';

jest.mock('config');

jest.mock('@aws-amplify/auth', () => ({
Expand All @@ -44,11 +43,6 @@ jest.mock('@aws-amplify/storage', () => ({
])),
}));

const expectedSampleNames = [
'Example 1',
'Another-Example no.2',
];

jest.mock('utils/data-management/downloadFromUrl');

jest.mock('react-sortable-hoc', () => ({
Expand Down Expand Up @@ -82,10 +76,13 @@ const experimentWithoutSamples = experiments.find(
const experimentWithSamplesId = experimentWithSamples.id;
const experimentWithoutSamplesId = experimentWithoutSamples.id;

const experimentCloneId = 'mockExperimentCloneId';

// Mocking samples update / delete routes
const customResponses = {
[`experiments/${experimentWithSamplesId}/samples/${experimentWithSamples.samplesOrder[0]}`]: () => statusResponse(200, 'OK'),
[`experiments/${experimentWithSamplesId}/samples/position`]: () => statusResponse(200, 'OK'),
[`experiments/${mockDemoExperiments[0].id}/clone`]: () => promiseResponse(JSON.stringify(experimentCloneId)),
};

const mockAPIResponse = _.merge(
Expand Down Expand Up @@ -115,73 +112,13 @@ describe('Samples table', () => {
await storeState.dispatch(loadEnvironment('test'));
});

it('Shows option to download datasets if there are no samples', async () => {
await renderSamplesTable(storeState);

// Load project without samples
storeState.dispatch(setActiveProject(experimentWithoutSamplesId));

expect(screen.getByText(/Start uploading your samples by clicking on Add samples./i)).toBeInTheDocument();
expect(screen.getByText(/Don't have data\? Get started using one of our example datasets:/i)).toBeInTheDocument();

// There should be n number of example datasets in the correct order
const linksContainer = screen.getByText(expectedSampleNames[0]).closest('ul');
const links = Array.from(linksContainer.children).map((el) => el.textContent);

expect(links.join(' ')).toEqual(expectedSampleNames.join(' '));

// Clicking on one of the samples downloads the file
const exampleFileLink = expectedSampleNames[0];

await act(async () => {
userEvent.click(screen.getByText(exampleFileLink));
});

expect(downloadFromUrl).toHaveBeenCalledTimes(1);
});

it('Does not show prompt to upload datasets if samples are available', async () => {
await renderSamplesTable(storeState);

expect(screen.queryByText(/Start uploading your samples by clicking on Add samples./i)).toBeNull();
expect(screen.queryByText(/Don't have data\? Get started using one of our example datasets:/i)).toBeNull();
});

it('Does not show option to download sample dataset if there are none available in S3 bucket', async () => {
Storage.list.mockImplementationOnce(() => Promise.resolve([]));

await renderSamplesTable(storeState);

// Load project without samples
storeState.dispatch(setActiveProject(experimentWithoutSamplesId));

// This prompt to upload samples is still visible
expect(screen.getByText(/Start uploading your samples by clicking on Add samples./i)).toBeInTheDocument();

// But the prompt to download data is not shown anymore
expect(screen.queryByText(/Don't have data\? Get started using one of our example datasets:/i)).toBeNull();
});

it('Should not show example datasets with incorrect names', async () => {
Storage.list.mockImplementationOnce(() => Promise.resolve([
{ key: '2.Another-Example_no.2.zip' },
{ key: '1.Example_1.zip' },
{ key: 'Dataset_with_no_order.zip' },
{ key: 'Invalid_key.Dataset.zip' },
{ key: 'Invalid_key.Dataset_no_extension' },
]));

await renderSamplesTable(storeState);

// Load project without samples
storeState.dispatch(setActiveProject(experimentWithoutSamplesId));

const linksContainer = screen.getByText(expectedSampleNames[0]).closest('ul');
const links = Array.from(linksContainer.children).map((el) => el.textContent);

expect(links.join(' ')).toEqual(expectedSampleNames.join(' '));
});

it('Should show all the samples', async () => {
await renderSamplesTable(storeState);

Expand Down Expand Up @@ -298,4 +235,60 @@ describe('Samples table', () => {
},
);
});

describe('Example experiments functionality', () => {
beforeEach(async () => {
await renderSamplesTable(storeState);

// Load project without samples
await act(async () => {
await storeState.dispatch(setActiveProject(experimentWithoutSamplesId));
});
});

it('Example experiments show up in an empty experiment', async () => {
expect(screen.getByText(/Start uploading your samples by clicking on Add samples./i)).toBeInTheDocument();
expect(screen.getByText(/Don't have data\? Get started using one of our example datasets:/i)).toBeInTheDocument();

const exampleExperimentNames = _.map(mockDemoExperiments, 'name');

exampleExperimentNames.forEach((name) => {
expect(screen.getByText(name)).toBeDefined();
});
});

it('Cloning from example experiments works correctly', async () => {
// Clear mock calls so we can distinguish the new calls made from the old ones
fetchMock.mockClear();

const newExperimentsResponse = _.cloneDeep(responseData.experiments);
const noSamplesExperiment = newExperimentsResponse.find(
({ id }) => id === experimentWithoutSamplesId,
);
noSamplesExperiment.samplesOrder = mockDemoExperiments[0].samplesOrder;
const newApiResponses = _.merge(
mockAPIResponse,
{ experiments: () => promiseResponse(JSON.stringify(newExperimentsResponse)) },
);
fetchMock.mockIf(/.*/, mockAPI(newApiResponses));

await act(async () => {
userEvent.click(screen.getByText(mockDemoExperiments[0].name));
});

expect(fetchMock).toHaveBeenCalledWith(
`http://localhost:3000/v2/experiments/${mockDemoExperiments[0].id}/clone`,
expect.objectContaining({
method: 'POST',
headers: { 'Content-Type': 'application/json' },
}),
);

// Reloads experiments
expect(fetchMock).toHaveBeenCalledWith(
'http://localhost:3000/v2/experiments',
{ headers: {} },
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -163,41 +163,6 @@ describe('Data Management page', () => {
expect(processProjectButton).toBeInTheDocument();
});

it('Example datasets are available for download', async () => {
await act(async () => {
render(
<Provider store={storeState}>
{dataManagementPageFactory()}
</Provider>,
);
});

// There are 2 elements with the name of the project, because of how Antd renders the element
// so we're only choosing one
const projectName = screen.getAllByText(experimentWithoutSamples.name)[0];

await act(async () => {
userEvent.click(projectName);
});

await waitFor(() => {
expect(screen.getByText(/Don't have data\? Get started using one of our example datasets/i)).toBeInTheDocument();
});

const downloadPromises = expectedSampleNames.map(async (sampleName) => {
const fileDownloadLink = screen.getByText(sampleName);

expect(fileDownloadLink).toBeInTheDocument();

// Clicking the link will trigger downlaod
userEvent.click(fileDownloadLink);
});

await Promise.all(downloadPromises);

expect(downloadFromUrl).toHaveBeenCalledTimes(expectedSampleNames.length);
});

it('Shows samples table if project contain samples', async () => {
// Change to project with samples
await act(async () => {
Expand Down
4 changes: 4 additions & 0 deletions src/__test__/test-utils/mockAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import _ from 'lodash';
import cellSetsData from '__test__/data/cell_sets.json';
import backendStatusData from '__test__/data/backend_status.json';
import processingConfigData from '__test__/data/processing_config.json';
import mockDemoExperiments from '__test__/test-utils/mockData/mockDemoExperiments.json';

// A ticket has been created to address this : https://biomage.atlassian.net/browse/BIOMAGE-1553
import {
Expand Down Expand Up @@ -47,6 +48,9 @@ const generateDefaultMockAPIResponses = (experimentId) => ({
[`experiments/${experimentId}/samples`]: () => promiseResponse(
JSON.stringify(responseData.samples[0]),
),
'/v2/experiments/examples': () => promiseResponse(
JSON.stringify(mockDemoExperiments),
),
});

const mockAPI = (apiMapping) => (req) => {
Expand Down
44 changes: 44 additions & 0 deletions src/__test__/test-utils/mockData/mockDemoExperiments.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[
{
"id": "a88e9bc2032867a96bf4166369c44b33",
"name": "Example0",
"description": "Analysis description",
"samplesOrder": [
"4580cdae-3107-438e-bf8a-3fe28b6ec0a5"
],
"notifyByEmail": true,
"createdAt": "2022-06-21 18:22:57.868439+00",
"updatedAt": "2022-06-21 18:22:57.868439+00",
"metadataKeys": [
"Track0"
]
},
{
"id": "b6cb756f851e1c9310cc5f3bc0cdcb73",
"name": "Example1",
"description": "Analysis description",
"samplesOrder": [
"af808bf4-1cd3-4646-966a-0a253063d2b2"
],
"notifyByEmail": true,
"createdAt": "2022-06-21 18:22:53.1091+00",
"updatedAt": "2022-06-21 18:22:53.1091+00",
"metadataKeys": [
"Track1"
]
},
{
"id": "840ad7454b1ad68af8c237b3320c7d3a",
"name": "Example2",
"description": "Analysis description",
"samplesOrder": [
"3eb4e715-03f1-4dc7-aac8-69d566103fd8"
],
"notifyByEmail": false,
"createdAt": "2022-06-21 18:23:02.688117+00",
"updatedAt": "2022-06-21 18:23:02.688117+00",
"metadataKeys": [
"Track2"
]
}
]
15 changes: 15 additions & 0 deletions src/__test__/utils/getAccountId.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import getAccountId from 'utils/getAccountId';

describe('getAccountId', () => {
it('Works in dev env', () => {
expect(getAccountId('development')).toEqual('000000000000');
});

it('Works in staging env', () => {
expect(getAccountId('staging')).toEqual('242905224710');
});

it('Works in prod env', () => {
expect(getAccountId('production')).toEqual('242905224710');
});
});
Loading

0 comments on commit 1331f8a

Please sign in to comment.