import {EventFixture} from 'sentry-fixture/event';
import {EventsStatsFixture} from 'sentry-fixture/events';
import {GroupFixture} from 'sentry-fixture/group';
import {IncidentFixture} from 'sentry-fixture/incident';
import {MetricRuleFixture} from 'sentry-fixture/metricRule';
import {OrganizationFixture} from 'sentry-fixture/organization';
import {ProjectFixture} from 'sentry-fixture/project';
import {SessionsFieldFixture} from 'sentry-fixture/sessions';
import {render, screen} from 'sentry-test/reactTestingLibrary';
import {IssueCategory, IssueType} from 'sentry/types/group';
import {Dataset, SessionsAggregate} from 'sentry/views/alerts/rules/metric/types';
import {MetricIssueChart} from 'sentry/views/issueDetails/metricIssues/metricIssueChart';
describe('MetricIssueChart', () => {
const organization = OrganizationFixture();
const project = ProjectFixture({organization});
const rule = MetricRuleFixture({projects: [project.slug]});
const incident = IncidentFixture({alertRule: rule});
const group = GroupFixture({
project,
issueCategory: IssueCategory.METRIC_ALERT,
issueType: IssueType.METRIC_ISSUE_POC,
});
const event = EventFixture({
contexts: {
metric_alert: {
alert_rule_id: rule.id,
},
},
});
let mockIncidents: jest.Mock;
beforeEach(() => {
MockApiClient.clearMockResponses();
MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/issues/${group.id}/events/recommended/`,
body: event,
});
mockIncidents = MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/incidents/`,
body: [incident],
});
});
it('renders the metric issue chart', async function () {
const mockRule = MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/alert-rules/${rule.id}/`,
body: rule,
query: {
expand: 'latestIncident',
},
});
const mockStats = MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/events-stats/`,
body: EventsStatsFixture(),
});
render(, {organization});
await screen.findByTestId('metric-issue-chart-loading');
expect(await screen.findByRole('figure')).toBeInTheDocument();
expect(mockRule).toHaveBeenCalled();
expect(mockIncidents).toHaveBeenCalled();
expect(mockStats).toHaveBeenCalledWith(
expect.anything(),
expect.objectContaining({
query: expect.objectContaining({
project: [parseInt(project.id, 10)],
query: 'event.type:error',
referrer: 'metric-issue-chart',
yAxis: rule.aggregate,
}),
})
);
});
it('displays error messages from bad queries', async function () {
const mockRule = MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/alert-rules/${rule.id}/`,
body: rule,
query: {
expand: 'latestIncident',
},
});
const mockStats = MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/events-stats/`,
body: {detail: 'timeout'},
statusCode: 500,
});
render(, {organization});
await screen.findByTestId('metric-issue-chart-error');
expect(mockRule).toHaveBeenCalled();
expect(mockIncidents).toHaveBeenCalled();
expect(mockStats).toHaveBeenCalled();
expect(screen.getByText('Unable to load the metric history')).toBeInTheDocument();
expect(screen.queryByRole('figure')).not.toBeInTheDocument();
});
it('renders the metric issue chart with session data', async function () {
const mockRule = MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/alert-rules/${rule.id}/`,
body: {
...rule,
dataset: Dataset.SESSIONS,
aggregate: SessionsAggregate.CRASH_FREE_SESSIONS,
query: 'event.type:error',
},
query: {
expand: 'latestIncident',
},
});
const mockSessionStats = MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/sessions/`,
body: SessionsFieldFixture('sum(session)'),
});
render(, {organization});
await screen.findByTestId('metric-issue-chart-loading');
expect(await screen.findByRole('figure')).toBeInTheDocument();
expect(mockRule).toHaveBeenCalled();
expect(mockIncidents).toHaveBeenCalled();
expect(mockSessionStats).toHaveBeenCalledWith(
expect.anything(),
expect.objectContaining({
query: expect.objectContaining({
project: [parseInt(project.id, 10)],
field: 'sum(session)',
groupBy: ['session.status'],
}),
})
);
});
});