sentryApplicationRowButtons.spec.tsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {SentryAppFixture} from 'sentry-fixture/sentryApp';
  3. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  4. import SentryApplicationRowButtons from 'sentry/views/settings/organizationDeveloperSettings/sentryApplicationRow/sentryApplicationRowButtons';
  5. describe('Sentry App Row Buttons', function () {
  6. const removeApp = jest.fn();
  7. const publishApp = jest.fn();
  8. const sentryApp = SentryAppFixture();
  9. afterEach(() => {
  10. MockApiClient.clearMockResponses();
  11. });
  12. it('renders', async () => {
  13. render(
  14. <SentryApplicationRowButtons
  15. organization={OrganizationFixture()}
  16. app={sentryApp}
  17. onClickRemove={removeApp}
  18. onClickPublish={publishApp}
  19. />
  20. );
  21. const publishButton = await screen.findByRole('button', {name: 'Publish'});
  22. expect(publishButton).toBeDisabled();
  23. const deleteButton = await screen.findByRole('button', {name: 'Delete'});
  24. expect(deleteButton).toBeEnabled();
  25. const dashboardButton = await screen.findByRole('button', {name: 'Dashboard'});
  26. expect(dashboardButton).toBeEnabled();
  27. });
  28. it('hides the publish button if the app is internal', async () => {
  29. const internalSentryApp = SentryAppFixture({status: 'internal'});
  30. render(
  31. <SentryApplicationRowButtons
  32. organization={OrganizationFixture()}
  33. app={internalSentryApp}
  34. onClickRemove={removeApp}
  35. onClickPublish={publishApp}
  36. />
  37. );
  38. expect(screen.queryByText('Publish')).not.toBeInTheDocument();
  39. const deleteButton = await screen.findByRole('button', {name: 'Delete'});
  40. expect(deleteButton).toBeEnabled();
  41. const dashboardButton = await screen.findByRole('button', {name: 'Dashboard'});
  42. expect(dashboardButton).toBeEnabled();
  43. });
  44. it('disables the delete and publish button if the app is published', async () => {
  45. const internalSentryApp = SentryAppFixture({status: 'published'});
  46. render(
  47. <SentryApplicationRowButtons
  48. organization={OrganizationFixture()}
  49. app={internalSentryApp}
  50. onClickRemove={removeApp}
  51. onClickPublish={publishApp}
  52. />
  53. );
  54. const publishButton = await screen.findByRole('button', {name: 'Publish'});
  55. expect(publishButton).toBeDisabled();
  56. await userEvent.hover(publishButton, {delay: 100});
  57. expect(
  58. screen.getByText('Published integrations cannot be re-published.')
  59. ).toBeInTheDocument();
  60. expect(publishButton).toBeDisabled();
  61. const deleteButton = await screen.findByRole('button', {name: 'Delete'});
  62. expect(deleteButton).toBeDisabled();
  63. await userEvent.hover(deleteButton, {delay: 100});
  64. expect(
  65. screen.getByText('Published integrations cannot be removed.')
  66. ).toBeInTheDocument();
  67. expect(publishButton).toBeDisabled();
  68. const dashboardButton = await screen.findByRole('button', {name: 'Dashboard'});
  69. expect(dashboardButton).toBeEnabled();
  70. });
  71. it('disables the publish button if the sentry app has a UI feature and no icon', async () => {
  72. const organization = OrganizationFixture();
  73. const internalSentryApp = SentryAppFixture({
  74. status: 'unpublished',
  75. avatars: [
  76. {
  77. avatarType: 'upload',
  78. avatarUuid: '1234561234561234561234567',
  79. avatarUrl: 'https://example.com/avatar/1234561234561234561234567/',
  80. color: true,
  81. photoType: 'logo',
  82. },
  83. {
  84. avatarType: 'default',
  85. avatarUuid: '1234561234561234561234567',
  86. avatarUrl: 'https://example.com/avatar/1234561234561234561234567/',
  87. color: false,
  88. photoType: 'icon',
  89. },
  90. ],
  91. schema: {
  92. elements: [
  93. {
  94. type: 'issue-link',
  95. create: {
  96. uri: '/api/sentry/issue-link/create/',
  97. required_fields: [
  98. {
  99. type: 'text',
  100. label: 'Task Name',
  101. name: 'title',
  102. default: 'issue.title',
  103. },
  104. ],
  105. },
  106. link: {
  107. uri: '/api/sentry/issue-link/link/',
  108. required_fields: [
  109. {
  110. type: 'select',
  111. label: 'Which task would you like to link to this Sentry Issue?',
  112. name: 'itemId',
  113. uri: '/api/sentry/options/items/',
  114. },
  115. ],
  116. },
  117. },
  118. ],
  119. },
  120. });
  121. render(
  122. <SentryApplicationRowButtons
  123. organization={organization}
  124. app={internalSentryApp}
  125. onClickRemove={removeApp}
  126. onClickPublish={publishApp}
  127. />
  128. );
  129. const publishButton = await screen.findByRole('button', {name: 'Publish'});
  130. await userEvent.hover(publishButton, {delay: 100});
  131. expect(
  132. screen.getByText('Integrations with a UI component must have an icon')
  133. ).toBeInTheDocument();
  134. expect(publishButton).toBeDisabled();
  135. const deleteButton = await screen.findByRole('button', {name: 'Delete'});
  136. expect(deleteButton).toBeEnabled();
  137. const dashboardButton = await screen.findByRole('button', {name: 'Dashboard'});
  138. expect(dashboardButton).toBeEnabled();
  139. });
  140. it('disables the publish button if the app is in progress of publishing', async () => {
  141. const organization = OrganizationFixture();
  142. const internalSentryApp = SentryAppFixture({status: 'publish_request_inprogress'});
  143. render(
  144. <SentryApplicationRowButtons
  145. organization={organization}
  146. app={internalSentryApp}
  147. onClickRemove={removeApp}
  148. onClickPublish={publishApp}
  149. />
  150. );
  151. const publishButton = await screen.findByRole('button', {name: 'Publish'});
  152. expect(publishButton).toBeDisabled();
  153. await userEvent.hover(publishButton, {delay: 100});
  154. expect(
  155. screen.getByText('This integration has already been submitted for publishing')
  156. ).toBeInTheDocument();
  157. const deleteButton = await screen.findByRole('button', {name: 'Delete'});
  158. expect(deleteButton).toBeEnabled();
  159. const dashboardButton = await screen.findByRole('button', {name: 'Dashboard'});
  160. expect(dashboardButton).toBeEnabled();
  161. });
  162. it('disables the publish button if the app is in progress of deletion', async () => {
  163. const organization = OrganizationFixture();
  164. const internalSentryApp = SentryAppFixture({status: 'deletion_in_progress'});
  165. render(
  166. <SentryApplicationRowButtons
  167. organization={organization}
  168. app={internalSentryApp}
  169. onClickRemove={removeApp}
  170. onClickPublish={publishApp}
  171. />
  172. );
  173. const publishButton = await screen.findByRole('button', {name: 'Publish'});
  174. expect(publishButton).toBeDisabled();
  175. await userEvent.hover(publishButton, {delay: 100});
  176. expect(
  177. screen.getByText('Only unpublished integrations can be published')
  178. ).toBeInTheDocument();
  179. const deleteButton = await screen.findByRole('button', {name: 'Delete'});
  180. expect(deleteButton).toBeEnabled();
  181. const dashboardButton = await screen.findByRole('button', {name: 'Dashboard'});
  182. expect(dashboardButton).toBeEnabled();
  183. });
  184. it('disables the publish button if the app doesnt have a logo', async () => {
  185. const organization = OrganizationFixture();
  186. const internalSentryApp = SentryAppFixture({status: 'unpublished'});
  187. render(
  188. <SentryApplicationRowButtons
  189. organization={organization}
  190. app={internalSentryApp}
  191. onClickRemove={removeApp}
  192. onClickPublish={publishApp}
  193. />
  194. );
  195. const publishButton = await screen.findByRole('button', {name: 'Publish'});
  196. expect(publishButton).toBeDisabled();
  197. await userEvent.hover(publishButton, {delay: 100});
  198. expect(
  199. screen.getByText('A logo is required to publish an integration')
  200. ).toBeInTheDocument();
  201. const deleteButton = await screen.findByRole('button', {name: 'Delete'});
  202. expect(deleteButton).toBeEnabled();
  203. const dashboardButton = await screen.findByRole('button', {name: 'Dashboard'});
  204. expect(dashboardButton).toBeEnabled();
  205. });
  206. });