diff --git a/backend/index.js b/backend/index.js index a713ea2..2444823 100644 --- a/backend/index.js +++ b/backend/index.js @@ -92,11 +92,13 @@ app.use("/runs", runDeleteRoute); // "/runcases" const runCaseIndexRoute = require("./routes/runcases/index")(sequelize); const runCaseNewRoute = require("./routes/runcases/new")(sequelize); +const runCaseEditRoute = require("./routes/runcases/edit")(sequelize); const runCaseBuldNewRoute = require("./routes/runcases/bulkNew")(sequelize); const runCaseDeleteRoute = require("./routes/runcases/delete")(sequelize); const runCaseBulkDeleteRoute = require("./routes/runcases/bulkDelete")(sequelize); app.use("/runcases", runCaseIndexRoute); app.use("/runcases", runCaseNewRoute); +app.use("/runcases", runCaseEditRoute); app.use("/runcases", runCaseBuldNewRoute); app.use("/runcases", runCaseDeleteRoute); app.use("/runcases", runCaseBulkDeleteRoute); diff --git a/backend/routes/runcases/edit.js b/backend/routes/runcases/edit.js new file mode 100644 index 0000000..6e372f2 --- /dev/null +++ b/backend/routes/runcases/edit.js @@ -0,0 +1,39 @@ +const express = require("express"); +const router = express.Router(); +const defineRunCase = require("../../models/runCases"); +const { DataTypes } = require("sequelize"); + +module.exports = function (sequelize) { + const RunCase = defineRunCase(sequelize, DataTypes); + + router.put("/", async (req, res) => { + const runId = req.query.runId; + const caseId = req.query.caseId; + const status = req.query.status; + + try { + const runCase = await RunCase.findOne({ + where: { + runId: runId, + caseId: caseId, + }, + }); + + if (!runCase) { + return res.status(404).send("Runcase not found"); + } + + await runCase.update({ + runId, + caseId, + status, + }); + res.json(runCase); + } catch (error) { + console.error(error); + res.status(500).send("Internal Server Error"); + } + }); + + return router; +}; diff --git a/frontend/app/projects/[projectId]/runs/[runId]/RunEditor.tsx b/frontend/app/projects/[projectId]/runs/[runId]/RunEditor.tsx index 5144931..76ecec2 100644 --- a/frontend/app/projects/[projectId]/runs/[runId]/RunEditor.tsx +++ b/frontend/app/projects/[projectId]/runs/[runId]/RunEditor.tsx @@ -36,6 +36,7 @@ import { updateRun, fetchRunCases, createRunCase, + updateRunCase, bulkCreateRunCases, deleteRunCase, bulkDeleteRunCases, @@ -117,6 +118,18 @@ export default function RunEditor({ projectId, runId }: Props) { fetchCasesData(); }, [selectedFolder]); + const handleChangeStatus = async (changeCaseId: number, status: number) => { + await updateRunCase(runId, changeCaseId, status); + setTestCases((prevTestCases) => { + return prevTestCases.map((testCase) => { + if (testCase.id === changeCaseId) { + return { ...testCase, runStatus: status }; + } + return testCase; + }); + }); + }; + const handleIncludeExcludeCase = async ( isInclude: boolean, clickedTestCaseId: number @@ -152,7 +165,6 @@ export default function RunEditor({ projectId, runId }: Props) { } else { keys = Array.from(selectedKeys).map(Number); } - console.log(keys) const runCaseInfo: RunCaseInfoType[] = keys.map((caseId) => ({ runId: runId, @@ -170,14 +182,13 @@ export default function RunEditor({ projectId, runId }: Props) { }); } - setTestCases((prevTestCases) => { - return prevTestCases.map((testCase) => { - const isCaseIncluded = isInclude - ? keys.includes(testCase.id) - : !keys.includes(testCase.id); - return { ...testCase, isIncluded: isCaseIncluded }; - }); + const updatedTestCases = testcases.map((testcase) => { + if (keys.includes(testcase.id)) { + return { ...testcase, isIncluded: isInclude }; + } + return testcase; }); + setTestCases(updatedTestCases); setSelectedKeys(new Set([])); }; @@ -329,6 +340,7 @@ export default function RunEditor({ projectId, runId }: Props) { cases={testcases} selectedKeys={selectedKeys} onSelectionChange={setSelectedKeys} + onStatusChange={handleChangeStatus} onIncludeCase={(includeTestId) => handleIncludeExcludeCase(true, includeTestId) } diff --git a/frontend/app/projects/[projectId]/runs/[runId]/TestCaseSelector.tsx b/frontend/app/projects/[projectId]/runs/[runId]/TestCaseSelector.tsx index 01a9ef7..e4f37b2 100644 --- a/frontend/app/projects/[projectId]/runs/[runId]/TestCaseSelector.tsx +++ b/frontend/app/projects/[projectId]/runs/[runId]/TestCaseSelector.tsx @@ -40,6 +40,7 @@ type Props = { cases: CaseType[]; selectedKeys: Selection; onSelectionChange: React.Dispatch>; + onStatusChange: (changeCaseId: number, status: number) => {}; onIncludeCase: (includeCaseId: number) => {}; onExcludeCase: (excludeCaseId: number) => {}; }; @@ -48,6 +49,7 @@ export default function TestCaseSelector({ cases, selectedKeys, onSelectionChange, + onStatusChange, onIncludeCase, onExcludeCase, }: Props) { @@ -121,7 +123,7 @@ export default function TestCaseSelector({ {}} + onPress={() => onStatusChange(testCase.id, index)} > {runCaseStatus.name} diff --git a/frontend/app/projects/[projectId]/runs/runsControl.ts b/frontend/app/projects/[projectId]/runs/runsControl.ts index a9f26c0..752c9cc 100644 --- a/frontend/app/projects/[projectId]/runs/runsControl.ts +++ b/frontend/app/projects/[projectId]/runs/runsControl.ts @@ -168,13 +168,36 @@ async function createRunCase(runId: string, caseId: number) { } } +async function updateRunCase(runId: string, caseId: number, status: number) { + const fetchOptions = { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + }; + + const url = `${apiServer}/runcases?runId=${runId}&caseId=${caseId}&status=${status}`; + + try { + const response = await fetch(url, fetchOptions); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + const data = await response.json(); + return data; + } catch (error: any) { + console.error("Error updating runcase:", error); + throw error; + } +} + async function bulkCreateRunCases(runCaseInfo: RunCaseInfoType[]) { const fetchOptions = { method: "POST", headers: { "Content-Type": "application/json", }, - body: JSON.stringify(runCaseInfo) + body: JSON.stringify(runCaseInfo), }; const url = `${apiServer}/runcases/bulknew`; @@ -219,7 +242,7 @@ async function bulkDeleteRunCases(runCaseInfo: RunCaseInfoType[]) { headers: { "Content-Type": "application/json", }, - body: JSON.stringify(runCaseInfo) + body: JSON.stringify(runCaseInfo), }; const url = `${apiServer}/runcases/bulkdelete`; @@ -243,6 +266,7 @@ export { deleteRun, fetchRunCases, createRunCase, + updateRunCase, bulkCreateRunCases, deleteRunCase, bulkDeleteRunCases,