include RunCases on testCase property
This commit is contained in:
@@ -63,11 +63,13 @@ app.use('/folders', foldersDeleteRoute);
|
||||
|
||||
// "/cases"
|
||||
const casesIndexRoute = require('./routes/cases/index')(sequelize);
|
||||
const casesIndexByProjectIdRoute = require('./routes/cases/indexByProjectId')(sequelize);
|
||||
const casesShowRoute = require('./routes/cases/show')(sequelize);
|
||||
const casesNewRoute = require('./routes/cases/new')(sequelize);
|
||||
const casesEditRoute = require('./routes/cases/edit')(sequelize);
|
||||
const casesDeleteRoute = require('./routes/cases/delete')(sequelize);
|
||||
app.use('/cases', casesIndexRoute);
|
||||
app.use('/cases', casesIndexByProjectIdRoute);
|
||||
app.use('/cases', casesShowRoute);
|
||||
app.use('/cases', casesNewRoute);
|
||||
app.use('/cases', casesEditRoute);
|
||||
|
||||
54
backend/routes/cases/indexByProjectId.js
Normal file
54
backend/routes/cases/indexByProjectId.js
Normal file
@@ -0,0 +1,54 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const defineProject = require('../../models/projects');
|
||||
const defineFolder = require('../../models/folders');
|
||||
const defineCase = require('../../models/cases');
|
||||
const defineRunCase = require('../../models/runCases');
|
||||
const { DataTypes } = require('sequelize');
|
||||
|
||||
module.exports = function (sequelize) {
|
||||
const Project = defineProject(sequelize, DataTypes);
|
||||
const Folder = defineFolder(sequelize, DataTypes);
|
||||
const Case = defineCase(sequelize, DataTypes);
|
||||
const RunCase = defineRunCase(sequelize, DataTypes);
|
||||
Project.hasMany(Folder, { foreignKey: 'projectId' });
|
||||
Folder.hasMany(Case, { foreignKey: 'folderId' });
|
||||
Folder.belongsTo(Project, { foreignKey: 'projectId' });
|
||||
Case.belongsTo(Folder, { foreignKey: 'folderId' });
|
||||
Case.hasMany(RunCase, { foreignKey: 'caseId' });
|
||||
RunCase.belongsTo(Case, { foreignKey: 'caseId' });
|
||||
const { verifySignedIn } = require('../../middleware/auth')(sequelize);
|
||||
const { verifyProjectVisibleFromProjectId } = require('../../middleware/verifyVisible')(sequelize);
|
||||
|
||||
router.get('/byproject', verifySignedIn, verifyProjectVisibleFromProjectId, async (req, res) => {
|
||||
const { projectId } = req.query;
|
||||
|
||||
if (!projectId) {
|
||||
return res.status(400).json({ error: 'projectId is required' });
|
||||
}
|
||||
|
||||
try {
|
||||
const cases = await Case.findAll({
|
||||
include: [
|
||||
{
|
||||
model: Folder,
|
||||
where: {
|
||||
projectId: projectId,
|
||||
},
|
||||
attributes: [],
|
||||
},
|
||||
{
|
||||
model: RunCase,
|
||||
attributes: ['runId', 'status'],
|
||||
},
|
||||
],
|
||||
});
|
||||
res.json(cases);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.status(500).send('Internal Server Error');
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
};
|
||||
@@ -4,7 +4,7 @@ const apiServer = Config.apiServer;
|
||||
/**
|
||||
* fetch folder records
|
||||
*/
|
||||
async function fetchFolders(jwt: string, projectId: string) {
|
||||
async function fetchFolders(jwt: string, projectId: number) {
|
||||
try {
|
||||
const url = `${apiServer}/folders?projectId=${projectId}`;
|
||||
const response = await fetch(url, {
|
||||
|
||||
@@ -22,12 +22,18 @@ import { Save, ArrowLeft, Folder, ChevronDown, CopyPlus, CopyMinus, RotateCw } f
|
||||
import RunProgressChart from './RunPregressDonutChart';
|
||||
import TestCaseSelector from './TestCaseSelector';
|
||||
import { testRunStatus } from '@/config/selection';
|
||||
import { RunType, RunCaseType, RunStatusCountType, RunMessages } from '@/types/run';
|
||||
import { RunType, RunStatusCountType, RunMessages } from '@/types/run';
|
||||
import { CaseType } from '@/types/case';
|
||||
import { FolderType } from '@/types/folder';
|
||||
import { fetchRun, updateRun, fetchRunCases, updateRunCases, processRunCases } from '../runsControl';
|
||||
import {
|
||||
fetchRun,
|
||||
updateRun,
|
||||
updateRunCases,
|
||||
processRunCases,
|
||||
fetchProjectCases,
|
||||
processTestCases,
|
||||
} from '../runsControl';
|
||||
import { fetchFolders } from '../../folders/foldersControl';
|
||||
import { fetchCases } from '@/utils/caseControl';
|
||||
import { TokenContext } from '@/utils/TokenProvider';
|
||||
import { useTheme } from 'next-themes';
|
||||
import { useFormGuard } from '@/utils/formGuard';
|
||||
@@ -55,11 +61,11 @@ export default function RunEditor({ projectId, runId, messages, locale }: Props)
|
||||
const { theme, setTheme } = useTheme();
|
||||
const [testRun, setTestRun] = useState<RunType>(defaultTestRun);
|
||||
const [folders, setFolders] = useState<FolderType[]>([]);
|
||||
const [runCases, setRunCases] = useState<RunCaseType[]>([]);
|
||||
const [runStatusCounts, setRunStatusCounts] = useState<RunStatusCountType[]>();
|
||||
const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set([]));
|
||||
const [selectedFolder, setSelectedFolder] = useState<FolderType | null>(null);
|
||||
const [testcases, setTestCases] = useState<CaseType[]>([]);
|
||||
const [testCases, setTestCases] = useState<CaseType[]>([]);
|
||||
const [filteredTestCases, setFilteredTestCases] = useState<CaseType[]>([]);
|
||||
const [isNameInvalid, setIsNameInvalid] = useState<boolean>(false);
|
||||
const [isUpdating, setIsUpdating] = useState<boolean>(false);
|
||||
const [isDirty, setIsDirty] = useState(false);
|
||||
@@ -80,9 +86,17 @@ export default function RunEditor({ projectId, runId, messages, locale }: Props)
|
||||
|
||||
try {
|
||||
await fetchRunAndStatusCount();
|
||||
const foldersData = await fetchFolders(context.token.access_token, projectId);
|
||||
const foldersData = await fetchFolders(context.token.access_token, Number(projectId));
|
||||
setFolders(foldersData);
|
||||
setSelectedFolder(foldersData[0]);
|
||||
|
||||
const casesData = await fetchProjectCases(context.token.access_token, Number(projectId));
|
||||
casesData.forEach((testCase: CaseType) => {
|
||||
if (testCase.RunCases && testCase.RunCases.length > 0) {
|
||||
testCase.RunCases[0].editState = 'notChanged';
|
||||
}
|
||||
});
|
||||
setTestCases(casesData);
|
||||
} catch (error: any) {
|
||||
console.error('Error in effect:', error.message);
|
||||
}
|
||||
@@ -92,39 +106,19 @@ export default function RunEditor({ projectId, runId, messages, locale }: Props)
|
||||
}, [context]);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchCasesData() {
|
||||
function onFilter() {
|
||||
if (selectedFolder && selectedFolder.id) {
|
||||
try {
|
||||
const latestRunCases: RunCaseType[] = await fetchRunCases(context.token.access_token, Number(runId));
|
||||
latestRunCases.forEach((runCase: RunCaseType) => {
|
||||
runCase.editState = 'notChanged';
|
||||
});
|
||||
setRunCases(latestRunCases);
|
||||
|
||||
const testCasesData: CaseType[] = await fetchCases(context.token.access_token, selectedFolder.id);
|
||||
// Check if each testCase has an association with testRun
|
||||
// and add "isIncluded" property
|
||||
const updatedTestCasesData = testCasesData.map((testCase) => {
|
||||
const runCase = latestRunCases.find((runCase) => runCase.caseId === testCase.id);
|
||||
|
||||
const isIncluded = runCase ? true : false;
|
||||
const runStatus = runCase ? runCase.status : 0;
|
||||
return {
|
||||
...testCase,
|
||||
isIncluded,
|
||||
runStatus,
|
||||
};
|
||||
});
|
||||
|
||||
setTestCases(updatedTestCasesData);
|
||||
const filteredData = testCases.filter((testCase) => testCase.folderId === selectedFolder.id);
|
||||
setFilteredTestCases(filteredData);
|
||||
} catch (error: any) {
|
||||
console.error('Error fetching cases data:', error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fetchCasesData();
|
||||
}, [selectedFolder]);
|
||||
onFilter();
|
||||
}, [selectedFolder, testCases]);
|
||||
|
||||
const handleChangeStatus = async (changeCaseId: number, status: number) => {
|
||||
setIsDirty(true);
|
||||
@@ -141,38 +135,21 @@ export default function RunEditor({ projectId, runId, messages, locale }: Props)
|
||||
const handleIncludeExcludeCase = async (isInclude: boolean, clickedTestCaseId: number) => {
|
||||
setIsDirty(true);
|
||||
const keys = [clickedTestCaseId];
|
||||
const newRunCases = processRunCases(isInclude, keys, Number(runId), runCases);
|
||||
setRunCases(newRunCases);
|
||||
|
||||
const updatedTestCases = testcases.map((testcase) => {
|
||||
if (testcase.id === clickedTestCaseId) {
|
||||
return { ...testcase, isIncluded: isInclude };
|
||||
}
|
||||
return testcase;
|
||||
});
|
||||
setTestCases(updatedTestCases);
|
||||
const newTestCases = processTestCases(isInclude, keys, Number(runId), testCases);
|
||||
setTestCases(newTestCases);
|
||||
};
|
||||
|
||||
const handleBulkIncludeExcludeCases = async (isInclude: boolean) => {
|
||||
setIsDirty(true);
|
||||
let keys: number[] = [];
|
||||
if (selectedKeys === 'all') {
|
||||
keys = testcases.map((item) => item.id);
|
||||
keys = testCases.map((item) => item.id);
|
||||
} else {
|
||||
keys = Array.from(selectedKeys).map(Number);
|
||||
}
|
||||
|
||||
const newRunCases = processRunCases(isInclude, keys, Number(runId), runCases);
|
||||
setRunCases(newRunCases);
|
||||
|
||||
const updatedTestCases = testcases.map((testcase) => {
|
||||
if (keys.includes(testcase.id)) {
|
||||
return { ...testcase, isIncluded: isInclude };
|
||||
}
|
||||
return testcase;
|
||||
});
|
||||
setTestCases(updatedTestCases);
|
||||
|
||||
const newTestCases = processTestCases(isInclude, keys, Number(runId), testCases);
|
||||
setTestCases(newTestCases);
|
||||
setSelectedKeys(new Set([]));
|
||||
};
|
||||
|
||||
@@ -204,7 +181,7 @@ export default function RunEditor({ projectId, runId, messages, locale }: Props)
|
||||
onPress={async () => {
|
||||
setIsUpdating(true);
|
||||
await updateRun(context.token.access_token, testRun);
|
||||
await updateRunCases(context.token.access_token, Number(runId), runCases);
|
||||
await updateRunCases(context.token.access_token, Number(runId), testCases);
|
||||
setIsUpdating(false);
|
||||
setIsDirty(false);
|
||||
}}
|
||||
@@ -335,7 +312,7 @@ export default function RunEditor({ projectId, runId, messages, locale }: Props)
|
||||
</div>
|
||||
<div className="w-9/12">
|
||||
<TestCaseSelector
|
||||
cases={testcases}
|
||||
cases={filteredTestCases}
|
||||
isDisabled={!context.isProjectReporter(Number(projectId))}
|
||||
selectedKeys={selectedKeys}
|
||||
onSelectionChange={setSelectedKeys}
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
} from 'lucide-react';
|
||||
import { priorities, testRunCaseStatus } from '@/config/selection';
|
||||
import { CaseType } from '@/types/case';
|
||||
import { RunsMessages } from '@/types/run';
|
||||
import { RunMessages } from '@/types/run';
|
||||
|
||||
type Props = {
|
||||
cases: CaseType[];
|
||||
@@ -37,7 +37,7 @@ type Props = {
|
||||
onStatusChange: (changeCaseId: number, status: number) => {};
|
||||
onIncludeCase: (includeCaseId: number) => {};
|
||||
onExcludeCase: (excludeCaseId: number) => {};
|
||||
messages: RunsMessages;
|
||||
messages: RunMessages;
|
||||
};
|
||||
|
||||
export default function TestCaseSelector({
|
||||
@@ -106,9 +106,22 @@ export default function TestCaseSelector({
|
||||
}
|
||||
};
|
||||
|
||||
const isCaseIncluded = (testCase: CaseType) => {
|
||||
let isIncluded = false;
|
||||
if (testCase.RunCases && testCase.RunCases.length > 0) {
|
||||
if (testCase.RunCases[0].editState !== 'deleted') {
|
||||
// Even if RunCase[0] exists, if 'deleted' it will be as not included.
|
||||
isIncluded = true;
|
||||
}
|
||||
}
|
||||
|
||||
return isIncluded;
|
||||
};
|
||||
|
||||
const renderCell = (testCase: CaseType, columnKey: Key) => {
|
||||
const cellValue = testCase[columnKey as keyof CaseType];
|
||||
const isIncluded = testCase.isIncluded;
|
||||
const isIncluded = isCaseIncluded(testCase);
|
||||
const runStatus = testCase.RunCases && testCase.RunCases.length > 0 ? testCase.RunCases[0].status : 0;
|
||||
|
||||
switch (columnKey) {
|
||||
case 'priority':
|
||||
@@ -130,10 +143,10 @@ export default function TestCaseSelector({
|
||||
size="sm"
|
||||
variant="light"
|
||||
isDisabled={!isIncluded}
|
||||
startContent={isIncluded && renderStatusIcon(testRunCaseStatus[cellValue].uid)}
|
||||
startContent={isIncluded && renderStatusIcon(testRunCaseStatus[runStatus].uid)}
|
||||
endContent={isIncluded && <ChevronDown size={16} />}
|
||||
>
|
||||
<span className="w-12">{isIncluded && messages[testRunCaseStatus[cellValue].uid]}</span>
|
||||
<span className="w-12">{isIncluded && messages[testRunCaseStatus[runStatus].uid]}</span>
|
||||
</Button>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu disabledKeys={disabledStatusKeys} aria-label="test case actions">
|
||||
@@ -143,7 +156,7 @@ export default function TestCaseSelector({
|
||||
startContent={renderStatusIcon(runCaseStatus.uid)}
|
||||
onPress={() => onStatusChange(testCase.id, index)}
|
||||
>
|
||||
{messages[runCaseStatus.uid]}
|
||||
{messages[runStatus.uid]}
|
||||
</DropdownItem>
|
||||
))}
|
||||
</DropdownMenu>
|
||||
@@ -162,7 +175,7 @@ export default function TestCaseSelector({
|
||||
key="include"
|
||||
startContent={<CopyPlus size={16} />}
|
||||
onPress={() => {
|
||||
if (testCase.isIncluded) {
|
||||
if (isIncluded) {
|
||||
return;
|
||||
}
|
||||
onIncludeCase(testCase.id);
|
||||
@@ -174,7 +187,7 @@ export default function TestCaseSelector({
|
||||
key="exclude"
|
||||
startContent={<CopyMinus size={16} />}
|
||||
onPress={() => {
|
||||
if (!testCase.isIncluded) {
|
||||
if (!isIncluded) {
|
||||
return;
|
||||
}
|
||||
onExcludeCase(testCase.id);
|
||||
@@ -239,8 +252,8 @@ export default function TestCaseSelector({
|
||||
</TableHeader>
|
||||
<TableBody emptyContent={messages.noCasesFound} items={sortedItems}>
|
||||
{(item) => (
|
||||
<TableRow key={item.id} className={!item.isIncluded ? notIncludedCaseClass : ''}>
|
||||
{(columnKey) => <TableCell>{renderCell(item, columnKey)}</TableCell>}
|
||||
<TableRow key={item.id} className={isCaseIncluded(item) ? '' : notIncludedCaseClass}>
|
||||
{(columnKey) => <TableCell key={`${item.id} + ${columnKey}`}>{renderCell(item, columnKey)}</TableCell>}
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { CaseType } from '@/types/case';
|
||||
import { RunType, RunCaseType } from '@/types/run';
|
||||
import Config from '@/config/config';
|
||||
const apiServer = Config.apiServer;
|
||||
import { RunType, RunCaseType } from '@/types/run';
|
||||
|
||||
async function fetchRun(jwt: string, runId: number) {
|
||||
const url = `${apiServer}/runs/${runId}`;
|
||||
@@ -150,61 +151,134 @@ async function fetchRunCases(jwt: string, runId: number) {
|
||||
}
|
||||
}
|
||||
|
||||
function processRunCases(
|
||||
isInclude: boolean,
|
||||
keys: number[],
|
||||
runId: number,
|
||||
currentRunCases: RunCaseType[]
|
||||
): RunCaseType[] {
|
||||
const updatedRunCases = [...currentRunCases];
|
||||
function processTestCases(isInclude: boolean, keys: number[], runId: number, currentTestCases: CaseType[]): CaseType[] {
|
||||
const updatedTestCases = [...currentTestCases];
|
||||
|
||||
if (isInclude) {
|
||||
keys.forEach((caseId) => {
|
||||
const existingRunCase = currentRunCases.find((runCase) => runCase.caseId === caseId);
|
||||
if (existingRunCase) {
|
||||
const targetCase = updatedTestCases.find((testCase) => testCase.id === caseId);
|
||||
if (!targetCase) {
|
||||
console.error('failed to find target case');
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetCase.RunCases && targetCase.RunCases.length > 0) {
|
||||
// already included
|
||||
if (existingRunCase.editState === 'notChanged') {
|
||||
if (targetCase.RunCases[0].editState === 'notChanged') {
|
||||
// do nothing
|
||||
} else if (existingRunCase.editState === 'changed') {
|
||||
} else if (targetCase.RunCases[0].editState === 'changed') {
|
||||
// do nothing
|
||||
} else if (existingRunCase.editState === 'new') {
|
||||
} else if (targetCase.RunCases[0].editState === 'new') {
|
||||
// do nothing
|
||||
} else if (existingRunCase.editState === 'deleted') {
|
||||
existingRunCase.editState = 'changed';
|
||||
} else if (targetCase.RunCases[0].editState === 'deleted') {
|
||||
targetCase.RunCases[0].editState = 'changed';
|
||||
}
|
||||
} else {
|
||||
updatedRunCases.push({
|
||||
id: -1,
|
||||
const newRunCase = {
|
||||
runId: runId,
|
||||
caseId: caseId,
|
||||
status: -1,
|
||||
status: 0,
|
||||
editState: 'new',
|
||||
});
|
||||
} as RunCaseType;
|
||||
targetCase.RunCases = [newRunCase];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
keys.forEach((caseId) => {
|
||||
const existingRunCase = currentRunCases.find((runCase) => runCase.caseId === caseId);
|
||||
if (!existingRunCase) {
|
||||
const targetCase = updatedTestCases.find((testCase) => testCase.id === caseId);
|
||||
if (!targetCase) {
|
||||
console.error('failed to find target case');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!targetCase.RunCases || targetCase.RunCases.length == 0) {
|
||||
// already excluded
|
||||
} else {
|
||||
if (existingRunCase.editState === 'notChanged') {
|
||||
existingRunCase.editState = 'deleted';
|
||||
} else if (existingRunCase.editState === 'changed') {
|
||||
existingRunCase.editState = 'deleted';
|
||||
} else if (existingRunCase.editState === 'new') {
|
||||
existingRunCase.editState = 'deleted';
|
||||
} else if (existingRunCase.editState === 'deleted') {
|
||||
if (targetCase.RunCases[0].editState === 'notChanged') {
|
||||
targetCase.RunCases[0].editState = 'deleted';
|
||||
} else if (targetCase.RunCases[0].editState === 'changed') {
|
||||
targetCase.RunCases[0].editState = 'deleted';
|
||||
} else if (targetCase.RunCases[0].editState === 'new') {
|
||||
targetCase.RunCases[0].editState = 'deleted';
|
||||
} else if (targetCase.RunCases[0].editState === 'deleted') {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return updatedRunCases;
|
||||
return updatedTestCases;
|
||||
}
|
||||
|
||||
async function updateRunCases(jwt: string, runId: number, runCases: RunCaseType[]) {
|
||||
// function processRunCases(
|
||||
// isInclude: boolean,
|
||||
// keys: number[],
|
||||
// runId: number,
|
||||
// currentRunCases: RunCaseType[]
|
||||
// ): RunCaseType[] {
|
||||
// const updatedRunCases = [...currentRunCases];
|
||||
|
||||
// if (isInclude) {
|
||||
// keys.forEach((caseId) => {
|
||||
// const existingRunCase = currentRunCases.find((runCase) => runCase.caseId === caseId);
|
||||
// if (existingRunCase) {
|
||||
// // already included
|
||||
// if (existingRunCase.editState === 'notChanged') {
|
||||
// // do nothing
|
||||
// } else if (existingRunCase.editState === 'changed') {
|
||||
// // do nothing
|
||||
// } else if (existingRunCase.editState === 'new') {
|
||||
// // do nothing
|
||||
// } else if (existingRunCase.editState === 'deleted') {
|
||||
// existingRunCase.editState = 'changed';
|
||||
// }
|
||||
// } else {
|
||||
// updatedRunCases.push({
|
||||
// id: -1,
|
||||
// runId: runId,
|
||||
// caseId: caseId,
|
||||
// status: 0,
|
||||
// editState: 'new',
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// } else {
|
||||
// keys.forEach((caseId) => {
|
||||
// const existingRunCase = currentRunCases.find((runCase) => runCase.caseId === caseId);
|
||||
// if (!existingRunCase) {
|
||||
// // already excluded
|
||||
// } else {
|
||||
// if (existingRunCase.editState === 'notChanged') {
|
||||
// existingRunCase.editState = 'deleted';
|
||||
// } else if (existingRunCase.editState === 'changed') {
|
||||
// existingRunCase.editState = 'deleted';
|
||||
// } else if (existingRunCase.editState === 'new') {
|
||||
// existingRunCase.editState = 'deleted';
|
||||
// } else if (existingRunCase.editState === 'deleted') {
|
||||
// // do nothing
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// return updatedRunCases;
|
||||
// }
|
||||
|
||||
async function updateRunCases(jwt: string, runId: number, testCases: CaseType[]) {
|
||||
const runCases: RunCaseType[] = [];
|
||||
testCases.forEach((itr) => {
|
||||
if (itr.RunCases && itr.RunCases.length > 0) {
|
||||
runCases.push({
|
||||
id: -1,
|
||||
caseId: itr.id,
|
||||
runId: runId,
|
||||
status: itr.RunCases[0].status,
|
||||
editState: itr.RunCases[0].editState,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
console.log(testCases, runCases);
|
||||
|
||||
const fetchOptions = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -227,4 +301,37 @@ async function updateRunCases(jwt: string, runId: number, runCases: RunCaseType[
|
||||
}
|
||||
}
|
||||
|
||||
export { fetchRun, fetchRuns, createRun, updateRun, deleteRun, fetchRunCases, processRunCases, updateRunCases };
|
||||
async function fetchProjectCases(jwt: string, projectId: number) {
|
||||
const url = `${apiServer}/cases/byproject?projectId=${projectId}`;
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${jwt}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
console.error('Error fetching data:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
fetchRun,
|
||||
fetchRuns,
|
||||
createRun,
|
||||
updateRun,
|
||||
deleteRun,
|
||||
fetchRunCases,
|
||||
processTestCases,
|
||||
updateRunCases,
|
||||
fetchProjectCases,
|
||||
};
|
||||
|
||||
@@ -11,9 +11,8 @@ type CaseType = {
|
||||
expectedResults: string;
|
||||
folderId: number;
|
||||
Steps?: StepType[];
|
||||
RunCases?: RunCaseType[];
|
||||
Attachments?: AttachmentType[];
|
||||
isIncluded?: boolean;
|
||||
runStatus?: number;
|
||||
};
|
||||
|
||||
type CaseStepType = {
|
||||
@@ -35,6 +34,12 @@ type StepType = {
|
||||
editState: 'notChanged' | 'changed' | 'new' | 'deleted';
|
||||
};
|
||||
|
||||
type RunCaseType = {
|
||||
runId: number;
|
||||
status: number;
|
||||
editState: 'notChanged' | 'changed' | 'new' | 'deleted';
|
||||
};
|
||||
|
||||
type CaseAttachmentType = {
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
|
||||
Reference in New Issue
Block a user