projectSourceMapsArtifacts.spec.tsx 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  3. import {textWithMarkupMatcher} from 'sentry-test/utils';
  4. import ConfigStore from 'sentry/stores/configStore';
  5. import {ProjectSourceMapsArtifacts} from 'sentry/views/settings/projectSourceMaps/projectSourceMapsArtifacts';
  6. function renderReleaseBundlesMockRequests({
  7. orgSlug,
  8. projectSlug,
  9. empty,
  10. }: {
  11. orgSlug: string;
  12. projectSlug: string;
  13. empty?: boolean;
  14. }) {
  15. const sourceMaps = MockApiClient.addMockResponse({
  16. url: `/projects/${orgSlug}/${projectSlug}/files/source-maps/`,
  17. body: empty
  18. ? []
  19. : [
  20. TestStubs.SourceMapArchive(),
  21. TestStubs.SourceMapArchive({
  22. id: 2,
  23. name: 'abc',
  24. fileCount: 3,
  25. date: '2023-05-06T13:41:00Z',
  26. }),
  27. ],
  28. });
  29. const sourceMapsFiles = MockApiClient.addMockResponse({
  30. url: `/projects/${orgSlug}/${projectSlug}/releases/bea7335dfaebc0ca6e65a057/files/`,
  31. body: empty ? [] : [TestStubs.SourceMapArtifact()],
  32. });
  33. return {sourceMaps, sourceMapsFiles};
  34. }
  35. function renderDebugIdBundlesMockRequests({
  36. orgSlug,
  37. projectSlug,
  38. empty,
  39. }: {
  40. orgSlug: string;
  41. projectSlug: string;
  42. empty?: boolean;
  43. }) {
  44. const artifactBundlesFiles = MockApiClient.addMockResponse({
  45. url: `/projects/${orgSlug}/${projectSlug}/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/files/`,
  46. body: empty ? {} : TestStubs.SourceMapsDebugIDBundlesArtifacts(),
  47. });
  48. return {artifactBundlesFiles};
  49. }
  50. describe('ProjectSourceMapsArtifacts', function () {
  51. describe('Release Bundles', function () {
  52. it('renders default state', async function () {
  53. const {organization, routerContext, project, routerProps} = initializeOrg({
  54. router: {
  55. location: {
  56. query: {},
  57. },
  58. params: {},
  59. },
  60. });
  61. ConfigStore.config = {
  62. ...ConfigStore.config,
  63. user: {...ConfigStore.config.user, isSuperuser: true},
  64. };
  65. renderReleaseBundlesMockRequests({
  66. orgSlug: organization.slug,
  67. projectSlug: project.slug,
  68. });
  69. render(
  70. <ProjectSourceMapsArtifacts
  71. {...routerProps}
  72. project={project}
  73. params={{
  74. orgId: organization.slug,
  75. projectId: project.slug,
  76. bundleId: 'bea7335dfaebc0ca6e65a057',
  77. }}
  78. />,
  79. {context: routerContext, organization}
  80. );
  81. // Title
  82. expect(screen.getByRole('heading')).toHaveTextContent('Release Bundle');
  83. // Subtitle
  84. expect(screen.getByText('bea7335dfaebc0ca6e65a057')).toBeInTheDocument();
  85. // Search bar
  86. expect(screen.getByPlaceholderText('Filter by Path')).toBeInTheDocument();
  87. // Path
  88. expect(
  89. await screen.findByText('https://example.com/AcceptOrganizationInvite.js')
  90. ).toBeInTheDocument();
  91. // Time
  92. expect(screen.getByText(/in 3 year/)).toBeInTheDocument();
  93. // File size
  94. expect(screen.getByText('8.1 KiB')).toBeInTheDocument();
  95. // Download button
  96. expect(screen.getByRole('button', {name: 'Download Artifact'})).toHaveAttribute(
  97. 'href',
  98. '/projects/org-slug/project-slug/releases/bea7335dfaebc0ca6e65a057/files/5678/?download=1'
  99. );
  100. });
  101. it('renders empty state', async function () {
  102. const {organization, routerProps, project, routerContext} = initializeOrg({
  103. router: {
  104. location: {
  105. query: {},
  106. },
  107. params: {},
  108. },
  109. });
  110. renderReleaseBundlesMockRequests({
  111. orgSlug: organization.slug,
  112. projectSlug: project.slug,
  113. empty: true,
  114. });
  115. render(
  116. <ProjectSourceMapsArtifacts
  117. {...routerProps}
  118. project={project}
  119. params={{
  120. orgId: organization.slug,
  121. projectId: project.slug,
  122. bundleId: 'bea7335dfaebc0ca6e65a057',
  123. }}
  124. />,
  125. {context: routerContext, organization}
  126. );
  127. expect(
  128. await screen.findByText('There are no artifacts in this archive.')
  129. ).toBeInTheDocument();
  130. });
  131. });
  132. describe('Artifact Bundles', function () {
  133. it('renders default state', async function () {
  134. const {organization, project, routerProps, routerContext} = initializeOrg({
  135. router: {
  136. location: {
  137. pathname: `/settings/${initializeOrg().organization.slug}/projects/${
  138. initializeOrg().project.slug
  139. }/source-maps/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/`,
  140. query: {},
  141. },
  142. params: {},
  143. },
  144. });
  145. ConfigStore.config = {
  146. ...ConfigStore.config,
  147. user: {...ConfigStore.config.user, isSuperuser: true},
  148. };
  149. renderDebugIdBundlesMockRequests({
  150. orgSlug: organization.slug,
  151. projectSlug: project.slug,
  152. });
  153. render(
  154. <ProjectSourceMapsArtifacts
  155. {...routerProps}
  156. project={project}
  157. params={{
  158. orgId: organization.slug,
  159. projectId: project.slug,
  160. bundleId: '7227e105-744e-4066-8c69-3e5e344723fc',
  161. }}
  162. />,
  163. {context: routerContext, organization}
  164. );
  165. // Title
  166. expect(screen.getByRole('heading')).toHaveTextContent('Artifact Bundle');
  167. // Subtitle
  168. expect(
  169. screen.getByText('7227e105-744e-4066-8c69-3e5e344723fc')
  170. ).toBeInTheDocument();
  171. // Release information
  172. expect(
  173. await screen.findByText(textWithMarkupMatcher('2 Releases associated'))
  174. ).toBeInTheDocument();
  175. await userEvent.hover(screen.getByText('2 Releases'));
  176. expect(
  177. await screen.findByText('frontend@2e318148eac9298ec04a662ae32b4b093b027f0a')
  178. ).toBeInTheDocument();
  179. // Search bar
  180. expect(screen.getByPlaceholderText('Filter by Path or ID')).toBeInTheDocument();
  181. // Path
  182. expect(await screen.findByText('files/_/_/main.js')).toBeInTheDocument();
  183. // Debug Id
  184. expect(
  185. screen.getByText('69ac68eb-cc62-44c0-a5dc-b67f219a3696')
  186. ).toBeInTheDocument();
  187. // Type
  188. expect(screen.getByText('Minified')).toBeInTheDocument();
  189. // Download Button
  190. expect(screen.getByRole('button', {name: 'Download Artifact'})).toHaveAttribute(
  191. 'href',
  192. '/projects/org-slug/project-slug/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/files/ZmlsZXMvXy9fL21haW4uanM=/?download=1'
  193. );
  194. });
  195. it('renders empty state', async function () {
  196. const {organization, project, routerProps, routerContext} = initializeOrg({
  197. router: {
  198. location: {
  199. pathname: `/settings/${initializeOrg().organization.slug}/projects/${
  200. initializeOrg().project.slug
  201. }/source-maps/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/`,
  202. query: {},
  203. },
  204. params: {},
  205. },
  206. });
  207. renderDebugIdBundlesMockRequests({
  208. orgSlug: organization.slug,
  209. projectSlug: project.slug,
  210. empty: true,
  211. });
  212. render(
  213. <ProjectSourceMapsArtifacts
  214. {...routerProps}
  215. project={project}
  216. params={{
  217. orgId: organization.slug,
  218. projectId: project.slug,
  219. bundleId: '7227e105-744e-4066-8c69-3e5e344723fc',
  220. }}
  221. />,
  222. {context: routerContext, organization}
  223. );
  224. expect(
  225. await screen.findByText('There are no artifacts in this bundle.')
  226. ).toBeInTheDocument();
  227. // TODO(Pri): Uncomment once fully transitioned to associations.
  228. // expect(
  229. // screen.getByText('No releases associated with this bundle')
  230. // ).toBeInTheDocument();
  231. });
  232. });
  233. });