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

ADM-691: [frontend] feat: add feat about rework settings #1138

Merged
merged 19 commits into from
Mar 12, 2024
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
2 changes: 2 additions & 0 deletions frontend/__tests__/constants/fileConfig/fileConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
BASIC_IMPORTED_OLD_CONFIG_FIXTURE,
REGULAR_CALENDAR,
CHINA_CALENDAR,
DEFAULT_REWORK_SETTINGS,
} from '../../fixtures';
import { convertToNewFileConfig } from '@src/constants/fileConfig';

Expand Down Expand Up @@ -43,6 +44,7 @@ describe('#fileConfig', () => {
organization: 'Thoughtworks-Heartbeat',
},
],
reworkTimesSettings: DEFAULT_REWORK_SETTINGS,
};

it('should return original config when it is not old config', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
MEAN_TIME_TO_RECOVERY,
REQUIRED_DATA,
REQUIRED_DATA_LIST,
REWORK_TIMES,
VELOCITY,
} from '../../fixtures';
import { act, fireEvent, render, waitFor, within, screen } from '@testing-library/react';
Expand Down Expand Up @@ -70,7 +71,7 @@ describe('MetricsTypeCheckbox', () => {

it('should show all selections when all option are select', async () => {
const { getByRole, getByText } = setup();
const displayedDataList = REQUIRED_DATA_LIST.slice(1, 8);
const displayedDataList = REQUIRED_DATA_LIST.slice(1);
await act(async () => {
await userEvent.click(getByRole('button', { name: REQUIRED_DATA }));
});
Expand All @@ -85,7 +86,7 @@ describe('MetricsTypeCheckbox', () => {

it('should show all selections when click velocity selection and then click all selection', async () => {
const { getByRole, getByText } = setup();
const displayedDataList = REQUIRED_DATA_LIST.slice(1, 8);
const displayedDataList = REQUIRED_DATA_LIST.slice(1);

await act(async () => {
await userEvent.click(getByRole('button', { name: REQUIRED_DATA }));
Expand Down Expand Up @@ -113,6 +114,7 @@ describe('MetricsTypeCheckbox', () => {
listBox.getByRole('option', { name: VELOCITY }),
listBox.getByRole('option', { name: CYCLE_TIME }),
listBox.getByRole('option', { name: CLASSIFICATION }),
listBox.getByRole('option', { name: REWORK_TIMES }),
listBox.getByRole('option', { name: LEAD_TIME_FOR_CHANGES }),
listBox.getByRole('option', { name: DEPLOYMENT_FREQUENCY }),
listBox.getByRole('option', { name: CHANGE_FAILURE_RATE }),
Expand All @@ -125,7 +127,7 @@ describe('MetricsTypeCheckbox', () => {

it('should show some selections when click all option and then click velocity selection', async () => {
const { getByRole, getByText } = setup();
const displayedDataList = REQUIRED_DATA_LIST.slice(1, 7);
const displayedDataList = REQUIRED_DATA_LIST.slice(1, REQUIRED_DATA_LIST.length - 1);

await act(async () => {
await userEvent.click(getByRole('button', { name: REQUIRED_DATA }));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { SingleSelection } from '@src/containers/MetricsStep/ReworkSettings/SingleSelection';
import { act, render, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { LIST_OPEN } from '@test/fixtures';

describe('SingleSelection', () => {
const mockOptions = ['opton1', 'opton2', 'opton3'];
const mockLabel = 'mockLabel';
const mockValue = 'mockOptions 1';
const mockOnValueChange = jest.fn();

afterEach(() => {
jest.clearAllMocks();
});

const setup = () =>
render(
<SingleSelection options={mockOptions} label={mockLabel} value={mockValue} onValueChange={mockOnValueChange} />,
);

it('should trigger onValueChange callback when select value option', async () => {
const { getByText, getByRole, getAllByRole } = setup();

await waitFor(() => {
expect(getByText(mockLabel)).toBeInTheDocument();
});

await act(async () => {
await userEvent.click(getAllByRole('button', { name: LIST_OPEN })[0]);
});

const stepsListBox = within(getByRole('listbox'));
await act(async () => {
await userEvent.click(stepsListBox.getByText(mockOptions[1]));
});

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

it('should show no options when search the wrong keyword', async () => {
const { getAllByRole, getByText } = setup();
const buttonElements = getAllByRole('button', { name: LIST_OPEN });

await act(async () => {
await userEvent.type(buttonElements[0], 'wrong keyword');
});

expect(getByText('No options')).toBeInTheDocument();
});
});
90 changes: 90 additions & 0 deletions frontend/__tests__/containers/MetricsStep/reworkSettings.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import {
ALL,
LIST_OPEN,
REWORK_EXCLUDE_WHICH_STATE,
REWORK_SETTINGS_TITLE,
REWORK_TO_WHICH_STATE,
} from '../../fixtures';
import { act, render, screen, waitFor, within } from '@testing-library/react';
import ReworkSettings from '@src/containers/MetricsStep/ReworkSettings';
import { CYCLE_TIME_LIST } from '@src/constants/resources';
import { setupStore } from '../../utils/setupStoreUtil';
import userEvent from '@testing-library/user-event';
import { Provider } from 'react-redux';
import React from 'react';

const mockedUseAppDispatch = jest.fn();
jest.mock('@src/hooks/useAppDispatch', () => ({
useAppDispatch: () => mockedUseAppDispatch,
}));

const store = setupStore();

describe('reworkSetting', () => {
const setup = () =>
render(
<Provider store={store}>
<ReworkSettings />
</Provider>,
);
afterEach(() => {
jest.clearAllMocks();
});

it('should show initial content', () => {
setup();

expect(screen.getByText(REWORK_SETTINGS_TITLE)).toBeInTheDocument();
expect(screen.getByText(REWORK_TO_WHICH_STATE)).toBeInTheDocument();
expect(screen.getByText(REWORK_EXCLUDE_WHICH_STATE)).toBeInTheDocument();
});

it('should get correct rework setting when pick option', async () => {
const { getByRole, getAllByRole } = setup();
await act(async () => {
await userEvent.click(getAllByRole('button', { name: LIST_OPEN })[0]);
});
const stepsListBox = within(getByRole('listbox'));
await act(async () => {
await userEvent.click(stepsListBox.getByText('----'));
});
await waitFor(async () => {
await expect(
(screen.getByTestId('rework-single-selection-rework-to-which-state').querySelector('input') as HTMLInputElement)
.value,
).toBe('----');
});
});

it('should get correct value when pick all or other value', async () => {
const { getByRole, getAllByRole, queryByRole } = setup();
await act(async () => {
await userEvent.click(getAllByRole('button', { name: LIST_OPEN })[1]);
});
const stepsListBox = within(getByRole('listbox'));
await act(async () => {
await userEvent.click(stepsListBox.getByText(ALL));
});
await waitFor(async () => {
CYCLE_TIME_LIST.forEach((value) => {
expect(getByRole('button', { name: value })).toBeInTheDocument();
});
});

await act(async () => {
await userEvent.click(stepsListBox.getByText(ALL));
});
await waitFor(() => {
CYCLE_TIME_LIST.forEach((value) => {
expect(queryByRole('button', { name: value })).not.toBeInTheDocument();
});
});

await act(async () => {
await userEvent.click(stepsListBox.getByText(CYCLE_TIME_LIST[0]));
});
await waitFor(async () => {
expect(getByRole('button', { name: CYCLE_TIME_LIST[0] })).toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
BASE_PAGE_ROUTE,
BOARD_TYPES,
CONFIRM_DIALOG_DESCRIPTION,
DEFAULT_REWORK_SETTINGS,
MOCK_REPORT_URL,
NEXT,
PIPELINE_TOOL_TYPES,
Expand Down Expand Up @@ -357,6 +358,7 @@ describe('MetricsStepper', () => {
deployment: undefined,
doneStatus: undefined,
leadTime: undefined,
reworkTimesSettings: DEFAULT_REWORK_SETTINGS,
};
setup();

Expand Down Expand Up @@ -388,6 +390,10 @@ describe('MetricsStepper', () => {
deployment: undefined,
doneStatus: undefined,
leadTime: undefined,
reworkTimesSettings: {
rework2State: null,
excludeStates: [],
},
};

setup();
Expand Down
16 changes: 8 additions & 8 deletions frontend/__tests__/containers/ReportStep/ReportStep.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,28 +182,28 @@ describe('Report Step', () => {
});

it('should render the Lead Time For Change component with correct props', () => {
setup([REQUIRED_DATA_LIST[4]]);
setup([REQUIRED_DATA_LIST[5]]);

expect(screen.getByText('60.79')).toBeInTheDocument();
expect(screen.getByText('39.03')).toBeInTheDocument();
expect(screen.getByText('99.82')).toBeInTheDocument();
});

it('should render the Deployment frequency component with correct props', () => {
setup([REQUIRED_DATA_LIST[5]]);
setup([REQUIRED_DATA_LIST[6]]);

expect(screen.getByText('0.40')).toBeInTheDocument();
});

it('should render the Change failure rate component with correct props', () => {
setup([REQUIRED_DATA_LIST[6]]);
setup([REQUIRED_DATA_LIST[7]]);

expect(screen.getByText('0.00')).toBeInTheDocument();
expect(screen.getByText('% (0/6)')).toBeInTheDocument();
});

it('should render the Mean time to recovery component with correct props', () => {
setup([REQUIRED_DATA_LIST[7]]);
setup([REQUIRED_DATA_LIST[8]]);

expect(screen.getByText('4.00')).toBeInTheDocument();
});
Expand Down Expand Up @@ -252,7 +252,7 @@ describe('Report Step', () => {
jest.useRealTimers();
});

it.each([[REQUIRED_DATA_LIST[1]], [REQUIRED_DATA_LIST[4]]])(
it.each([[REQUIRED_DATA_LIST[2]], [REQUIRED_DATA_LIST[5]]])(
'should render detail page when clicking show more button given metric %s',
async (requiredData) => {
setup([requiredData], MOCK_DATE_RANGE);
Expand All @@ -266,7 +266,7 @@ describe('Report Step', () => {
},
);

it.each([[REQUIRED_DATA_LIST[1]], [REQUIRED_DATA_LIST[4]]])(
it.each([[REQUIRED_DATA_LIST[2]], [REQUIRED_DATA_LIST[5]]])(
'should return report page when clicking back button in Breadcrumb in detail page given metric %s',
async (requiredData) => {
setup([requiredData]);
Expand All @@ -286,7 +286,7 @@ describe('Report Step', () => {
},
);

it.each([[REQUIRED_DATA_LIST[1]], [REQUIRED_DATA_LIST[4]]])(
it.each([[REQUIRED_DATA_LIST[2]], [REQUIRED_DATA_LIST[5]]])(
'should return report page when clicking previous button in detail page given metric %s',
async (requiredData) => {
setup([requiredData]);
Expand Down Expand Up @@ -318,7 +318,7 @@ describe('Report Step', () => {
expect(exportPipelineButton).not.toBeInTheDocument();
});

it.each([[REQUIRED_DATA_LIST[4]], [REQUIRED_DATA_LIST[5]], [REQUIRED_DATA_LIST[6]], [REQUIRED_DATA_LIST[7]]])(
it.each([[REQUIRED_DATA_LIST[5]], [REQUIRED_DATA_LIST[6]], [REQUIRED_DATA_LIST[7]], [REQUIRED_DATA_LIST[8]]])(
'should show export pipeline button when selecting %s',
(requiredData) => {
setup([requiredData]);
Expand Down
11 changes: 10 additions & 1 deletion frontend/__tests__/context/metricsSlice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@ import saveMetricsSettingReducer, {
updatePipelineStep,
updateTreatFlagCardAsBlock,
} from '@src/context/Metrics/metricsSlice';
import {
CLASSIFICATION_WARNING_MESSAGE,
DEFAULT_REWORK_SETTINGS,
NO_RESULT_DASH,
PIPELINE_SETTING_TYPES,
} from '../fixtures';
import { ASSIGNEE_FILTER_TYPES, CYCLE_TIME_SETTINGS_TYPES, MESSAGE } from '@src/constants/resources';
import { CLASSIFICATION_WARNING_MESSAGE, NO_RESULT_DASH, PIPELINE_SETTING_TYPES } from '../fixtures';
import { setupStore } from '../utils/setupStoreUtil';
import { store } from '@src/store';

Expand Down Expand Up @@ -50,6 +55,7 @@ const initState = {
importedDeployment: [],
importedLeadTime: [],
importedAdvancedSettings: null,
reworkTimesSettings: DEFAULT_REWORK_SETTINGS,
},
cycleTimeWarningMessage: null,
classificationWarningMessage: null,
Expand Down Expand Up @@ -111,6 +117,7 @@ describe('saveMetricsSetting reducer', () => {
importedDeployment: [],
importedPipelineCrews: [],
importedAdvancedSettings: null,
reworkTimesSettings: DEFAULT_REWORK_SETTINGS,
});
});

Expand Down Expand Up @@ -193,6 +200,7 @@ describe('saveMetricsSetting reducer', () => {
storyPoint: '1',
flag: '2',
},
reworkTimesSettings: DEFAULT_REWORK_SETTINGS,
};
const savedMetricsSetting = saveMetricsSettingReducer(
initState,
Expand All @@ -212,6 +220,7 @@ describe('saveMetricsSetting reducer', () => {
importedDeployment: mockMetricsImportedData.deployment,
importedLeadTime: mockMetricsImportedData.leadTime,
importedAdvancedSettings: mockMetricsImportedData.advancedSettings,
reworkTimesSettings: mockMetricsImportedData.reworkTimesSettings,
});
});

Expand Down
19 changes: 19 additions & 0 deletions frontend/__tests__/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const REQUIRED_DATA_LIST = [
'Velocity',
'Cycle time',
'Classification',
'Rework times',
'Lead time for changes',
'Deployment frequency',
'Change failure rate',
Expand All @@ -58,6 +59,7 @@ export const ALL = 'All';
export const VELOCITY = 'Velocity';
export const CYCLE_TIME = 'Cycle time';
export const CLASSIFICATION = 'Classification';
export const REWORK_TIMES = 'Rework times';
export const LEAD_TIME_FOR_CHANGES = 'Lead time for changes';
export const DEPLOYMENT_FREQUENCY = 'Deployment frequency';
export const CHANGE_FAILURE_RATE = 'Change failure rate';
Expand Down Expand Up @@ -247,6 +249,10 @@ export const IMPORTED_NEW_CONFIG_FIXTURE = {
},
],
},
reworkTimesSettings: {
rework2State: null,
excludeStates: [],
},
};

export const MOCK_EXPORT_CSV_REQUEST_PARAMS: CSVReportRequestDTO = {
Expand Down Expand Up @@ -701,6 +707,10 @@ export const BASIC_IMPORTED_OLD_CONFIG_FIXTURE = {
orgId: 'Thoughtworks-Heartbeat',
},
],
reworkTimesSettings: {
rework2State: null,
excludeStates: [],
},
};

export const ERROR_MESSAGE_TIME_DURATION = 4000;
Expand Down Expand Up @@ -743,3 +753,12 @@ export const FAKE_TOKEN = 'fake-token';
export const FAKE_PIPELINE_TOKEN = 'bkua_mockTokenMockTokenMockTokenMockToken1234';

export const ADVANCED_SETTINGS_TITLE = 'Advanced settings';

export const REWORK_SETTINGS_TITLE = 'Rework times settings';
export const REWORK_TO_WHICH_STATE = 'Rework to which state';
export const REWORK_EXCLUDE_WHICH_STATE = 'Exclude which states (optional)';

export const DEFAULT_REWORK_SETTINGS = {
rework2State: null,
excludeStates: [],
};
Loading
Loading