Skip to content

Commit a69d8d2

Browse files
committed
v2 updates
1 parent 08f1e20 commit a69d8d2

14 files changed

Lines changed: 810 additions & 110 deletions

web-report/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"@radix-ui/react-scroll-area": "^1.2.3",
2020
"@radix-ui/react-slot": "^1.1.2",
2121
"@radix-ui/react-tabs": "^1.1.3",
22-
"@radix-ui/react-tooltip": "^1.1.8",
22+
"@radix-ui/react-tooltip": "^1.2.7",
2323
"@tailwindcss/vite": "^4.0.14",
2424
"class-variance-authority": "^0.7.1",
2525
"clsx": "^2.1.1",

web-report/src/assets/info.json

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
{
2+
"number_of_endpoints": "Number of endpoints.",
3+
"number_of_http_calls": "Total number of HTTP calls.",
4+
"number_of_fault_codes": "Number of codes",
5+
"fault_codes": [
6+
{
7+
"short_definition": "HTTP_STATUS_500",
8+
"code": 100,
9+
"description": "HTTP Status 500",
10+
"test_case_name": "causes500_internalServerError"
11+
},
12+
{
13+
"short_definition": "HTTP_INVALID_PAYLOAD_SYNTAX",
14+
"code": 101,
15+
"description": "Invalid Payload Syntax",
16+
"test_case_name": "rejectedWithInvalidPayloadSyntax"
17+
},
18+
{
19+
"short_definition": "HTTP_INVALID_LOCATION",
20+
"code": 102,
21+
"description": "Invalid Location HTTP Header",
22+
"test_case_name": "returnsInvalidLocationHeader"
23+
},
24+
{
25+
"short_definition": "HTTP_NONWORKING_DELETE",
26+
"code": 103,
27+
"description": "DELETE Method Does Not Work",
28+
"test_case_name": "deleteDoesNotWork"
29+
},
30+
{
31+
"short_definition": "HTTP_REPEATED_CREATE_PUT",
32+
"code": 104,
33+
"description": "Repeated PUT Creates Resource With 201",
34+
"test_case_name": "repeatedCreatePut"
35+
},
36+
{
37+
"short_definition": "SCHEMA_INVALID_RESPONSE",
38+
"code": 200,
39+
"description": "Received A Response From API That Is Not Valid According To Its Schema",
40+
"test_case_name": "returnsSchemaInvalidResponse"
41+
},
42+
{
43+
"short_definition": "GQL_ERROR_FIELD",
44+
"code": 301,
45+
"description": "Error Field",
46+
"test_case_name": "returnedErrors"
47+
},
48+
{
49+
"short_definition": "RPC_INTERNAL_ERROR",
50+
"code": 400,
51+
"description": "Internal Error",
52+
"test_case_name": "causesInternalError"
53+
},
54+
{
55+
"short_definition": "RPC_SERVICE_ERROR",
56+
"code": 401,
57+
"description": "Service Error",
58+
"test_case_name": "causesServiceError"
59+
},
60+
{
61+
"short_definition": "RPC_DECLARED_EXCEPTION",
62+
"code": 402,
63+
"description": "Declared Exception",
64+
"test_case_name": "throwsExpectedException"
65+
},
66+
{
67+
"short_definition": "RPC_UNEXPECTED_EXCEPTION",
68+
"code": 403,
69+
"description": "Unexpected Exception",
70+
"test_case_name": "throwsUnexpectedException"
71+
},
72+
{
73+
"short_definition": "RPC_HANDLED_ERROR",
74+
"code": 404,
75+
"description": "Business Logic Error",
76+
"test_case_name": "failsToExecuteCall"
77+
},
78+
{
79+
"short_definition": "WEB_BROKEN_LINK",
80+
"code": 500,
81+
"description": "Broken Link",
82+
"test_case_name": "returnsBrokenLink"
83+
},
84+
{
85+
"short_definition": "SECURITY_EXISTENCE_LEAKAGE",
86+
"code": 800,
87+
"description": "Leakage Information Existence of Protected Resource",
88+
"test_case_name": "allowsUnauthorizedAccessToProtectedResource"
89+
},
90+
{
91+
"short_definition": "SECURITY_NOT_RECOGNIZED_AUTHENTICATED",
92+
"code": 801,
93+
"description": "Wrongly Not Recognized as Authenticated",
94+
"test_case_name": "failedToAuthenticateWithValidCredentials"
95+
},
96+
{
97+
"short_definition": "SECURITY_FORBIDDEN_DELETE",
98+
"code": 802,
99+
"description": "Forbidden Delete But Allowed Modifications",
100+
"test_case_name": "forbidsDeleteButAllowsModifications"
101+
},
102+
{
103+
"short_definition": "SECURITY_FORBIDDEN_PUT",
104+
"code": 803,
105+
"description": "Forbidden Replacement But Allowed Modifications",
106+
"test_case_name": "forbidsReplacementButAllowsModifications"
107+
},
108+
{
109+
"short_definition": "SECURITY_FORBIDDEN_PATCH",
110+
"code": 804,
111+
"description": "Forbidden Updates But Allowed Modifications",
112+
"test_case_name": "forbidsUpdatesButAllowsModifications"
113+
},
114+
{
115+
"short_definition": "SECURITY_ALLOW_MODIFICATION_BY_ALL",
116+
"code": 805,
117+
"description": "Resource Created By An User Can Be Modified By All Other Users",
118+
"test_case_name": "createdResourceCanBeModifiedByEveryone"
119+
},
120+
{
121+
"short_definition": "SECURITY_FORGOTTEN_AUTHENTICATION",
122+
"code": 806,
123+
"description": "A Protected Resource Is Accessible Without Providing Any Authentication",
124+
"test_case_name": "forgottenAuthentication"
125+
}
126+
]
127+
}

