refactor: test run case status messages duplication

This commit is contained in:
Takeshi Kimata
2024-07-21 15:30:04 +09:00
parent f797ae2581
commit 1da19ed43c
12 changed files with 91 additions and 69 deletions

View File

@@ -1,6 +1,6 @@
import { TestTypeType } from '@/types/testType'; import { TestTypeType } from '@/types/testType';
import { PriorityType } from '@/types/priority'; import { PriorityType } from '@/types/priority';
import { TestStatusType } from '@/types/testStatus'; import { TestRunCaseStatusType } from '@/types/testRunCaseStatus';
const roles = [{ uid: 'administrator' }, { uid: 'user' }]; const roles = [{ uid: 'administrator' }, { uid: 'user' }];
@@ -13,7 +13,18 @@ const locales = [
{ code: 'ja', name: '日本語' }, { code: 'ja', name: '日本語' },
]; ];
const testRunCaseStatus: TestStatusType[] = [ // The status of each test run
const testRunStatus = [
{ uid: 'new' },
{ uid: 'inProgress' },
{ uid: 'underReview' },
{ uid: 'rejected' },
{ uid: 'done' },
{ uid: 'closed' },
];
// The status of each test case in test run
const testRunCaseStatus: TestRunCaseStatusType[] = [
{ {
uid: 'untested', uid: 'untested',
color: 'primary', color: 'primary',
@@ -57,15 +68,6 @@ const automationStatus = [
const templates = [{ uid: 'text' }, { uid: 'step' }]; const templates = [{ uid: 'text' }, { uid: 'step' }];
const testRunStatus = [
{ uid: 'new' },
{ uid: 'inProgress' },
{ uid: 'underReview' },
{ uid: 'rejected' },
{ uid: 'done' },
{ uid: 'closed' },
];
export { export {
roles, roles,
memberRoles, memberRoles,

View File

@@ -1,5 +1,5 @@
{ {
"Status": { "RunCaseStatus": {
"untested": "Untested", "untested": "Untested",
"passed": "Passed", "passed": "Passed",
"failed": "Failed", "failed": "Failed",

View File

@@ -1,5 +1,5 @@
{ {
"Status": { "RunCaseStatus": {
"untested": "未実行", "untested": "未実行",
"passed": "成功", "passed": "成功",
"failed": "失敗", "failed": "失敗",

View File

@@ -13,7 +13,7 @@ import { useTheme } from 'next-themes';
import TestTypesChart from './TestTypesDonutChart'; import TestTypesChart from './TestTypesDonutChart';
import TestPriorityChart from './TestPriorityDonutChart'; import TestPriorityChart from './TestPriorityDonutChart';
import TestProgressBarChart from './TestProgressColumnChart'; import TestProgressBarChart from './TestProgressColumnChart';
import { TestStatusMessages } from '@/types/testStatus'; import { TestRunCaseStatusMessages } from '@/types/testRunCaseStatus';
import { TestTypeMessages } from '@/types/testType'; import { TestTypeMessages } from '@/types/testType';
import { PriorityMessages } from '@/types/priority'; import { PriorityMessages } from '@/types/priority';
@@ -45,12 +45,18 @@ async function fetchProject(jwt: string, projectId: number) {
type Props = { type Props = {
projectId: string; projectId: string;
messages: HomeMessages; messages: HomeMessages;
statusMessages: TestStatusMessages; testRunCaseStatusMessages: TestRunCaseStatusMessages;
testTypeMessages: TestTypeMessages; testTypeMessages: TestTypeMessages;
priorityMessages: PriorityMessages; priorityMessages: PriorityMessages;
}; };
export function ProjectHome({ projectId, messages, statusMessages, testTypeMessages, priorityMessages }: Props) { export function ProjectHome({
projectId,
messages,
testRunCaseStatusMessages,
testTypeMessages,
priorityMessages,
}: Props) {
const context = useContext(TokenContext); const context = useContext(TokenContext);
const { theme, setTheme } = useTheme(); const { theme, setTheme } = useTheme();
const [project, setProject] = useState({ const [project, setProject] = useState({
@@ -97,7 +103,7 @@ export function ProjectHome({ projectId, messages, statusMessages, testTypeMessa
const priorityRet = aggregateTestPriority(project); const priorityRet = aggregateTestPriority(project);
setPriorityCounts([...priorityRet]); setPriorityCounts([...priorityRet]);
const { series, categories } = aggregateProgress(project, statusMessages); const { series, categories } = aggregateProgress(project, testRunCaseStatusMessages);
setProgressSeries([...series]); setProgressSeries([...series]);
setProgressCategories([...categories]); setProgressCategories([...categories]);
} }

View File

@@ -1,6 +1,6 @@
import { ProjectType } from '@/types/project'; import { ProjectType } from '@/types/project';
import { testTypes, priorities, testRunCaseStatus } from '@/config/selection'; import { testTypes, priorities, testRunCaseStatus } from '@/config/selection';
import { TestStatusMessages } from '@/types/testStatus'; import { TestRunCaseStatusMessages } from '@/types/testRunCaseStatus';
// aggregate folder, case, run mum // aggregate folder, case, run mum
function aggregateBasicInfo(project: ProjectType) { function aggregateBasicInfo(project: ProjectType) {
@@ -50,9 +50,9 @@ function aggregateTestPriority(project: ProjectType) {
return result; return result;
} }
function aggregateProgress(project: ProjectType, statusMessages: TestStatusMessages) { function aggregateProgress(project: ProjectType, testRunCaseStatusMessages: TestRunCaseStatusMessages) {
let series = testRunCaseStatus.map((status) => { let series = testRunCaseStatus.map((status) => {
return { name: statusMessages[status.uid], data: [] }; return { name: testRunCaseStatusMessages[status.uid], data: [] };
}); });
let categories = []; let categories = [];

View File

@@ -2,7 +2,7 @@ import { ProjectHome } from './ProjectHome';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { PriorityMessages } from '@/types/priority'; import { PriorityMessages } from '@/types/priority';
import { TestTypeMessages } from '@/types/testType'; import { TestTypeMessages } from '@/types/testType';
import { TestStatusMessages } from '@/types/testStatus'; import { TestRunCaseStatusMessages } from '@/types/testRunCaseStatus';
export type HomeMessages = { export type HomeMessages = {
folders: string; folders: string;
@@ -26,13 +26,13 @@ export default function Page({ params }: { params: { projectId: string } }) {
byPriority: t('by_priority'), byPriority: t('by_priority'),
}; };
const st = useTranslations('Status'); const rcst = useTranslations('RunCaseStatus');
const statusMessages: TestStatusMessages = { const testRunCaseStatusMessages: TestRunCaseStatusMessages = {
untested: st('untested'), untested: rcst('untested'),
passed: st('passed'), passed: rcst('passed'),
failed: st('failed'), failed: rcst('failed'),
retest: st('retest'), retest: rcst('retest'),
skipped: st('skipped'), skipped: rcst('skipped'),
}; };
const tt = useTranslations('Type'); const tt = useTranslations('Type');
@@ -65,7 +65,7 @@ export default function Page({ params }: { params: { projectId: string } }) {
<ProjectHome <ProjectHome
projectId={params.projectId} projectId={params.projectId}
messages={messages} messages={messages}
statusMessages={statusMessages} testRunCaseStatusMessages={testRunCaseStatusMessages}
testTypeMessages={testTypeMessages} testTypeMessages={testTypeMessages}
priorityMessages={priorityMessages} priorityMessages={priorityMessages}
/> />

View File

@@ -38,7 +38,7 @@ import { TokenContext } from '@/utils/TokenProvider';
import { useTheme } from 'next-themes'; import { useTheme } from 'next-themes';
import { useFormGuard } from '@/utils/formGuard'; import { useFormGuard } from '@/utils/formGuard';
import { PriorityMessages } from '@/types/priority'; import { PriorityMessages } from '@/types/priority';
import { TestStatusMessages } from '@/types/testStatus'; import { TestRunCaseStatusMessages } from '@/types/testRunCaseStatus';
const defaultTestRun = { const defaultTestRun = {
id: 0, id: 0,
@@ -55,12 +55,19 @@ type Props = {
projectId: string; projectId: string;
runId: string; runId: string;
messages: RunMessages; messages: RunMessages;
statusMessages: TestStatusMessages; testRunCaseStatusMessages: TestRunCaseStatusMessages;
priorityMessages: PriorityMessages; priorityMessages: PriorityMessages;
locale: string; locale: string;
}; };
export default function RunEditor({ projectId, runId, messages, statusMessages, priorityMessages, locale }: Props) { export default function RunEditor({
projectId,
runId,
messages,
testRunCaseStatusMessages,
priorityMessages,
locale,
}: Props) {
const context = useContext(TokenContext); const context = useContext(TokenContext);
const { theme, setTheme } = useTheme(); const { theme, setTheme } = useTheme();
const [testRun, setTestRun] = useState<RunType>(defaultTestRun); const [testRun, setTestRun] = useState<RunType>(defaultTestRun);
@@ -206,7 +213,11 @@ export default function RunEditor({ projectId, runId, messages, statusMessages,
</Tooltip> </Tooltip>
</div> </div>
<RunProgressChart statusCounts={runStatusCounts} statusMessages={statusMessages} theme={theme} /> <RunProgressChart
statusCounts={runStatusCounts}
testRunCaseStatusMessages={testRunCaseStatusMessages}
theme={theme}
/>
</div> </div>
</div> </div>
<div className="flex-grow"> <div className="flex-grow">
@@ -318,7 +329,7 @@ export default function RunEditor({ projectId, runId, messages, statusMessages,
onIncludeCase={(includeTestId) => handleIncludeExcludeCase(true, includeTestId)} onIncludeCase={(includeTestId) => handleIncludeExcludeCase(true, includeTestId)}
onExcludeCase={(excludeCaseId) => handleIncludeExcludeCase(false, excludeCaseId)} onExcludeCase={(excludeCaseId) => handleIncludeExcludeCase(false, excludeCaseId)}
messages={messages} messages={messages}
statusMessages={statusMessages} testRunCaseStatusMessages={testRunCaseStatusMessages}
priorityMessages={priorityMessages} priorityMessages={priorityMessages}
/> />
</div> </div>

View File

@@ -3,16 +3,16 @@ import { useState, useEffect } from 'react';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { testRunCaseStatus } from '@/config/selection'; import { testRunCaseStatus } from '@/config/selection';
import { RunStatusCountType } from '@/types/run'; import { RunStatusCountType } from '@/types/run';
import { TestStatusMessages } from '@/types/testStatus'; import { TestRunCaseStatusMessages } from '@/types/testRunCaseStatus';
const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); const Chart = dynamic(() => import('react-apexcharts'), { ssr: false });
type Props = { type Props = {
statusCounts: RunStatusCountType[]; statusCounts: RunStatusCountType[];
statusMessages: TestStatusMessages; testRunCaseStatusMessages: TestRunCaseStatusMessages;
theme: string | undefined; theme: string | undefined;
}; };
export default function RunProgressDounut({ statusCounts, statusMessages, theme }: Props) { export default function RunProgressDounut({ statusCounts, testRunCaseStatusMessages, theme }: Props) {
const [chartData, setChartData] = useState({ const [chartData, setChartData] = useState({
series: [], series: [],
options: { options: {
@@ -29,7 +29,7 @@ export default function RunProgressDounut({ statusCounts, statusMessages, theme
return found ? found.count : 0; return found ? found.count : 0;
}); });
const labels = testRunCaseStatus.map((entry) => statusMessages[entry.uid]); const labels = testRunCaseStatus.map((entry) => testRunCaseStatusMessages[entry.uid]);
const colors = testRunCaseStatus.map((entry) => entry.chartColor); const colors = testRunCaseStatus.map((entry) => entry.chartColor);
const legend = { const legend = {
labels: { labels: {

View File

@@ -32,7 +32,7 @@ import { RunMessages } from '@/types/run';
import TestCaseDetailDialog from './TestCaseDetailDialog'; import TestCaseDetailDialog from './TestCaseDetailDialog';
import { PriorityMessages } from '@/types/priority'; import { PriorityMessages } from '@/types/priority';
import TestCasePriority from '@/components/TestCasePriority'; import TestCasePriority from '@/components/TestCasePriority';
import { TestStatusMessages } from '@/types/testStatus'; import { TestRunCaseStatusMessages } from '@/types/testRunCaseStatus';
type Props = { type Props = {
cases: CaseType[]; cases: CaseType[];
@@ -43,7 +43,7 @@ type Props = {
onIncludeCase: (includeCaseId: number) => {}; onIncludeCase: (includeCaseId: number) => {};
onExcludeCase: (excludeCaseId: number) => {}; onExcludeCase: (excludeCaseId: number) => {};
messages: RunMessages; messages: RunMessages;
statusMessages: TestStatusMessages; testRunCaseStatusMessages: TestRunCaseStatusMessages;
priorityMessages: PriorityMessages; priorityMessages: PriorityMessages;
}; };
@@ -56,7 +56,7 @@ export default function TestCaseSelector({
onIncludeCase, onIncludeCase,
onExcludeCase, onExcludeCase,
messages, messages,
statusMessages, testRunCaseStatusMessages,
priorityMessages, priorityMessages,
}: Props) { }: Props) {
const headerColumns = [ const headerColumns = [
@@ -160,7 +160,9 @@ export default function TestCaseSelector({
startContent={isIncluded && renderStatusIcon(testRunCaseStatus[runStatus].uid)} startContent={isIncluded && renderStatusIcon(testRunCaseStatus[runStatus].uid)}
endContent={isIncluded && <ChevronDown size={16} />} endContent={isIncluded && <ChevronDown size={16} />}
> >
<span className="w-12">{isIncluded && statusMessages[testRunCaseStatus[runStatus].uid]}</span> <span className="w-12">
{isIncluded && testRunCaseStatusMessages[testRunCaseStatus[runStatus].uid]}
</span>
</Button> </Button>
</DropdownTrigger> </DropdownTrigger>
<DropdownMenu disabledKeys={disabledStatusKeys} aria-label="test case actions"> <DropdownMenu disabledKeys={disabledStatusKeys} aria-label="test case actions">
@@ -170,7 +172,7 @@ export default function TestCaseSelector({
startContent={renderStatusIcon(runCaseStatus.uid)} startContent={renderStatusIcon(runCaseStatus.uid)}
onPress={() => onChangeStatus(testCase.id, index)} onPress={() => onChangeStatus(testCase.id, index)}
> >
{statusMessages[runCaseStatus.uid]} {testRunCaseStatusMessages[runCaseStatus.uid]}
</DropdownItem> </DropdownItem>
))} ))}
</DropdownMenu> </DropdownMenu>

View File

@@ -2,7 +2,7 @@ import RunEditor from './RunEditor';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import { RunMessages } from '@/types/run'; import { RunMessages } from '@/types/run';
import { PriorityMessages } from '@/types/priority'; import { PriorityMessages } from '@/types/priority';
import { TestStatusMessages } from '@/types/testStatus'; import { TestRunCaseStatusMessages } from '@/types/testRunCaseStatus';
export default function Page({ params }: { params: { projectId: string; runId: string; locale: string } }) { export default function Page({ params }: { params: { projectId: string; runId: string; locale: string } }) {
const t = useTranslations('Run'); const t = useTranslations('Run');
@@ -38,13 +38,13 @@ export default function Page({ params }: { params: { projectId: string; runId: s
close: t('close'), close: t('close'),
}; };
const st = useTranslations('Status'); const rcst = useTranslations('RunCaseStatus');
const statusMessages: TestStatusMessages = { const testRunCaseStatusMessages: TestRunCaseStatusMessages = {
untested: st('untested'), untested: rcst('untested'),
passed: st('passed'), passed: rcst('passed'),
failed: st('failed'), failed: rcst('failed'),
retest: st('retest'), retest: rcst('retest'),
skipped: st('skipped'), skipped: rcst('skipped'),
}; };
const pt = useTranslations('Priority'); const pt = useTranslations('Priority');
@@ -60,7 +60,7 @@ export default function Page({ params }: { params: { projectId: string; runId: s
projectId={params.projectId} projectId={params.projectId}
runId={params.runId} runId={params.runId}
messages={messages} messages={messages}
statusMessages={statusMessages} testRunCaseStatusMessages={testRunCaseStatusMessages}
priorityMessages={priorityMessages} priorityMessages={priorityMessages}
locale={params.locale} locale={params.locale}
/> />

View File

@@ -0,0 +1,18 @@
// The status of each test case in test run
type TestRunCaseStatusUidType = 'untested' | 'passed' | 'failed' | 'retest' | 'skipped';
type TestRunCaseStatusType = {
uid: TestRunCaseStatusUidType;
color: string;
chartColor: string;
};
type TestRunCaseStatusMessages = {
untested: string;
passed: string;
failed: string;
retest: string;
skipped: string;
};
export type { TestRunCaseStatusUidType, TestRunCaseStatusType, TestRunCaseStatusMessages };

View File

@@ -1,17 +0,0 @@
type TestStatusUidType = 'untested' | 'passed' | 'failed' | 'retest' | 'skipped';
type TestStatusType = {
uid: TestStatusUidType;
color: string;
chartColor: string;
};
type TestStatusMessages = {
untested: string;
passed: string;
failed: string;
retest: string;
skipped: string;
};
export type { TestStatusUidType, TestStatusType, TestStatusMessages };