Browse Source

feat(source-maps): Add unit tests for new design changes - Part 2 (#45981)

Priscila Oliveira 2 years ago
parent
commit
19fd882c8e

+ 16 - 0
fixtures/js-stubs/sourceMapsDebugIDBundlesArtifacts.ts

@@ -0,0 +1,16 @@
+import type {DebugIdBundleArtifact} from 'sentry/types';
+
+export function SourceMapsDebugIDBundlesArtifacts(
+  debugBundleIdArtifact: Partial<DebugIdBundleArtifact> = {}
+): DebugIdBundleArtifact[] {
+  return [
+    {
+      id: 'ZmlsZXMvXy9fL21haW4uanM=',
+      fileType: 2,
+      filePath: 'files/_/_/main.js',
+      fileSize: 239093,
+      debugId: '69ac68eb-cc62-44c0-a5dc-b67f219a3696',
+      ...debugBundleIdArtifact,
+    },
+  ];
+}

+ 1 - 0
fixtures/js-stubs/types.tsx

@@ -136,6 +136,7 @@ type TestStubFixtures = {
   SourceMapArchive: OverridableStub;
   SourceMapArtifact: OverridableStub;
   SourceMapsDebugIDBundles: OverridableStub;
+  SourceMapsDebugIDBundlesArtifacts: OverridableStub;
   Span: OverridableStub;
   Subscriptions: OverridableStubList;
   TagValues: OverridableStubList;

+ 8 - 0
static/app/types/sourceMaps.ts

@@ -5,3 +5,11 @@ export type DebugIdBundle = {
   fileCount: number;
   release: string | null;
 };
+
+export type DebugIdBundleArtifact = {
+  debugId: string;
+  filePath: string;
+  fileSize: number;
+  fileType: number;
+  id: string;
+};

+ 2 - 2
static/app/views/settings/projectSourceMaps/projectSourceMaps.spec.tsx

@@ -111,7 +111,7 @@ describe('ProjectSourceMaps', function () {
           '/projects/org-slug/project-slug/files/source-maps/',
           expect.objectContaining({
             query: expect.objectContaining({
-              orderby: '-date_added',
+              sortBy: '-date_added',
             }),
           })
         );
@@ -256,7 +256,7 @@ describe('ProjectSourceMaps', function () {
           '/projects/org-slug/project-slug/files/artifact-bundles/',
           expect.objectContaining({
             query: expect.objectContaining({
-              orderby: '-date_added',
+              sortBy: '-date_added',
             }),
           })
         );

+ 7 - 5
static/app/views/settings/projectSourceMaps/projectSourceMaps.tsx

@@ -136,12 +136,12 @@ export function ProjectSourceMaps({location, router, project}: Props) {
     [
       sourceMapsEndpoint,
       {
-        query: {query, cursor, orderby: sortBy},
+        query: {query, cursor, sortBy},
       },
     ],
     () => {
       return api.requestPromise(sourceMapsEndpoint, {
-        query: {query, cursor, orderby: sortBy},
+        query: {query, cursor, sortBy},
         includeAllArgs: true,
       });
     },
@@ -160,12 +160,12 @@ export function ProjectSourceMaps({location, router, project}: Props) {
     [
       debugIdBundlesEndpoint,
       {
-        query: {query, cursor, orderby: sortBy},
+        query: {query, cursor, sortBy},
       },
     ],
     () => {
       return api.requestPromise(debugIdBundlesEndpoint, {
-        query: {query, cursor, orderby: sortBy},
+        query: {query, cursor, sortBy},
         includeAllArgs: true,
       });
     },
@@ -311,6 +311,7 @@ export function ProjectSourceMaps({location, router, project}: Props) {
                         tooltipText={tct('Associated with release "[distribution]"', {
                           distribution: data.dist,
                         })}
+                        type="info"
                       >
                         {data.dist}
                       </Tag>
@@ -320,6 +321,7 @@ export function ProjectSourceMaps({location, router, project}: Props) {
                         tooltipText={tct('Associated with release "[releaseName]"', {
                           releaseName: data.release,
                         })}
+                        type="info"
                       >
                         {data.release}
                       </Tag>
@@ -397,7 +399,7 @@ const IDColumn = styled(Column)`
   flex-direction: column;
   justify-content: center;
   align-items: flex-start;
-  gap: ${space(0.25)};
+  gap: ${space(0.5)};
 `;
 
 const ActionsColumn = styled(Column)`

+ 128 - 23
static/app/views/settings/projectSourceMaps/projectSourceMapsArtifacts.spec.tsx

@@ -21,6 +21,23 @@ function renderReleaseBundlesMockRequests({
   return {files};
 }
 
+function renderDebugIdBundlesMockRequests({
+  orgSlug,
+  projectSlug,
+  empty,
+}: {
+  orgSlug: string;
+  projectSlug: string;
+  empty?: boolean;
+}) {
+  const artifactBundles = MockApiClient.addMockResponse({
+    url: `/projects/${orgSlug}/${projectSlug}/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/files/`,
+    body: empty ? [] : TestStubs.SourceMapsDebugIDBundlesArtifacts(),
+  });
+
+  return {artifactBundles};
+}
+
 describe('ProjectSourceMapsArtifacts', function () {
   describe('Release Bundles', function () {
     it('renders default state', async function () {
@@ -62,21 +79,9 @@ describe('ProjectSourceMapsArtifacts', function () {
       );
 
       // Title
-      expect(
-        screen.getByRole('heading', {name: 'bea7335dfaebc0ca6e65a057'})
-      ).toBeInTheDocument();
-
-      // Active tab
-      const tabs = screen.getAllByRole('listitem');
-      expect(tabs).toHaveLength(2);
-
-      // Tab 1
-      expect(tabs[0]).toHaveTextContent('Release Bundles');
-      expect(tabs[0]).toHaveClass('active');
-
-      // Tab 2
-      expect(tabs[1]).toHaveTextContent('Debug ID Bundles');
-      expect(tabs[1]).not.toHaveClass('active');
+      expect(screen.getByRole('heading')).toHaveTextContent(
+        'Release Artifact (bea7335dfaebc0ca6e65a057)'
+      );
 
       // Search bar
       expect(screen.getByPlaceholderText('Filter by Path')).toBeInTheDocument();
@@ -97,14 +102,6 @@ describe('ProjectSourceMapsArtifacts', function () {
         'href',
         '/projects/org-slug/project-slug/releases/bea7335dfaebc0ca6e65a057/files/5678/?download=1'
       );
-
-      // Switch tab
-      await userEvent.click(screen.getByRole('link', {name: 'Debug ID Bundles'}));
-      expect(router.push).toHaveBeenCalledWith({
-        pathname:
-          '/settings/org-slug/projects/project-slug/source-maps/debug-id-bundles/bea7335dfaebc0ca6e65a057',
-        query: undefined,
-      });
     });
 
     it('renders empty state', async function () {
@@ -146,4 +143,112 @@ describe('ProjectSourceMapsArtifacts', function () {
       ).toBeInTheDocument();
     });
   });
+
+  describe('Debug ID Bundles', function () {
+    it('renders default state', async function () {
+      const {organization, route, project, router, routerContext} = initializeOrg({
+        ...initializeOrg(),
+        router: {
+          location: {
+            pathname: `/settings/${initializeOrg().organization.slug}/projects/${
+              initializeOrg().project.slug
+            }/source-maps/debug-id-bundles/7227e105-744e-4066-8c69-3e5e344723fc/`,
+            query: {},
+          },
+          params: {},
+        },
+      });
+
+      ConfigStore.config = {
+        ...ConfigStore.config,
+        user: {...ConfigStore.config.user, isSuperuser: true},
+      };
+
+      renderDebugIdBundlesMockRequests({
+        orgSlug: organization.slug,
+        projectSlug: project.slug,
+      });
+
+      render(
+        <ProjectSourceMapsArtifacts
+          location={routerContext.context.location}
+          project={project}
+          route={route}
+          routeParams={{orgId: organization.slug, projectId: project.slug}}
+          router={router}
+          routes={[]}
+          params={{
+            orgId: organization.slug,
+            projectId: project.slug,
+            bundleId: '7227e105-744e-4066-8c69-3e5e344723fc',
+          }}
+        />,
+        {context: routerContext, organization}
+      );
+
+      // Title
+      expect(screen.getByRole('heading')).toHaveTextContent(
+        'Debug Id Bundle Artifact (7227e105-744e-4066-8c69-3e5e344723fc)'
+      );
+
+      // Search bar
+      expect(screen.getByPlaceholderText('Filter by Path or ID')).toBeInTheDocument();
+
+      // Path
+      expect(await screen.findByText('files/_/_/main.js')).toBeInTheDocument();
+      // Bundle Id
+      expect(
+        screen.getByText('69ac68eb-cc62-44c0-a5dc-b67f219a3696')
+      ).toBeInTheDocument();
+      // Type
+      expect(screen.getByText('Minified')).toBeInTheDocument();
+      // Download Button
+      expect(screen.getByRole('button', {name: 'Download Artifact'})).toHaveAttribute(
+        'href',
+        '/projects/org-slug/project-slug/artifact-bundles/7227e105-744e-4066-8c69-3e5e344723fc/files/ZmlsZXMvXy9fL21haW4uanM=/?download=1'
+      );
+    });
+
+    it('renders empty state', async function () {
+      const {organization, route, project, router, routerContext} = initializeOrg({
+        ...initializeOrg(),
+        router: {
+          location: {
+            pathname: `/settings/${initializeOrg().organization.slug}/projects/${
+              initializeOrg().project.slug
+            }/source-maps/debug-id-bundles/7227e105-744e-4066-8c69-3e5e344723fc/`,
+            query: {},
+          },
+          params: {},
+        },
+      });
+
+      renderDebugIdBundlesMockRequests({
+        orgSlug: organization.slug,
+        projectSlug: project.slug,
+        empty: true,
+      });
+
+      render(
+        <ProjectSourceMapsArtifacts
+          location={routerContext.context.location}
+          project={project}
+          route={route}
+          routeParams={{orgId: organization.slug, projectId: project.slug}}
+          router={router}
+          routes={[]}
+          params={{
+            orgId: organization.slug,
+            projectId: project.slug,
+            bundleId: '7227e105-744e-4066-8c69-3e5e344723fc',
+          }}
+        />,
+        {context: routerContext, organization}
+      );
+
+      expect(
+        await screen.findByText('There are no artifacts in this bundle.')
+      ).toBeInTheDocument();
+    });
+  });
 });

+ 36 - 28
static/app/views/settings/projectSourceMaps/projectSourceMapsArtifacts.tsx

@@ -6,18 +6,18 @@ import {Role} from 'sentry/components/acl/role';
 import {Button} from 'sentry/components/button';
 import FileSize from 'sentry/components/fileSize';
 import Link from 'sentry/components/links/link';
-import ListLink from 'sentry/components/links/listLink';
-import NavTabs from 'sentry/components/navTabs';
 import Pagination from 'sentry/components/pagination';
 import {PanelTable} from 'sentry/components/panels';
 import SearchBar from 'sentry/components/searchBar';
 import Tag from 'sentry/components/tag';
+import TextOverflow from 'sentry/components/textOverflow';
 import TimeSince from 'sentry/components/timeSince';
 import {Tooltip} from 'sentry/components/tooltip';
+import Version from 'sentry/components/version';
 import {IconClock, IconDownload} from 'sentry/icons';
 import {t, tct} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
-import {Artifact, Project} from 'sentry/types';
+import {Artifact, DebugIdBundleArtifact, Project} from 'sentry/types';
 import {useQuery} from 'sentry/utils/queryClient';
 import {decodeScalar} from 'sentry/utils/queryString';
 import useApi from 'sentry/utils/useApi';
@@ -25,14 +25,6 @@ import useOrganization from 'sentry/utils/useOrganization';
 import {normalizeUrl} from 'sentry/utils/withDomainRequired';
 import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
 
-type DebugIdBundleArtifact = {
-  debugId: string;
-  filePath: string;
-  fileSize: number;
-  fileType: number;
-  id: string;
-};
-
 enum DebugIdBundleArtifactType {
   INVALID = 0,
   SOURCE = 1,
@@ -125,14 +117,13 @@ export function ProjectSourceMapsArtifacts({params, location, router, project}:
   const artifactsEndpoint = `/projects/${organization.slug}/${
     project.slug
   }/releases/${encodeURIComponent(params.bundleId)}/files/`;
-  const debugIdBundlesEndpoint = ``;
+  const debugIdBundlesEndpoint = `/projects/${organization.slug}/${
+    project.slug
+  }/artifact-bundles/${encodeURIComponent(params.bundleId)}/files/`;
 
-  // tab urls
-  const releaseBundlesUrl = normalizeUrl(
-    `/settings/${organization.slug}/projects/${project.slug}/source-maps/release-bundles/${params.bundleId}`
-  );
+  // debug id bundles tab url
   const debugIdsUrl = normalizeUrl(
-    `/settings/${organization.slug}/projects/${project.slug}/source-maps/debug-id-bundles/${params.bundleId}`
+    `/settings/${organization.slug}/projects/${project.slug}/source-maps/debug-id-bundles/${params.bundleId}/`
   );
 
   const tabDebugIdBundlesActive = location.pathname === debugIdsUrl;
@@ -193,18 +184,28 @@ export function ProjectSourceMapsArtifacts({params, location, router, project}:
 
   return (
     <Fragment>
-      <SettingsPageHeader title={params.bundleId} />
-      <NavTabs underlined>
-        <ListLink to={releaseBundlesUrl} index isActive={() => !tabDebugIdBundlesActive}>
-          {t('Release Bundles')}
-        </ListLink>
-        <ListLink to={debugIdsUrl} isActive={() => tabDebugIdBundlesActive}>
-          {t('Debug ID Bundles')}
-        </ListLink>
-      </NavTabs>
+      <SettingsPageHeader
+        title={
+          <Title>
+            {tabDebugIdBundlesActive
+              ? t('Debug Id Bundle Artifact')
+              : t('Release Artifact')}
+            {' ('}
+            <TextOverflow>
+              <Version
+                version={params.bundleId}
+                tooltipRawVersion
+                anchor={false}
+                truncate
+              />
+            </TextOverflow>
+            {')'}
+          </Title>
+        }
+      />
       <SearchBarWithMarginBottom
         placeholder={
-          tabDebugIdBundlesActive ? t('Filter by Path or ID ') : t('Filter by Path')
+          tabDebugIdBundlesActive ? t('Filter by Path or ID') : t('Filter by Path')
         }
         onSearch={handleSearch}
         query={query}
@@ -218,6 +219,8 @@ export function ProjectSourceMapsArtifacts({params, location, router, project}:
         emptyMessage={
           query
             ? t('No artifacts match your search query.')
+            : tabDebugIdBundlesActive
+            ? t('There are no artifacts in this bundle.')
             : t('There are no artifacts in this archive.')
         }
         isEmpty={
@@ -232,7 +235,7 @@ export function ProjectSourceMapsArtifacts({params, location, router, project}:
           ? debugIdBundlesData?.[0].map(data => {
               const downloadUrl = `${api.baseUrl}/projects/${organization.slug}/${
                 project.slug
-              }/releases/${encodeURIComponent(params.bundleId)}/files/${
+              }/artifact-bundles/${encodeURIComponent(params.bundleId)}/files/${
                 data.id
               }/?download=1`;
 
@@ -362,3 +365,8 @@ const DebugIdAndFileTypeWrapper = styled('div')`
   font-size: ${p => p.theme.fontSizeSmall};
   color: ${p => p.theme.subText};
 `;
+
+const Title = styled('div')`
+  display: flex;
+  align-items: center;
+`;