Compare commits

...

14 Commits

Author SHA1 Message Date
Rajat Dabade
ee4086dce5 Merge branch 'develop' into unit-testing-1 2023-12-29 14:27:45 +05:30
Rajat Dabade
7d73b144c9 Merge branch 'develop' into unit-testing-1 2023-12-27 10:56:59 +05:30
Rajat Dabade
5fd919a369 Merge branch 'develop' into unit-testing-1 2023-12-27 10:52:41 +05:30
Rajat Dabade
3159121929 Merge branch 'develop' into unit-testing-1 2023-12-27 10:19:45 +05:30
Rajat Dabade
d5c3760dc9 Merge branch 'develop' into unit-testing-1 2023-12-14 14:01:56 +05:30
Rajat-Dabade
950584af36 refactor: updated with dummy url 2023-12-06 16:41:36 +05:30
Rajat-Dabade
fb5d4475e2 refactor: removed the test which case build failure 2023-12-06 12:16:59 +05:30
Rajat-Dabade
6771857941 refactor: build failure fixes 2023-12-06 11:11:39 +05:30
Rajat-Dabade
1e16df65ac refactor: updated test case 2023-12-06 10:31:09 +05:30
Rajat-Dabade
933b70134c chore: updated test case 2023-12-06 09:47:46 +05:30
Rajat-Dabade
581e80cd37 refactor: added more test case 2023-12-05 20:34:18 +05:30
Rajat-Dabade
50836593a4 chore: done with unit testing or triggeredAlerts 2023-12-05 16:57:13 +05:30
Rajat-Dabade
f647e828dd chore: done with unit test for list alert rules 2023-12-05 16:07:24 +05:30
Rajat-Dabade
56fb58abed chore: added few test case for alerts 2023-12-04 15:24:38 +05:30
11 changed files with 694 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
import { act } from 'react-dom/test-utils';
import { fireEvent, render, screen, within } from 'tests/test-utils';
import ListAlertRules from '.';
describe('ListAlertRules', () => {
test('Should render the table', async () => {
act(() => {
render(<ListAlertRules />);
});
const newAlert = await screen.findByRole('button', {
name: /plus new alert/i,
});
expect(newAlert).toBeInTheDocument();
const status = await screen.findByText(/status/i);
expect(status).toBeInTheDocument();
const alertName = await screen.findByText(/alert name/i);
expect(alertName).toBeInTheDocument();
const severity = await screen.findByText(/severity/i);
expect(severity).toBeInTheDocument();
const label = await screen.findByText(/label/i);
expect(label).toBeInTheDocument();
const action = await screen.findByText(/action/i);
expect(action).toBeInTheDocument();
});
test('Should render the table data', async () => {
act(() => {
render(<ListAlertRules />);
});
const status = await screen.findByText(/status/i);
expect(status).toBeInTheDocument();
const disabledRow = await screen.findByRole('row', {
name: /disabled Test Rule 1 warning details: https:\/\/stagi\.\.\. hello: world region: us \+1 ellipsis/i,
});
expect(disabledRow).toBeInTheDocument();
const actionButton = within(disabledRow).getByRole('button', {
name: /ellipsis/i,
});
expect(actionButton).toBeInTheDocument();
fireEvent.mouseOver(actionButton);
const enabled = await screen.findByRole('menuitem', {
name: /enable/i,
});
expect(enabled).toBeInTheDocument();
});
test('Should render enabled for disabled alert in menu', async () => {
act(() => {
render(<ListAlertRules />);
});
const disabledRow = await screen.findByRole('row', {
name: /disabled Test Rule 1 warning details: https:\/\/stagi\.\.\. hello: world region: us \+1 ellipsis/i,
});
expect(disabledRow).toBeInTheDocument();
const actionButton = within(disabledRow).getByRole('button', {
name: /ellipsis/i,
});
expect(actionButton).toBeInTheDocument();
fireEvent.mouseOver(actionButton);
const enabled = await screen.findByRole('menuitem', {
name: /enable/i,
});
expect(enabled).toBeInTheDocument();
});
test('Should render disabled for Ok alert in menu', async () => {
act(() => {
render(<ListAlertRules />);
});
const enabledRow = await screen.findByRole('row', {
name: /ok test rule 2 warning - ellipsis/i,
});
expect(enabledRow).toBeInTheDocument();
const actionButton = within(enabledRow).getByRole('button', {
name: /ellipsis/i,
});
expect(actionButton).toBeInTheDocument();
fireEvent.mouseOver(actionButton);
const disabled = await screen.findByRole('menuitem', {
name: /disable/i,
});
expect(disabled).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,68 @@
import { render, screen } from 'tests/test-utils';
import { Alerts } from 'types/api/alerts/getTriggered';
import ExapandableRow from './ExapandableRow';
jest.mock('lib/convertDateToAmAndPm', () => jest.fn(() => '12:00 PM'));
jest.mock('lib/getFormatedDate', () => jest.fn(() => '2023-12-05'));
describe('ExapandableRow component', () => {
const allAlerts: Alerts[] = [
{
id: 1,
annotations: { description: 'Description 1', summary: 'Summary 1' },
state: 'active',
name: 'Alert 1',
labels: {
alertname: 'Critical Alert',
severity: 'critical',
tag1: 'value1',
tag2: 'value2',
},
status: { inhibitedBy: [], silencedBy: [], state: 'active' },
startsAt: '2023-12-05T11:00:00Z',
fingerprint: 'fingerprint1',
endsAt: '2023-12-05T12:00:00Z',
generatorURL: 'generatorURL1',
receivers: [],
updatedAt: '2023-12-05T11:30:00Z',
},
{
id: 2,
annotations: { description: 'Description 2', summary: 'Summary 2' },
state: 'inactive',
name: 'Alert 2',
labels: {
alertname: 'Warning Alert',
severity: 'warning',
tag1: 'value3',
tag2: 'value4',
tag3: 'value5',
},
status: { inhibitedBy: [], silencedBy: [], state: 'inactive' },
startsAt: '2023-12-05T13:00:00Z',
fingerprint: 'fingerprint2',
endsAt: '2023-12-05T14:00:00Z',
generatorURL: 'generatorURL2',
receivers: [],
updatedAt: '2023-12-05T13:30:00Z',
},
];
test('should render correct content for each alert', () => {
render(<ExapandableRow allAlerts={allAlerts} />);
expect(screen.getByText('Critical Alert')).toBeInTheDocument();
expect(screen.getByText('critical')).toBeInTheDocument();
expect(screen.getByText('Warning Alert')).toBeInTheDocument();
expect(screen.getByText('warning')).toBeInTheDocument();
});
test('Should render the unknown status if tag is not corrently mentioned', () => {
render(<ExapandableRow allAlerts={allAlerts} />);
const unknowStatus = screen.getByText('Unknown Status');
expect(unknowStatus).toBeInTheDocument();
screen.debug();
});
});

View File

@@ -0,0 +1,44 @@
// FilteredTable.test.tsx
import { render } from 'tests/test-utils';
import { Alerts } from 'types/api/alerts/getTriggered';
import FilteredTable from '.';
describe('FilteredTable component', () => {
const selectedGroup = [{ value: 'group1' }, { value: 'group2' }];
const allAlerts: Alerts[] = [
{
labels: { group1: 'value1', group2: 'value2' },
annotations: { description: 'Description 1', summary: 'Summary 1' },
state: 'active',
name: 'Alert 1',
id: 1,
endsAt: '2023-12-05T12:00:00Z',
fingerprint: 'fingerprint1',
generatorURL: 'generatorURL1',
receivers: [],
startsAt: '2023-12-05T11:00:00Z',
status: { inhibitedBy: [], silencedBy: [], state: 'active' },
updatedAt: '2023-12-05T11:30:00Z',
},
];
const selectedFilter = [{ value: 'severity:critical' }];
it('should render table headers', () => {
const { getByText } = render(
<FilteredTable
selectedGroup={selectedGroup}
allAlerts={allAlerts}
selectedFilter={selectedFilter}
/>,
);
// Assert that each header is present
expect(getByText('Status')).toBeInTheDocument();
expect(getByText('Alert Name')).toBeInTheDocument();
expect(getByText('Severity')).toBeInTheDocument();
expect(getByText('Firing Since')).toBeInTheDocument();
expect(getByText('Tags')).toBeInTheDocument();
});
});

View File

@@ -0,0 +1,68 @@
import { render, screen } from 'tests/test-utils';
import { Alerts } from 'types/api/alerts/getTriggered';
import TableRowComponent from './TableRow';
jest.mock('types/api/alerts/getTriggered', () => ({}));
describe('TableRowComponent component', () => {
const tags = ['tag1', 'tag2'];
const tagsAlerts: Alerts[] = [
{
labels: {
alertname: 'Critical Alert',
severity: 'critical',
tag1: 'value1',
tag2: 'value2',
},
annotations: {
description: 'Description 1',
summary: 'Summary 1',
customProperty: 'Custom Value 1',
},
state: 'active',
name: 'Alert 1',
id: 1,
endsAt: '2023-12-05T12:00:00Z',
fingerprint: 'fingerprint1',
generatorURL: 'generatorURL1',
receivers: [],
startsAt: '2023-12-05T11:00:00Z',
status: { inhibitedBy: [], silencedBy: [], state: 'active' },
updatedAt: '2023-12-05T11:30:00Z',
},
{
labels: {
alertname: 'Warning Alert',
severity: 'warning',
tag1: 'value3',
tag2: 'value4',
tag3: 'value5',
},
annotations: {
description: 'Description 2',
summary: 'Summary 2',
customProperty: 'Custom Value 2',
},
state: 'inactive',
name: 'Alert 2',
id: 2,
endsAt: '2023-12-05T13:00:00Z',
fingerprint: 'fingerprint2',
generatorURL: 'generatorURL2',
receivers: [],
startsAt: '2023-12-05T12:30:00Z',
status: { inhibitedBy: [], silencedBy: [], state: 'inactive' },
updatedAt: '2023-12-05T12:45:00Z',
},
// Add more test alerts as needed
];
test('should render tags and expandable row when clicked', () => {
render(<TableRowComponent tags={tags} tagsAlert={tagsAlerts} />);
expect(screen.getByText('tag1')).toBeInTheDocument();
expect(screen.getByText('tag2')).toBeInTheDocument();
});
// Add more test cases as needed
});

View File

@@ -0,0 +1,39 @@
import { Alerts } from 'types/api/alerts/getTriggered';
import { Value } from './Filter';
import { FilterAlerts } from './utils';
describe('FilterAlerts function', () => {
const alerts: Alerts[] = [
{
labels: { severity: 'critical', app: 'myApp' },
annotations: { description: 'Alert description', summary: 'Alert summary' },
state: 'active',
name: 'Alert 1',
id: 1,
endsAt: '2023-12-05T12:00:00Z',
fingerprint: 'fingerprint1',
generatorURL: 'generatorURL1',
receivers: [],
startsAt: '2023-12-05T11:00:00Z',
status: { inhibitedBy: [], silencedBy: [], state: 'active' },
updatedAt: '2023-12-05T11:30:00Z',
},
];
const selectedFilter: Value[] = [
{ value: 'severity:critical' },
{ value: 'app:myApp' },
];
it('should filter alerts based on the selected filter', () => {
const filteredAlerts = FilterAlerts(alerts, selectedFilter);
expect(filteredAlerts).toHaveLength(1);
expect(filteredAlerts[0].fingerprint).toEqual('fingerprint1');
});
it('should return all alerts when no filter is selected', () => {
const allAlerts = FilterAlerts(alerts, []);
expect(allAlerts).toHaveLength(alerts.length);
});
});

View File

@@ -0,0 +1,37 @@
import { render } from 'tests/test-utils';
import Severity from './AlertStatus';
describe('Severity component', () => {
it('should render UnProcessed tag for severity "unprocessed"', () => {
const { getByText } = render(<Severity severity="unprocessed" />);
const tagElement = getByText('UnProcessed');
expect(tagElement).toBeInTheDocument();
expect(tagElement).toHaveClass('ant-tag-green');
});
it('should render Firing tag for severity "active"', () => {
const { getByText } = render(<Severity severity="active" />);
const tagElement = getByText('Firing');
expect(tagElement).toBeInTheDocument();
expect(tagElement).toHaveClass('ant-tag-red');
});
it('should render Suppressed tag for severity "suppressed"', () => {
const { getByText } = render(<Severity severity="suppressed" />);
const tagElement = getByText('Suppressed');
expect(tagElement).toBeInTheDocument();
expect(tagElement).toHaveClass('ant-tag-red');
});
it('should render Unknown Status tag for unknown severity', () => {
const { getByText } = render(<Severity severity="unknown" />);
const tagElement = getByText('Unknown Status');
expect(tagElement).toBeInTheDocument();
expect(tagElement).toHaveClass('ant-tag-default');
});
});

View File

@@ -0,0 +1,38 @@
import { act } from 'react-dom/test-utils';
import { render, screen } from 'tests/test-utils';
import TriggeredAlerts from '.';
describe('TriggeredAlerts', () => {
test('Should render the table', async () => {
act(() => {
render(<TriggeredAlerts />);
});
const status = await screen.findByText('Status');
expect(status).toBeInTheDocument();
const alertName = await screen.findByText('Alert Name');
expect(alertName).toBeInTheDocument();
const severity = await screen.findByText('Severity');
expect(severity).toBeInTheDocument();
const tags = await screen.findByText('Tags');
expect(tags).toBeInTheDocument();
const firedSince = await screen.findByText('Firing Since');
expect(firedSince).toBeInTheDocument();
});
// test('Should render the table data in triggeredAlert', async () => {
// act(() => {
// render(<TriggeredAlerts />);
// });
// const row = await screen.findByRole('row', {
// name: /firing above 400ms alertname: above 400ms component: net\/http details: https:\/\/demo\.\.\.\. \+2 warning 11\/30\/2023 10:04:19 am/i,
// });
// expect(row).toBeInTheDocument();
// });
});

View File

@@ -0,0 +1,116 @@
import {
NumTypeQueryOperators,
QueryOperatorsMultiVal,
QueryTypes,
StringTypeQueryOperators,
ValidTypeSequence,
ValidTypeValue,
} from './tokens';
describe('ValidTypeValue', () => {
test('should return true for valid numeric values with number operators', () => {
expect(ValidTypeValue(NumTypeQueryOperators.GTE, '42')).toBe(true);
expect(ValidTypeValue(NumTypeQueryOperators.LT, '3.14')).toBe(true);
});
test('should return false for invalid numeric values with number operators', () => {
expect(ValidTypeValue(NumTypeQueryOperators.GTE, 'abc')).toBe(false);
expect(ValidTypeValue(NumTypeQueryOperators.LT, '12xyz')).toBe(false);
});
test('should return true for string values with string operators', () => {
expect(ValidTypeValue(StringTypeQueryOperators.CONTAINS, 'example')).toBe(
true,
);
expect(ValidTypeValue(StringTypeQueryOperators.NCONTAINS, 'test')).toBe(true);
});
test('should return true for any value with other operators', () => {
expect(ValidTypeValue('anything', 'whatever')).toBe(true);
expect(ValidTypeValue(QueryOperatorsMultiVal.IN, ['1', '2', '3'])).toBe(true);
});
test('should return false if value is array', () => {
expect(ValidTypeValue(NumTypeQueryOperators.GTE, ['1', '2', '3'])).toBe(
false,
);
});
});
describe('ValidTypeSequence', () => {
test('should return true for valid type sequences', () => {
expect(
ValidTypeSequence(
undefined,
QueryTypes.QUERY_KEY,
QueryTypes.CONDITIONAL_OPERATOR,
),
).toBe(true);
expect(
ValidTypeSequence(
QueryTypes.QUERY_KEY,
QueryTypes.QUERY_OPERATOR,
QueryTypes.QUERY_VALUE,
),
).toBe(true);
expect(
ValidTypeSequence(
QueryTypes.QUERY_OPERATOR,
QueryTypes.QUERY_VALUE,
undefined,
),
).toBe(true);
});
test('should return false for invalid type sequences', () => {
expect(
ValidTypeSequence(
undefined,
QueryTypes.QUERY_OPERATOR,
QueryTypes.QUERY_VALUE,
),
).toBe(false);
expect(
ValidTypeSequence(
QueryTypes.QUERY_KEY,
QueryTypes.QUERY_VALUE,
QueryTypes.QUERY_OPERATOR,
),
).toBe(false);
expect(
ValidTypeSequence(
QueryTypes.QUERY_OPERATOR,
QueryTypes.QUERY_KEY,
QueryTypes.QUERY_VALUE,
),
).toBe(false);
expect(
ValidTypeSequence(
QueryTypes.QUERY_VALUE,
QueryTypes.QUERY_OPERATOR,
undefined,
),
).toBe(false);
expect(
ValidTypeSequence(
QueryTypes.CONDITIONAL_OPERATOR,
QueryTypes.QUERY_OPERATOR,
QueryTypes.QUERY_KEY,
),
).toBe(false);
expect(
ValidTypeSequence(
QueryTypes.CONDITIONAL_OPERATOR,
undefined,
QueryTypes.QUERY_KEY,
),
).toBe(false);
expect(
ValidTypeSequence(
QueryTypes.QUERY_KEY,
QueryTypes.CONDITIONAL_OPERATOR,
undefined,
),
).toBe(false);
});
});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,163 @@
export const rulesSuccessResponse = {
status: 'success',
data: {
rules: [
{
id: '5',
state: 'disabled',
alert: 'Test Rule 1',
alertType: 'LOGS_BASED_ALERT',
ruleType: 'threshold_rule',
evalWindow: '1h0m0s',
frequency: '1m0s',
condition: {
compositeQuery: {
builderQueries: {
A: {
queryName: 'A',
stepInterval: 60,
dataSource: 'metrics',
aggregateOperator: 'noop',
aggregateAttribute: {
key: '',
dataType: 'float64',
type: '',
isColumn: true,
isJSON: false,
},
filters: {
op: 'AND',
items: null,
},
expression: 'A',
disabled: false,
limit: 0,
offset: 0,
pageSize: 0,
reduceTo: 'last',
},
},
chQueries: {
A: {
query:
'select \ntoStartOfInterval(fromUnixTimestamp64Nano(timestamp), INTERVAL 1 MINUTE) AS interval, \ntoFloat64(count()) as value \nFROM signoz_logs.distributed_logs \nWHERE timestamp BETWEEN {{.start_timestamp_nano}} AND {{.end_timestamp_nano}}\n\nGROUP BY interval;\n\n-- available variables:\n-- \t{{.start_timestamp_nano}}\n-- \t{{.end_timestamp_nano}}\n\n-- required columns (or alias):\n-- \tvalue\n-- \tinterval',
disabled: false,
},
},
promQueries: {
A: {
query: '',
disabled: false,
},
},
panelType: 'graph',
queryType: 'clickhouse_sql',
},
op: '1',
target: 2000,
matchType: '1',
},
labels: {
details: 'https://stagingapp.signoz.io/logs',
hello: 'world',
region: 'us',
severity: 'warning',
type: 'test',
},
annotations: {
description: 'description',
summary: 'summary',
},
disabled: true,
source:
'https://stagingapp.signoz.io/alerts/edit?ruleId=5\u0026compositeQuery=%7B%22builder%22%3A%7B%22queryData%22%3A%5B%7B%22dataSource%22%3A%22metrics%22%2C%22queryName%22%3A%22A%22%2C%22aggregateOperator%22%3A%22noop%22%2C%22aggregateAttribute%22%3A%7B%22key%22%3A%22%22%2C%22dataType%22%3A%22float64%22%2C%22type%22%3A%22%22%2C%22isColumn%22%3Atrue%2C%22isJSON%22%3Afalse%7D%2C%22filters%22%3A%7B%22op%22%3A%22AND%22%2C%22items%22%3Anull%7D%2C%22expression%22%3A%22A%22%2C%22disabled%22%3Afalse%2C%22having%22%3A%5B%5D%2C%22stepInterval%22%3A60%2C%22limit%22%3A0%2C%22orderBy%22%3A%5B%5D%2C%22groupBy%22%3A%5B%5D%2C%22legend%22%3A%22%22%2C%22reduceTo%22%3A%22last%22%2C%22offset%22%3A0%2C%22pageSize%22%3A0%7D%5D%2C%22queryFormulas%22%3A%5B%5D%7D%2C%22promql%22%3A%5B%7B%22query%22%3A%22%22%2C%22disabled%22%3Afalse%2C%22name%22%3A%22A%22%7D%5D%2C%22clickhouse_sql%22%3A%5B%7B%22query%22%3A%22select%20%5CntoStartOfInterval(fromUnixTimestamp64Nano(timestamp)%2C%20INTERVAL%201%20MINUTE)%20AS%20interval%2C%20%5CntoFloat64(count())%20as%20value%20%5CnFROM%20signoz_logs.distributed_logs%20%20%5CnWHERE%20timestamp%20BETWEEN%20%7B%7B.start_timestamp_nano%7D%7D%20AND%20%7B%7B.end_timestamp_nano%7D%7D%5Cn%5CnGROUP%20BY%20interval%3B%5Cn%5Cn--%20available%20variables%3A%5Cn--%20%5Ct%7B%7B.start_timestamp_nano%7D%7D%5Cn--%20%5Ct%7B%7B.end_timestamp_nano%7D%7D%5Cn%5Cn--%20required%20columns%20(or%20alias)%3A%5Cn--%20%5Ctvalue%5Cn--%20%5Ctinterval%22%2C%22disabled%22%3Afalse%2C%22name%22%3A%22A%22%7D%5D%2C%22queryType%22%3A%22clickhouse_sql%22%2C%22id%22%3A%22f17cf0cd-f479-4452-aded-e426aeda45ff%22%7D',
preferredChannels: ['webhook-site'],
createAt: null,
createBy: null,
updateAt: '2023-10-27T14:03:49.79371099Z',
updateBy: 'ankit@signoz.io',
},
{
id: '6',
state: 'inactive',
alert: 'Test Rule 2',
alertType: 'METRIC_BASED_ALERT',
ruleType: 'threshold_rule',
evalWindow: '5m0s',
frequency: '1m0s',
condition: {
compositeQuery: {
builderQueries: {
A: {
queryName: 'A',
stepInterval: 60,
dataSource: 'metrics',
aggregateOperator: 'sum_rate',
aggregateAttribute: {
key: 'signoz_calls_total',
dataType: 'float64',
type: '',
isColumn: true,
isJSON: false,
},
filters: {
op: 'AND',
items: [],
},
groupBy: [
{
key: 'service_name',
dataType: 'string',
type: 'tag',
isColumn: false,
isJSON: false,
},
],
expression: 'A',
disabled: false,
limit: 0,
offset: 0,
pageSize: 0,
reduceTo: 'sum',
},
},
chQueries: {
A: {
query: '',
disabled: false,
},
},
promQueries: {
A: {
query: '',
disabled: false,
},
},
panelType: 'graph',
queryType: 'builder',
},
op: '1',
target: 20,
matchType: '1',
},
labels: {
severity: 'warning',
},
annotations: {
description:
'This alert is fired when the defined metric (current value: {{$value}}) crosses the threshold ({{$threshold}})',
summary:
'The rule threshold is set to {{$threshold}}, and the observed metric value is {{$value}}',
},
disabled: false,
source:
'http://localhost:3301/alerts/edit?ruleId=6\u0026compositeQuery=%7B%22builder%22%3A%7B%22queryData%22%3A%5B%7B%22dataSource%22%3A%22metrics%22%2C%22queryName%22%3A%22A%22%2C%22aggregateOperator%22%3A%22sum_rate%22%2C%22aggregateAttribute%22%3A%7B%22key%22%3A%22signoz_calls_total%22%2C%22dataType%22%3A%22float64%22%2C%22type%22%3A%22%22%2C%22isColumn%22%3Atrue%7D%2C%22filters%22%3A%7B%22op%22%3A%22AND%22%2C%22items%22%3A%5B%5D%7D%2C%22expression%22%3A%22A%22%2C%22disabled%22%3Afalse%2C%22having%22%3A%5B%5D%2C%22stepInterval%22%3A60%2C%22limit%22%3A0%2C%22orderBy%22%3A%5B%5D%2C%22groupBy%22%3A%5B%7B%22key%22%3A%22service_name%22%2C%22dataType%22%3A%22string%22%2C%22type%22%3A%22tag%22%2C%22isColumn%22%3Afalse%7D%5D%2C%22legend%22%3A%22%22%2C%22reduceTo%22%3A%22sum%22%2C%22offset%22%3A0%2C%22pageSize%22%3A0%7D%5D%2C%22queryFormulas%22%3A%5B%5D%7D%2C%22promql%22%3A%5B%7B%22query%22%3A%22%22%2C%22disabled%22%3Afalse%2C%22name%22%3A%22A%22%7D%5D%2C%22clickhouse_sql%22%3A%5B%7B%22query%22%3A%22%22%2C%22disabled%22%3Afalse%2C%22name%22%3A%22A%22%7D%5D%2C%22queryType%22%3A%22builder%22%2C%22id%22%3A%22c6486149-69b9-4e75-92ab-dde3282e558f%22%7D',
preferredChannels: ['Slack-Discord-Compatible', 'Discord-webhook'],
createAt: null,
createBy: null,
updateAt: '2023-10-06T09:48:07.047188664Z',
updateBy: null,
},
],
},
};

View File

@@ -1,8 +1,10 @@
import { rest } from 'msw';
import { alertsSuccessResponse } from './__mockdata__/alerts';
import { billingSuccessResponse } from './__mockdata__/billing';
import { licensesSuccessResponse } from './__mockdata__/licenses';
import { queryRangeSuccessResponse } from './__mockdata__/query_range';
import { rulesSuccessResponse } from './__mockdata__/rules';
import { serviceSuccessResponse } from './__mockdata__/services';
import { topLevelOperationSuccessResponse } from './__mockdata__/top_level_operations';
@@ -81,4 +83,12 @@ export const handlers = [
rest.get('http://localhost/api/v1/billing', (req, res, ctx) =>
res(ctx.status(200), ctx.json(billingSuccessResponse)),
),
rest.get('http://localhost/api/v1/rules', (req, res, ctx) =>
res(ctx.status(200), ctx.json(rulesSuccessResponse)),
),
rest.get('http://localhost/api/v1/alerts', (req, res, ctx) =>
res(ctx.status(200), ctx.json(alertsSuccessResponse)),
),
];