Skip to content

Commit

Permalink
ADM-1000 [frontend][backend]: support lead time for changes for singl…
Browse files Browse the repository at this point in the history
…e data source in the metrics page (#1610)

* ADM-1000 [frontend]: show source control configuration when pipeline tool select buildkite

* ADM-1000 [frontend]: add test for source control configuration when pipeline tool select buildkite

* ADM-1000 [backend]: add repo name in the pipeline info api

* ADM-1000 [backend]: finish test for repo name in the pipeline info api

* ADM-1000 [backend]: format

* ADM-1000 [backend]: update repoName data

* ADM-1000 [frontend]: add repo name for pipeline configuration in the metrics page

* ADM-1000 [frontend]: fix test

* ADM-1000 [frontend]: fix test coverage

* ADM-1000 [frontend]: disable repo name in the source control settings when pipeline configuration select repo name

* ADM-1000 [frontend]: fix test

* ADM-1000 [frontend]: adjust the logic for the next button in the metrics page

* ADM-1000 [frontend]: fix test

* ADM-1000 [backend]: fix sonar issues

* ADM-1000 [frontend]: fix sonar issues

* ADM-1000 [frontend]: adjust the logic for the next button in the metrics page

* ADM-1000 [frontend]: fix e2e test

* ADM-1000 [frontend]: refactor: rename the deployment settings in the state

* ADM-1000 [frontend]: refactor: rename the deployment frequency settings component

* ADM-1000 [frontend]: fix the bug of branch selection in the source control settings

* ADM-1000 [frontend]: format and rename

* ADM-1000 [frontend]: fix test coverage

* ADM-1000 [frontend]: fix save config file

* ADM-1000 [frontend]: fix e2e test

* ADM-1000 [frontend][backend]: fix comments

* ADM-1000 [frontend]: fix sonar issues
  • Loading branch information
zhou-yinyuan authored Sep 24, 2024
1 parent 03564e6 commit a8ece41
Show file tree
Hide file tree
Showing 49 changed files with 572 additions and 373 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public class Pipeline {

String repository;

String repoName;

List<String> steps;

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@

import heartbeat.client.dto.pipeline.buildkite.BuildKitePipelineDTO;
import heartbeat.client.dto.pipeline.buildkite.StepsDTO;
import heartbeat.util.GithubUtil;

import java.util.stream.Collectors;

public interface PipelineTransformer {

static Pipeline fromBuildKitePipelineDto(BuildKitePipelineDTO dto, String orgId, String orgName) {
String repositoryFullName = dto.getRepository();
String repoName = GithubUtil.getGithubUrlFullName(repositoryFullName);

return Pipeline.builder()
.orgId(orgId)
.orgName(orgName)
.id(dto.getSlug())
.name(dto.getName())
.repository(dto.getRepository())
.repository(repositoryFullName)
.repoName(repoName)
.steps(dto.getSteps()
.stream()
.map(StepsDTO::getName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import heartbeat.client.dto.pipeline.buildkite.BuildKitePipelineDTO;
import heartbeat.client.dto.pipeline.buildkite.StepsDTO;
import heartbeat.util.GithubUtil;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mockStatic;

class PipelineTransformerTest {

Expand All @@ -23,16 +26,20 @@ void shouldTransformToPipeline() {
.steps(steps)
.build();

Pipeline pipeline = PipelineTransformer.fromBuildKitePipelineDto(dto, orgId, orgName);
try (MockedStatic<GithubUtil> githubUtilMockedStatic = mockStatic(GithubUtil.class)) {
githubUtilMockedStatic.when(() -> GithubUtil.getGithubUrlFullName("repository")).thenReturn("repoName");

assertEquals(pipeline.id, "SLUG");
assertEquals(pipeline.name, "Name");
assertEquals(pipeline.repository, "repository");
assertEquals(pipeline.orgId, orgId);
assertEquals(pipeline.orgName, orgName);
assertEquals(pipeline.steps.size(), 1);
assertEquals(pipeline.steps.get(0), "Name1");
Pipeline pipeline = PipelineTransformer.fromBuildKitePipelineDto(dto, orgId, orgName);

assertEquals("SLUG", pipeline.id);
assertEquals("Name", pipeline.name);
assertEquals("repository", pipeline.repository);
assertEquals(orgId, pipeline.orgId);
assertEquals(orgName, pipeline.orgName);
assertEquals("repoName", pipeline.repoName);
assertEquals(1, pipeline.steps.size());
assertEquals("Name1", pipeline.steps.get(0));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ import {
REQUIRED_DATA_LIST,
SELECT_CONSIDER_AS_DONE_MESSAGE,
SOURCE_CONTROL_SETTINGS,
REMOVE_BUTTON,
} from '../../fixtures';
import {
updateCycleTimeSettings,
saveDoneColumn,
setCycleTimeSettingsType,
updateShouldGetBoardConfig,
addOneSourceControlSetting,
} from '@src/context/Metrics/metricsSlice';
import { updateJiraVerifyResponse, updateMetrics, updatePipelineTool } from '@src/context/config/configSlice';
import { closeAllNotifications } from '@src/context/notification/NotificationSlice';
Expand Down Expand Up @@ -122,9 +124,12 @@ describe('MetricsStep', () => {

it('should show DeploymentFrequencySettings component when select deployment frequency in config page', async () => {
await store.dispatch(updateMetrics([REQUIRED_DATA_LIST[5]]));
await store.dispatch(addOneSourceControlSetting());
setup();

expect(screen.getByText(DEPLOYMENT_FREQUENCY_SETTINGS)).toBeInTheDocument();
expect(screen.getByText(SOURCE_CONTROL_SETTINGS)).toBeInTheDocument();
expect(screen.getByText(REMOVE_BUTTON)).toBeInTheDocument();
});

it('should show SourceControlConfiguration component when select lead time for changes and the pipeline configuration value is none in config page', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MOCK_SOURCE_CONTROL_VERIFY_BRANCH_URL, MOCK_SOURCE_CONTROL_VERIFY_REQUEST_PARAMS } from '@test/fixtures';
import { BranchSelection } from '@src/containers/MetricsStep/DeploymentFrequencySettings/BranchSelection';
import { updatePipelineToolVerifyResponse, updateSourceControl } from '@src/context/config/configSlice';
import { BranchSelection } from '@src/containers/MetricsStep/PipelineConfiguration/BranchSelection';
import { render, screen, waitFor } from '@testing-library/react';
import { setupStore } from '@test/utils/setupStoreUtil';
import userEvent from '@testing-library/user-event';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import {
addADeploymentFrequencySetting,
deleteADeploymentFrequencySetting,
updateDeploymentFrequencySettings,
} from '@src/context/Metrics/metricsSlice';
import { addAPipelineSetting, deleteAPipelineSetting, updatePipelineSetting } from '@src/context/Metrics/metricsSlice';
import { DEPLOYMENT_FREQUENCY_SETTINGS, LIST_OPEN, LOADING, ORGANIZATION, REMOVE_BUTTON } from '@test/fixtures';
import { DeploymentFrequencySettings } from '@src/containers/MetricsStep/DeploymentFrequencySettings';
import { IUseVerifyPipeLineToolStateInterface } from '@src/hooks/useGetPipelineToolInfoEffect';
import { PipelineConfiguration } from '@src/containers/MetricsStep/PipelineConfiguration';
import { TokenAccessAlert } from '@src/containers/MetricsStep/TokenAccessAlert';
import { act, render, screen, waitFor, within } from '@testing-library/react';
import { setupStore } from '@test/utils/setupStoreUtil';
import userEvent from '@testing-library/user-event';
import { Provider } from 'react-redux';

import { setupStore } from '@test/utils/setupStoreUtil';

let mockSelectShouldGetPipelineConfig = true;
let mockSelectPipelineNames: string[] = [];
const mockSelectStepsParams = {
Expand All @@ -37,10 +32,10 @@ jest.mock('@src/hooks', () => ({

jest.mock('@src/context/Metrics/metricsSlice', () => ({
...jest.requireActual('@src/context/Metrics/metricsSlice'),
addADeploymentFrequencySetting: jest.fn(),
deleteADeploymentFrequencySetting: jest.fn(),
updateDeploymentFrequencySettings: jest.fn(),
selectDeploymentFrequencySettings: jest.fn().mockReturnValue([
addAPipelineSetting: jest.fn(),
deleteAPipelineSetting: jest.fn(),
updatePipelineSetting: jest.fn(),
selectPipelineSettings: jest.fn().mockReturnValue([
{ id: 0, organization: 'mockOrgName', pipelineName: '1', steps: '', branches: [] },
{ id: 1, organization: '', pipelineName: '', steps: '', branches: [] },
]),
Expand Down Expand Up @@ -85,6 +80,7 @@ const mockGetPipelineToolInfoOkResponse = {
orgName: 'Thoughtworks-Heartbeat',
repository: '[email protected]:au-heartbeat/Heartbeat.git',
steps: [':pipeline: Upload pipeline.yml'],
repoName: 'au-heartbeat/Heartbeat',
branches: [],
crews: [],
},
Expand All @@ -99,13 +95,13 @@ let mockGetPipelineToolInfoSpy: IUseVerifyPipeLineToolStateInterface = mockGetPi
jest.mock('@src/hooks/useGetPipelineToolInfoEffect', () => ({
useGetPipelineToolInfoEffect: () => mockGetPipelineToolInfoSpy,
}));
describe('DeploymentFrequencySettings', () => {
describe('PipelineConfiguration', () => {
let store = null;
const setup = () => {
store = setupStore();
return render(
<Provider store={store}>
<DeploymentFrequencySettings />
<PipelineConfiguration />
</Provider>,
);
};
Expand Down Expand Up @@ -148,24 +144,79 @@ describe('DeploymentFrequencySettings', () => {
expect(getAllByText(ORGANIZATION).length).toBe(2);
});

it('should call addADeploymentFrequencySetting function when click add another pipeline button', async () => {
it('should call addAPipelineSetting function when click add another pipeline button', async () => {
const { getByTestId } = await setup();

await userEvent.click(getByTestId('AddIcon'));

expect(addADeploymentFrequencySetting).toHaveBeenCalledTimes(1);
expect(addAPipelineSetting).toHaveBeenCalledTimes(1);
});

it('should call deleteADeploymentFrequencySetting function when click remove pipeline button', async () => {
it('should call deleteAPipelineSetting function when click remove pipeline button', async () => {
const { getAllByRole } = await setup();

await act(async () => {
await userEvent.click(getAllByRole('button', { name: REMOVE_BUTTON })[0]);
});
expect(deleteADeploymentFrequencySetting).toHaveBeenCalledTimes(1);

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

it('should call updatePipelineSetting function and clearErrorMessages function when select organization and the value doesnt match pipeline info', async () => {
const { getAllByRole, getByRole } = setup();

await act(async () => {
await userEvent.click(getAllByRole('button', { name: LIST_OPEN })[0]);
});
const listBox = within(getByRole('listbox'));
await userEvent.click(listBox.getByText('mockOrgName2'));

expect(updatePipelineSetting).toHaveBeenCalledTimes(2);
});

it('should call updatePipelineSetting function and clearErrorMessages function when select organization and the value match pipeline info', async () => {
mockGetPipelineToolInfoSpy = {
...mockGetPipelineToolInfoOkResponse,
result: {
...mockGetPipelineToolInfoOkResponse.result,
data: {
pipelineList: [
{
id: 'heartbeat',
name: 'Heartbeat',
orgId: 'thoughtworks-Heartbeat',
orgName: 'mockOrgName2',
repository: '[email protected]:au-heartbeat/Heartbeat.git',
steps: [':pipeline: Upload pipeline.yml'],
repoName: 'au-heartbeat/Heartbeat',
branches: [],
crews: [],
},
],
},
},
};
const { getAllByRole, getByRole } = setup();

await act(async () => {
await userEvent.click(getAllByRole('button', { name: LIST_OPEN })[0]);
});
const listBox = within(getByRole('listbox'));
await act(async () => {
await userEvent.click(listBox.getByText('mockOrgName2'));
});

expect(updatePipelineSetting).toHaveBeenCalledTimes(2);
});

it('should call updateDeploymentFrequencySetting function and clearErrorMessages function when select organization', async () => {
it('should call updatePipelineSetting function and clearErrorMessages function when select organization and pipeline info is undefined', async () => {
mockGetPipelineToolInfoSpy = {
...mockGetPipelineToolInfoOkResponse,
result: {
...mockGetPipelineToolInfoOkResponse.result,
data: undefined,
},
};
const { getAllByRole, getByRole } = setup();

await act(async () => {
Expand All @@ -176,7 +227,7 @@ describe('DeploymentFrequencySettings', () => {
await userEvent.click(listBox.getByText('mockOrgName2'));
});

expect(updateDeploymentFrequencySettings).toHaveBeenCalledTimes(1);
expect(updatePipelineSetting).toHaveBeenCalledTimes(2);
});

it('show render crews component when all pipelines load completed', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
REMOVE_BUTTON,
STEP,
} from '@test/fixtures';
import { PipelineMetricSelection } from '@src/containers/MetricsStep/DeploymentFrequencySettings/PipelineMetricSelection';
import { PipelineMetricSelection } from '@src/containers/MetricsStep/PipelineConfiguration/PipelineMetricSelection';
import { IPipelineConfig, updateShouldGetPipelineConfig } from '@src/context/Metrics/metricsSlice';
import { act, render, screen, waitFor, within } from '@testing-library/react';
import { metricsClient } from '@src/clients/MetricsClient';
Expand Down Expand Up @@ -92,6 +92,7 @@ describe('PipelineMetricSelection', () => {
organization: '',
pipelineName: '',
step: '',
repoName: '',
branches: [],
};
const mockHandleClickRemoveButton = jest.fn();
Expand Down Expand Up @@ -175,7 +176,7 @@ describe('PipelineMetricSelection', () => {
return Promise.reject('error');
});
const { getByText, getByRole, getAllByRole } = await setup(
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: '', branches: [] },
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: '', repoName: '', branches: [] },
false,
false,
);
Expand All @@ -198,7 +199,7 @@ describe('PipelineMetricSelection', () => {
.fn()
.mockReturnValue({ response: [], haveStep: false, pipelineCrews: [], branches: [] });
const { getByText, getByRole, getAllByRole } = await setup(
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: '', branches: [] },
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: '', repoName: '', branches: [] },
false,
false,
);
Expand Down Expand Up @@ -227,7 +228,7 @@ describe('PipelineMetricSelection', () => {
.fn()
.mockReturnValue({ response: [], haveStep: false, pipelineCrews: [], branches: [] });
const { getByRole, getAllByRole } = await setup(
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: '', branches: [] },
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: '', repoName: '', branches: [] },
true,
false,
);
Expand All @@ -250,7 +251,7 @@ describe('PipelineMetricSelection', () => {
.fn()
.mockReturnValue({ response: ['steps'], haveStep: true, pipelineCrews: [], branches: [] });
const { getByRole, getByText, getAllByRole } = await setup(
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: '', branches: [] },
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: '', repoName: '', branches: [] },
false,
false,
);
Expand All @@ -276,7 +277,14 @@ describe('PipelineMetricSelection', () => {
.fn()
.mockReturnValue({ response: ['steps'], haveStep: true, branches: ['branch1', 'branch2'], pipelineCrews: [] });
const { getByRole, getByText } = await setup(
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: '', branches: ['branch1', 'branch2'] },
{
id: 0,
organization: 'mockOrgName',
pipelineName: 'mockName',
step: '',
repoName: '',
branches: ['branch1', 'branch2'],
},
false,
false,
);
Expand All @@ -298,7 +306,14 @@ describe('PipelineMetricSelection', () => {
.fn()
.mockReturnValue({ response: ['steps'], haveStep: true, branches: ['branch1', 'branch2'], pipelineCrews: [] });
const { getByRole, queryByRole, getByText } = await setup(
{ id: 0, organization: 'mockOrgName3', pipelineName: 'mockName3', step: '', branches: ['branch6', 'branch7'] },
{
id: 0,
organization: 'mockOrgName3',
pipelineName: 'mockName3',
step: '',
repoName: '',
branches: ['branch6', 'branch7'],
},
false,
false,
);
Expand All @@ -320,7 +335,7 @@ describe('PipelineMetricSelection', () => {
.fn()
.mockReturnValue({ response: ['steps'], haveStep: true, pipelineCrews: [], branches: [] });
const { getByText } = await setup(
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: 'step1', branches: [] },
{ id: 0, organization: 'mockOrgName', pipelineName: 'mockName', step: 'step1', repoName: '', branches: [] },
false,
true,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { render, waitFor } from '@testing-library/react';
import { setupStore } from '@test/utils/setupStoreUtil';
import { Provider } from 'react-redux';

import { PipelineMetricSelection } from '@src/containers/MetricsStep/DeploymentFrequencySettings/PipelineMetricSelection';
import { PipelineMetricSelection } from '@src/containers/MetricsStep/PipelineConfiguration/PipelineMetricSelection';
import { IPipelineConfig, updateShouldGetPipelineConfig } from '@src/context/Metrics/metricsSlice';
import { addNotification } from '@src/context/notification/NotificationSlice';
import { MetricsDataFailStatus } from '@src/constants/commons';
Expand Down Expand Up @@ -32,6 +32,7 @@ describe('PipelineMetricSelection', () => {
organization: '',
pipelineName: '',
step: '',
repoName: '',
branches: [],
};
const mockHandleClickRemoveButton = jest.fn();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SingleSelection } from '@src/containers/MetricsStep/DeploymentFrequencySettings/SingleSelection';
import { SingleSelection } from '@src/containers/MetricsStep/PipelineConfiguration/SingleSelection';
import { act, render, within } from '@testing-library/react';
import { setupStore } from '@test/utils/setupStoreUtil';
import userEvent from '@testing-library/user-event';
Expand Down
Loading

0 comments on commit a8ece41

Please sign in to comment.