inviteBanner.spec.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import moment from 'moment';
  2. import {render, screen} from 'sentry-test/reactTestingLibrary';
  3. import {DEFAULT_SNOOZE_PROMPT_DAYS} from 'sentry/utils/promptIsDismissed';
  4. import {InviteBanner} from 'sentry/views/settings/organizationMembers/inviteBanner';
  5. const missingMembers = {
  6. integration: 'github',
  7. users: TestStubs.MissingMembers(),
  8. };
  9. const noMissingMembers = {
  10. integration: 'github',
  11. users: [],
  12. };
  13. describe('inviteBanner', function () {
  14. beforeEach(function () {
  15. MockApiClient.clearMockResponses();
  16. MockApiClient.addMockResponse({
  17. url: '/organizations/org-slug/missing-members/',
  18. method: 'GET',
  19. body: [],
  20. });
  21. MockApiClient.addMockResponse({
  22. url: '/prompts-activity/',
  23. method: 'GET',
  24. body: {
  25. dismissed_ts: undefined,
  26. snoozed_ts: undefined,
  27. },
  28. });
  29. });
  30. it('render banners with feature flag', async function () {
  31. const org = TestStubs.Organization({
  32. features: ['integrations-gh-invite'],
  33. });
  34. render(
  35. <InviteBanner
  36. missingMembers={missingMembers}
  37. onSendInvite={() => undefined}
  38. organization={org}
  39. />
  40. );
  41. expect(
  42. await screen.findByRole('heading', {
  43. name: 'Bring your full GitHub team on board in Sentry',
  44. })
  45. ).toBeInTheDocument();
  46. expect(screen.queryAllByTestId('invite-missing-member')).toHaveLength(5);
  47. expect(screen.getByText('See all 5 missing members')).toBeInTheDocument();
  48. });
  49. it('does not render banner if no feature flag', function () {
  50. const org = TestStubs.Organization({
  51. features: [],
  52. });
  53. render(
  54. <InviteBanner
  55. missingMembers={missingMembers}
  56. onSendInvite={() => undefined}
  57. organization={org}
  58. />
  59. );
  60. expect(
  61. screen.queryByRole('heading', {
  62. name: 'Bring your full GitHub team on board in Sentry',
  63. })
  64. ).not.toBeInTheDocument();
  65. });
  66. it('does not render banner if no missing members', function () {
  67. const org = TestStubs.Organization({
  68. features: ['integrations-gh-invite'],
  69. });
  70. render(
  71. <InviteBanner
  72. missingMembers={noMissingMembers}
  73. onSendInvite={() => undefined}
  74. organization={org}
  75. />
  76. );
  77. expect(
  78. screen.queryByRole('heading', {
  79. name: 'Bring your full GitHub team on board in Sentry',
  80. })
  81. ).not.toBeInTheDocument();
  82. });
  83. it('does not render banner if lacking org:write', function () {
  84. const org = TestStubs.Organization({
  85. features: ['integrations-gh-invite'],
  86. access: [],
  87. });
  88. render(
  89. <InviteBanner
  90. missingMembers={noMissingMembers}
  91. onSendInvite={() => undefined}
  92. organization={org}
  93. />
  94. );
  95. expect(
  96. screen.queryByRole('heading', {
  97. name: 'Bring your full GitHub team on board in Sentry',
  98. })
  99. ).not.toBeInTheDocument();
  100. });
  101. it('renders banner if snoozed_ts days is longer than threshold', async function () {
  102. const org = TestStubs.Organization({
  103. features: ['integrations-gh-invite'],
  104. });
  105. const promptResponse = {
  106. dismissed_ts: undefined,
  107. snoozed_ts: moment
  108. .utc()
  109. .subtract(DEFAULT_SNOOZE_PROMPT_DAYS + 1, 'days')
  110. .unix(),
  111. };
  112. MockApiClient.addMockResponse({
  113. url: '/prompts-activity/',
  114. method: 'GET',
  115. body: {data: promptResponse},
  116. });
  117. render(
  118. <InviteBanner
  119. missingMembers={missingMembers}
  120. onSendInvite={() => undefined}
  121. organization={org}
  122. />
  123. );
  124. expect(
  125. await screen.findByRole('heading', {
  126. name: 'Bring your full GitHub team on board in Sentry',
  127. })
  128. ).toBeInTheDocument();
  129. });
  130. it('does not render banner if snoozed_ts days is shorter than threshold', function () {
  131. const org = TestStubs.Organization({
  132. features: ['integrations-gh-invite'],
  133. });
  134. const promptResponse = {
  135. dismissed_ts: undefined,
  136. snoozed_ts: moment
  137. .utc()
  138. .subtract(DEFAULT_SNOOZE_PROMPT_DAYS - 1, 'days')
  139. .unix(),
  140. };
  141. const mockPrompt = MockApiClient.addMockResponse({
  142. url: '/prompts-activity/',
  143. method: 'GET',
  144. body: {data: promptResponse},
  145. });
  146. render(
  147. <InviteBanner
  148. missingMembers={missingMembers}
  149. onSendInvite={() => undefined}
  150. organization={org}
  151. />
  152. );
  153. expect(mockPrompt).toHaveBeenCalled();
  154. expect(
  155. screen.queryByRole('heading', {
  156. name: 'Bring your full GitHub team on board in Sentry',
  157. })
  158. ).not.toBeInTheDocument();
  159. });
  160. });