projectSourceMapsArtifacts.spec.tsx 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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, route, project, router, routerContext} = 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. location={routerContext.context.location}
  72. project={project}
  73. route={route}
  74. routeParams={{orgId: organization.slug, projectId: project.slug}}
  75. router={router}
  76. routes={[]}
  77. params={{
  78. orgId: organization.slug,
  79. projectId: project.slug,
  80. bundleId: 'bea7335dfaebc0ca6e65a057',
  81. }}
  82. />,
  83. {context: routerContext, organization}
  84. );
  85. // Title
  86. expect(screen.getByRole('heading')).toHaveTextContent('Release Bundle');
  87. // Subtitle
  88. expect(screen.getByText('bea7335dfaebc0ca6e65a057')).toBeInTheDocument();
  89. // Search bar
  90. expect(screen.getByPlaceholderText('Filter by Path')).toBeInTheDocument();
  91. // Path
  92. expect(
  93. await screen.findByText('https://example.com/AcceptOrganizationInvite.js')
  94. ).toBeInTheDocument();
  95. // Time
  96. expect(screen.getByText(/in 3 year/)).toBeInTheDocument();
  97. // File size
  98. expect(screen.getByText('8.1 KiB')).toBeInTheDocument();
  99. // Download button
  100. expect(screen.getByRole('button', {name: 'Download Artifact'})).toHaveAttribute(
  101. 'href',
  102. '/projects/org-slug/project-slug/releases/bea7335dfaebc0ca6e65a057/files/5678/?download=1'
  103. );
  104. });
  105. it('renders empty state', async function () {
  106. const {organization, route, project, router, routerContext} = initializeOrg({
  107. router: {
  108. location: {
  109. query: {},
  110. },
  111. params: {},
  112. },
  113. });
  114. renderReleaseBundlesMockRequests({
  115. orgSlug: organization.slug,
  116. projectSlug: project.slug,
  117. empty: true,
  118. });
  119. render(
  120. <ProjectSourceMapsArtifacts
  121. location={routerContext.context.location}
  122. project={project}
  123. route={route}
  124. routeParams={{orgId: organization.slug, projectId: project.slug}}
  125. router={router}
  126. routes={[]}
  127. params={{
  128. orgId: organization.slug,
  129. projectId: project.slug,
  130. bundleId: 'bea7335dfaebc0ca6e65a057',
  131. }}
  132. />,
  133. {context: routerContext, organization}
  134. );
  135. expect(
  136. await screen.findByText('There are no artifacts in this archive.')
  137. ).toBeInTheDocument();
  138. });
  139. });
  140. describe('Artifact Bundles', function () {
  141. it('renders default state', async function () {
  142. const {organization, route, project, router, routerContext} = initializeOrg({
  143. router: {
  144. location: {
  145. pathname: `/settings/${initializeOrg().organization.slug}/projects/${
  146. initializeOrg().project.slug
  147. }/source-maps/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/`,
  148. query: {},
  149. },
  150. params: {},
  151. },
  152. });
  153. ConfigStore.config = {
  154. ...ConfigStore.config,
  155. user: {...ConfigStore.config.user, isSuperuser: true},
  156. };
  157. renderDebugIdBundlesMockRequests({
  158. orgSlug: organization.slug,
  159. projectSlug: project.slug,
  160. });
  161. render(
  162. <ProjectSourceMapsArtifacts
  163. location={routerContext.context.location}
  164. project={project}
  165. route={route}
  166. routeParams={{orgId: organization.slug, projectId: project.slug}}
  167. router={router}
  168. routes={[]}
  169. params={{
  170. orgId: organization.slug,
  171. projectId: project.slug,
  172. bundleId: '7227e105-744e-4066-8c69-3e5e344723fc',
  173. }}
  174. />,
  175. {context: routerContext, organization}
  176. );
  177. // Title
  178. expect(screen.getByRole('heading')).toHaveTextContent('Artifact Bundle');
  179. // Subtitle
  180. expect(
  181. screen.getByText('7227e105-744e-4066-8c69-3e5e344723fc')
  182. ).toBeInTheDocument();
  183. // Release information
  184. expect(
  185. await screen.findByText(textWithMarkupMatcher('2 Releases associated'))
  186. ).toBeInTheDocument();
  187. await userEvent.hover(screen.getByText('2 Releases'));
  188. expect(
  189. await screen.findByText('frontend@2e318148eac9298ec04a662ae32b4b093b027f0a')
  190. ).toBeInTheDocument();
  191. // Search bar
  192. expect(screen.getByPlaceholderText('Filter by Path or ID')).toBeInTheDocument();
  193. // Path
  194. expect(await screen.findByText('files/_/_/main.js')).toBeInTheDocument();
  195. // Debug Id
  196. expect(
  197. screen.getByText('69ac68eb-cc62-44c0-a5dc-b67f219a3696')
  198. ).toBeInTheDocument();
  199. // Type
  200. expect(screen.getByText('Minified')).toBeInTheDocument();
  201. // Download Button
  202. expect(screen.getByRole('button', {name: 'Download Artifact'})).toHaveAttribute(
  203. 'href',
  204. '/projects/org-slug/project-slug/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/files/ZmlsZXMvXy9fL21haW4uanM=/?download=1'
  205. );
  206. });
  207. it('renders empty state', async function () {
  208. const {organization, route, project, router, routerContext} = initializeOrg({
  209. router: {
  210. location: {
  211. pathname: `/settings/${initializeOrg().organization.slug}/projects/${
  212. initializeOrg().project.slug
  213. }/source-maps/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/`,
  214. query: {},
  215. },
  216. params: {},
  217. },
  218. });
  219. renderDebugIdBundlesMockRequests({
  220. orgSlug: organization.slug,
  221. projectSlug: project.slug,
  222. empty: true,
  223. });
  224. render(
  225. <ProjectSourceMapsArtifacts
  226. location={routerContext.context.location}
  227. project={project}
  228. route={route}
  229. routeParams={{orgId: organization.slug, projectId: project.slug}}
  230. router={router}
  231. routes={[]}
  232. params={{
  233. orgId: organization.slug,
  234. projectId: project.slug,
  235. bundleId: '7227e105-744e-4066-8c69-3e5e344723fc',
  236. }}
  237. />,
  238. {context: routerContext, organization}
  239. );
  240. expect(
  241. await screen.findByText('There are no artifacts in this bundle.')
  242. ).toBeInTheDocument();
  243. // TODO(Pri): Uncomment once fully transitioned to associations.
  244. // expect(
  245. // screen.getByText('No releases associated with this bundle')
  246. // ).toBeInTheDocument();
  247. });
  248. });
  249. });