Browse Source

ref(replay): Refactor callsites to use useReplayCountFor* buffer helpers (#61858)

This PR replaces (and deletes) the older `useReplaysCount` hook, and its
related react context Providers, with the new `useReplayCountForXYZ()`
hooks.

- The new hooks don't need any react context, so all those callsites are
just gone
- Before we could call `useReplaysCount` and pass in any type of id. But
with the new code we have to choose the correct hook to match with the
type of id that we have. So `useReplaysCount()` with `groupId` needs to
be converted to `useReplayCountForIssues`
- A bunch of tests needed updating because the previous
Provider/Consumer combination was easy to mock and skipped calling into
the apiClient, now we need default mocks instead.
- half the removed code is from
static/app/components/replays/useReplaysCount.spec.tsx, so don't be
worried, it's not actually a huge change to review.
Ryan Albrecht 1 year ago
parent
commit
7209c45086

+ 16 - 20
static/app/components/discover/transactionsTable.tsx

@@ -7,7 +7,6 @@ import Link from 'sentry/components/links/link';
 import LoadingIndicator from 'sentry/components/loadingIndicator';
 import PanelTable from 'sentry/components/panels/panelTable';
 import QuestionTooltip from 'sentry/components/questionTooltip';
-import ReplayIdCountProvider from 'sentry/components/replays/replayIdCountProvider';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import {Organization} from 'sentry/types';
@@ -221,35 +220,32 @@ class TransactionsTable extends PureComponent<Props> {
   }
 
   render() {
-    const {isLoading, organization, tableData} = this.props;
+    const {isLoading, tableData} = this.props;
 
     const hasResults =
       tableData && tableData.data && tableData.meta && tableData.data.length > 0;
-    const replayIds = tableData?.data?.map(row => row.replayId);
 
     // Custom set the height so we don't have layout shift when results are loaded.
     const loader = <LoadingIndicator style={{margin: '70px auto'}} />;
 
     return (
-      <ReplayIdCountProvider organization={organization} replayIds={replayIds}>
-        <VisuallyCompleteWithData
-          id="TransactionsTable"
-          hasData={hasResults}
+      <VisuallyCompleteWithData
+        id="TransactionsTable"
+        hasData={hasResults}
+        isLoading={isLoading}
+      >
+        <PanelTable
+          data-test-id="transactions-table"
+          isEmpty={!hasResults}
+          emptyMessage={t('No transactions found')}
+          headers={this.renderHeader()}
           isLoading={isLoading}
+          disablePadding
+          loader={loader}
         >
-          <PanelTable
-            data-test-id="transactions-table"
-            isEmpty={!hasResults}
-            emptyMessage={t('No transactions found')}
-            headers={this.renderHeader()}
-            isLoading={isLoading}
-            disablePadding
-            loader={loader}
-          >
-            {this.renderResults()}
-          </PanelTable>
-        </VisuallyCompleteWithData>
-      </ReplayIdCountProvider>
+          {this.renderResults()}
+        </PanelTable>
+      </VisuallyCompleteWithData>
     );
   }
 }

+ 14 - 17
static/app/components/feedback/feedbackItem/replaySection.tsx

@@ -1,7 +1,6 @@
 import {useCallback} from 'react';
 
 import LazyLoad from 'sentry/components/lazyLoad';
-import ReplayIdCountProvider from 'sentry/components/replays/replayIdCountProvider';
 import {Organization} from 'sentry/types';
 import {TabKey} from 'sentry/utils/replays/hooks/useActiveReplayTab';
 
@@ -18,21 +17,19 @@ export default function ReplaySection({eventTimestampMs, organization, replayId}
   );
 
   return (
-    <ReplayIdCountProvider organization={organization} replayIds={[replayId]}>
-      <LazyLoad
-        component={replayPreview}
-        eventTimestampMs={eventTimestampMs}
-        focusTab={TabKey.BREADCRUMBS}
-        orgSlug={organization.slug}
-        replaySlug={replayId}
-        buttonProps={{
-          analyticsEventKey: 'feedback_details.open_replay_details_clicked',
-          analyticsEventName: 'Feedback Details: Open Replay Details Clicked',
-          analyticsParams: {
-            organization,
-          },
-        }}
-      />
-    </ReplayIdCountProvider>
+    <LazyLoad
+      component={replayPreview}
+      eventTimestampMs={eventTimestampMs}
+      focusTab={TabKey.BREADCRUMBS}
+      orgSlug={organization.slug}
+      replaySlug={replayId}
+      buttonProps={{
+        analyticsEventKey: 'feedback_details.open_replay_details_clicked',
+        analyticsEventName: 'Feedback Details: Open Replay Details Clicked',
+        analyticsParams: {
+          organization,
+        },
+      }}
+    />
   );
 }

