mirror of
https://github.com/SigNoz/signoz.git
synced 2026-05-07 02:50:31 +01:00
Compare commits
7 Commits
main
...
ingestion-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c19ce0854 | ||
|
|
11212100be | ||
|
|
fb91440f56 | ||
|
|
6087c3aa09 | ||
|
|
4c191b60fa | ||
|
|
9106930cbd | ||
|
|
f6bc255f4d |
@@ -56,4 +56,5 @@ export enum QueryParams {
|
||||
showClassicCreateAlertsPage = 'showClassicCreateAlertsPage',
|
||||
isTestAlert = 'isTestAlert',
|
||||
yAxisUnit = 'yAxisUnit',
|
||||
ruleName = 'ruleName',
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
useEffect,
|
||||
useMemo,
|
||||
useReducer,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
@@ -123,6 +124,7 @@ export function CreateAlertProvider(
|
||||
const location = useLocation();
|
||||
const queryParams = new URLSearchParams(location.search);
|
||||
const thresholdsFromURL = queryParams.get(QueryParams.thresholds);
|
||||
const ruleNameFromURL = queryParams.get(QueryParams.ruleName);
|
||||
|
||||
const [alertType, setAlertType] = useState<AlertTypes>(() => {
|
||||
if (isEditMode) {
|
||||
@@ -154,6 +156,8 @@ export function CreateAlertProvider(
|
||||
[redirectWithQueryBuilderData],
|
||||
);
|
||||
|
||||
const ruleNameAppliedRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
setCreateAlertState({
|
||||
slice: CreateAlertSlice.THRESHOLD,
|
||||
@@ -191,7 +195,18 @@ export function CreateAlertProvider(
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [alertType, thresholdsFromURL]);
|
||||
|
||||
if (ruleNameFromURL && !ruleNameAppliedRef.current) {
|
||||
ruleNameAppliedRef.current = true;
|
||||
setCreateAlertState({
|
||||
slice: CreateAlertSlice.BASIC,
|
||||
action: {
|
||||
type: 'SET_ALERT_NAME',
|
||||
payload: ruleNameFromURL,
|
||||
},
|
||||
});
|
||||
}
|
||||
}, [alertType, thresholdsFromURL, ruleNameFromURL]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isEditMode && initialAlertState) {
|
||||
|
||||
@@ -443,7 +443,25 @@
|
||||
|
||||
.signal-limit-save-discard {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
gap: var(--spacing-4);
|
||||
|
||||
.signal-limit-save-discard-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-4);
|
||||
}
|
||||
|
||||
.signal-limit-alert-helper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-2);
|
||||
font-size: var(--paragraph-small-400-font-size);
|
||||
color: var(--l2-foreground);
|
||||
border-bottom: 1px dashed var(--l2-foreground);
|
||||
padding-bottom: 1px;
|
||||
font-style: italic;
|
||||
margin-left: var(--spacing-6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -475,6 +493,7 @@
|
||||
.ant-modal-footer {
|
||||
padding: 16px;
|
||||
margin-top: 0;
|
||||
gap: 8px;
|
||||
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
@@ -3,8 +3,8 @@ import { useTranslation } from 'react-i18next';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useCopyToClipboard } from 'react-use';
|
||||
import { Color } from '@signozhq/design-tokens';
|
||||
import { Badge, Button } from '@signozhq/ui';
|
||||
import {
|
||||
Button,
|
||||
Col,
|
||||
Collapse,
|
||||
DatePicker,
|
||||
@@ -394,7 +394,7 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
notifications.success({
|
||||
message: 'Ingestion key deleted successfully',
|
||||
});
|
||||
refetchAPIKeys();
|
||||
void refetchAPIKeys();
|
||||
setIsDeleteModalOpen(false);
|
||||
},
|
||||
onError: (error) => {
|
||||
@@ -426,7 +426,7 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
notifications.success({
|
||||
message: 'Ingestion key updated successfully',
|
||||
});
|
||||
refetchAPIKeys();
|
||||
void refetchAPIKeys();
|
||||
setIsEditModalOpen(false);
|
||||
},
|
||||
onError: (error) => {
|
||||
@@ -466,7 +466,7 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
setActiveAPIKey(null);
|
||||
setUpdatedTags([]);
|
||||
hideAddViewModal();
|
||||
refetchAPIKeys();
|
||||
void refetchAPIKeys();
|
||||
},
|
||||
onError: (error) => {
|
||||
showErrorNotification(notifications, error as AxiosError);
|
||||
@@ -630,13 +630,14 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
onSuccess: () => {
|
||||
notifications.success({
|
||||
message: 'Limit created successfully',
|
||||
description: "Set up an alert to know when you're close to hitting it.",
|
||||
});
|
||||
setActiveSignal(null);
|
||||
setActiveAPIKey(null);
|
||||
setIsEditAddLimitOpen(false);
|
||||
setUpdatedTags([]);
|
||||
hideAddViewModal();
|
||||
refetchAPIKeys();
|
||||
void refetchAPIKeys();
|
||||
setHasCreateLimitForIngestionKeyError(false);
|
||||
},
|
||||
onError: (error: AxiosError<RenderErrorResponseDTO>) => {
|
||||
@@ -733,13 +734,14 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
onSuccess: () => {
|
||||
notifications.success({
|
||||
message: 'Limit updated successfully',
|
||||
description: "Set up an alert to know when you're close to hitting it.",
|
||||
});
|
||||
setActiveSignal(null);
|
||||
setActiveAPIKey(null);
|
||||
setIsEditAddLimitOpen(false);
|
||||
setUpdatedTags([]);
|
||||
hideAddViewModal();
|
||||
refetchAPIKeys();
|
||||
void refetchAPIKeys();
|
||||
setHasUpdateLimitForIngestionKeyError(false);
|
||||
},
|
||||
onError: (error: AxiosError<RenderErrorResponseDTO>) => {
|
||||
@@ -824,7 +826,7 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
});
|
||||
setIsDeleteModalOpen(false);
|
||||
setIsDeleteLimitModalOpen(false);
|
||||
refetchAPIKeys();
|
||||
void refetchAPIKeys();
|
||||
},
|
||||
onError: (error) => {
|
||||
showErrorNotification(notifications, error as AxiosError);
|
||||
@@ -889,11 +891,18 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
const thresholds = cloneDeep(INITIAL_ALERT_THRESHOLD_STATE.thresholds);
|
||||
thresholds[0].thresholdValue = threshold;
|
||||
|
||||
const keyName = APIKey.name?.trim();
|
||||
const ruleName = keyName
|
||||
? `${keyName} - daily ${signal.signal} ingestion limit`
|
||||
: `Daily ${signal.signal} ingestion limit`;
|
||||
|
||||
const URL = `${ROUTES.ALERTS_NEW}?${
|
||||
QueryParams.compositeQuery
|
||||
}=${encodeURIComponent(stringifiedQuery)}&${
|
||||
QueryParams.thresholds
|
||||
}=${encodeURIComponent(JSON.stringify(thresholds))}`;
|
||||
}=${encodeURIComponent(JSON.stringify(thresholds))}&${
|
||||
QueryParams.ruleName
|
||||
}=${encodeURIComponent(ruleName)}`;
|
||||
|
||||
history.push(URL);
|
||||
};
|
||||
@@ -980,13 +989,18 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
</div>
|
||||
<div className="action-btn">
|
||||
<Button
|
||||
className="periscope-btn ghost"
|
||||
icon={<PenLine size={14} />}
|
||||
variant="link"
|
||||
size="icon"
|
||||
color="secondary"
|
||||
suffix={<PenLine size={14} />}
|
||||
aria-label="Edit ingestion key"
|
||||
onClick={onEditKey}
|
||||
/>
|
||||
<Button
|
||||
className="periscope-btn ghost"
|
||||
icon={<Trash2 color={Color.BG_CHERRY_500} size={14} />}
|
||||
variant="link"
|
||||
size="icon"
|
||||
color="destructive"
|
||||
suffix={<Trash2 color={Color.BG_CHERRY_500} size={14} />}
|
||||
onClick={onDeleteKey}
|
||||
/>
|
||||
</div>
|
||||
@@ -1092,16 +1106,22 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
{hasLimits(signalName) ? (
|
||||
<>
|
||||
<Button
|
||||
className="periscope-btn ghost"
|
||||
icon={<PenLine size={14} />}
|
||||
variant="link"
|
||||
size="icon"
|
||||
color="secondary"
|
||||
prefix={<PenLine size={14} />}
|
||||
aria-label={`Edit ${signalName} limit`}
|
||||
disabled={
|
||||
!!(activeAPIKey?.id === APIKey?.id && activeSignal)
|
||||
}
|
||||
onClick={onEditSignalLimit}
|
||||
/>
|
||||
<Button
|
||||
className="periscope-btn ghost"
|
||||
icon={<Trash2 color={Color.BG_CHERRY_500} size={14} />}
|
||||
variant="link"
|
||||
size="icon"
|
||||
color="destructive"
|
||||
prefix={<Trash2 color={Color.BG_CHERRY_500} size={14} />}
|
||||
aria-label={`Delete ${signalName} limit`}
|
||||
disabled={
|
||||
!!(activeAPIKey?.id === APIKey?.id && activeSignal)
|
||||
}
|
||||
@@ -1110,10 +1130,10 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
className="periscope-btn"
|
||||
size="small"
|
||||
shape="round"
|
||||
icon={<PlusIcon size={14} />}
|
||||
variant="link"
|
||||
size="sm"
|
||||
color="secondary"
|
||||
prefix={<PlusIcon size={14} />}
|
||||
disabled={!!(activeAPIKey?.id === APIKey?.id && activeSignal)}
|
||||
onClick={onAddSignalLimit}
|
||||
>
|
||||
@@ -1344,31 +1364,35 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
activeSignal.signal === signalName &&
|
||||
isEditAddLimitOpen && (
|
||||
<div className="signal-limit-save-discard">
|
||||
<Button
|
||||
type="primary"
|
||||
className="periscope-btn primary"
|
||||
size="small"
|
||||
disabled={
|
||||
isLoadingLimitForKey || isLoadingUpdatedLimitForKey
|
||||
}
|
||||
loading={
|
||||
isLoadingLimitForKey || isLoadingUpdatedLimitForKey
|
||||
}
|
||||
onClick={onSaveSignalLimit}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
<Button
|
||||
type="default"
|
||||
className="periscope-btn"
|
||||
size="small"
|
||||
disabled={
|
||||
isLoadingLimitForKey || isLoadingUpdatedLimitForKey
|
||||
}
|
||||
onClick={handleDiscardSaveLimit}
|
||||
>
|
||||
Discard
|
||||
</Button>
|
||||
<div className="signal-limit-save-discard-actions">
|
||||
<Button
|
||||
variant="solid"
|
||||
size="sm"
|
||||
disabled={
|
||||
isLoadingLimitForKey || isLoadingUpdatedLimitForKey
|
||||
}
|
||||
loading={
|
||||
isLoadingLimitForKey || isLoadingUpdatedLimitForKey
|
||||
}
|
||||
onClick={onSaveSignalLimit}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
size="sm"
|
||||
disabled={
|
||||
isLoadingLimitForKey || isLoadingUpdatedLimitForKey
|
||||
}
|
||||
onClick={handleDiscardSaveLimit}
|
||||
>
|
||||
Discard
|
||||
</Button>
|
||||
<span className="signal-limit-alert-helper">
|
||||
You can set up an alert after saving
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Form>
|
||||
@@ -1425,19 +1449,18 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
limit?.config?.day?.size !== undefined) ||
|
||||
(signalCfg.usesCount &&
|
||||
limit?.config?.day?.count !== undefined)) && (
|
||||
<Tooltip
|
||||
title="Set alert on this limit"
|
||||
placement="top"
|
||||
arrow={false}
|
||||
<Badge
|
||||
asChild
|
||||
color="cherry"
|
||||
variant="outline"
|
||||
testId={`set-alert-btn-${signalName}`}
|
||||
className="set-alert-btn"
|
||||
>
|
||||
<Button
|
||||
icon={<BellPlus size={14} color={Color.BG_CHERRY_400} />}
|
||||
className="set-alert-btn periscope-btn ghost"
|
||||
type="text"
|
||||
data-testid={`set-alert-btn-${signalName}`}
|
||||
onClick={onCreateSignalAlert}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Button onClick={onCreateSignalAlert} size="sm">
|
||||
<BellPlus size={12} />
|
||||
Set alert
|
||||
</Button>
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1617,7 +1640,13 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
}
|
||||
placement="topLeft"
|
||||
>
|
||||
<Button type="text" icon={<TriangleAlert size={14} />} />
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
color="secondary"
|
||||
prefix={<TriangleAlert size={14} />}
|
||||
aria-label="Ingestion URL error details"
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
@@ -1633,11 +1662,12 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant="solid"
|
||||
className="add-new-ingestion-key-btn"
|
||||
type="primary"
|
||||
prefix={<Plus size={14} />}
|
||||
onClick={showAddModal}
|
||||
>
|
||||
<Plus size={14} /> New Ingestion key
|
||||
New Ingestion key
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -1670,15 +1700,19 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
footer={[
|
||||
<Button
|
||||
key="cancel"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
prefix={<X size={16} />}
|
||||
onClick={hideDeleteViewModal}
|
||||
className="cancel-btn"
|
||||
icon={<X size={16} />}
|
||||
>
|
||||
Cancel
|
||||
</Button>,
|
||||
<Button
|
||||
key="submit"
|
||||
icon={<Trash2 size={16} />}
|
||||
variant="solid"
|
||||
color="destructive"
|
||||
prefix={<Trash2 size={16} />}
|
||||
loading={isDeleteingAPIKey}
|
||||
onClick={onDeleteHandler}
|
||||
className="delete-btn"
|
||||
@@ -1706,15 +1740,19 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
footer={[
|
||||
<Button
|
||||
key="cancel"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
prefix={<X size={16} />}
|
||||
onClick={hideDeleteLimitModal}
|
||||
className="cancel-btn"
|
||||
icon={<X size={16} />}
|
||||
>
|
||||
Cancel
|
||||
</Button>,
|
||||
<Button
|
||||
key="submit"
|
||||
icon={<Trash2 size={16} />}
|
||||
variant="solid"
|
||||
color="destructive"
|
||||
prefix={<Trash2 size={16} />}
|
||||
loading={isDeletingLimit}
|
||||
onClick={onDeleteLimitHandler}
|
||||
className="delete-btn"
|
||||
@@ -1745,18 +1783,18 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
footer={[
|
||||
<Button
|
||||
key="cancel"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
prefix={<X size={16} />}
|
||||
onClick={hideEditViewModal}
|
||||
className="periscope-btn cancel-btn"
|
||||
icon={<X size={16} />}
|
||||
>
|
||||
Cancel
|
||||
</Button>,
|
||||
<Button
|
||||
className="periscope-btn primary"
|
||||
key="submit"
|
||||
type="primary"
|
||||
variant="solid"
|
||||
prefix={<Check size={14} />}
|
||||
loading={isLoadingUpdateAPIKey}
|
||||
icon={<Check size={14} />}
|
||||
onClick={onUpdateApiKey}
|
||||
>
|
||||
Update Ingestion Key
|
||||
@@ -1813,18 +1851,18 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
footer={[
|
||||
<Button
|
||||
key="cancel"
|
||||
variant="ghost"
|
||||
color="secondary"
|
||||
prefix={<X size={16} />}
|
||||
onClick={hideAddViewModal}
|
||||
className="periscope-btn cancel-btn"
|
||||
icon={<X size={16} />}
|
||||
>
|
||||
Cancel
|
||||
</Button>,
|
||||
<Button
|
||||
className="periscope-btn primary"
|
||||
test-id="create-new-key"
|
||||
key="submit"
|
||||
type="primary"
|
||||
icon={<Check size={14} />}
|
||||
variant="solid"
|
||||
testId="create-new-key"
|
||||
prefix={<Check size={14} />}
|
||||
loading={isLoadingCreateAPIKey}
|
||||
onClick={onCreateIngestionKey}
|
||||
>
|
||||
@@ -1858,7 +1896,7 @@ function MultiIngestionSettings(): JSX.Element {
|
||||
]}
|
||||
validateTrigger="onBlur"
|
||||
>
|
||||
<Input placeholder="Enter Ingestion Key name" autoFocus />
|
||||
<Input placeholder="Enter Ingestion Key name" />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { GatewaytypesGettableIngestionKeysDTO } from 'api/generated/services/sigNoz.schemas';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { rest, server } from 'mocks-server/server';
|
||||
import { render, screen, userEvent, waitFor } from 'tests/test-utils';
|
||||
import {
|
||||
fireEvent,
|
||||
render,
|
||||
screen,
|
||||
userEvent,
|
||||
waitFor,
|
||||
} from 'tests/test-utils';
|
||||
import { LimitProps } from 'types/api/ingestionKeys/limits/types';
|
||||
import {
|
||||
AllIngestionKeyProps,
|
||||
@@ -40,6 +46,16 @@ const TEST_EXPIRES_AT = '2030-01-01T00:00:00Z';
|
||||
const TEST_WORKSPACE_ID = 'w1';
|
||||
const INGESTION_SETTINGS_ROUTE = '/ingestion-settings';
|
||||
|
||||
const GLOBAL_CONFIG_RESPONSE = {
|
||||
status: 'success',
|
||||
data: {
|
||||
external_url: '',
|
||||
ingestion_url: 'http://ingest.example.com',
|
||||
ai_assistant_url: null,
|
||||
mcp_url: null,
|
||||
},
|
||||
};
|
||||
|
||||
describe('MultiIngestionSettings Page', () => {
|
||||
beforeEach(() => {
|
||||
mockPush.mockClear();
|
||||
@@ -71,9 +87,6 @@ describe('MultiIngestionSettings Page', () => {
|
||||
});
|
||||
|
||||
it('navigates to create alert with metrics count threshold', async () => {
|
||||
const user = userEvent.setup({ pointerEventsCheck: 0 });
|
||||
|
||||
// Arrange API response with a metrics daily count limit so the alert button is visible
|
||||
const response: TestGatewayIngestionKeysResponse = {
|
||||
status: 'success',
|
||||
data: {
|
||||
@@ -101,59 +114,48 @@ describe('MultiIngestionSettings Page', () => {
|
||||
};
|
||||
|
||||
server.use(
|
||||
rest.get('*/api/v1/global/config*', (_req, res, ctx) =>
|
||||
res(ctx.status(200), ctx.json(GLOBAL_CONFIG_RESPONSE)),
|
||||
),
|
||||
rest.get('*/api/v2/gateway/ingestion_keys*', (_req, res, ctx) =>
|
||||
res(ctx.status(200), ctx.json(response)),
|
||||
),
|
||||
);
|
||||
|
||||
// Render with initial route to test navigation
|
||||
render(<MultiIngestionSettings />, undefined, {
|
||||
initialRoute: INGESTION_SETTINGS_ROUTE,
|
||||
});
|
||||
// Wait for ingestion key to load and expand the row to show limits
|
||||
await screen.findByText('Key One');
|
||||
const expandButton = screen.getByRole('button', { name: /right Key One/i });
|
||||
await user.click(expandButton);
|
||||
fireEvent.click(screen.getByRole('button', { name: /right Key One/i }));
|
||||
|
||||
// Wait for limits section to render and click metrics alert button by test id
|
||||
await screen.findByText('LIMITS');
|
||||
const metricsAlertBtn = (await screen.findByTestId(
|
||||
'set-alert-btn-metrics',
|
||||
)) as HTMLButtonElement;
|
||||
await user.click(metricsAlertBtn);
|
||||
fireEvent.click(
|
||||
(await screen.findByTestId('set-alert-btn-metrics')) as HTMLButtonElement,
|
||||
);
|
||||
|
||||
// Wait for navigation to occur
|
||||
await waitFor(() => {
|
||||
expect(mockPush).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
// Assert: navigation occurred with correct query parameters
|
||||
const navigationCall = mockPush.mock.calls[0][0] as string;
|
||||
|
||||
// Check URL contains alerts/new route
|
||||
expect(navigationCall).toContain('/alerts/new');
|
||||
|
||||
// Parse query parameters
|
||||
const urlParams = new URLSearchParams(navigationCall.split('?')[1]);
|
||||
|
||||
const thresholds = JSON.parse(urlParams.get(QueryParams.thresholds) || '{}');
|
||||
expect(thresholds).toBeDefined();
|
||||
expect(thresholds[0].thresholdValue).toBe(1000);
|
||||
|
||||
// Verify compositeQuery parameter exists and contains correct data
|
||||
const compositeQuery = JSON.parse(
|
||||
urlParams.get(QueryParams.compositeQuery) || '{}',
|
||||
);
|
||||
expect(compositeQuery.builder).toBeDefined();
|
||||
expect(compositeQuery.builder.queryData).toBeDefined();
|
||||
|
||||
// Check that the query contains the correct filter expression for the key
|
||||
const firstQueryData = compositeQuery.builder.queryData[0];
|
||||
expect(firstQueryData.filter.expression).toContain(
|
||||
"signoz.workspace.key.id='k1'",
|
||||
);
|
||||
|
||||
// Verify metric name for metrics signal
|
||||
expect(firstQueryData.aggregations[0].metricName).toBe(
|
||||
'signoz.meter.metric.datapoint.count',
|
||||
);
|
||||
@@ -248,6 +250,66 @@ describe('MultiIngestionSettings Page', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('shows alert CTAs in view mode and helper text in edit mode for configured limits', async () => {
|
||||
const KEY_NAME = 'Key With Limits';
|
||||
const response: TestGatewayIngestionKeysResponse = {
|
||||
status: 'success',
|
||||
data: {
|
||||
keys: [
|
||||
{
|
||||
name: KEY_NAME,
|
||||
expires_at: new Date(TEST_EXPIRES_AT),
|
||||
value: 'secret',
|
||||
workspace_id: TEST_WORKSPACE_ID,
|
||||
id: 'k1',
|
||||
created_at: new Date(TEST_CREATED_UPDATED),
|
||||
updated_at: new Date(TEST_CREATED_UPDATED),
|
||||
tags: [],
|
||||
limits: [
|
||||
{
|
||||
id: 'l1',
|
||||
signal: 'metrics',
|
||||
config: { day: { count: 1000 } },
|
||||
},
|
||||
{
|
||||
id: 'l2',
|
||||
signal: 'logs',
|
||||
config: { day: { size: 1073741824 } },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
_pagination: { page: 1, per_page: 10, pages: 1, total: 1 },
|
||||
},
|
||||
};
|
||||
|
||||
server.use(
|
||||
rest.get('*/api/v1/global/config*', (_req, res, ctx) =>
|
||||
res(ctx.status(200), ctx.json(GLOBAL_CONFIG_RESPONSE)),
|
||||
),
|
||||
rest.get('*/api/v2/gateway/ingestion_keys*', (_req, res, ctx) =>
|
||||
res(ctx.status(200), ctx.json(response)),
|
||||
),
|
||||
);
|
||||
|
||||
render(<MultiIngestionSettings />, undefined, {
|
||||
initialRoute: INGESTION_SETTINGS_ROUTE,
|
||||
});
|
||||
|
||||
await screen.findByText(KEY_NAME);
|
||||
fireEvent.click(
|
||||
screen.getByRole('button', { name: new RegExp(`right ${KEY_NAME}`, 'i') }),
|
||||
);
|
||||
await screen.findByText('LIMITS');
|
||||
|
||||
expect(screen.getAllByText('Set alert').length).toBeGreaterThan(0);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Edit logs limit' }));
|
||||
expect(
|
||||
screen.getByText('You can set up an alert after saving'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('switches to search API when search text is entered', async () => {
|
||||
const user = userEvent.setup({ pointerEventsCheck: 0 });
|
||||
|
||||
@@ -295,6 +357,9 @@ describe('MultiIngestionSettings Page', () => {
|
||||
const searchHandler = jest.fn();
|
||||
|
||||
server.use(
|
||||
rest.get('*/api/v1/global/config*', (_req, res, ctx) =>
|
||||
res(ctx.status(200), ctx.json(GLOBAL_CONFIG_RESPONSE)),
|
||||
),
|
||||
rest.get('*/api/v2/gateway/ingestion_keys', (req, res, ctx) => {
|
||||
if (req.url.pathname.endsWith('/search')) {
|
||||
return undefined;
|
||||
|
||||
Reference in New Issue
Block a user