inviteBanner.spec.tsx 4.8 KB

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