Files
prowler/ui/__tests__/msw/handlers/attack-paths.ts
T
Pablo Fernandez Guerra (PFE) 853610bbbf feat(ui): resolve public SaaS config at container runtime (#11500)
Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 15:12:18 +02:00

232 lines
7.0 KiB
TypeScript

import { http, HttpResponse } from "msw";
import type { PageFixture } from "@/app/(prowler)/attack-paths/(workflow)/query-builder/attack-paths-page.fixtures";
import type {
AttackPathQueriesResponse,
AttackPathQuery,
AttackPathQueryResult,
AttackPathScan,
AttackPathScansResponse,
QueryResultAttributes,
} from "@/types/attack-paths";
const API = process.env.UI_API_BASE_URL;
type JsonApiErrorBody = {
errors: Array<{ detail: string; status: string }>;
};
const toScansApiResponse = (
scans: AttackPathScan[],
): AttackPathScansResponse => ({
data: scans,
links: {
first: `${API}/attack-paths-scans?page=1`,
last: `${API}/attack-paths-scans?page=1`,
next: null,
prev: null,
},
});
const toQueriesApiResponse = (
queries: AttackPathQuery[],
): AttackPathQueriesResponse => ({
data: queries,
});
const toQueryResultApiResponse = (
attrs: QueryResultAttributes,
queryId: string,
): AttackPathQueryResult => ({
data: {
type: "attack-paths-query-run-requests",
id: queryId,
attributes: attrs,
},
});
const toErrorBody = (detail: string, status: number): JsonApiErrorBody => ({
errors: [{ detail, status: String(status) }],
});
const toFindingApiResponse = (fx: PageFixture, findingId: string) => {
const findingNode = fx.queryResult?.nodes.find(
(node) => node.id === findingId,
);
const resourceNode = fx.queryResult?.nodes.find((node) =>
fx.queryResult?.relationships?.some(
(rel) =>
(rel.source === node.id && rel.target === findingId) ||
(rel.target === node.id && rel.source === findingId),
),
);
const scan = fx.scans[0];
const providerId = scan?.relationships?.provider?.data?.id ?? "provider-1";
const resourceId = resourceNode?.id ?? "resource-1";
return {
data: {
type: "findings",
id: findingId,
attributes: {
uid: String(findingNode?.properties.id ?? findingId),
delta: null,
status: String(findingNode?.properties.status ?? "FAIL"),
status_extended: "Status extended",
severity: String(findingNode?.properties.severity ?? "critical"),
check_id: "attack_path_check",
muted: false,
muted_reason: null,
check_metadata: {
risk: "High",
notes: "",
checkid: "attack_path_check",
provider: "aws",
severity: String(findingNode?.properties.severity ?? "critical"),
checktype: [],
dependson: [],
relatedto: [],
categories: ["security"],
checktitle: String(
findingNode?.properties.check_title ?? "Attack path finding",
),
compliance: null,
relatedurl: "",
description: "Attack path finding description",
remediation: {
code: { cli: "", other: "", nativeiac: "", terraform: "" },
recommendation: { url: "", text: "Fix the finding" },
},
additionalurls: [],
servicename: String(resourceNode?.properties.service ?? "s3"),
checkaliases: [],
resourcetype: String(resourceNode?.labels[0] ?? "Resource"),
subservicename: "",
resourceidtemplate: "",
},
raw_result: null,
inserted_at: "2026-04-21T10:00:00Z",
updated_at: "2026-04-21T10:05:00Z",
first_seen_at: null,
},
relationships: {
resources: { data: [{ type: "resources", id: resourceId }] },
scan: { data: { type: "scans", id: scan?.id ?? "scan-1" } },
},
},
included: [
{
type: "resources",
id: resourceId,
attributes: {
uid: String(resourceNode?.properties.arn ?? resourceId),
name: String(resourceNode?.properties.name ?? resourceId),
region: "us-east-1",
service: String(resourceNode?.properties.service ?? "s3"),
tags: {},
type: String(resourceNode?.labels[0] ?? "Resource"),
inserted_at: "2026-04-21T10:00:00Z",
updated_at: "2026-04-21T10:05:00Z",
details: null,
partition: null,
},
},
{
type: "scans",
id: scan?.id ?? "scan-1",
attributes: {
name: "Attack path scan",
trigger: "manual",
state: scan?.attributes.state ?? "completed",
unique_resource_count: 1,
progress: scan?.attributes.progress ?? 100,
duration: scan?.attributes.duration ?? 0,
started_at: scan?.attributes.started_at ?? "2026-04-21T10:00:00Z",
inserted_at: scan?.attributes.inserted_at ?? "2026-04-21T10:00:00Z",
completed_at: scan?.attributes.completed_at ?? "2026-04-21T10:05:00Z",
scheduled_at: null,
next_scan_at: "",
},
relationships: {
provider: { data: { type: "providers", id: providerId } },
},
},
{
type: "providers",
id: providerId,
attributes: {
provider: scan?.attributes.provider_type ?? "aws",
uid: scan?.attributes.provider_uid ?? "123456789",
alias: scan?.attributes.provider_alias ?? "Provider",
connection: {
connected: true,
last_checked_at: "2026-04-21T10:00:00Z",
},
inserted_at: "2026-04-21T10:00:00Z",
updated_at: "2026-04-21T10:05:00Z",
},
},
],
};
};
export const handlersForFixture = (fx: PageFixture) => [
http.get(`${API}/attack-paths-scans`, () =>
HttpResponse.json<AttackPathScansResponse>(toScansApiResponse(fx.scans)),
),
http.get<{ scanId: string }>(
`${API}/attack-paths-scans/:scanId/queries`,
() =>
HttpResponse.json<AttackPathQueriesResponse>(
toQueriesApiResponse(fx.queries),
),
),
http.post<{ scanId: string }>(
`${API}/attack-paths-scans/:scanId/queries/run`,
() => {
if (fx.queryError) {
return HttpResponse.json<JsonApiErrorBody>(
toErrorBody(fx.queryError.error, fx.queryError.status),
{ status: fx.queryError.status },
);
}
if (!fx.queryResult) {
return HttpResponse.json<JsonApiErrorBody>(
toErrorBody("No data found", 404),
{ status: 404 },
);
}
return HttpResponse.json<AttackPathQueryResult>(
toQueryResultApiResponse(fx.queryResult, fx.queryId),
);
},
),
http.post<{ scanId: string }>(
`${API}/attack-paths-scans/:scanId/queries/custom`,
() => {
if (fx.queryError) {
return HttpResponse.json<JsonApiErrorBody>(
toErrorBody(fx.queryError.error, fx.queryError.status),
{ status: fx.queryError.status },
);
}
if (!fx.queryResult) {
return HttpResponse.json<JsonApiErrorBody>(
toErrorBody("No data found", 404),
{ status: 404 },
);
}
return HttpResponse.json<AttackPathQueryResult>(
toQueryResultApiResponse(fx.queryResult, fx.queryId),
);
},
),
http.get<{ findingId: string }>(`${API}/findings/:findingId`, ({ params }) =>
HttpResponse.json(toFindingApiResponse(fx, params.findingId)),
),
];