inviteBanner.spec.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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. githubNudgeInvite: true,
  34. });
  35. render(
  36. <InviteBanner
  37. missingMembers={missingMembers}
  38. onSendInvite={() => {}}
  39. organization={org}
  40. allowedRoles={[]}
  41. onModalClose={() => {}}
  42. />
  43. );
  44. expect(
  45. await screen.findByRole('heading', {
  46. name: 'Bring your full GitHub team on board in Sentry',
  47. })
  48. ).toBeInTheDocument();
  49. expect(screen.queryAllByTestId('invite-missing-member')).toHaveLength(5);
  50. expect(screen.getByText('See all 5 missing members')).toBeInTheDocument();
  51. });
  52. it('does not render banner if no feature flag', function () {
  53. const org = TestStubs.Organization({
  54. features: [],
  55. });
  56. render(
  57. <InviteBanner
  58. missingMembers={missingMembers}
  59. onSendInvite={() => {}}
  60. organization={org}
  61. allowedRoles={[]}
  62. onModalClose={() => {}}
  63. />
  64. );
  65. expect(
  66. screen.queryByRole('heading', {
  67. name: 'Bring your full GitHub team on board in Sentry',
  68. })
  69. ).not.toBeInTheDocument();
  70. });
  71. it('does not render banner if no missing members', function () {
  72. const org = TestStubs.Organization({
  73. features: ['integrations-gh-invite'],
  74. });
  75. render(
  76. <InviteBanner
  77. missingMembers={noMissingMembers}
  78. onSendInvite={() => {}}
  79. organization={org}
  80. allowedRoles={[]}
  81. onModalClose={() => {}}
  82. />
  83. );
  84. expect(
  85. screen.queryByRole('heading', {
  86. name: 'Bring your full GitHub team on board in Sentry',
  87. })
  88. ).not.toBeInTheDocument();
  89. });
  90. it('does not render banner if lacking org:write', function () {
  91. const org = TestStubs.Organization({
  92. features: ['integrations-gh-invite'],
  93. access: [],
  94. });
  95. render(
  96. <InviteBanner
  97. missingMembers={noMissingMembers}
  98. onSendInvite={() => {}}
  99. organization={org}
  100. allowedRoles={[]}
  101. onModalClose={() => {}}
  102. />
  103. );
  104. expect(
  105. screen.queryByRole('heading', {
  106. name: 'Bring your full GitHub team on board in Sentry',
  107. })
  108. ).not.toBeInTheDocument();
  109. });
  110. it('renders banner if snoozed_ts days is longer than threshold', async function () {
  111. const org = TestStubs.Organization({
  112. features: ['integrations-gh-invite'],
  113. githubNudgeInvite: true,
  114. });
  115. const promptResponse = {
  116. dismissed_ts: undefined,
  117. snoozed_ts: moment
  118. .utc()
  119. .subtract(DEFAULT_SNOOZE_PROMPT_DAYS + 1, 'days')
  120. .unix(),
  121. };
  122. MockApiClient.addMockResponse({
  123. url: '/prompts-activity/',
  124. method: 'GET',
  125. body: {data: promptResponse},
  126. });
  127. render(
  128. <InviteBanner
  129. missingMembers={missingMembers}
  130. onSendInvite={() => {}}
  131. organization={org}
  132. allowedRoles={[]}
  133. onModalClose={() => {}}
  134. />
  135. );
  136. expect(
  137. await screen.findByRole('heading', {
  138. name: 'Bring your full GitHub team on board in Sentry',
  139. })
  140. ).toBeInTheDocument();
  141. });
  142. it('does not render banner if snoozed_ts days is shorter than threshold', function () {
  143. const org = TestStubs.Organization({
  144. features: ['integrations-gh-invite'],
  145. githubNudgeInvite: true,
  146. });
  147. const promptResponse = {
  148. dismissed_ts: undefined,
  149. snoozed_ts: moment
  150. .utc()
  151. .subtract(DEFAULT_SNOOZE_PROMPT_DAYS - 1, 'days')
  152. .unix(),
  153. };
  154. const mockPrompt = MockApiClient.addMockResponse({
  155. url: '/prompts-activity/',
  156. method: 'GET',
  157. body: {data: promptResponse},
  158. });
  159. render(
  160. <InviteBanner
  161. missingMembers={missingMembers}
  162. onSendInvite={() => {}}
  163. organization={org}
  164. allowedRoles={[]}
  165. onModalClose={() => {}}
  166. />
  167. );
  168. expect(mockPrompt).toHaveBeenCalled();
  169. expect(
  170. screen.queryByRole('heading', {
  171. name: 'Bring your full GitHub team on board in Sentry',
  172. })
  173. ).not.toBeInTheDocument();
  174. });
  175. });