web-report/src/components/EndpointAccordion.tsx

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,50 @@ export const EndpointAccordion: React.FC<IEndpointAccordionProps> = ({
3131
const selectedTestCases = status_codes.find((code) => code.code === selectedCode)?.test_cases || [];
3232
const selectedFaultTestCases = faults.find((code) => code.code === selectedCode)?.test_cases || [];
3333

34-
const faultColors = ["bg-red-300", "bg-red-500", "bg-red-700"];
34+
const sortedStatusCodes = status_codes.sort((a, b) =>
35+
{
36+
const codeA = Number(a.code);
37+
const codeB = Number(b.code);
38+
if (isNaN(codeA) || isNaN(codeB)) {
39+
return String(a.code).localeCompare(String(b.code));
40+
}
41+
return codeA - codeB;
42+
}
43+
);
44+
45+
const sortedFaults = faults.sort((a, b) => {
46+
const codeA = Number(a.code);
47+
const codeB = Number(b.code);
48+
if (isNaN(codeA) || isNaN(codeB)) {
49+
return String(a.code).localeCompare(String(b.code));
50+
}
51+
return codeA - codeB;
52+
});
3553

54+
const faultColors = ["bg-red-300", "bg-red-500", "bg-red-700"];
3655
return (
3756
<AccordionItem value={value} className="border-2 border-black mb-4 overflow-hidden" data-testid={endpoint}>
3857
<AccordionTrigger className="bg-blue-100 px-4 py-3 text-lg font-bold hover:no-underline hover:bg-blue-200">
39-
{endpoint}
58+
<div className="flex-1 font-mono">{endpoint}</div>
59+
<div className="flex flex-wrap justify-end gap-2 mr-4">
60+
{sortedStatusCodes.map((code, idx) => (
61+
<Badge key={`_${idx}`} className={`${getColor(code.code, true, false)}`}>
62+
{code.code}
63+
</Badge>
64+
))}
65+
{sortedFaults.map((code, idx) => (
66+
<Badge key={`_${idx}`} className={`${getColor(code.code, true, true)}`}>
67+
{code.code}
68+
</Badge>
69+
))}
70+
</div>
4071
</AccordionTrigger>
4172
<AccordionContent className="p-4">
4273
<div className="mb-6">
43-
<div className="font-bold text-lg mb-2">HTTP</div>
74+
<div className="font-bold text-lg mb-2">HTTP CODES</div>
4475
<div className="flex flex-wrap gap-2">
4576
{
46-
status_codes.map((code, index) => (
77+
sortedStatusCodes.map((code, index) => (
4778
<Badge key={index} onClick={() => {
4879
setSelectedCode(code.code);
4980
setIsFault(false);
@@ -54,17 +85,17 @@ export const EndpointAccordion: React.FC<IEndpointAccordionProps> = ({
5485
))
5586
}
5687
{
57-
status_codes.length == 0 &&
88+
sortedStatusCodes.length == 0 &&
5889
<div className="text-gray-500 italic">No status codes recorded for this endpoint.</div>
5990
}
6091
</div>
6192
</div>
6293

6394
<div>
64-
<div className="font-bold text-lg mb-2 text-red-500">FAULTS</div>
95+
<div className="font-bold text-lg mb-2 text-red-500">FAULT CODES</div>
6596
<div className="flex flex-wrap gap-2">
6697
{
67-
faults.map((fault, index) => (
98+
sortedFaults.map((fault, index) => (
6899
<Badge key={index} onClick={() => {
69100
setSelectedCode(fault.code)
70101
setIsFault(true);
@@ -75,7 +106,7 @@ export const EndpointAccordion: React.FC<IEndpointAccordionProps> = ({
75106
))
76107
}
77108
{
78-
faults.length == 0 &&
109+
sortedFaults.length == 0 &&
79110
<div className="text-gray-500 italic">No faults recorded for this endpoint.</div>
80111
}
81112
</div>

web-report/src/components/FaultsComponent.tsx

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
11
import {Card} from "@/components/ui/card.tsx";
22
import {ShieldAlert} from "lucide-react";
3-
import type React from "react";
3+
import React, {useState} from "react";
44
import {Faults} from "@/types/GeneratedTypes.tsx";
55
import {getFaultCounts} from "@/utils.tsx";
6+
import {Tooltip, TooltipContent, TooltipTrigger} from "@/components/ui/tooltip.tsx";
7+
import info from "@/assets/info.json";
8+
import {StatusCodeModal} from "@/components/StatusCodeModal.tsx";
69

710
export const FaultsComponent: React.FC<Faults> = ({total_number, found_faults}) => {
811
const faultCounts = getFaultCounts(found_faults);
12+
const [isModalOpen, setIsModalOpen] = useState(false)
13+
const [currentStatus, setCurrentStatus] = useState(-1);
914

15+
const handleOpenModal = (status: number) => {
16+
setCurrentStatus(status);
17+
setIsModalOpen(true);
18+
}
19+
20+
const getShortNameOfCode = (code: number) => {
21+
const codeInfo = info.fault_codes.find((fault) => fault.code === code);
22+
if (codeInfo) {
23+
return codeInfo.short_definition;
24+
}
25+
}
1026
return(
1127
<Card className="border-2 border-black p-6 rounded-none">
1228
<div className="flex items-start gap-4 mb-4">
@@ -25,20 +41,30 @@ export const FaultsComponent: React.FC<Faults> = ({total_number, found_faults})
2541

2642
<div className="mt-4">
2743
<div className="flex justify-between font-bold border-b border-black pb-2">
28-
<span>Codes</span>
44+
<Tooltip>
45+
<TooltipTrigger asChild>
46+
<span>Codes</span>
47+
</TooltipTrigger>
48+
<TooltipContent>
49+
<p>{info.number_of_fault_codes}</p>
50+
</TooltipContent>
51+
</Tooltip>
52+
<span>Name</span>
2953
<span>#</span>
3054
</div>
3155
<div className="border-2 border-black mt-2 p-2">
3256
{
3357
Array.from(faultCounts).map(([code, count]) => (
3458
<div className="flex justify-between py-1" key={code}>
35-
<span className="font-bold">{code}</span>
59+
<span className="font-bold cursor-help font-mono hover:text-green-300" onClick={() => handleOpenModal(code)}>{code}</span>
60+
<span className="font-mono cursor-help hover:text-green-300" onClick={() => handleOpenModal(code)}>{getShortNameOfCode(code)}</span>
3661
<span className="font-bold">{count}</span>
3762
</div>
3863
))
3964
}
4065
</div>
4166
</div>
67+
<StatusCodeModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} statusCode={currentStatus} />
4268
</Card>
4369
)
4470
}

web-report/src/components/GeneratedTests.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import {Card} from "@/components/ui/card.tsx";
22
import {Target} from "lucide-react";
33
import type React from "react";
4+
import {getFileColor} from "@/utils.tsx";
45

56
interface IGeneratedTests {
67
total_tests: number
7-
total_test_files: number
8+
test_files: Array<string>
89
}
910

10-
export const GeneratedTests: React.FC<IGeneratedTests> = ({total_tests, total_test_files}) => (
11+
export const GeneratedTests: React.FC<IGeneratedTests> = ({total_tests, test_files}) => (
1112
<Card className="border-2 border-black p-6 rounded-none">
1213
<div className="flex items-start gap-4">
1314
<Target className="w-6 h-6 text-gray-500"/>
@@ -18,7 +19,24 @@ export const GeneratedTests: React.FC<IGeneratedTests> = ({total_tests, total_te
1819
</div>
1920
<div className="flex justify-between">
2021
<span className="text-lg font-bold">Generated Test Files:</span>
21-
<span className="text-lg font-bold" data-testid="generated-tests-total-test-files">{total_test_files}</span>
22+
<span className="text-lg font-bold" data-testid="generated-tests-total-test-files">{test_files.length}</span>
23+
</div>
24+
<div className="mt-4 pt-4 border-t border-gray-200">
25+
<div className="text-sm font-medium text-gray-700 mb-2">Test Files</div>
26+
<div className="space-y-1">
27+
{
28+
test_files.length > 0 ? (
29+
test_files.map((file, index) => (
30+
<div className="flex items-center gap-2 text-sm text-gray-600" key={index}>
31+
<div className={`w-2 h-2 ${getFileColor(index, file)} rounded-full`}></div>
32+
<span>{file}</span>
33+
</div>
34+
))
35+
) : (
36+
<div className="text-gray-500 italic">No test files generated.</div>
37+
)
38+
}
39+
</div>
2240
</div>
2341
</div>
2442
</div>

web-report/src/components/RestReports.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type React from "react";
33
import {CoveragePieChart} from "@/components/CoveragePieChart.tsx";
44
import {RESTReport} from "@/types/GeneratedTypes.tsx";
55
import {calculateAllStatusCounts} from "@/utils.tsx";
6+
import {Tooltip, TooltipContent, TooltipTrigger} from "@/components/ui/tooltip.tsx";
7+
import info from "@/assets/info.json";
68

79
export const RestReports: React.FC<RESTReport> = ({total_http_calls, covered_http_status, endpoint_ids}) => {
810
const total = endpoint_ids.length;
@@ -11,7 +13,7 @@ export const RestReports: React.FC<RESTReport> = ({total_http_calls, covered_htt
1113
return (
1214
<Card className="border-2 border-black p-6 rounded-none">
1315
<div className="mb-4">
14-
<h3 className="text-xl font-bold">REST Reports</h3>
16+
<h3 className="text-xl font-bold">REST Report</h3>
1517
</div>
1618
<div className="border-t border-black my-2"></div>
1719

@@ -23,13 +25,29 @@ export const RestReports: React.FC<RESTReport> = ({total_http_calls, covered_htt
2325
</div>
2426

2527
<div className="mt-6">
28+
2629
<div className="flex justify-between font-bold">
27-
<span># Endpoints:</span>
30+
<Tooltip>
31+
<TooltipTrigger asChild>
32+
<span># Endpoints:</span>
33+
</TooltipTrigger>
34+
<TooltipContent>
35+
<p>{info.number_of_endpoints}</p>
36+
</TooltipContent>
37+
</Tooltip>
2838
<span data-testid="rest-report-endpoint">{endpoint_ids.length}</span>
2939
</div>
40+
3041
<div className="border-t border-black my-2"></div>
3142
<div className="flex justify-between font-bold">
32-
<span># HTTP Calls:</span>
43+
<Tooltip>
44+
<TooltipTrigger asChild>
45+
<span># HTTP Calls:</span>
46+
</TooltipTrigger>
47+
<TooltipContent>
48+
<p>{info.number_of_http_calls}</p>
49+
</TooltipContent>
50+
</Tooltip>
3351
<span data-testid="rest-report-http-calls">{total_http_calls}</span>
3452
</div>
3553
<div className="border-t border-black my-2"></div>

0 commit comments

Comments
 (0)