metricIssueChart.spec.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import {EventFixture} from 'sentry-fixture/event';
  2. import {EventsStatsFixture} from 'sentry-fixture/events';
  3. import {GroupFixture} from 'sentry-fixture/group';
  4. import {IncidentFixture} from 'sentry-fixture/incident';
  5. import {MetricRuleFixture} from 'sentry-fixture/metricRule';
  6. import {OrganizationFixture} from 'sentry-fixture/organization';
  7. import {ProjectFixture} from 'sentry-fixture/project';
  8. import {SessionsFieldFixture} from 'sentry-fixture/sessions';
  9. import {render, screen} from 'sentry-test/reactTestingLibrary';
  10. import {IssueCategory, IssueType} from 'sentry/types/group';
  11. import {Dataset, SessionsAggregate} from 'sentry/views/alerts/rules/metric/types';
  12. import {MetricIssueChart} from 'sentry/views/issueDetails/metricIssues/metricIssueChart';
  13. describe('MetricIssueChart', () => {
  14. const organization = OrganizationFixture();
  15. const project = ProjectFixture({organization});
  16. const rule = MetricRuleFixture({projects: [project.slug]});
  17. const incident = IncidentFixture({alertRule: rule});
  18. const group = GroupFixture({
  19. project,
  20. issueCategory: IssueCategory.METRIC_ALERT,
  21. issueType: IssueType.METRIC_ISSUE_POC,
  22. });
  23. const event = EventFixture({
  24. contexts: {
  25. metric_alert: {
  26. alert_rule_id: rule.id,
  27. },
  28. },
  29. });
  30. let mockIncidents: jest.Mock;
  31. beforeEach(() => {
  32. MockApiClient.clearMockResponses();
  33. MockApiClient.addMockResponse({
  34. url: `/organizations/${organization.slug}/issues/${group.id}/events/recommended/`,
  35. body: event,
  36. });
  37. mockIncidents = MockApiClient.addMockResponse({
  38. url: `/organizations/${organization.slug}/incidents/`,
  39. body: [incident],
  40. });
  41. });
  42. it('renders the metric issue chart', async function () {
  43. const mockRule = MockApiClient.addMockResponse({
  44. url: `/organizations/${organization.slug}/alert-rules/${rule.id}/`,
  45. body: rule,
  46. query: {
  47. expand: 'latestIncident',
  48. },
  49. });
  50. const mockStats = MockApiClient.addMockResponse({
  51. url: `/organizations/${organization.slug}/events-stats/`,
  52. body: EventsStatsFixture(),
  53. });
  54. render(<MetricIssueChart group={group} project={project} />, {organization});
  55. await screen.findByTestId('metric-issue-chart-loading');
  56. expect(await screen.findByRole('figure')).toBeInTheDocument();
  57. expect(mockRule).toHaveBeenCalled();
  58. expect(mockIncidents).toHaveBeenCalled();
  59. expect(mockStats).toHaveBeenCalledWith(
  60. expect.anything(),
  61. expect.objectContaining({
  62. query: expect.objectContaining({
  63. project: [parseInt(project.id, 10)],
  64. query: 'event.type:error',
  65. referrer: 'metric-issue-chart',
  66. yAxis: rule.aggregate,
  67. }),
  68. })
  69. );
  70. });
  71. it('displays error messages from bad queries', async function () {
  72. const mockRule = MockApiClient.addMockResponse({
  73. url: `/organizations/${organization.slug}/alert-rules/${rule.id}/`,
  74. body: rule,
  75. query: {
  76. expand: 'latestIncident',
  77. },
  78. });
  79. const mockStats = MockApiClient.addMockResponse({
  80. url: `/organizations/${organization.slug}/events-stats/`,
  81. body: {detail: 'timeout'},
  82. statusCode: 500,
  83. });
  84. render(<MetricIssueChart group={group} project={project} />, {organization});
  85. await screen.findByTestId('metric-issue-chart-error');
  86. expect(mockRule).toHaveBeenCalled();
  87. expect(mockIncidents).toHaveBeenCalled();
  88. expect(mockStats).toHaveBeenCalled();
  89. expect(screen.getByText('Unable to load the metric history')).toBeInTheDocument();
  90. expect(screen.queryByRole('figure')).not.toBeInTheDocument();
  91. });
  92. it('renders the metric issue chart with session data', async function () {
  93. const mockRule = MockApiClient.addMockResponse({
  94. url: `/organizations/${organization.slug}/alert-rules/${rule.id}/`,
  95. body: {
  96. ...rule,
  97. dataset: Dataset.SESSIONS,
  98. aggregate: SessionsAggregate.CRASH_FREE_SESSIONS,
  99. query: 'event.type:error',
  100. },
  101. query: {
  102. expand: 'latestIncident',
  103. },
  104. });
  105. const mockSessionStats = MockApiClient.addMockResponse({
  106. url: `/organizations/${organization.slug}/sessions/`,
  107. body: SessionsFieldFixture('sum(session)'),
  108. });
  109. render(<MetricIssueChart group={group} project={project} />, {organization});
  110. await screen.findByTestId('metric-issue-chart-loading');
  111. expect(await screen.findByRole('figure')).toBeInTheDocument();
  112. expect(mockRule).toHaveBeenCalled();
  113. expect(mockIncidents).toHaveBeenCalled();
  114. expect(mockSessionStats).toHaveBeenCalledWith(
  115. expect.anything(),
  116. expect.objectContaining({
  117. query: expect.objectContaining({
  118. project: [parseInt(project.id, 10)],
  119. field: 'sum(session)',
  120. groupBy: ['session.status'],
  121. }),
  122. })
  123. );
  124. });
  125. });