details.spec.tsx 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {BillingConfigFixture} from 'getsentry-test/fixtures/billingConfig';
  3. import {SubscriptionFixture} from 'getsentry-test/fixtures/subscription';
  4. import {act, render, screen} from 'sentry-test/reactTestingLibrary';
  5. import Details from 'getsentry/components/upsellModal/details';
  6. import {PlanTier} from 'getsentry/types';
  7. describe('Upsell Modal Details', function () {
  8. const organization = OrganizationFixture({access: ['org:billing']});
  9. const subscription = SubscriptionFixture({organization, plan: 'am1_f'});
  10. const billingConfig = BillingConfigFixture(PlanTier.AM2);
  11. beforeEach(function () {
  12. MockApiClient.clearMockResponses();
  13. MockApiClient.addMockResponse({
  14. url: `/subscriptions/${organization.slug}/`,
  15. method: 'GET',
  16. body: subscription,
  17. });
  18. MockApiClient.addMockResponse({
  19. url: `/customers/${organization.slug}/billing-config/`,
  20. query: {tier: 'am2'},
  21. body: billingConfig,
  22. });
  23. });
  24. it('renders', async function () {
  25. const sub = SubscriptionFixture({
  26. organization,
  27. plan: 'am1_f',
  28. canTrial: true,
  29. isTrial: false,
  30. isFree: true,
  31. });
  32. render(
  33. <Details
  34. source="test"
  35. subscription={sub}
  36. organization={organization}
  37. onCloseModal={jest.fn()}
  38. />
  39. );
  40. // framer-motion causes 2 of these to exist
  41. expect(await screen.findByTestId('default-messaging')).toBeInTheDocument();
  42. expect(screen.queryByTestId('highlighted-feature')).not.toBeInTheDocument();
  43. expect(screen.getByRole('button', {name: 'Upgrade now'})).toBeInTheDocument();
  44. });
  45. it('renders team features with subscription trial plan', async function () {
  46. const sub = SubscriptionFixture({
  47. organization,
  48. plan: 'am1_t',
  49. canTrial: false,
  50. isTrial: true,
  51. isFree: false,
  52. });
  53. render(
  54. <Details
  55. source="event-volume"
  56. subscription={sub}
  57. organization={organization}
  58. onCloseModal={jest.fn()}
  59. />
  60. );
  61. expect(await screen.findByText('Features Include')).toBeInTheDocument();
  62. // Check that the source feature is highlighted.
  63. expect(screen.getByTestId('extended-data-retention')).not.toHaveAttribute(
  64. 'aria-selected'
  65. );
  66. expect(screen.getByTestId('event-volume')).toHaveAttribute('aria-selected');
  67. });
  68. it('renders team features with free plan', async function () {
  69. const sub = SubscriptionFixture({
  70. organization,
  71. plan: 'am1_f',
  72. canTrial: true,
  73. isTrial: false,
  74. isFree: true,
  75. });
  76. render(
  77. <Details
  78. source="event-volume"
  79. subscription={sub}
  80. organization={organization}
  81. onCloseModal={jest.fn()}
  82. />
  83. );
  84. expect(await screen.findByText('Features Include')).toBeInTheDocument();
  85. // Check that the source feature is highlighted.
  86. expect(screen.getByTestId('extended-data-retention')).not.toHaveAttribute(
  87. 'aria-selected'
  88. );
  89. expect(screen.getByTestId('event-volume')).toHaveAttribute('aria-selected');
  90. });
  91. it('renders business features with paid plan', async function () {
  92. const sub = SubscriptionFixture({
  93. organization,
  94. plan: 'am1_team',
  95. canTrial: true,
  96. isTrial: false,
  97. isFree: false,
  98. });
  99. render(
  100. <Details
  101. source="sso"
  102. subscription={sub}
  103. organization={organization}
  104. onCloseModal={jest.fn()}
  105. />
  106. );
  107. expect(await screen.findByText('Business Features Include')).toBeInTheDocument();
  108. // Check that the source feature is highlighted.
  109. expect(screen.queryByTestId('extended-data-retention')).not.toBeInTheDocument();
  110. expect(screen.getByTestId('sso')).toHaveAttribute('aria-selected');
  111. });
  112. it('shows performance features when on a old mm2 plan', async function () {
  113. const sub = SubscriptionFixture({
  114. organization,
  115. plan: 'mm2_a_100k',
  116. canTrial: true,
  117. isTrial: false,
  118. isFree: false,
  119. });
  120. render(
  121. <Details
  122. source="tracing"
  123. subscription={sub}
  124. organization={organization}
  125. onCloseModal={jest.fn()}
  126. />
  127. );
  128. expect(await screen.findByText('Features Include')).toBeInTheDocument();
  129. // Check that the source feature is highlighted.
  130. expect(screen.queryByTestId('global-views')).not.toBeInTheDocument();
  131. expect(screen.getByTestId('tracing')).toHaveAttribute('aria-selected');
  132. });
  133. it('cycles the list on a timer when no section is clicked', async function () {
  134. jest.useFakeTimers();
  135. const sub = SubscriptionFixture({
  136. organization,
  137. plan: 'mm2_a_100k',
  138. canTrial: true,
  139. isTrial: false,
  140. isFree: false,
  141. });
  142. render(
  143. <Details
  144. source="test"
  145. subscription={sub}
  146. organization={organization}
  147. onCloseModal={jest.fn()}
  148. />
  149. );
  150. // First timeout is waiting for it to cycle to a feature
  151. act(() => jest.advanceTimersByTime(10000));
  152. // First feature in the displayed list.
  153. const tracing = screen.getByTestId('tracing');
  154. expect(tracing).toHaveAttribute('aria-selected');
  155. // Next timeout is for it to cycle to the _next_ feature
  156. act(() => jest.advanceTimersByTime(8000));
  157. // Avoid act warning after state change
  158. jest.useRealTimers();
  159. await act(tick);
  160. // Tracing should now not be highlighted.
  161. expect(tracing).not.toHaveAttribute('aria-selected');
  162. });
  163. });