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-999 [frontend]: fix bug and fix e2e test #1595

Merged
merged 5 commits into from
Sep 4, 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
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ let mockRepoEffectResponse: IUseGetSourceControlConfigurationRepoInterface = moc
let mockBranchEffectResponse: IUseGetSourceControlConfigurationBranchInterface = mockInitBranchEffectResponse;
let mockCrewEffectResponse: IUseGetSourceControlConfigurationCrewInterface = mockInitCrewEffectResponse;

const mockInitSelectSourceControlRepos = ['mockRepoName', 'mockRepoName1'];
let mockSelectSourceControlRepos = mockInitSelectSourceControlRepos;

const mockInitSelectSourceControlBranches = ['mockBranchName', 'mockBranchName1'];
let mockSelectSourceControlBranches = mockInitSelectSourceControlBranches;

jest.mock('@src/hooks/useGetSourceControlConfigurationRepoEffect', () => {
return {
useGetSourceControlConfigurationRepoEffect: () => mockRepoEffectResponse,
Expand All @@ -54,8 +60,8 @@ jest.mock('@src/context/Metrics/metricsSlice', () => ({
jest.mock('@src/context/config/configSlice', () => ({
...jest.requireActual('@src/context/config/configSlice'),
selectSourceControlOrganizations: jest.fn().mockReturnValue(['mockOrgName', 'mockOrgName1']),
selectSourceControlRepos: jest.fn().mockImplementation(() => ['mockRepoName', 'mockRepoName1']),
selectSourceControlBranches: jest.fn().mockImplementation(() => ['mockBranchName', 'mockBranchName1']),
selectSourceControlRepos: jest.fn().mockImplementation(() => mockSelectSourceControlRepos),
selectSourceControlBranches: jest.fn().mockImplementation(() => mockSelectSourceControlBranches),
selectDateRange: jest.fn().mockReturnValue([
{ startDate: '2024-07-31T00:00:00.000+08:00', endDate: '2024-08-02T23:59:59.999+08:00' },
{ startDate: '2024-07-15T00:00:00.000+08:00', endDate: '2024-07-28T23:59:59.999+08:00' },
Expand All @@ -69,6 +75,8 @@ describe('SourceControlMetricSelection', () => {
mockRepoEffectResponse = mockInitRepoEffectResponse;
mockBranchEffectResponse = mockInitBranchEffectResponse;
mockCrewEffectResponse = mockInitCrewEffectResponse;
mockSelectSourceControlBranches = mockInitSelectSourceControlBranches;
mockSelectSourceControlRepos = mockInitSelectSourceControlRepos;
});
const onUpdateSourceControl = jest.fn();
const setup = (isDuplicated: boolean = false) => {
Expand Down Expand Up @@ -110,6 +118,7 @@ describe('SourceControlMetricSelection', () => {
});

it('should call getSourceControlRepoInfo function when isGetRepo is false and organization exists', () => {
mockSelectSourceControlRepos = [];
const getSourceControlRepoInfoFunction = jest.fn();
mockRepoEffectResponse = {
...mockInitRepoEffectResponse,
Expand All @@ -122,6 +131,7 @@ describe('SourceControlMetricSelection', () => {
});

it('should call getSourceControlBranchInfo function when isGetBranch is false and organization and repo exist', () => {
mockSelectSourceControlBranches = [];
const getSourceControlBranchInfoFunction = jest.fn();
mockBranchEffectResponse = {
...mockBranchEffectResponse,
Expand Down
20 changes: 13 additions & 7 deletions frontend/__tests__/context/metricsSlice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1612,8 +1612,8 @@ describe('saveMetricsSetting reducer', () => {
{ id: 3, organization: 'test-org3', repo: 'test-repo3', branches: ['test-branch3-1', 'test-branch3-2'] },
];
const expectedSourceControlConfigurationSettings = [
{ id: 1, organization: 'test-org-update1', repo: 'test-repo1', branches: ['test-branch1-1', 'test-branch1-2'] },
{ id: 2, organization: 'test-org2', repo: 'test-repo-update2', branches: ['test-branch2-1', 'test-branch2-2'] },
{ id: 1, organization: 'test-org-update1', repo: '', branches: [] },
{ id: 2, organization: 'test-org2', repo: 'test-repo-update2', branches: [] },
{ id: 3, organization: 'test-org3', repo: 'test-repo3', branches: ['test-branch-update3-1'] },
];

Expand Down Expand Up @@ -1644,21 +1644,21 @@ describe('saveMetricsSetting reducer', () => {
initState,
updateSourceControlConfigurationSettingsFirstInto({
name: ['test1', 'test2'],
isProjectCreated: true,
type: 'organization',
}),
);

expect(savedMetricsSetting.sourceControlConfigurationSettings).toEqual(expectedSourceControlConfigurationSettings);
});

it('should return source control settings when handle updateSourceControlConfigurationSettingsFirstInto and setting is empty', () => {
it('should return source control settings when handle updateSourceControlConfigurationSettingsFirstInto and import data is not empty', () => {
const existedImportedSourceControlSettings = [
{ id: 1, organization: 'test-org1', repo: 'test-repo1', branches: ['test-branch1'] },
{ id: 2, organization: 'test-org2', repo: 'test-repo2', branches: ['test-branch2'] },
];
const expectedSourceControlConfigurationSettings = [
{ id: 1, organization: 'test-org1', repo: 'test-repo1', branches: ['test-branch1'] },
{ id: 2, organization: '', repo: '', branches: [] },
];
const state = {
...initState,
Expand All @@ -1678,16 +1678,22 @@ describe('saveMetricsSetting reducer', () => {
savedMetricsSetting,
updateSourceControlConfigurationSettingsFirstInto({
name: ['test-repo1', 'test2'],
isProjectCreated: false,
type: 'repo',
id: 1,
}),
);
savedMetricsSetting = saveMetricsSettingReducer(
savedMetricsSetting,
updateSourceControlConfigurationSettingsFirstInto({
name: ['test-repo1', 'test2'],
type: 'repo',
}),
);
savedMetricsSetting = saveMetricsSettingReducer(
savedMetricsSetting,
updateSourceControlConfigurationSettingsFirstInto({
name: ['test-branch1'],
isProjectCreated: false,
type: 'branch',
type: 'branches',
}),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('use get source control configuration branch info side effect', () => {
const mockRepo = 'mockRepo';

await act(async () => {
result.current.getSourceControlBranchInfo(mockOrganization, mockRepo);
result.current.getSourceControlBranchInfo(mockOrganization, mockRepo, 1);
});

await waitFor(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('use get source control configuration repo info side effect', () => {
];

await act(async () => {
result.current.getSourceControlRepoInfo(mockOrganization, mockDateRanges);
result.current.getSourceControlRepoInfo(mockOrganization, mockDateRanges, 1);
});

await waitFor(() => {
Expand Down
26 changes: 13 additions & 13 deletions frontend/e2e/fixtures/create-new/report-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ export interface IBoardClassificationDetailItem {
export interface ICsvComparedLines extends Record<string, number> {}

export const BOARD_METRICS_RESULT: IBoardMetricsResult = {
velocity: '7.5',
throughput: '5',
averageCycleTimeForSP: '4.49',
averageCycleTimeForCard: '6.73',
totalReworkTimes: '2',
totalReworkCards: '2',
reworkCardsRatio: '0.4000',
reworkThroughput: '5',
velocity: '14',
throughput: '6',
averageCycleTimeForSP: '1.13',
averageCycleTimeForCard: '2.64',
totalReworkTimes: '0',
totalReworkCards: '0',
reworkCardsRatio: '0.0000',
reworkThroughput: '6',
};

export const BOARD_METRICS_RESULT_MULTIPLE_RANGES: IBoardMetricsResult[] = [
Expand Down Expand Up @@ -765,12 +765,12 @@ export const FLAG_AS_BLOCK_PROJECT_BOARD_METRICS_RESULT: IBoardMetricsResult = {

export const DORA_METRICS_RESULT = {
PrLeadTime: '0.00',
PipelineLeadTime: '22.72',
TotalLeadTime: '22.72',
DeploymentFrequency: '0.20',
FailureRate: '0.00% (0/1)',
PipelineLeadTime: '0.00',
TotalLeadTime: '0.00',
DeploymentFrequency: '0.00',
FailureRate: '100.00% (1/1)',
DevMeanTimeToRecovery: '0.00',
DeploymentTimes: '1',
DeploymentTimes: '0',
};

export const DORA_METRICS_RESULT_MULTIPLE_RANGES: IDoraMetricsResultItem[] = [
Expand Down
10 changes: 5 additions & 5 deletions frontend/e2e/fixtures/import-file/unhappy-path-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const importInputWrongProjectFromFile = {
{
id: 0,
organization: 'Heartbeat-backup',
pipelineName: 'Heartbeat-E2E',
pipelineName: 'Heartbeat',
step: ':rocket: Run e2e',
branches: ['main'],
isStepEmptyString: false,
Expand All @@ -96,10 +96,10 @@ export const importInputWrongProjectFromFile = {

export const importModifiedCorrectConfig = {
projectName: 'Heartbeat Metrics',
deletedBranch: 'ADM-747',
deletedBranch: 'ADM-998',
dateRange: {
startDate: '2024-06-03T00:00:00.000+08:00',
endDate: '2024-06-07T23:59:59.999+08:00',
startDate: '2024-08-12T00:00:00.000+08:00',
endDate: '2024-09-02T23:59:59.999+08:00',
},
board: {
type: 'Jira',
Expand All @@ -117,7 +117,7 @@ export const importModifiedCorrectConfig = {
type: 'GitHub',
token: process.env.E2E_TOKEN_GITHUB as string,
},
crews: ['Man Tang', 'heartbeat user', 'Qiuhong Lei', 'Chao Wang', 'YinYuan Zhou'],
crews: ['Man Tang', 'YinYuan Zhou'],
assigneeFilter: 'lastAssignee',
cycleTime: {
type: 'byColumn',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
{
"id": 0,
"organization": "Heartbeat-backup",
"pipelineName": "Heartbeat-E2E",
"pipelineName": "Heartbeat",
"step": ":rocket: Run e2e",
"branches": ["main", "ADM-747"]
}
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/containers/MetricsStep/Crews/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ export const Crews = ({ options, title, label, type = 'board' }: crewsProps) =>
const isAllSelected = options.length > 0 && selectedCrews.length === options.length;
const isEmptyCrewData = selectedCrews.length === 0;

useEffect(() => {
if (isSourceControl) {
setSelectedCrews(getValidSelectedCrews(sourceControlCrews, options));
}
}, [isSourceControl, options, sourceControlCrews]);

useEffect(() => {
const crews = isSourceControl ? sourceControlCrews : pipelineCrews;
setSelectedCrews(isBoardCrews ? users : crews);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,24 @@ export const SourceControlMetricSelection = ({
};

useEffect(() => {
if (!isGetRepo && organization) {
getSourceControlRepoInfo(organization, dateRanges);
if (!isGetRepo && organization && repoNameOptions.length === 0) {
getSourceControlRepoInfo(organization, dateRanges, id);
}
}, [dateRanges, getSourceControlRepoInfo, isGetRepo, organization]);
}, [dateRanges, getSourceControlRepoInfo, id, isGetRepo, organization, repoNameOptions.length]);

useEffect(() => {
if (!isGetBranch && organization && repo) {
getSourceControlBranchInfo(organization, repo);
if (!isGetBranch && organization && repo && branchNameOptions.length === 0) {
getSourceControlBranchInfo(organization, repo, id);
}
}, [getSourceControlBranchInfo, getSourceControlRepoInfo, isGetBranch, organization, repo]);
}, [
branchNameOptions.length,
getSourceControlBranchInfo,
getSourceControlRepoInfo,
id,
isGetBranch,
organization,
repo,
]);

useEffect(() => {
if (!isGetAllCrews && organization && repo && selectedBranches) {
Expand All @@ -105,19 +113,20 @@ export const SourceControlMetricSelection = ({

const handleOnUpdateOrganization = (id: number, label: string, value: string | []): void => {
onUpdateSourceControl(id, label, value);
getSourceControlRepoInfo(value.toString(), dateRanges);
getSourceControlRepoInfo(value.toString(), dateRanges, id);
};

const handleOnUpdateRepo = (id: number, label: string, value: string | []): void => {
onUpdateSourceControl(id, label, value);
getSourceControlBranchInfo(organization, value.toString());
getSourceControlBranchInfo(organization, value.toString(), id);
};

const handleOnUpdateBranches = (id: number, label: string, value: string[]): void => {
const branchNeedGetCrews = value.filter((it) => selectedBranches?.every((branch) => branch !== it));
onUpdateSourceControl(id, label, value);
branchNeedGetCrews.forEach((branch) => getSourceControlCrewInfo(organization, repo, branch, dateRanges));
};

useEffect(() => {
if (isGetAllCrews) {
setLoadingCompletedNumber((value) => Math.min(totalSourceControlNumber, value + 1));
Expand Down
68 changes: 50 additions & 18 deletions frontend/src/context/Metrics/metricsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,17 +401,34 @@ export const metricsSlice = createSlice({
const { updateId, label, value } = action.payload;
const sourceControlConfigurationSettings = state.sourceControlConfigurationSettings;
state.sourceControlConfigurationSettings = sourceControlConfigurationSettings.map((it) => {
return it.id !== updateId
? it
: {
if (it.id !== updateId) {
return it;
} else {
if (label === 'organization') {
return {
...it,
organization: value,
repo: '',
branches: [],
};
} else if (label === 'repo') {
return {
...it,
[label]: value,
repo: value,
branches: [],
};
} else {
return {
...it,
branches: value,
};
}
}
});
},

updateSourceControlConfigurationSettingsFirstInto: (state, action) => {
const { name, type } = action.payload;
const { name, type, id } = action.payload;

const sourceControlConfigurationSettings = state.sourceControlConfigurationSettings;

Expand All @@ -438,19 +455,34 @@ export const metricsSlice = createSlice({
},
];

if (type === 'organization') {
validSourceControlConfigurationSettings = validSourceControlConfigurationSettings.filter(
(it) => it['organization'] === '' || name.includes(it['organization']),
);
} else if (type === 'repo') {
validSourceControlConfigurationSettings = validSourceControlConfigurationSettings.filter(
(it) => it['repo'] === '' || name.includes(it['repo']),
);
} else {
validSourceControlConfigurationSettings = validSourceControlConfigurationSettings.filter(
(it) => it['branches'].length === 0 || it['branches'].filter((branch) => name.includes(branch)),
);
}
const func = (type: string, it: ISourceControlConfig) => {
if (type === 'organization') {
if (name.includes(it['organization'])) {
return it['organization'];
} else {
return '';
}
} else if (type === 'repo') {
if (name.includes(it['repo'])) {
return it['repo'];
} else {
return '';
}
} else {
return it.branches.filter((branch) => name.includes(branch));
}
};

validSourceControlConfigurationSettings = validSourceControlConfigurationSettings.map((it) => {
if (id !== undefined && id !== it.id) {
return it;
}
const newValue = func(type, it);
return {
...it,
[type]: newValue,
};
});

state.sourceControlConfigurationSettings = validSourceControlConfigurationSettings;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useState } from 'react';

export interface IUseGetSourceControlConfigurationBranchInterface {
readonly isLoading: boolean;
readonly getSourceControlBranchInfo: (organization: string, repo: string) => Promise<void>;
readonly getSourceControlBranchInfo: (organization: string, repo: string, id: number) => Promise<void>;
readonly isGetBranch: boolean;
}
export const useGetSourceControlConfigurationBranchEffect = (): IUseGetSourceControlConfigurationBranchInterface => {
Expand All @@ -23,7 +23,7 @@ export const useGetSourceControlConfigurationBranchEffect = (): IUseGetSourceCon
.map((it) => it[1])[0];
}

const getSourceControlBranchInfo = async (organization: string, repo: string) => {
const getSourceControlBranchInfo = async (organization: string, repo: string, id: number) => {
const params = {
type: getEnumKeyByEnumValue(restoredSourceControlInfo.type),
token: restoredSourceControlInfo.token,
Expand Down Expand Up @@ -52,7 +52,8 @@ export const useGetSourceControlConfigurationBranchEffect = (): IUseGetSourceCon
dispatch(
updateSourceControlConfigurationSettingsFirstInto({
...response.data,
type: 'branch',
id,
type: 'branches',
}),
);
}
Expand Down
Loading
Loading