Intergate api test report

This commit is contained in:
Truong Vo 2024-09-18 02:10:13 +07:00
parent c800178848
commit 5554be97e0
3 changed files with 354 additions and 206 deletions

View File

@ -20,11 +20,6 @@ class TestCaseForSprintController extends Controller
public function getAllReportsForSprint($sprintId)
{
$testReports = TestCaseForSprint::where('sprint_id', $sprintId)->get();
if ($testReports->isEmpty()) {
return AbstractController::ResultError('No test reports found for this sprint', [], 404);
}
return AbstractController::ResultSuccess($testReports);
}

View File

@ -12,25 +12,30 @@ export const deleteTracking = API_URL + 'v1/admin/tracking/delete'
export const fetchAllIssues = API_URL + 'v1/admin/jira/fetch-issues'
export const exportIssues = API_URL + 'v1/admin/jira/export-issues'
export const getAllProjects = API_URL + 'v1/admin/jira/all-project'
export const getAllIssuesByProject = API_URL + 'v1/admin/jira/all-issue-by-project'
export const getAllIssuesByProject =
API_URL + 'v1/admin/jira/all-issue-by-project'
export const getAllUserWorklogs = API_URL + 'v1/admin/jira/worklogs'
export const getAllUserDoing = API_URL + 'v1/admin/jira/allocation'
export const getDetailIssByKey = API_URL + 'v1/admin/jira/issue/detail'
//Timekeeping
export const getTheTimesheet = API_URL + 'v1/admin/timekeeping'
export const updateMultipleUserWorkingTime = API_URL + 'v1/admin/timekeeping/addMutilple'
export const updateMultipleUserWorkingTime =
API_URL + 'v1/admin/timekeeping/addMutilple'
export const updateNote = API_URL + 'v1/admin/timekeeping/addNote'
export const deleteNote = API_URL + 'v1/admin/timekeeping/delete'
export const updateCacheMonth = API_URL + 'v1/admin/timekeeping/update-cache-month'
export const updateWorkingDays = API_URL + 'v1/admin/timekeeping/update-working-days'
export const updateCacheMonth =
API_URL + 'v1/admin/timekeeping/update-cache-month'
export const updateWorkingDays =
API_URL + 'v1/admin/timekeeping/update-working-days'
//Category
export const getListMaster = API_URL + 'v1/admin/category/get-list-master'
//LeaveManagement
export const getLeaveManagement = API_URL + 'v1/admin/leave-management'
export const updateNoteLeave = API_URL + 'v1/admin/leave-management/saveNoteLeave'
export const updateNoteLeave =
API_URL + 'v1/admin/leave-management/saveNoteLeave'
//Tickets
export const getTickets = API_URL + 'v1/admin/ticket/all'
@ -50,9 +55,18 @@ export const getQRCode = API_URL + 'v1/users/qrcode'
export const getAllCriteriasBySprint = API_URL + 'v1/admin/criterias/sprints'
export const getAllProject = API_URL + 'v1/admin/jira/all-project'
export const getAllBoardByIdProject = API_URL + 'v1/admin/jira/get-all-board-by-id-project'
export const getDetailProjectById = API_URL + 'v1/admin/jira/get-detail-project-by-id'
export const getAllSprintByIdBoard = API_URL + 'v1/admin/jira/get-all-sprint-by-id-board'
export const getAllIssuesByIdSprint = API_URL + 'v1/admin/jira/get-all-issue-by-id-sprint'
export const getAllBoardByIdProject =
API_URL + 'v1/admin/jira/get-all-board-by-id-project'
export const getDetailProjectById =
API_URL + 'v1/admin/jira/get-detail-project-by-id'
export const getAllSprintByIdBoard =
API_URL + 'v1/admin/jira/get-all-sprint-by-id-board'
export const getAllIssuesByIdSprint =
API_URL + 'v1/admin/jira/get-all-issue-by-id-sprint'
export const updateSprintReview = API_URL + 'v1/admin/sprint-review/update'
export const updateSprintReview = API_URL + 'v1/admin/sprint-review/update'
//TestReport
export const getAllTestCase = API_URL + 'v1/admin/criterias/test-cases/getAll'
export const deleteTestCase = API_URL + 'v1/admin/criterias/test-cases/delete'
export const createTestCase = API_URL + 'v1/admin/criterias/test-cases'

