mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 21:11:53 +00:00
fix(ui): address grouped Jira review feedback
This commit is contained in:
@@ -100,7 +100,27 @@ describe("sendJiraDispatch", () => {
|
||||
// Then
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
error: "Jira dispatch completed with 1 failed and 2 created issues.",
|
||||
error:
|
||||
"Jira dispatch completed with 1 failed and 2 created/updated issues.",
|
||||
});
|
||||
});
|
||||
|
||||
it("should include updated issues in partial failure summaries", async () => {
|
||||
// Given
|
||||
pollTaskUntilSettledMock.mockResolvedValue({
|
||||
ok: true,
|
||||
state: "completed",
|
||||
result: { created_count: 0, updated_count: 2, failed_count: 1 },
|
||||
});
|
||||
|
||||
// When
|
||||
const result = await pollJiraDispatchTask("task-1");
|
||||
|
||||
// Then
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
error:
|
||||
"Jira dispatch completed with 1 failed and 2 created/updated issues.",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -118,7 +138,8 @@ describe("sendJiraDispatch", () => {
|
||||
// Then
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
error: "Jira dispatch completed with 1 failed and 1 created issue.",
|
||||
error:
|
||||
"Jira dispatch completed with 1 failed and 1 created/updated issue.",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -186,4 +207,22 @@ describe("sendJiraDispatch", () => {
|
||||
error: "Jira dispatch completed but did not create or update any issues.",
|
||||
});
|
||||
});
|
||||
|
||||
it("should fail completed task polling when Jira dispatch has no result payload", async () => {
|
||||
// Given
|
||||
pollTaskUntilSettledMock.mockResolvedValue({
|
||||
ok: true,
|
||||
state: "completed",
|
||||
result: null,
|
||||
});
|
||||
|
||||
// When
|
||||
const result = await pollJiraDispatchTask("task-1");
|
||||
|
||||
// Then
|
||||
expect(result).toEqual({
|
||||
success: false,
|
||||
error: "Jira dispatch completed but did not create or update any issues.",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -63,7 +63,9 @@ const buildJiraDispatchFailureMessage = (
|
||||
if (result?.error) return result.error;
|
||||
|
||||
const createdCount = result?.created_count ?? 0;
|
||||
return `Jira dispatch completed with ${failedCount} failed and ${createdCount} created issue${createdCount === 1 ? "" : "s"}.`;
|
||||
const updatedCount = result?.updated_count ?? 0;
|
||||
const successCount = createdCount + updatedCount;
|
||||
return `Jira dispatch completed with ${failedCount} failed and ${successCount} created/updated issue${successCount === 1 ? "" : "s"}.`;
|
||||
};
|
||||
|
||||
export const getJiraIssueTypes = async (
|
||||
@@ -254,7 +256,7 @@ export const pollJiraDispatchTask = async (
|
||||
};
|
||||
}
|
||||
|
||||
if (jiraResult && getJiraDispatchSuccessCount(jiraResult) === 0) {
|
||||
if (!jiraResult || getJiraDispatchSuccessCount(jiraResult) === 0) {
|
||||
return {
|
||||
success: false,
|
||||
error:
|
||||
|
||||
@@ -260,7 +260,7 @@ describe("FloatingMuteButton — onBeforeOpen error handling", () => {
|
||||
).toBeVisible();
|
||||
expect(
|
||||
screen.getByRole("button", {
|
||||
name: "Send to Jira",
|
||||
name: "Send 1 Group and 1 Finding to Jira",
|
||||
}),
|
||||
).toHaveTextContent("Send 1 Group and 1 Finding to Jira");
|
||||
});
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/components/shadcn/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { MuteFindingsModal } from "./mute-findings-modal";
|
||||
|
||||
@@ -171,12 +172,11 @@ export function FloatingMuteButton({
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
className={
|
||||
canSendToJira
|
||||
? "w-full justify-start"
|
||||
: "w-full justify-start pr-56"
|
||||
}
|
||||
aria-label="Send to Jira"
|
||||
className={cn(
|
||||
"w-full justify-start",
|
||||
!canSendToJira && "pr-56",
|
||||
)}
|
||||
aria-label={sendToJiraLabel}
|
||||
disabled={!canSendToJira}
|
||||
onClick={handleJiraClick}
|
||||
>
|
||||
|
||||
@@ -38,4 +38,21 @@ describe("buildJiraDispatchChoiceCopy", () => {
|
||||
"Use this when each selected resource should be tracked independently.",
|
||||
});
|
||||
});
|
||||
|
||||
it("uses neutral Findings copy outside a single Finding Group", () => {
|
||||
expect(
|
||||
buildJiraDispatchChoiceCopy({
|
||||
selectedCount: 2,
|
||||
isSelectedFindingGroupFlow: false,
|
||||
selectionKind: "findings",
|
||||
}),
|
||||
).toEqual({
|
||||
description: "Create Jira issue(s) for 2 selected Findings.",
|
||||
groupedTitle: "Create one Jira issue for all selected Findings",
|
||||
groupedHelp:
|
||||
"Recommended. The issue will include every selected Finding.",
|
||||
individualHelp:
|
||||
"Use this when each selected Finding should be tracked independently.",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
interface JiraDispatchChoiceCopyParams {
|
||||
selectedCount: number;
|
||||
isSelectedFindingGroupFlow: boolean;
|
||||
selectionKind?: "findings" | "resources";
|
||||
}
|
||||
|
||||
interface JiraDispatchChoiceCopy {
|
||||
@@ -13,6 +14,7 @@ interface JiraDispatchChoiceCopy {
|
||||
export const buildJiraDispatchChoiceCopy = ({
|
||||
selectedCount,
|
||||
isSelectedFindingGroupFlow,
|
||||
selectionKind = "resources",
|
||||
}: JiraDispatchChoiceCopyParams): JiraDispatchChoiceCopy => {
|
||||
if (isSelectedFindingGroupFlow) {
|
||||
return {
|
||||
@@ -26,6 +28,17 @@ export const buildJiraDispatchChoiceCopy = ({
|
||||
};
|
||||
}
|
||||
|
||||
if (selectionKind === "findings") {
|
||||
return {
|
||||
description: `Create Jira issue(s) for ${selectedCount} selected Findings.`,
|
||||
groupedTitle: "Create one Jira issue for all selected Findings",
|
||||
groupedHelp:
|
||||
"Recommended. The issue will include every selected Finding.",
|
||||
individualHelp:
|
||||
"Use this when each selected Finding should be tracked independently.",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
description: `Create Jira issue(s) for ${selectedCount} selected affected failing resources.`,
|
||||
groupedTitle:
|
||||
|
||||
@@ -129,12 +129,41 @@ describe("SendToJiraModal", () => {
|
||||
"Create one Jira issue for all selected Findings in this Finding Group",
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Create Jira issues for 1 Group and 2 Findings."),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Create separate Jira issues")).toBeInTheDocument();
|
||||
expect(sendFindingToJiraMock).not.toHaveBeenCalled();
|
||||
expect(sendJiraDispatchMock).not.toHaveBeenCalled();
|
||||
await waitFor(() => expect(getJiraIntegrationsMock).toHaveBeenCalled());
|
||||
});
|
||||
|
||||
it("uses neutral Findings copy for ordinary multi-Finding selections", async () => {
|
||||
render(
|
||||
<SendToJiraModal
|
||||
isOpen
|
||||
onOpenChange={vi.fn()}
|
||||
findingId="finding-1"
|
||||
findingTitle="Finding 1"
|
||||
targetIds={["finding-1", "finding-2"]}
|
||||
targetType="finding_id"
|
||||
defaultDispatchMode="grouped"
|
||||
canChooseGroupedDispatch
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText("Jira issue creation mode")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("Create one Jira issue for all selected Findings"),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText(
|
||||
"Create one Jira issue for all selected Findings in this Finding Group",
|
||||
),
|
||||
).not.toBeInTheDocument();
|
||||
await waitFor(() => expect(getJiraIntegrationsMock).toHaveBeenCalled());
|
||||
});
|
||||
|
||||
it("submits mixed Group and Finding batches with the correct dispatch filters and modes", async () => {
|
||||
// Given
|
||||
const user = userEvent.setup();
|
||||
@@ -520,4 +549,64 @@ describe("SendToJiraModal", () => {
|
||||
expect.objectContaining({ title: "Success!" }),
|
||||
);
|
||||
});
|
||||
|
||||
it("polls started tasks when a later mixed dispatch batch fails to launch", async () => {
|
||||
// Given
|
||||
const user = userEvent.setup();
|
||||
const onOpenChange = vi.fn();
|
||||
sendJiraDispatchMock
|
||||
.mockResolvedValueOnce({
|
||||
success: true,
|
||||
taskId: "group-task",
|
||||
message: "Group started",
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
success: false,
|
||||
error: "Failed to launch Finding batch.",
|
||||
});
|
||||
render(
|
||||
<SendToJiraModal
|
||||
isOpen
|
||||
onOpenChange={onOpenChange}
|
||||
findingId="check-a"
|
||||
findingTitle="Check A"
|
||||
targetBatches={[
|
||||
{
|
||||
targetIds: ["check-a"],
|
||||
targetType: "check_id",
|
||||
dispatchMode: "grouped",
|
||||
},
|
||||
{
|
||||
targetIds: ["finding-1", "finding-2"],
|
||||
targetType: "finding_id",
|
||||
},
|
||||
]}
|
||||
defaultDispatchMode="grouped"
|
||||
selectedResourceCount={1}
|
||||
/>,
|
||||
);
|
||||
await waitFor(() => expect(getJiraIntegrationsMock).toHaveBeenCalled());
|
||||
await user.click(
|
||||
screen.getByRole("button", { name: "Select a Jira project" }),
|
||||
);
|
||||
await user.click(
|
||||
screen.getByRole("button", { name: "Select an issue type" }),
|
||||
);
|
||||
|
||||
// When
|
||||
await user.click(screen.getByRole("button", { name: "Send to Jira" }));
|
||||
|
||||
// Then
|
||||
await waitFor(() =>
|
||||
expect(pollJiraDispatchTaskMock).toHaveBeenCalledWith("group-task"),
|
||||
);
|
||||
await waitFor(() =>
|
||||
expect(toastMock).toHaveBeenCalledWith({
|
||||
variant: "destructive",
|
||||
title: "Error",
|
||||
description:
|
||||
"Some Jira dispatches started, but Failed to launch Finding batch.",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -56,6 +56,7 @@ interface SendToJiraModalProps {
|
||||
targetBatches?: JiraDispatchTargetBatch[];
|
||||
defaultDispatchMode?: JiraDispatchMode;
|
||||
canChooseGroupedDispatch?: boolean;
|
||||
isFindingGroupSelection?: boolean;
|
||||
selectedResourceCount?: number;
|
||||
description?: string;
|
||||
}
|
||||
@@ -99,6 +100,7 @@ export const SendToJiraModal = ({
|
||||
targetBatches,
|
||||
defaultDispatchMode = JIRA_DISPATCH_MODE.INDIVIDUAL,
|
||||
canChooseGroupedDispatch = false,
|
||||
isFindingGroupSelection = false,
|
||||
selectedResourceCount,
|
||||
description,
|
||||
}: SendToJiraModalProps) => {
|
||||
@@ -142,14 +144,14 @@ export const SendToJiraModal = ({
|
||||
(multiFindingTargetCount > 1 || jiraSelectedResourceCount > 1);
|
||||
const isSelectedFindingGroupFlow =
|
||||
shouldShowDispatchChoice &&
|
||||
(targetType === JIRA_DISPATCH_TARGET.FINDING_ID ||
|
||||
multiFindingTargetCount > 1);
|
||||
(targetType === JIRA_DISPATCH_TARGET.CHECK_ID || isFindingGroupSelection);
|
||||
const jiraDispatchChoiceCopy = buildJiraDispatchChoiceCopy({
|
||||
selectedCount:
|
||||
multiFindingTargetCount > 1
|
||||
? multiFindingTargetCount
|
||||
: jiraSelectedResourceCount,
|
||||
isSelectedFindingGroupFlow,
|
||||
selectionKind: multiFindingTargetCount > 1 ? "findings" : "resources",
|
||||
});
|
||||
|
||||
const selectedIntegration = form.watch("integration");
|
||||
@@ -217,6 +219,7 @@ export const SendToJiraModal = ({
|
||||
void (async () => {
|
||||
try {
|
||||
const taskIds: string[] = [];
|
||||
const launchErrors: string[] = [];
|
||||
|
||||
for (const batch of jiraTargetBatches) {
|
||||
const batchDispatchMode = batch.dispatchMode ?? data.dispatchMode;
|
||||
@@ -240,12 +243,17 @@ export const SendToJiraModal = ({
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
throw new Error(result.error || "Failed to send to Jira");
|
||||
launchErrors.push(result.error || "Failed to send to Jira");
|
||||
continue;
|
||||
}
|
||||
|
||||
taskIds.push(result.taskId);
|
||||
}
|
||||
|
||||
if (taskIds.length === 0 && launchErrors.length > 0) {
|
||||
throw new Error(launchErrors.join(" "));
|
||||
}
|
||||
|
||||
// Poll for task completion and notify once
|
||||
const taskResults = await Promise.all(
|
||||
taskIds.map((taskId) => pollJiraDispatchTaskUntilDone(taskId)),
|
||||
@@ -258,6 +266,12 @@ export const SendToJiraModal = ({
|
||||
throw new Error(failedTask.error || "Failed to create Jira issue");
|
||||
}
|
||||
|
||||
if (launchErrors.length > 0) {
|
||||
throw new Error(
|
||||
`Some Jira dispatches started, but ${launchErrors.join(" ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
toast({
|
||||
title: "Success!",
|
||||
description:
|
||||
@@ -375,10 +389,10 @@ export const SendToJiraModal = ({
|
||||
onOpenChange={onOpenChange}
|
||||
title="Send Finding to Jira"
|
||||
description={
|
||||
shouldShowDispatchChoice
|
||||
? jiraDispatchChoiceCopy.description
|
||||
: description
|
||||
? description
|
||||
description
|
||||
? description
|
||||
: shouldShowDispatchChoice
|
||||
? jiraDispatchChoiceCopy.description
|
||||
: findingTitle
|
||||
? `Create a Jira issue for: "${findingTitle}"`
|
||||
: "Select integration, project and issue type to create a Jira issue"
|
||||
|
||||
@@ -496,6 +496,44 @@ describe("DataTableRowActions", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps single finding Jira dispatch enabled when other rows are selected outside cloud", async () => {
|
||||
// Given
|
||||
isGroupedJiraDispatchEnabledMock.mockReturnValue(false);
|
||||
const user = userEvent.setup();
|
||||
render(
|
||||
<FindingsSelectionContext.Provider
|
||||
value={{
|
||||
selectedFindingIds: ["finding-2", "finding-3"],
|
||||
selectedFindings: [],
|
||||
clearSelection: vi.fn(),
|
||||
isSelected: vi.fn(),
|
||||
}}
|
||||
>
|
||||
<DataTableRowActions row={makeFindingRow()} />
|
||||
</FindingsSelectionContext.Provider>,
|
||||
);
|
||||
|
||||
// When
|
||||
await user.click(
|
||||
screen.getByRole("button", { name: "Send 1 Finding to Jira" }),
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(
|
||||
screen.getByRole("button", { name: "Send 1 Finding to Jira" }),
|
||||
).toBeEnabled();
|
||||
expect(SendToJiraModalMock).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
isOpen: true,
|
||||
targetIds: ["finding-1"],
|
||||
targetType: "finding_id",
|
||||
defaultDispatchMode: "individual",
|
||||
canChooseGroupedDispatch: false,
|
||||
}),
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
it("shows Add Triage Note for editable findings without a note", () => {
|
||||
// Given / When
|
||||
render(
|
||||
|
||||
@@ -153,8 +153,6 @@ export function DataTableRowActions<T extends FindingRowData>({
|
||||
const isCurrentSelected = selectedFindingIds.includes(muteKey);
|
||||
const hasMultipleSelected = selectedFindingIds.length > 1;
|
||||
const groupedJiraDispatchEnabled = isGroupedJiraDispatchEnabled();
|
||||
const isJiraActionDisabled =
|
||||
(isGroup || hasMultipleSelected) && !groupedJiraDispatchEnabled;
|
||||
|
||||
const getDisplayIds = (): string[] => {
|
||||
if (isCurrentSelected && hasMultipleSelected) {
|
||||
@@ -188,6 +186,8 @@ export function DataTableRowActions<T extends FindingRowData>({
|
||||
};
|
||||
|
||||
const jiraTargetIds = getJiraTargetIds();
|
||||
const isJiraActionDisabled =
|
||||
(isGroup || jiraTargetIds.length > 1) && !groupedJiraDispatchEnabled;
|
||||
const selectedJiraResourceCount = isGroup
|
||||
? (finding.resourcesFail ?? 0)
|
||||
: undefined;
|
||||
|
||||
@@ -251,7 +251,7 @@ export function FindingsGroupDrillDown({
|
||||
return resolveSelectedFindingIds(selectedFindingIds);
|
||||
}}
|
||||
onComplete={handleMuteComplete}
|
||||
isBulkOperation
|
||||
isBulkOperation={selectedFindingIds.length > 1}
|
||||
showSendToJira
|
||||
canSendToJira={canSendSelectedFindingsToJira}
|
||||
jiraDisabledTooltip={PROWLER_CLOUD_ONLY_TOOLTIP}
|
||||
|
||||
@@ -407,6 +407,38 @@ describe("FindingsGroupTable", () => {
|
||||
screen.queryByRole("button", { name: "Select finding-1" }),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("clears the expanded group when expandedCheckId is removed", () => {
|
||||
// Given
|
||||
const data = [
|
||||
{ checkId: "check-a", resourcesTotal: 1 },
|
||||
] as unknown as Parameters<typeof FindingsGroupTable>[0]["data"];
|
||||
const { rerender } = render(
|
||||
<FindingsGroupTable
|
||||
data={data}
|
||||
resolvedFilters={{}}
|
||||
hasHistoricalData={false}
|
||||
expandedCheckId="check-a"
|
||||
/>,
|
||||
);
|
||||
expect(
|
||||
screen.getByRole("button", { name: "Select finding-1" }),
|
||||
).toBeInTheDocument();
|
||||
|
||||
// When
|
||||
rerender(
|
||||
<FindingsGroupTable
|
||||
data={data}
|
||||
resolvedFilters={{}}
|
||||
hasHistoricalData={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Then
|
||||
expect(
|
||||
screen.queryByRole("button", { name: "Select finding-1" }),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe("bulk Jira action", () => {
|
||||
|
||||
@@ -101,6 +101,9 @@ export function FindingsGroupTable({
|
||||
const [resourceSelection, setResourceSelection] = useState<string[]>([]);
|
||||
const [isJiraModalOpen, setIsJiraModalOpen] = useState(false);
|
||||
const inlineRef = useRef<InlineResourceContainerHandle>(null);
|
||||
const previousRequestedExpandedCheckIdRef = useRef<string | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
const safeData = data ?? [];
|
||||
const hasResourceSelection = resourceSelection.length > 0;
|
||||
@@ -108,7 +111,21 @@ export function FindingsGroupTable({
|
||||
const groupedJiraDispatchEnabled = isGroupedJiraDispatchEnabled();
|
||||
|
||||
useEffect(() => {
|
||||
if (!requestedExpandedCheckId) return;
|
||||
const previousRequestedExpandedCheckId =
|
||||
previousRequestedExpandedCheckIdRef.current;
|
||||
previousRequestedExpandedCheckIdRef.current = requestedExpandedCheckId;
|
||||
|
||||
if (!requestedExpandedCheckId) {
|
||||
if (previousRequestedExpandedCheckId) {
|
||||
setExpandedCheckId(null);
|
||||
setExpandedGroup(null);
|
||||
setResourceSearchInput("");
|
||||
setResourceSearch("");
|
||||
setResourceSelection([]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const requestedGroup = safeData.find(
|
||||
(group) => group.checkId === requestedExpandedCheckId,
|
||||
@@ -430,6 +447,9 @@ export function FindingsGroupTable({
|
||||
targetType={jiraTargetType}
|
||||
targetBatches={jiraBatches}
|
||||
defaultDispatchMode={jiraDispatchMode}
|
||||
isFindingGroupSelection={
|
||||
!jiraGroupSelectionTakesPrecedence && Boolean(expandedGroup)
|
||||
}
|
||||
canChooseGroupedDispatch={canChooseGroupedJiraDispatch}
|
||||
selectedResourceCount={selectedJiraResourceCount}
|
||||
description={jiraDescription}
|
||||
|
||||
@@ -116,6 +116,8 @@ export function ActionDropdownItem({
|
||||
destructive = false,
|
||||
className,
|
||||
disabledTooltip,
|
||||
disabled,
|
||||
onSelect,
|
||||
...props
|
||||
}: ActionDropdownItemProps) {
|
||||
const item = (
|
||||
@@ -126,6 +128,16 @@ export function ActionDropdownItem({
|
||||
"text-text-error-primary focus:text-text-error-primary hover:bg-destructive/10",
|
||||
className,
|
||||
)}
|
||||
aria-disabled={disabled || undefined}
|
||||
disabled={disabled && !disabledTooltip}
|
||||
onSelect={(event) => {
|
||||
if (disabled) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
onSelect?.(event);
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{icon && (
|
||||
@@ -154,12 +166,10 @@ export function ActionDropdownItem({
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
|
||||
if (props.disabled && disabledTooltip) {
|
||||
if (disabled && disabledTooltip) {
|
||||
return (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<span className="block">{item}</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipTrigger asChild>{item}</TooltipTrigger>
|
||||
<TooltipContent>{disabledTooltip}</TooltipContent>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -68,7 +68,7 @@ describe("enterprise feature flags", () => {
|
||||
|
||||
it("should enable grouped Jira dispatch from the enterprise env flag in cloud", async () => {
|
||||
// Given
|
||||
vi.stubEnv("NEXT_PUBLIC_IS_CLOUD_ENV", "true");
|
||||
vi.stubEnv("NEXT_PUBLIC_PROWLER_DEPLOYMENT_MODE", "cloud");
|
||||
vi.stubEnv(
|
||||
"NEXT_PUBLIC_PROWLER_ENTERPRISE_GROUPED_JIRA_DISPATCH_ENABLED",
|
||||
"true",
|
||||
@@ -83,7 +83,7 @@ describe("enterprise feature flags", () => {
|
||||
|
||||
it("should keep grouped Jira dispatch disabled outside cloud", async () => {
|
||||
// Given
|
||||
vi.stubEnv("NEXT_PUBLIC_IS_CLOUD_ENV", "false");
|
||||
vi.stubEnv("NEXT_PUBLIC_PROWLER_DEPLOYMENT_MODE", "onpremise");
|
||||
vi.stubEnv(
|
||||
"NEXT_PUBLIC_PROWLER_ENTERPRISE_GROUPED_JIRA_DISPATCH_ENABLED",
|
||||
"true",
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { isCloud } from "./shared/env";
|
||||
|
||||
export const DEPLOYMENT_MODE = {
|
||||
CLOUD: "cloud",
|
||||
ON_PREMISE: "onpremise",
|
||||
@@ -67,5 +65,5 @@ export const isPostHogEnabled = (): boolean =>
|
||||
getBooleanEnv(ENTERPRISE_FEATURE_ENV.POSTHOG_ENABLED, true);
|
||||
|
||||
export const isGroupedJiraDispatchEnabled = (): boolean =>
|
||||
isCloud() &&
|
||||
getDeploymentMode() === DEPLOYMENT_MODE.CLOUD &&
|
||||
getBooleanEnv(ENTERPRISE_FEATURE_ENV.GROUPED_JIRA_DISPATCH_ENABLED, false);
|
||||
|
||||
Reference in New Issue
Block a user