eventDetailsHeader.spec.tsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import {EventFixture} from 'sentry-fixture/event';
  2. import {EventsStatsFixture} from 'sentry-fixture/events';
  3. import {GroupFixture} from 'sentry-fixture/group';
  4. import {LocationFixture} from 'sentry-fixture/locationFixture';
  5. import {OrganizationFixture} from 'sentry-fixture/organization';
  6. import {ProjectFixture} from 'sentry-fixture/project';
  7. import {RouterFixture} from 'sentry-fixture/routerFixture';
  8. import {TagsFixture} from 'sentry-fixture/tags';
  9. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  10. import PageFiltersStore from 'sentry/stores/pageFiltersStore';
  11. import ProjectsStore from 'sentry/stores/projectsStore';
  12. import {IssueCategory, IssueType} from 'sentry/types/group';
  13. import {EventDetailsHeader} from './eventDetailsHeader';
  14. const mockUseNavigate = jest.fn();
  15. jest.mock('sentry/utils/useNavigate', () => ({
  16. useNavigate: () => mockUseNavigate,
  17. }));
  18. describe('EventDetailsHeader', () => {
  19. const organization = OrganizationFixture();
  20. const project = ProjectFixture({
  21. environments: ['production', 'staging', 'development'],
  22. });
  23. const group = GroupFixture();
  24. const event = EventFixture({id: 'event-id'});
  25. const defaultProps = {group, event, project};
  26. const router = RouterFixture({
  27. location: LocationFixture({query: {streamline: '1'}}),
  28. });
  29. beforeEach(() => {
  30. MockApiClient.clearMockResponses();
  31. MockApiClient.addMockResponse({
  32. url: '/organizations/org-slug/flags/logs/',
  33. body: {data: []},
  34. });
  35. MockApiClient.addMockResponse({
  36. url: `/organizations/${organization.slug}/issues/${group.id}/tags/`,
  37. body: TagsFixture(),
  38. method: 'GET',
  39. });
  40. MockApiClient.addMockResponse({
  41. url: `/organizations/${organization.slug}/releases/stats/`,
  42. body: [],
  43. });
  44. PageFiltersStore.init();
  45. PageFiltersStore.onInitializeUrlState(
  46. {
  47. projects: [],
  48. environments: [],
  49. datetime: {start: null, end: null, period: '14d', utc: null},
  50. },
  51. new Set(['environments'])
  52. );
  53. ProjectsStore.loadInitialData([project]);
  54. MockApiClient.addMockResponse({
  55. url: '/projects/org-slug/project-slug/',
  56. body: [project],
  57. });
  58. MockApiClient.addMockResponse({
  59. url: `/organizations/${organization.slug}/events-stats/`,
  60. body: {'count()': EventsStatsFixture(), 'count_unique(user)': EventsStatsFixture()},
  61. method: 'GET',
  62. });
  63. MockApiClient.addMockResponse({
  64. url: `/organizations/${organization.slug}/events/`,
  65. body: {data: [{'count_unique(user)': 21}]},
  66. });
  67. });
  68. it('renders filters alongside the graph', async function () {
  69. render(<EventDetailsHeader {...defaultProps} />, {organization, router});
  70. expect(await screen.findByTestId('event-graph-loading')).not.toBeInTheDocument();
  71. expect(screen.getByRole('button', {name: 'All Envs'})).toBeInTheDocument();
  72. expect(screen.getByRole('button', {name: '14D'})).toBeInTheDocument();
  73. expect(screen.getByPlaceholderText('Filter events\u2026')).toBeInTheDocument();
  74. expect(
  75. screen.getByRole('button', {
  76. name: 'Toggle graph series - Events',
  77. })
  78. ).toBeInTheDocument();
  79. expect(
  80. screen.getByRole('button', {name: 'Toggle graph series - Users'})
  81. ).toBeInTheDocument();
  82. expect(screen.getByRole('figure')).toBeInTheDocument();
  83. expect(screen.getByRole('button', {name: 'Close sidebar'})).toBeInTheDocument();
  84. });
  85. it('updates the query params with search tokens', async function () {
  86. const [tagKey, tagValue] = ['user.email', 'leander.rodrigues@sentry.io'];
  87. const locationQuery = {
  88. query: {
  89. ...router.location.query,
  90. query: `${tagKey}:${tagValue}`,
  91. },
  92. };
  93. MockApiClient.addMockResponse({
  94. url: `/organizations/${organization.slug}/tags/${tagKey}/values/`,
  95. body: [
  96. {
  97. key: tagKey,
  98. name: tagValue,
  99. value: tagValue,
  100. },
  101. ],
  102. method: 'GET',
  103. });
  104. render(<EventDetailsHeader {...defaultProps} />, {organization, router});
  105. expect(await screen.findByTestId('event-graph-loading')).not.toBeInTheDocument();
  106. const search = screen.getByPlaceholderText('Filter events\u2026');
  107. await userEvent.type(search, `${tagKey}:`);
  108. await userEvent.keyboard(`${tagValue}{enter}{enter}`);
  109. expect(mockUseNavigate).toHaveBeenCalledWith(expect.objectContaining(locationQuery), {
  110. replace: true,
  111. });
  112. });
  113. it('does not render timeline summary if disabled', async function () {
  114. render(<EventDetailsHeader {...defaultProps} />, {organization, router});
  115. expect(await screen.findByTestId('event-graph-loading')).not.toBeInTheDocument();
  116. expect(screen.queryByText('Duration')).not.toBeInTheDocument();
  117. });
  118. it('renders timeline summary if enabled', async function () {
  119. render(
  120. <EventDetailsHeader
  121. {...defaultProps}
  122. group={GroupFixture({
  123. issueCategory: IssueCategory.UPTIME,
  124. issueType: IssueType.UPTIME_DOMAIN_FAILURE,
  125. })}
  126. />,
  127. {organization, router}
  128. );
  129. expect(await screen.findByTestId('event-graph-loading')).not.toBeInTheDocument();
  130. expect(screen.getByText('Duration')).toBeInTheDocument();
  131. });
  132. });