spikeProtectionHistoryTable.spec.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {ProjectFixture} from 'sentry-fixture/project';
  3. import {SubscriptionFixture} from 'getsentry-test/fixtures/subscription';
  4. import {initializeOrg} from 'sentry-test/initializeOrg';
  5. import {cleanup, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  6. import {DATA_CATEGORY_INFO} from 'sentry/constants';
  7. import {DataCategoryExact} from 'sentry/types/core';
  8. import SubscriptionStore from 'getsentry/stores/subscriptionStore';
  9. import SpikeProtectionHistoryTable from 'getsentry/views/spikeProtection/spikeProtectionHistoryTable';
  10. import type {SpikeDetails} from 'getsentry/views/spikeProtection/types';
  11. import {SPIKE_PROTECTION_OPTION_DISABLED} from './constants';
  12. describe('SpikeProtectionHistoryTable', () => {
  13. const {router, organization} = initializeOrg({
  14. organization: OrganizationFixture({
  15. features: ['discover-basic'],
  16. }),
  17. });
  18. const subscription = SubscriptionFixture({organization});
  19. const project = ProjectFixture();
  20. const dataCategoryInfo = DATA_CATEGORY_INFO[DataCategoryExact.ERROR];
  21. let mockPost: any;
  22. beforeEach(() => {
  23. project.options = {[SPIKE_PROTECTION_OPTION_DISABLED]: false};
  24. SubscriptionStore.set(organization.slug, subscription);
  25. mockPost = MockApiClient.addMockResponse({
  26. url: `/organizations/${organization.slug}/spike-protections/`,
  27. method: 'POST',
  28. body: [],
  29. statusCode: 200,
  30. });
  31. });
  32. afterEach(() => {
  33. cleanup();
  34. });
  35. it('renders an empty state when no spikes are provided', async () => {
  36. render(
  37. <SpikeProtectionHistoryTable
  38. spikes={[]}
  39. dataCategoryInfo={dataCategoryInfo}
  40. project={project}
  41. onEnableSpikeProtection={() => {}}
  42. />,
  43. {router, organization}
  44. );
  45. const emptyState = await screen.findByTestId('spike-history-empty');
  46. expect(emptyState).toBeInTheDocument();
  47. const emptyMessage = screen.getByText(/No Significant Spikes/);
  48. expect(emptyMessage).toBeInTheDocument();
  49. });
  50. it("renders a disabled state for projects that aren't enabled", async () => {
  51. project.options![SPIKE_PROTECTION_OPTION_DISABLED] = true;
  52. const onEnableFunction = jest.fn();
  53. render(
  54. <SpikeProtectionHistoryTable
  55. spikes={[]}
  56. dataCategoryInfo={dataCategoryInfo}
  57. project={project}
  58. onEnableSpikeProtection={onEnableFunction}
  59. />,
  60. {router, organization}
  61. );
  62. const disabledState = screen.getByTestId('spike-history-disabled');
  63. expect(disabledState).toBeInTheDocument();
  64. const disabledMessage = screen.getByText(/Spike Protection Disabled/);
  65. expect(disabledMessage).toBeInTheDocument();
  66. expect(onEnableFunction).not.toHaveBeenCalled();
  67. const enableButton = screen.getByTestId('enable-sp-button');
  68. await userEvent.click(enableButton);
  69. expect(mockPost).toHaveBeenCalledWith(
  70. expect.anything(),
  71. expect.objectContaining({data: {projects: [project.slug]}})
  72. );
  73. expect(onEnableFunction).toHaveBeenCalled();
  74. });
  75. it('renders when spikes are provided', async () => {
  76. const spikes: SpikeDetails[] = [
  77. {
  78. start: new Date(2022, 0, 1, 0, 0, 0, 0).toISOString(),
  79. end: new Date(2022, 0, 15, 0, 0, 0, 0).toISOString(),
  80. threshold: 1250000,
  81. dropped: 500000,
  82. dataCategory: dataCategoryInfo.name,
  83. },
  84. ];
  85. render(
  86. <SpikeProtectionHistoryTable
  87. spikes={spikes}
  88. dataCategoryInfo={dataCategoryInfo}
  89. project={project}
  90. onEnableSpikeProtection={() => {}}
  91. />,
  92. {router, organization}
  93. );
  94. await screen.findByTestId('spike-protection-history-table');
  95. screen.getByText('2wk');
  96. screen.getByText('1.3M');
  97. screen.getByText('500K');
  98. const headers = screen.getAllByTestId('table-header');
  99. expect(headers).toHaveLength(5);
  100. const discoverLink = screen.getByTestId('spike-protection-discover-button');
  101. expect(discoverLink).toHaveTextContent(/Discover/);
  102. await userEvent.click(discoverLink);
  103. expect(router.push).toHaveBeenCalledWith(
  104. expect.objectContaining({
  105. pathname: expect.stringContaining('discover/homepage'),
  106. query: expect.objectContaining({
  107. project: project.id,
  108. start: expect.stringContaining('2022-01-01'),
  109. end: expect.stringContaining('2022-01-15'),
  110. }),
  111. })
  112. );
  113. });
  114. it('renders ongoing stored spike', async () => {
  115. const storedSpikes: SpikeDetails[] = [
  116. {
  117. start: new Date(2022, 0, 2, 6, 0, 0, 0).toISOString(),
  118. end: undefined,
  119. threshold: 200000,
  120. dropped: undefined,
  121. dataCategory: dataCategoryInfo.name,
  122. },
  123. ];
  124. render(
  125. <SpikeProtectionHistoryTable
  126. spikes={storedSpikes}
  127. dataCategoryInfo={dataCategoryInfo}
  128. project={project}
  129. onEnableSpikeProtection={() => {}}
  130. />,
  131. {router, organization}
  132. );
  133. await screen.findByTestId('spike-protection-history-table');
  134. screen.getByText('Ongoing');
  135. screen.getByText('200K');
  136. screen.getByText('Jan 2nd 2022 - present');
  137. });
  138. });