+ 35 - 33
static/app/components/group/issueReplayCount.spec.tsx

@@ -2,64 +2,66 @@ import {initializeOrg} from 'sentry-test/initializeOrg';
 import {render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
 
 import IssueReplayCount from 'sentry/components/group/issueReplayCount';
-import ReplayCountContext from 'sentry/components/replays/replayCountContext';
+import useReplayCountForIssues from 'sentry/utils/replayCount/useReplayCountForIssues';
 
-jest.mock('sentry/components/replays/replayCountContext');
+jest.mock('sentry/utils/replayCount/useReplayCountForIssues');
+
+function mockCount(count: undefined | number) {
+  const getReplayCountForIssue = jest.fn().mockReturnValue(count);
+  jest.mocked(useReplayCountForIssues).mockReturnValue({
+    getReplayCountForIssue,
+    getReplayCountForIssues: jest.fn(),
+    issueHasReplay: jest.fn(),
+    issuesHaveReplay: jest.fn(),
+  });
+  return getReplayCountForIssue;
+}
 
 describe('IssueReplayCount', function () {
   const groupId = '3363325111';
   const {organization, routerContext} = initializeOrg();
 
   it('does not render when a group has undefined count', async function () {
-    const mockReplaysCount = {};
+    const mockGetReplayCountForIssue = mockCount(undefined);
 
-    const {container} = render(
-      <ReplayCountContext.Provider value={mockReplaysCount}>
-        <IssueReplayCount groupId={groupId} />
-      </ReplayCountContext.Provider>
-    );
+    const {container} = render(<IssueReplayCount groupId={groupId} />);
 
     await waitFor(() => {
       expect(container).toBeEmptyDOMElement();
     });
+
+    expect(mockGetReplayCountForIssue).toHaveBeenCalledWith(groupId);
   });
 
   it('does not render when a group has a count of zero', async function () {
-    const mockReplaysCount = {
-      [groupId]: 0,
-    };
-
-    const {container} = render(
-      <ReplayCountContext.Provider value={mockReplaysCount}>
-        <IssueReplayCount groupId={groupId} />
-      </ReplayCountContext.Provider>
-    );
+    const mockGetReplayCountForIssue = mockCount(0);
+
+    const {container} = render(<IssueReplayCount groupId={groupId} />);
 
     await waitFor(() => {
       expect(container).toBeEmptyDOMElement();
     });
+
+    expect(mockGetReplayCountForIssue).toHaveBeenCalledWith(groupId);
   });
 
   it('renders the correct replay count', async function () {
-    const mockReplaysCount = {
-      [groupId]: 2,
-    };
-
-    const {container} = render(
-      <ReplayCountContext.Provider value={mockReplaysCount}>
-        <IssueReplayCount groupId={groupId} />
-      </ReplayCountContext.Provider>,
-      {context: routerContext}
-    );
+    const mockGetReplayCountForIssue = mockCount(2);
+
+    const {container} = render(<IssueReplayCount groupId={groupId} />, {
+      context: routerContext,
+    });
 
     await waitFor(() => {
       expect(container).not.toBeEmptyDOMElement();
-      const replayCount = screen.getByLabelText('replay-count');
-      expect(replayCount).toHaveTextContent('2');
-      expect(replayCount).toHaveAttribute(
-        'href',
-        `/organizations/${organization.slug}/issues/${groupId}/replays/`
-      );
     });
+
+    const replayCount = screen.getByLabelText('replay-count');
+    expect(replayCount).toHaveTextContent('2');
+    expect(replayCount).toHaveAttribute(
+      'href',
+      `/organizations/${organization.slug}/issues/${groupId}/replays/`
+    );
+    expect(mockGetReplayCountForIssue).toHaveBeenCalledWith(groupId);
   });
 });

+ 3 - 3
static/app/components/group/issueReplayCount.tsx

@@ -1,12 +1,11 @@
-import {useContext} from 'react';
 import styled from '@emotion/styled';
 
 import Link from 'sentry/components/links/link';
-import ReplayCountContext from 'sentry/components/replays/replayCountContext';
 import {Tooltip} from 'sentry/components/tooltip';
 import {IconPlay} from 'sentry/icons';
 import {t, tn} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
+import useReplayCountForIssues from 'sentry/utils/replayCount/useReplayCountForIssues';
 import useOrganization from 'sentry/utils/useOrganization';
 import {normalizeUrl} from 'sentry/utils/withDomainRequired';
 
@@ -19,7 +18,8 @@ type Props = {
  */
 function IssueReplayCount({groupId}: Props) {
   const organization = useOrganization();
-  const count = useContext(ReplayCountContext)[groupId];
+  const {getReplayCountForIssue} = useReplayCountForIssues();
+  const count = getReplayCountForIssue(groupId);
 
   if (count === undefined || count === 0) {
     return null;

+ 3 - 4
static/app/components/issues/groupList.tsx

@@ -1,4 +1,4 @@
-import {Component} from 'react';
+import {Component, Fragment} from 'react';
 import {browserHistory, WithRouterProps} from 'react-router';
 import styled from '@emotion/styled';
 import isEqual from 'lodash/isEqual';
@@ -13,7 +13,6 @@ import Pagination from 'sentry/components/pagination';
 import Panel from 'sentry/components/panels/panel';
 import PanelBody from 'sentry/components/panels/panelBody';
 import Placeholder from 'sentry/components/placeholder';
-import IssuesReplayCountProvider from 'sentry/components/replays/issuesReplayCountProvider';
 import {parseSearch, Token} from 'sentry/components/searchSyntax/parser';
 import {treeResultLocator} from 'sentry/components/searchSyntax/utils';
 import StreamGroup, {
@@ -280,7 +279,7 @@ class GroupList extends Component<Props, State> {
         : DEFAULT_STREAM_GROUP_STATS_PERIOD;
 
     return (
-      <IssuesReplayCountProvider groupIds={groups.map(({id}) => id)}>
+      <Fragment>
         <Panel>
           <GroupListHeader
             withChart={!!withChart}
@@ -327,7 +326,7 @@ class GroupList extends Component<Props, State> {
         {withPagination && (
           <Pagination pageLinks={pageLinks} onCursor={this.handleCursorChange} />
         )}
-      </IssuesReplayCountProvider>
+      </Fragment>
     );
   }
 }

+ 0 - 51
static/app/components/replays/issuesReplayCountProvider.tsx

@@ -1,51 +0,0 @@
-import {Fragment, ReactNode} from 'react';
-
-import ReplayCountContext from 'sentry/components/replays/replayCountContext';
-import useReplaysCount from 'sentry/components/replays/useReplaysCount';
-import type {Organization} from 'sentry/types';
-import useOrganization from 'sentry/utils/useOrganization';
-
-type Props = {
-  children: ReactNode;
-  groupIds: string[];
-};
-
-/**
- * Component to make it easier to query for replay counts against a list of groups
- * that exist across many projects.
- *
- * Later on when you want to read the fetched data:
- * ```
- * import ReplayCountContext from 'sentry/components/replays/replayCountContext';
- * const count = useContext(ReplayCountContext)[groupId];
- * ```
- */
-export default function IssuesReplayCountProvider({children, groupIds}: Props) {
-  const organization = useOrganization();
-  const hasSessionReplay = organization.features.includes('session-replay');
-
-  if (hasSessionReplay) {
-    return (
-      <Provider organization={organization} groupIds={groupIds}>
-        {children}
-      </Provider>
-    );
-  }
-
-  return <Fragment>{children}</Fragment>;
-}
-
-function Provider({
-  children,
-  groupIds,
-  organization,
-}: Props & {organization: Organization}) {
-  const counts = useReplaysCount({
-    groupIds,
-    organization,
-  });
-
-  return (
-    <ReplayCountContext.Provider value={counts}>{children}</ReplayCountContext.Provider>
-  );
-}

+ 0 - 22
static/app/components/replays/replayCountContext.tsx

@@ -1,22 +0,0 @@
-import {createContext} from 'react';
-
-import type useReplaysCount from 'sentry/components/replays/useReplaysCount';
-
-/**
- * To set things up:
- * ```
- * const counts = useReplaysCount({
- *   groupIds: [id],
- *   organization,
- * });
- * return <ReplayCountContext.Provider value={counts}>{children}</ReplayCountContext.Provider>
- * ```
- *
- * And then read the data later:
- * ```
- * const count = useContext(ReplayCountContext)[groupId];
- * ```
- */
-const ReplayCountContext = createContext<ReturnType<typeof useReplaysCount>>({});
-
-export default ReplayCountContext;

+ 0 - 29
static/app/components/replays/replayIdCountProvider.tsx

@@ -1,29 +0,0 @@
-import {ReactNode, ReactText, useMemo} from 'react';
-
-import ReplayCountContext from 'sentry/components/replays/replayCountContext';
-import useReplaysCount from 'sentry/components/replays/useReplaysCount';
-import {Organization} from 'sentry/types';
-
-type Props = {
-  children: ReactNode;
-  organization: Organization;
-  replayIds: ReactText[] | string[] | undefined;
-};
-
-function unique<T>(arr: T[]) {
-  return Array.from(new Set(arr));
-}
-
-function ReplayIdCountProvider({children, organization, replayIds}: Props) {
-  const ids = useMemo(() => replayIds?.map(String)?.filter(Boolean) || [], [replayIds]);
-  const counts = useReplaysCount({
-    replayIds: unique(ids),
-    organization,
-  });
-
-  return (
-    <ReplayCountContext.Provider value={counts}>{children}</ReplayCountContext.Provider>
-  );
-}
-
-export default ReplayIdCountProvider;

+ 0 - 465
static/app/components/replays/useReplaysCount.spec.tsx

@@ -1,465 +0,0 @@
-import {ReactNode} from 'react';
-import {Organization} from 'sentry-fixture/organization';
-
-import {makeTestQueryClient} from 'sentry-test/queryClient';
-import {reactHooks} from 'sentry-test/reactTestingLibrary';
-
-import {IssueCategory} from 'sentry/types';
-import {QueryClientProvider} from 'sentry/utils/queryClient';
-import {useLocation} from 'sentry/utils/useLocation';
-
-import useReplaysCount from './useReplaysCount';
-
-jest.mock('sentry/utils/useLocation');
-
-function wrapper({children}: {children?: ReactNode}) {
-  return (
-    <QueryClientProvider client={makeTestQueryClient()}>{children}</QueryClientProvider>
-  );
-}
-
-describe('useReplaysCount', () => {
-  const mockGroupIds = ['123', '456'];
-  const mockReplayIds = ['abc', 'def'];
-  const mockTransactionNames = ['/home', '/profile'];
-
-  jest.mocked(useLocation).mockReturnValue({
-    pathname: '',
-    search: '',
-    query: {},
-    hash: '',
-    state: undefined,
-    action: 'PUSH',
-    key: '',
-  });
-
-  const organization = Organization({
-    features: ['session-replay'],
-  });
-
-  it('should throw if none of groupIds, replayIds, transactionNames is provided', () => {
-    const {result} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-      },
-    });
-    expect(result.error).toBeTruthy();
-  });
-
-  it('should throw if more than one of groupIds, replayIds, transactionNames are provided', () => {
-    const {result: result1} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        groupIds: [],
-        transactionNames: [],
-      },
-    });
-    expect(result1.error).toBeTruthy();
-
-    const {result: result2} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        groupIds: [],
-        replayIds: [],
-      },
-    });
-    expect(result2.error).toBeTruthy();
-
-    const {result: result3} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        replayIds: [],
-        transactionNames: [],
-      },
-    });
-    expect(result3.error).toBeTruthy();
-  });
-
-  it('should query for groupIds', async () => {
-    const replayCountRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {},
-    });
-
-    const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        groupIds: mockGroupIds,
-      },
-    });
-
-    expect(result.current).toEqual({});
-    expect(replayCountRequest).toHaveBeenCalledWith(
-      '/organizations/org-slug/replay-count/',
-      expect.objectContaining({
-        query: {
-          query: `issue.id:[${mockGroupIds.join(',')}]`,
-          data_source: 'discover',
-          statsPeriod: '14d',
-          project: -1,
-        },
-      })
-    );
-
-    await waitForNextUpdate();
-  });
-
-  it('should query for groupIds on performance issues', async () => {
-    const replayCountRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {},
-    });
-
-    const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        issueCategory: IssueCategory.PERFORMANCE,
-        groupIds: mockGroupIds,
-      },
-    });
-
-    expect(result.current).toEqual({});
-    expect(replayCountRequest).toHaveBeenCalledWith(
-      '/organizations/org-slug/replay-count/',
-      expect.objectContaining({
-        query: {
-          query: `issue.id:[${mockGroupIds.join(',')}]`,
-          data_source: 'search_issues',
-          statsPeriod: '14d',
-          project: -1,
-        },
-      })
-    );
-
-    await waitForNextUpdate();
-  });
-
-  it('should return the count of each groupId, or zero if not included in the response', async () => {
-    const replayCountRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {
-        123: 42,
-      },
-    });
-
-    const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        groupIds: mockGroupIds,
-      },
-    });
-
-    expect(result.current).toEqual({});
-    expect(replayCountRequest).toHaveBeenCalled();
-
-    await waitForNextUpdate();
-
-    expect(result.current).toEqual({
-      '123': 42,
-      '456': 0,
-    });
-  });
-
-  it('should request the count for a group only once', async () => {
-    const replayCountRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {},
-    });
-
-    const {result, rerender, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        groupIds: mockGroupIds,
-      },
-    });
-
-    await waitForNextUpdate();
-
-    expect(replayCountRequest).toHaveBeenCalledTimes(1);
-    expect(replayCountRequest).toHaveBeenCalledWith(
-      '/organizations/org-slug/replay-count/',
-      expect.objectContaining({
-        query: {
-          query: `issue.id:[123,456]`,
-          data_source: 'discover',
-          statsPeriod: '14d',
-          project: -1,
-        },
-      })
-    );
-    expect(result.current).toEqual({
-      123: 0,
-      456: 0,
-    });
-
-    rerender({
-      organization,
-      groupIds: [...mockGroupIds, '789'],
-    });
-
-    await waitForNextUpdate();
-
-    expect(replayCountRequest).toHaveBeenCalledTimes(2);
-    expect(replayCountRequest).toHaveBeenCalledWith(
-      '/organizations/org-slug/replay-count/',
-      expect.objectContaining({
-        query: {
-          query: `issue.id:[789]`,
-          data_source: 'discover',
-          statsPeriod: '14d',
-          project: -1,
-        },
-      })
-    );
-    expect(result.current).toEqual({
-      123: 0,
-      456: 0,
-      789: 0,
-    });
-  });
-
-  it('should not request anything if there are no new ids to query', async () => {
-    const replayCountRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {},
-    });
-
-    const {result, rerender, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        groupIds: mockGroupIds,
-      },
-    });
-
-    await waitForNextUpdate();
-
-    expect(replayCountRequest).toHaveBeenCalledTimes(1);
-    expect(replayCountRequest).toHaveBeenCalledWith(
-      '/organizations/org-slug/replay-count/',
-      expect.objectContaining({
-        query: {
-          query: `issue.id:[123,456]`,
-          data_source: 'discover',
-          statsPeriod: '14d',
-          project: -1,
-        },
-      })
-    );
-    expect(result.current).toEqual({
-      123: 0,
-      456: 0,
-    });
-
-    rerender({
-      organization,
-      groupIds: mockGroupIds,
-    });
-
-    expect(replayCountRequest).toHaveBeenCalledTimes(1);
-    expect(result.current).toEqual({
-      123: 0,
-      456: 0,
-    });
-  });
-
-  it('should query for replayId', async () => {
-    const replayCountRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {},
-    });
-
-    const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        replayIds: mockReplayIds,
-      },
-    });
-
-    expect(result.current).toEqual({});
-    expect(replayCountRequest).toHaveBeenCalledWith(
-      '/organizations/org-slug/replay-count/',
-      expect.objectContaining({
-        query: {
-          query: `replay_id:[abc,def]`,
-          data_source: 'discover',
-          statsPeriod: '14d',
-          project: -1,
-        },
-      })
-    );
-
-    await waitForNextUpdate();
-  });
-
-  it('should return the count of each replayId, or zero if not included in the response', async () => {
-    const countRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {
-        abc: 42,
-      },
-    });
-
-    const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        replayIds: mockReplayIds,
-      },
-    });
-
-    expect(result.current).toEqual({});
-    expect(countRequest).toHaveBeenCalled();
-
-    await waitForNextUpdate();
-
-    expect(result.current).toEqual({
-      abc: 42,
-      def: 0,
-    });
-  });
-
-  it('should query for transactionNames', async () => {
-    const replayCountRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {},
-    });
-
-    const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        transactionNames: mockTransactionNames,
-      },
-    });
-
-    expect(result.current).toEqual({});
-    expect(replayCountRequest).toHaveBeenCalledWith(
-      '/organizations/org-slug/replay-count/',
-      expect.objectContaining({
-        query: {
-          query: `transaction:["/home","/profile"]`,
-          data_source: 'discover',
-          statsPeriod: '14d',
-          project: -1,
-        },
-      })
-    );
-
-    await waitForNextUpdate();
-  });
-
-  it('should return the count of each transactionName, or zero if not included in the response', async () => {
-    const countRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {
-        '/home': 42,
-      },
-    });
-
-    const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        transactionNames: mockTransactionNames,
-      },
-    });
-
-    expect(result.current).toEqual({});
-    expect(countRequest).toHaveBeenCalled();
-
-    await waitForNextUpdate();
-
-    expect(result.current).toEqual({
-      '/home': 42,
-      '/profile': 0,
-    });
-  });
-
-  it('should accept start and end times and override statsPeriod', async () => {
-    const replayCountRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {},
-    });
-    const mockDate = new Date(Date.now());
-
-    const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        transactionNames: mockTransactionNames,
-        datetime: {
-          start: mockDate,
-          end: mockDate,
-        },
-      },
-    });
-
-    expect(result.current).toEqual({});
-    expect(replayCountRequest).toHaveBeenCalledWith(
-      '/organizations/org-slug/replay-count/',
-      expect.objectContaining({
-        query: {
-          query: `transaction:["/home","/profile"]`,
-          data_source: 'discover',
-          project: -1,
-          start: mockDate,
-          end: mockDate,
-        },
-      })
-    );
-
-    await waitForNextUpdate();
-  });
-
-  it('passes along extra conditions and appends them to the query', async () => {
-    const replayCountRequest = MockApiClient.addMockResponse({
-      url: `/organizations/${organization.slug}/replay-count/`,
-      method: 'GET',
-      body: {},
-    });
-
-    const {result, waitForNextUpdate} = reactHooks.renderHook(useReplaysCount, {
-      wrapper,
-      initialProps: {
-        organization,
-        transactionNames: mockTransactionNames,
-        extraConditions: 'transaction.duration>:300ms',
-      },
-    });
-
-    expect(result.current).toEqual({});
-    expect(replayCountRequest).toHaveBeenCalledWith(
-      '/organizations/org-slug/replay-count/',
-      expect.objectContaining({
-        query: {
-          query: `transaction:["/home","/profile"] transaction.duration>:300ms`,
-          data_source: 'discover',
-          project: -1,
-          statsPeriod: '14d',
-        },
-      })
-    );
-
-    await waitForNextUpdate();
-  });
-});

