projectSourceMapsArtifacts.spec.tsx 7.9 KB

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