inviteBanner.spec.tsx 4.9 KB

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