View File

@ -1,9 +1,19 @@
import { TUser } from '@/variables/types'
import {
createTestCase,
deleteTestCase,
getAllBoardByIdProject,
getAllProject,
getAllSprintByIdBoard,
getAllTestCase,
} from '@/api/Admin'
import { get, post } from '@/rtk/helpers/apiService'
import { Xdelete } from '@/rtk/helpers/CRUD'
import {
Box,
Button,
Dialog,
Group,
Loader,
Modal,
Select,
Table,
@ -13,115 +23,239 @@ import {
Title,
} from '@mantine/core'
import { useForm } from '@mantine/form'
import { notifications } from '@mantine/notifications'
import { IconInfoSquare, IconSquareXFilled } from '@tabler/icons-react'
import { useEffect, useState } from 'react'
import classes from './TestReport.module.css'
type DataProject = {
id: number
name: string
}
type DataSprint = {
id: number
name: string
}
type DataTestCases = {
id?: number
name: string
position: string
input: string
expect_output: string
actual_output: string
issue_id_on_jira: string
bug_id_on_jira: string
note: string
created_by?: string
}
const TestReport = () => {
// const [users, setUsers] = useState<TUser[]>([])
const [action, setAction] = useState('')
const [activeBtn, setActiveBtn] = useState(false)
// const [item, setItem] = useState({ id: 0 })
const [disableBtn, setDisableBtn] = useState(false)
// const [info, setInfo] = useState('')
const [filter, setFilter] = useState({
typeReason: '',
statusFilter: '',
const [item, setItem] = useState<DataTestCases>({
id: 0,
name: '',
position: '',
input: '',
expect_output: '',
actual_output: '',
issue_id_on_jira: '',
bug_id_on_jira: '',
note: '',
created_by: '',
})
// const [dataTimeType, setDataTimeType] = useState<DataTimeType[]>([])
// const [dataReason, setDataReason] = useState<DataReason[]>([])
const [disableBtn, setDisableBtn] = useState(false)
const [loading, setLoading] = useState(false)
// const getListMasterByType = async (type: string) => {
// try {
// const params = {
// type: type,
// }
// const res = await get(getListMaster, params)
// if (res.status) {
// return res.data
// }
// } catch (error: any) {
// notifications.show({
// title: 'Error',
// message: error.message ?? error,
// color: 'red',
// })
// }
// return []
// }
const [infoBoard, setInfoBoard] = useState('')
const [filter, setFilter] = useState({
project: '',
sprint: '',
})
const [dataProject, setDataProject] = useState<DataProject[]>([])
const [dataSprint, setDataSprint] = useState<DataSprint[]>([])
// useEffect(() => {
// const fetchData = async () => {
// const resultTimeType = await getListMasterByType('TIME_TYPE')
// setDataTimeType(
// resultTimeType.filter((item: DataTimeType) => item.c_code !== 'ALL'),
// )
const [dataListTestCases, setDataListTestCases] = useState<any[]>([])
// const resultReason = await getListMasterByType('REASON')
// setDataReason(resultReason)
// }
const getListDataProject = async () => {
try {
const params = {}
const res = await get(getAllProject, params)
if (res.status) {
return res.data
}
} catch (error: any) {
notifications.show({
title: 'Error',
message: error.message ?? error,
color: 'red',
})
}
return []
}
// fetchData()
// }, [])
const getBoardByIdProject = async (id: string) => {
try {
const params = {}
const res = await get(`${getAllBoardByIdProject}?id=${id}`, params)
if (res.status) {
return res.data
}
} catch (error: any) {
notifications.show({
title: 'Error',
message: error.message ?? error,
color: 'red',
})
}
return []
}
const getListDataSprint = async (id: string) => {
try {
const params = {}
const res = await get(`${getAllSprintByIdBoard}?id=${id}`, params)
if (res.status) {
return res.data
}
} catch (error: any) {
notifications.show({
title: 'Error',
message: error.message ?? error,
color: 'red',
})
}
return []
}
const getListTestCase = async (id: string) => {
try {
const params = {}
const res = await get(`${getAllTestCase}/${id}`, params)
if (res.status) {
return res.data
}
} catch (error: any) {
notifications.show({
title: 'Error',
message: error.message ?? error,
color: 'red',
})
}
return []
}
useEffect(() => {
const fetchData = async () => {
const result = await getListDataProject()
setDataProject(result ?? [])
}
fetchData()
}, [])
useEffect(() => {
if (filter.project) {
setLoading(true)
const fetchData = async () => {
const result = await getBoardByIdProject(filter.project)
if (result.values[0]) {
setInfoBoard(result.values[0].id ?? '')
setLoading(false)
}
}
fetchData()
}
}, [filter.project])
useEffect(() => {
if (infoBoard != '') {
const fetchData = async () => {
const result = await getListDataSprint(infoBoard)
if (result.values) {
setDataSprint(
result.values.filter(
(item: any) =>
typeof item.completeDate !== 'undefined' &&
item.completeDate !== '',
) ?? [],
)
}
}
fetchData()
}
}, [infoBoard])
useEffect(() => {
setLoading(true)
setDataListTestCases([])
if (filter.sprint) {
const fetchData = async () => {
const result = await getListTestCase(filter.sprint)
if (result) {
setDataListTestCases(result ?? [])
setLoading(false)
}
}
fetchData()
} else {
setLoading(false)
}
}, [filter])
const form = useForm({
initialValues: {
id: 0,
name: '',
email: '',
permission: '',
position: '',
input: '',
expect_output: '',
actual_output: '',
issue_id_on_jira: '',
bug_id_on_jira: '',
note: '',
},
})
// const getAll = async () => {
// try {
// const res = await get(getAllUsers)
// if (res.status) {
// setUsers(res.data)
// }
// } catch (error) {
// console.log(error)
// }
// }
const handleCreate = async (values: TUser) => {
const handleCreate = async (values: DataTestCases) => {
try {
const { id, ...data } = values
console.log(data, 'data')
const { ...data } = values
delete data.id
// const res = await post(createOrUpdateUser, data)
// if (res.status === true) {
// setAction('review')
// form.reset()
// // getAll()
// setInfo(JSON.stringify(res.data, null, 2))
// }
const res = await post(`${createTestCase}/${filter.sprint}`, data)
if (res.status === true) {
setAction('')
form.reset()
getAll()
notifications.show({
title: 'Success',
message: 'Add success',
color: 'green',
})
}
} catch (error) {
console.log(error)
}
}
const getAll = async () => {
const fetchData = async () => {
const result = await getListTestCase(filter.sprint)
if (result) {
setDataListTestCases(result ?? [])
setLoading(false)
}
}
fetchData()
}
const handleDelete = async (id: number) => {
try {
const data = {
id: id,
}
console.log(data, 'data')
// await Xdelete(
// deleteUser,
// { id: id },
// // , getAll
// )
await Xdelete(deleteTestCase, { id: id }, getAll)
} catch (error) {
console.log(error)
}
}
useEffect(() => {
// getAll()
}, [])
const rowStyle = {
height: '30px', // Điều chỉnh chiều cao hàng
}
@ -138,6 +272,9 @@ const TestReport = () => {
setAction('add')
form.reset()
}}
style={{
display: filter.sprint ? 'block' : 'none',
}}
>
+ Add
</Button>
@ -149,7 +286,7 @@ const TestReport = () => {
display: 'flex',
flexFlow: 'column',
}}
w={'40%'}
w={'50%'}
>
<Box w="100%" display={'flex'}>
<Text
@ -162,13 +299,16 @@ const TestReport = () => {
</Text>
<Select
clearable
w="50%"
value={filter.typeReason}
w="60%"
value={filter.project}
size="xs"
label=""
data={[]}
data={dataProject.map((project) => ({
value: project.id.toString(),
label: project.name,
}))}
onChange={(e) => {
setFilter({ ...filter, typeReason: e! })
setFilter({ ...filter, project: e! })
}}
></Select>
<Text
@ -181,20 +321,17 @@ const TestReport = () => {
</Text>
<Select
clearable
w="50%"
value={filter.statusFilter}
w="40%"
value={filter.sprint}
size="xs"
ml={'sm'}
label=""
data={
[
// { value: 'WAITING', label: 'WAITING' },
// { value: 'CONFIRMED', label: 'CONFIRMED' },
// { value: 'REFUSED', label: 'REFUSED' },
]
}
data={dataSprint.map((sprint) => ({
value: sprint.id.toString(),
label: sprint.name,
}))}
onChange={(e) => {
setFilter({ ...filter, statusFilter: e! })
setFilter({ ...filter, sprint: e! })
}}
></Select>
</Box>
@ -206,15 +343,33 @@ const TestReport = () => {
// backgroundColor: 'yellow',
alignSelf: 'center',
}}
w={'60%'}
w={'50%'}
>
<Text style={{ textAlign: 'center' }} fw={600}>
Project Name/ Sprint Name
{dataProject.find((item: any) => item.id === filter.project)?.name}{' '}
{dataSprint.find((item: any) => item.id === Number(filter.sprint))
?.name
? '/'
: ''}{' '}
{dataSprint.find((item) => item.id === Number(filter.sprint))?.name}
</Text>
</Box>
</Box>
<Box>
<Box
style={{
marginTop: '20%',
textAlign: 'center',
display: loading ? 'block' : 'none',
// display: 'none',
}}
>
<Loader size={'sm'} color="green" type="bars" m={'0 auto'} />
<Text fw={600} c={'gray'}>
Loading . . .
</Text>
</Box>
<Box style={loading ? { display: 'none' } : {}}>
{/* Tiêu đề Criteria for Sprint */}
<Title order={5} ml="xs">
List bug:
@ -236,16 +391,13 @@ const TestReport = () => {
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
Position
</Table.Th>
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
<Table.Th style={{ textAlign: 'center', width: '220px' }}>
Input
</Table.Th>
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
Note
</Table.Th>
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
<Table.Th style={{ textAlign: 'center', width: '220px' }}>
Expect output
</Table.Th>
<Table.Th style={{ textAlign: 'center', width: '150px' }}>
<Table.Th style={{ textAlign: 'center', width: '220px' }}>
Actual output
</Table.Th>
<Table.Th style={{ textAlign: 'center' }}>Note</Table.Th>
@ -255,22 +407,21 @@ const TestReport = () => {
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{[...Array(5)].map((_, index) => (
{dataListTestCases.map((item, index) => (
<Table.Tr key={index} style={rowStyle}>
<Table.Td>string</Table.Td>
<Table.Td>string</Table.Td>
<Table.Td>string</Table.Td>
<Table.Td>string</Table.Td>
<Table.Td>string</Table.Td>
<Table.Td>string</Table.Td>
<Table.Td>string</Table.Td>
<Table.Td>{item.name}</Table.Td>
<Table.Td>{item.position}</Table.Td>
<Table.Td>{item.input}</Table.Td>
<Table.Td>{item.expect_output}</Table.Td>
<Table.Td>{item.actual_output}</Table.Td>
<Table.Td>{item.note}</Table.Td>
<Table.Td>
<Box className={classes.optionIcon}>
<IconInfoSquare
className={classes.editIcon}
onClick={() => {
setAction('review')
// setItem(row)
setItem(item)
form.reset()
}}
width={20}
@ -280,7 +431,7 @@ const TestReport = () => {
className={classes.deleteIcon}
onClick={() => {
setAction('delete')
// setItem(row)
setItem(item)
form.reset()
}}
width={20}
@ -303,7 +454,7 @@ const TestReport = () => {
}}
title={
<Text pl={'sm'} fw={700} fz={'lg'}>
{action === 'add' ? 'Add Test' : ''}
{action === 'add' ? 'Add Test Report' : ''}
</Text>
}
>
@ -328,33 +479,42 @@ const TestReport = () => {
required
label="Position"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
value={form.values.position}
onChange={(e) => form.setFieldValue('position', e.target.value)}
/>
<TextInput
required
<Textarea
label="Input"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
required
value={form.values.input}
onChange={(e) => form.setFieldValue('input', e.target.value)}
/>
<Textarea
label="Expect Output"
required
value={form.values.expect_output}
onChange={(e) =>
form.setFieldValue('expect_output', e.target.value)
}
/>
<Textarea
label="Actual Output"
required
value={form.values.actual_output}
onChange={(e) =>
form.setFieldValue('actual_output', e.target.value)
}
/>
<Box display={'flex'}>
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'45%'}>
<TextInput
label="Expect Output"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
/>
<TextInput
label="Issue ID On Jira"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
value={form.values.issue_id_on_jira}
onChange={(e) =>
form.setFieldValue('issue_id_on_jira', e.target.value)
}
/>
</Box>
<Box
@ -362,27 +522,21 @@ const TestReport = () => {
w={'10%'}
></Box>
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'45%'}>
<TextInput
label="Actual Output"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
/>
<TextInput
label="Bug ID On Jira"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
value={form.values.bug_id_on_jira}
onChange={(e) =>
form.setFieldValue('bug_id_on_jira', e.target.value)
}
/>
</Box>
</Box>
<Textarea
label="Note"
required
value={form.values.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
value={form.values.note}
onChange={(e) => form.setFieldValue('note', e.target.value)}
/>
<Box ta={'center'}>
<Button
@ -416,9 +570,7 @@ const TestReport = () => {
readOnly
style={{ pointerEvents: 'none' }}
mb={'md'}
value={'!23123'}
error={form.errors.name}
onChange={(e) => form.setFieldValue('name', e.target.value)}
value={item.name}
/>
<TextInput
@ -426,62 +578,50 @@ const TestReport = () => {
readOnly
style={{ pointerEvents: 'none' }}
mb={'md'}
value={'12312231'}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
value={item.position}
/>
<TextInput
<Textarea
readOnly
style={{ pointerEvents: 'none' }}
label="Input"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
value={item.input}
/>
<Textarea
readOnly
style={{ pointerEvents: 'none' }}
label="Expect Output"
value={item.expect_output}
/>
<Textarea
readOnly
style={{ pointerEvents: 'none' }}
label="Actual Output"
value={item.actual_output}
/>
<Box display={'flex'}>
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'40%'}>
<TextInput
readOnly
style={{ pointerEvents: 'none' }}
label="Expect Output"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
/>
<TextInput
readOnly
style={{ pointerEvents: 'none' }}
label="Actual Output"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
/>
</Box>
<Box
style={{ display: 'flex', flexFlow: 'column' }}
w={'20%'}
></Box>
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'40%'}>
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'45%'}>
<TextInput
readOnly
style={{ pointerEvents: 'none' }}
label="Issue ID On Jira"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
value={item.issue_id_on_jira}
/>
</Box>
<Box
style={{ display: 'flex', flexFlow: 'column' }}
w={'10%'}
></Box>
<Box style={{ display: 'flex', flexFlow: 'column' }} w={'45%'}>
<TextInput
readOnly
style={{ pointerEvents: 'none' }}
label="Bug ID On Jira"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
value={item.bug_id_on_jira}
/>
</Box>
</Box>
@ -489,17 +629,14 @@ const TestReport = () => {
readOnly
style={{ pointerEvents: 'none' }}
label="Note"
value={form.values.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
value={item.note}
/>
<TextInput
readOnly
style={{ pointerEvents: 'none', marginTop: '10px' }}
label="Create By"
mb={'md'}
value={form.values.email}
error={form.errors.email}
onChange={(e) => form.setFieldValue('email', e.target.value)}
value={item.created_by}
/>
</Box>
</Modal>
@ -523,7 +660,9 @@ const TestReport = () => {
variant="light"
onClick={async () => {
setActiveBtn(true)
await handleDelete(2)
if (item.id !== undefined) {
await handleDelete(item.id)
}
setActiveBtn(false)
setAction('')
}}