teamMisery.spec.jsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import range from 'lodash/range';
  2. import {
  3. render,
  4. screen,
  5. userEvent,
  6. waitForElementToBeRemoved,
  7. } from 'sentry-test/reactTestingLibrary';
  8. import TeamMisery from 'sentry/views/organizationStats/teamInsights/teamMisery';
  9. describe('TeamMisery', () => {
  10. it('should render misery from projects and expand hidden items', async () => {
  11. const project = TestStubs.Project();
  12. const meta = {
  13. fields: {
  14. transaction: 'string',
  15. project: 'string',
  16. tpm: 'number',
  17. 'count_unique(user)': 'number',
  18. 'count_miserable(user)': 'number',
  19. 'user_misery()': 'number',
  20. },
  21. };
  22. const extraData = {
  23. project: project.slug,
  24. tpm: 30,
  25. count_unique_user: 1000,
  26. count_miserable_user: 122,
  27. project_threshold_config: ['duration', 300],
  28. };
  29. const noChangeItems = 10;
  30. const noChange = range(0, noChangeItems).map(x => ({
  31. transaction: `/apple/${x}`,
  32. 'user_misery()': 0.1,
  33. ...extraData,
  34. }));
  35. const weekMisery = MockApiClient.addMockResponse({
  36. url: `/organizations/org-slug/events/`,
  37. body: {
  38. meta,
  39. data: [
  40. {
  41. transaction: '/apple/cart',
  42. 'user_misery()': 0.5,
  43. ...extraData,
  44. },
  45. {
  46. transaction: '/apple/checkout',
  47. 'user_misery()': 0.1,
  48. ...extraData,
  49. },
  50. ...noChange,
  51. ],
  52. },
  53. match: [MockApiClient.matchQuery({statsPeriod: '7d'})],
  54. });
  55. const periodMisery = MockApiClient.addMockResponse({
  56. url: `/organizations/org-slug/events/`,
  57. body: {
  58. meta,
  59. data: [
  60. {
  61. transaction: '/apple/cart',
  62. 'user_misery()': 0.25,
  63. ...extraData,
  64. },
  65. {
  66. transaction: '/apple/checkout',
  67. 'user_misery()': 0.2,
  68. ...extraData,
  69. },
  70. ...noChange,
  71. ],
  72. },
  73. match: [MockApiClient.matchQuery({statsPeriod: '8w'})],
  74. });
  75. render(
  76. <TeamMisery
  77. organization={TestStubs.Organization()}
  78. projects={[project]}
  79. period="8w"
  80. location={location}
  81. />
  82. );
  83. await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator'));
  84. expect(weekMisery).toHaveBeenCalledTimes(1);
  85. expect(periodMisery).toHaveBeenCalledTimes(1);
  86. // Should have 8 items, the rest are collapsed.
  87. expect(screen.getAllByText(project.slug)).toHaveLength(5);
  88. expect(screen.getByText('10% better')).toBeInTheDocument();
  89. expect(screen.getByText('25% worse')).toBeInTheDocument();
  90. expect(screen.getAllByText('0% change')).toHaveLength(3);
  91. expect(screen.getByText('More')).toBeInTheDocument();
  92. userEvent.click(screen.getByText('More'));
  93. expect(screen.getAllByText('0% change')).toHaveLength(noChangeItems);
  94. });
  95. it('should render empty state', () => {
  96. render(
  97. <TeamMisery
  98. organization={TestStubs.Organization()}
  99. projects={[]}
  100. period="8w"
  101. location={location}
  102. />
  103. );
  104. expect(
  105. screen.getByText('No key transactions starred by this team')
  106. ).toBeInTheDocument();
  107. });
  108. it('should render empty state on error', async () => {
  109. MockApiClient.addMockResponse({
  110. url: `/organizations/org-slug/events/`,
  111. statusCode: 500,
  112. body: {},
  113. });
  114. render(
  115. <TeamMisery
  116. organization={TestStubs.Organization()}
  117. projects={[TestStubs.Project()]}
  118. period="8w"
  119. location={location}
  120. />
  121. );
  122. await waitForElementToBeRemoved(screen.queryByTestId('loading-indicator'));
  123. expect(screen.getByText('There was an error loading data.')).toBeInTheDocument();
  124. });
  125. });