Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion web-report/src/AppContent.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
import {useAppContext} from "@/AppProvider.tsx";
import {LoadingScreen} from "@/components/LoadingScreen.tsx";
import {Dashboard} from "@/components/Dashboard.tsx";
import {ErrorDisplay} from "@/components/ErrorDisplay.tsx";

export const AppContent: React.FC = () => {
const {data, loading, error} = useAppContext();
const {data, loading, error, invalidReportErrors} = useAppContext();

if(invalidReportErrors)
{
return(
<div className="min-h-screen bg-gray-50 py-8">
<ErrorDisplay
title="Validation Error"
description="Invalid report format. Please ensure the report is generated correctly."
issues={invalidReportErrors}
/>
</div>
)
}
if (error){
return (
<main className="min-h-screen p-4 bg-gray-100">
Expand All @@ -14,6 +27,7 @@ export const AppContent: React.FC = () => {
<p>{error}</p>
</div>
</div>

</main>
)
}
Expand Down
7 changes: 6 additions & 1 deletion web-report/src/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {WebFuzzingCommonsReport} from "@/types/GeneratedTypes.tsx";
import {ITestFiles} from "@/types/General.tsx";
import {fetchFileContent, ITransformedReport, transformWebFuzzingReport} from "@/lib/utils.tsx";
import {webFuzzingCommonsReportSchema} from "@/types/GeneratedTypesZod.ts";
import {ZodIssue} from "zod";

type AppContextType = {
data: WebFuzzingCommonsReport | null;
Expand All @@ -12,6 +13,7 @@ type AppContextType = {
transformedReport: ITransformedReport[];
filterEndpoints: (activeFilters: Record<number, string>) => ITransformedReport[];
filteredEndpoints: ITransformedReport[];
invalidReportErrors: ZodIssue[] | null;
};

const AppContext = createContext<AppContextType | undefined>(undefined);
Expand All @@ -25,6 +27,7 @@ export const AppProvider = ({ children }: AppProviderProps) => {
const [data, setData] = useState<WebFuzzingCommonsReport | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [invalidReportErrors, setInvalidReportErrors] = useState<ZodIssue[] | null>(null);
const [testFiles, setTestFiles] = useState<ITestFiles[]>([]);
const transformedReport = transformWebFuzzingReport(data);

Expand All @@ -35,8 +38,10 @@ export const AppProvider = ({ children }: AppProviderProps) => {

// Validate the JSON data against the schema
const report = webFuzzingCommonsReportSchema.safeParse(jsonData);
console.log(report)
if (!report.success) {
setError("Invalid report format. Please ensure the report is generated correctly.");
setInvalidReportErrors(report.error.issues);
return;
}
setData(jsonData);
Expand Down Expand Up @@ -143,7 +148,7 @@ export const AppProvider = ({ children }: AppProviderProps) => {
return filtered;
}

const value: AppContextType = { data, loading, error, testFiles, transformedReport, filterEndpoints, filteredEndpoints };
const value: AppContextType = { data, loading, error, testFiles, transformedReport, filterEndpoints, filteredEndpoints, invalidReportErrors };

return (
<AppContext.Provider value={value}>
Expand Down
105 changes: 105 additions & 0 deletions web-report/src/components/ErrorDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {AlertTriangle, Code, ArrowRight} from "lucide-react"
import {ZodIssue} from "zod";

interface ErrorDisplayProps {
title?: string
description?: string
issues?: ZodIssue[]
}

export function ErrorDisplay({
title = "Error",
description = "Invalid report format. Please ensure the report is generated correctly.",
issues = [],
}: ErrorDisplayProps) {

const getIssueTypeColor = (code: string) => {
switch (code) {
case "invalid_type":
return "bg-red-50 border-red-200 text-red-800"
default:
return "bg-gray-50 border-gray-200 text-gray-800"
}
}

const getPathString = (path: (string | number)[]) => {
return path.length > 0 ? path.join(".") : "root"
}

return (
<div className="max-w-4xl mx-auto p-6">
<div className="text-center mb-6">
<div className="flex items-center justify-center mb-3">
<AlertTriangle className="w-12 h-12 text-red-500 mr-3"/>
<h1 className="text-4xl font-bold text-gray-900">{title}</h1>
</div>
<p className="text-lg text-gray-600">{description}</p>
</div>

{issues.length > 0 && (
<div className="space-y-4">
<div className="flex items-center mb-4">
<div className="h-px bg-gray-300 flex-1"></div>
<span className="px-4 text-sm font-medium text-gray-500">
{issues.length} Validation Issue{issues.length !== 1 ? "s" : ""}
</span>
<div className="h-px bg-gray-300 flex-1"></div>
</div>

{issues.map((issue, index) => (
<div
key={index}
className={`rounded-lg border-2 p-6 transition-all duration-200 hover:shadow-md ${getIssueTypeColor(issue.code)}`}
>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 items-center">
<div className="space-y-2">
<div className="flex items-center">
<Code className="w-4 h-4 mr-2 opacity-70"/>
<span className="font-mono text-sm font-semibold uppercase tracking-wide">
{issue.code.replace("_", " ")}
</span>
</div>
<div className="font-mono text-lg font-bold">{getPathString(issue.path)}</div>
</div>
<div className="flex justify-center">
<ArrowRight className="w-6 h-6 opacity-50"/>
</div>
{issue.code === "invalid_type" &&
<div className="space-y-3">
<div className="text-base font-medium">{issue.message}</div>
<div
className="flex flex-col space-y-2">
<div className="flex items-center">
<span className="text-sm text-gray-600 mr-2">Expected:</span>
<span
className="px-2 py-1 bg-green-100 text-green-800 rounded font-mono text-sm font-medium">
{issue.expected}
</span>
</div>
<div className="flex items-center">
<span className="text-sm text-gray-600 mr-2">Received:</span>
<span
className="px-2 py-1 bg-red-100 text-red-800 rounded font-mono text-sm font-medium">
{issue.received}
</span>
</div>
</div>
</div>
}
</div>
</div>
))}
</div>
)}

{issues.length === 0 && (
<div className="text-center py-8">
<div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
<AlertTriangle className="w-8 h-8 text-gray-400"/>
</div>
<p className="text-gray-500">No detailed validation issues available.</p>
</div>
)}
</div>
)
}
4 changes: 2 additions & 2 deletions web-report/src/components/GeneratedTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ export const GeneratedTests: React.FC<IGeneratedTests> = ({totalTests, testFiles
<div className="flex-1">
<div className="flex justify-between">
<ReportTooltip tooltipText={info.generatedTestFiles}>
<span className="text-lg font-bold">Generated Test Files:</span>
<span className="text-lg font-bold"># Generated Test Files:</span>
</ReportTooltip>
<span className="text-lg font-bold" data-testid="generated-tests-total-test-files">{testFiles.length}</span>
</div>
<div className="flex justify-between">
<ReportTooltip tooltipText={info.generatedTestCases}>
<span className="text-lg font-bold">Generated Tests Cases:</span>
<span className="text-lg font-bold"># Generated Tests Cases:</span>
</ReportTooltip>
<span className="text-lg font-bold" data-testid="generated-tests-total-tests">{totalTests}</span>
</div>
Expand Down