+ 0 - 169
static/app/components/replays/useReplaysCount.tsx

@@ -1,169 +0,0 @@
-import {useCallback, useEffect, useMemo, useState} from 'react';
-
-import {DateString, IssueCategory, Organization} from 'sentry/types';
-import {ApiQueryKey, useApiQuery} from 'sentry/utils/queryClient';
-import toArray from 'sentry/utils/toArray';
-
-type DateTime = {
-  end: DateString;
-  start: DateString;
-};
-
-type Options = {
-  organization: Organization;
-  datetime?: DateTime;
-  extraConditions?: string;
-  groupIds?: string | string[];
-  issueCategory?: IssueCategory;
-  replayIds?: string | string[];
-  transactionNames?: string | string[];
-};
-
-type CountState = Record<string, undefined | number>;
-
-function useReplaysCount({
-  issueCategory,
-  groupIds,
-  organization,
-  replayIds,
-  transactionNames,
-  extraConditions,
-  datetime,
-}: Options) {
-  const [lastData, setLastData] = useState<CountState>({});
-
-  const filterUnseen = useCallback(
-    (ids: string | string[]) => {
-      return toArray(ids).filter(id => !(id in lastData));
-    },
-    [lastData]
-  );
-
-  const zeroCounts = useMemo(() => {
-    const gIds = toArray(groupIds || []);
-    const txnNames = toArray(transactionNames || []);
-    const rIds = toArray(replayIds || []);
-    return [...gIds, ...txnNames, ...rIds].reduce<CountState>((record, key) => {
-      record[key] = 0;
-      return record;
-    }, {});
-  }, [groupIds, replayIds, transactionNames]);
-
-  const queryField = useMemo(() => {
-    const fieldsProvided = [
-      groupIds !== undefined,
-      transactionNames !== undefined,
-      replayIds !== undefined,
-    ].filter(Boolean);
-    if (fieldsProvided.length === 0) {
-      throw new Error(
-        'Missing one of: groupIds|transactionNames|replayIds in useReplaysCount()'
-      );
-    }
-    if (fieldsProvided.length > 1) {
-      throw new Error(
-        'Unable to query more than one of: groupIds|transactionNames|replayIDs simultaneously in useReplaysCount()'
-      );
-    }
-
-    if (groupIds && groupIds.length) {
-      const groupsToFetch = filterUnseen(groupIds);
-      if (groupsToFetch.length) {
-        return {
-          field: 'issue.id' as const,
-          conditions: `issue.id:[${groupsToFetch.join(',')}]`,
-        };
-      }
-      return null;
-    }
-
-    if (replayIds && replayIds.length) {
-      const replaysToFetch = filterUnseen(replayIds);
-      if (replaysToFetch.length) {
-        return {
-          field: 'replay_id' as const,
-          conditions: `replay_id:[${replaysToFetch.join(',')}]`,
-        };
-      }
-      return null;
-    }
-
-    if (transactionNames && transactionNames.length) {
-      const txnsToFetch = filterUnseen(transactionNames);
-      if (txnsToFetch.length) {
-        return {
-          field: 'transaction' as const,
-          conditions: `transaction:[${txnsToFetch.map(t => `"${t}"`).join(',')}]`,
-        };
-      }
-      return null;
-    }
-    return null;
-  }, [filterUnseen, groupIds, replayIds, transactionNames]);
-
-  const hasSessionReplay = organization.features.includes('session-replay');
-  const {data, isFetched} = useApiQuery<CountState>(
-    makeReplayCountsQueryKey({
-      organization,
-      conditions: [queryField?.conditions ?? '', extraConditions ?? ''],
-      datetime,
-      issueCategory,
-    }),
-    {
-      staleTime: Infinity,
-      enabled: Boolean(queryField) && hasSessionReplay,
-    }
-  );
-
-  useEffect(() => {
-    if (isFetched) {
-      setLastData(last => ({
-        ...zeroCounts,
-        ...last,
-        ...data,
-      }));
-    }
-  }, [isFetched, zeroCounts, data]);
-
-  return useMemo<CountState>(() => {
-    return {
-      ...lastData,
-      ...data,
-    };
-  }, [lastData, data]);
-}
-
-function makeReplayCountsQueryKey({
-  conditions,
-  datetime,
-  issueCategory,
-  organization,
-}: {
-  conditions: string[];
-  datetime: undefined | DateTime;
-  issueCategory: undefined | IssueCategory;
-  organization: Organization;
-}): ApiQueryKey {
-  return [
-    `/organizations/${organization.slug}/replay-count/`,
-    {
-      query: {
-        query: conditions.filter(Boolean).join(' ').trim(),
-        data_source: getDatasource(issueCategory),
-        project: -1,
-        ...(datetime ? {...datetime, statsPeriod: undefined} : {statsPeriod: '14d'}),
-      },
-    },
-  ];
-}
-
-function getDatasource(issueCategory: undefined | IssueCategory) {
-  switch (issueCategory) {
-    case IssueCategory.PERFORMANCE:
-      return 'search_issues';
-    default:
-      return 'discover';
-  }
-}
-
-export default useReplaysCount;

Some files were not shown because too many files changed in this diff