mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-08-19 09:30:21 +00:00
fix(ui): refresh the Slack page after a connection test
- Revalidate the Slack path so the badge and last-checked date update - Hide the decorative Slack icon from assistive technology - Keep the Slack integration card a Server Component - Match Slack error codes on own properties only - Assert the callback redirects back to the integration page
This commit is contained in:
@@ -341,6 +341,7 @@ export const testIntegrationConnection = async (
|
||||
revalidatePath("/integrations/amazon-s3");
|
||||
revalidatePath("/integrations/aws-security-hub");
|
||||
revalidatePath("/integrations/jira");
|
||||
revalidatePath("/integrations/slack");
|
||||
|
||||
if ("error" in pollResult) {
|
||||
return { success: false, error: pollResult.error };
|
||||
|
||||
@@ -760,8 +760,7 @@ export const SlackIcon: React.FC<IconSvgProps> = ({
|
||||
...props
|
||||
}) => (
|
||||
<svg
|
||||
aria-hidden="false"
|
||||
aria-label="Slack logo"
|
||||
aria-hidden="true"
|
||||
fill="none"
|
||||
focusable="false"
|
||||
height={size || height}
|
||||
|
||||
@@ -15,20 +15,27 @@ import { SlackCallback } from "./slack-callback";
|
||||
|
||||
const COMPLETED_QUERY = "code=slack-code-1f4a&state=st-2f1c9d7a";
|
||||
|
||||
const { exchangeSlackOAuthCode, callbackQuery } = vi.hoisted(() => ({
|
||||
exchangeSlackOAuthCode: vi.fn(),
|
||||
callbackQuery: { value: "" },
|
||||
}));
|
||||
const { exchangeSlackOAuthCode, callbackQuery, routerReplace } = vi.hoisted(
|
||||
() => ({
|
||||
exchangeSlackOAuthCode: vi.fn(),
|
||||
callbackQuery: { value: "" },
|
||||
routerReplace: vi.fn(),
|
||||
}),
|
||||
);
|
||||
|
||||
vi.mock("@/actions/integrations/slack", () => ({ exchangeSlackOAuthCode }));
|
||||
|
||||
// One router across renders, so the redirect off the spent code is assertable.
|
||||
const router = { replace: routerReplace };
|
||||
|
||||
vi.mock("next/navigation", () => ({
|
||||
useRouter: () => ({ replace: vi.fn() }),
|
||||
useRouter: () => router,
|
||||
useSearchParams: () => new URLSearchParams(callbackQuery.value),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
callbackQuery.value = COMPLETED_QUERY;
|
||||
routerReplace.mockClear();
|
||||
});
|
||||
|
||||
const SPINNER_COPY = /Connecting your Slack workspace/;
|
||||
@@ -94,6 +101,8 @@ describe("returning from Slack when the completion answers unexpectedly", () =>
|
||||
expect(
|
||||
screen.queryByRole("link", { name: /Back to Slack integration/ }),
|
||||
).not.toBeInTheDocument();
|
||||
// `replace`, not `push`: a back navigation must not remount onto the code.
|
||||
expect(routerReplace).toHaveBeenCalledWith("/integrations/slack");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { SettingsIcon } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
|
||||
@@ -77,7 +77,8 @@ export interface SlackApiFailure extends SlackErrorSource {
|
||||
}
|
||||
|
||||
const isKnownCode = (code: string | null | undefined): code is SlackErrorCode =>
|
||||
typeof code === "string" && code in SLACK_ERROR_MESSAGES;
|
||||
typeof code === "string" &&
|
||||
Object.prototype.hasOwnProperty.call(SLACK_ERROR_MESSAGES, code);
|
||||
|
||||
/**
|
||||
* Copy for a refusal: Prowler's wording for a known `code`, else the API's
|
||||
|
||||
Reference in New Issue
Block a user