Просмотр исходного кода

Elias/fix/mock api client warn mode (#39289)

This is a follow up PR to this:
https://github.com/getsentry/sentry/pull/38769

tldr; mock client errors were being gobbled up by a `setTimeout` and in
certain scenarios where we had alot of tests we would associate mock
client errors with the wrong test. this PR enforces that we error if we
are missing a mock response. for existing tests which are missing mocks
we've exposed a `warnOnMissingMocks` mode. this method is marked as
`@deprecated` and should show up with a strikethrough/message w/
intellisense

![image](https://user-images.githubusercontent.com/7349258/192304820-eb649a4f-9e1d-484f-aa4f-d932f60d08e3.png)
Elias Hussary 2 лет назад
Родитель
Сommit
a314f964fa

+ 13 - 2
static/app/__mocks__/api.tsx

@@ -61,11 +61,17 @@ afterEach(() => {
   const errors = Object.values(Client.errors);
   if (errors.length > 0) {
     for (const err of errors) {
+      if (Client.shouldWarnOnMissingMocks) {
+        // eslint-disable-next-line no-console
+        console.warn(err);
+        continue;
+      }
       // eslint-disable-next-line no-console
-      console.warn(err);
+      console.error(err);
     }
     Client.errors = {};
   }
+  Client.shouldWarnOnMissingMocks = false;
 });
 
 class Client implements ApiNamespace.Client {
@@ -212,9 +218,14 @@ class Client implements ApiNamespace.Client {
     });
   }
 
-  // XXX(ts): We type the return type for requestPromise and request as `any`. Typically these woul
+  static shouldWarnOnMissingMocks: boolean = false;
 
+  /**
+   * @deprecated DO NOT USE THIS FUNCTION; we're using it to mark existing tests which do not correctly mock responses and would otherwise throw
+   */
+  static warnOnMissingMocks = () => (Client.shouldWarnOnMissingMocks = true);
   static errors: Record<string, Error> = {};
+  // XXX(ts): We type the return type for requestPromise and request as `any`. Typically these woul
   request(url: string, options: Readonly<ApiNamespace.RequestOptions> = {}): any {
     const [response, mock] = Client.findMockResponse(url, options) || [
       undefined,

+ 5 - 0
static/app/actionCreators/group.spec.jsx

@@ -86,6 +86,7 @@ describe('group', () => {
     });
 
     it('should use itemIds as query if provided', function () {
+      MockApiClient.warnOnMissingMocks();
       bulkUpdate(api, {
         orgId: '1337',
         projectId: '1337',
@@ -102,6 +103,7 @@ describe('group', () => {
     });
 
     it('should use query as query if itemIds are absent', function () {
+      MockApiClient.warnOnMissingMocks();
       bulkUpdate(api, {
         orgId: '1337',
         projectId: '1337',
@@ -118,6 +120,7 @@ describe('group', () => {
     });
 
     it('should apply project option', function () {
+      MockApiClient.warnOnMissingMocks();
       bulkUpdate(api, {
         orgId: '1337',
         project: [99],
@@ -142,6 +145,7 @@ describe('group', () => {
     });
 
     it('should use itemIds as query if provided', function () {
+      MockApiClient.warnOnMissingMocks();
       mergeGroups(api, {
         orgId: '1337',
         projectId: '1337',
@@ -158,6 +162,7 @@ describe('group', () => {
     });
 
     it('should use query as query if itemIds are absent', function () {
+      MockApiClient.warnOnMissingMocks();
       mergeGroups(api, {
         orgId: '1337',
         projectId: '1337',

+ 4 - 0
static/app/components/events/interfaces/frame/stacktraceLink.spec.jsx

@@ -79,6 +79,7 @@ describe('StacktraceLink', function () {
       query: {file: frame.filename, commitId: 'master', platform},
       body: {config, sourceUrl: 'https://something.io', integrations: [integration]},
     });
+    MockApiClient.warnOnMissingMocks();
     const wrapper = mountWithTheme(
       <StacktraceLink
         frame={frame}
@@ -104,6 +105,7 @@ describe('StacktraceLink', function () {
         attemptedUrl: 'https://something.io/blah',
       },
     });
+    MockApiClient.warnOnMissingMocks();
     const wrapper = mountWithTheme(
       <StacktraceLink
         frame={frame}
@@ -131,6 +133,7 @@ describe('StacktraceLink', function () {
         integrations: [integration],
       },
     });
+    MockApiClient.warnOnMissingMocks();
     const wrapper = mountWithTheme(
       <StacktraceLink
         frame={frame}
@@ -156,6 +159,7 @@ describe('StacktraceLink', function () {
         integrations: [integration],
       },
     });
+    MockApiClient.warnOnMissingMocks();
     const wrapper = mountWithTheme(
       <StacktraceLink
         frame={frame}

+ 1 - 0
static/app/components/events/interfaces/threadsV2.spec.tsx

@@ -1079,6 +1079,7 @@ describe('ThreadsV2', function () {
         ).toBeInTheDocument();
 
         // Click on raw stack trace option
+        MockApiClient.warnOnMissingMocks();
         userEvent.click(screen.getByText(displayOptions['raw-stack-trace']));
 
         // Download button is displayed

+ 1 - 0
static/app/components/forms/teamSelector.spec.jsx

@@ -125,6 +125,7 @@ describe('Team Selector', function () {
     createWrapper({useId: true, onChange: onChangeMock});
     userEvent.type(screen.getByText('Select...'), '{keyDown}');
 
+    MockApiClient.warnOnMissingMocks();
     userEvent.type(screen.getByLabelText('Select a team'), 'team2');
 
     expect(screen.getByText('#team2')).toBeInTheDocument();

+ 1 - 0
static/app/components/globalSdkUpdateAlert.spec.tsx

@@ -234,6 +234,7 @@ describe('GlobalSDKUpdateAlert', () => {
       organization: TestStubs.Organization(),
     });
 
+    MockApiClient.warnOnMissingMocks();
     userEvent.click(await screen.findByText(/Remind me later/));
 
     expect(promptsActivityMock).toHaveBeenCalledWith(

+ 1 - 0
static/app/components/modals/diffModal.spec.jsx

@@ -6,6 +6,7 @@ describe('DiffModal', function () {
   it('renders', function () {
     const project = TestStubs.ProjectDetails();
 
+    MockApiClient.warnOnMissingMocks();
     render(
       <DiffModal
         orgId="123"

+ 2 - 0
static/app/components/modals/emailVerificationModal.spec.tsx

@@ -4,6 +4,7 @@ import EmailVerificationModal from 'sentry/components/modals/emailVerificationMo
 
 describe('Email Verification Modal', function () {
   it('renders', function () {
+    MockApiClient.warnOnMissingMocks();
     render(
       <EmailVerificationModal
         Body={(p => p.children) as any}
@@ -23,6 +24,7 @@ describe('Email Verification Modal', function () {
 
   it('renders with action param', function () {
     const actionMessage = 'accepting the tenet';
+    MockApiClient.warnOnMissingMocks();
     render(
       <EmailVerificationModal
         Body={(p => p.children) as any}

+ 6 - 0
static/app/components/quickTrace/quickTrace.spec.tsx

@@ -127,6 +127,7 @@ describe('Quick Trace', function () {
     });
 
     it('renders partial trace with no children', function () {
+      MockApiClient.warnOnMissingMocks();
       const quickTrace = mountWithTheme(
         <QuickTrace
           event={makeTransactionEvent(4) as Event}
@@ -169,6 +170,7 @@ describe('Quick Trace', function () {
     });
 
     it('renders partial trace with multiple children', function () {
+      MockApiClient.warnOnMissingMocks();
       const quickTrace = mountWithTheme(
         <QuickTrace
           event={makeTransactionEvent(4) as Event}
@@ -242,6 +244,7 @@ describe('Quick Trace', function () {
     });
 
     it('renders full trace with multiple ancestors', function () {
+      MockApiClient.warnOnMissingMocks();
       const quickTrace = mountWithTheme(
         <QuickTrace
           event={makeTransactionEvent(5) as Event}
@@ -297,6 +300,7 @@ describe('Quick Trace', function () {
     });
 
     it('renders full trace with multiple descendants', function () {
+      MockApiClient.warnOnMissingMocks();
       const quickTrace = mountWithTheme(
         <QuickTrace
           event={makeTransactionEvent(0) as Event}
@@ -325,6 +329,7 @@ describe('Quick Trace', function () {
     });
 
     it('renders full trace', function () {
+      MockApiClient.warnOnMissingMocks();
       const quickTrace = mountWithTheme(
         <QuickTrace
           event={makeTransactionEvent(5) as Event}
@@ -394,6 +399,7 @@ describe('Quick Trace', function () {
     });
 
     it('renders multiple event targets', function () {
+      MockApiClient.warnOnMissingMocks();
       const quickTrace = mountWithTheme(
         <QuickTrace
           event={makeTransactionEvent(0) as Event}

+ 1 - 0
static/app/views/admin/adminBuffer.spec.jsx

@@ -7,6 +7,7 @@ import AdminBuffer from 'sentry/views/admin/adminBuffer';
 describe('AdminBuffer', function () {
   describe('render()', function () {
     it('renders', function () {
+      MockApiClient.warnOnMissingMocks();
       const wrapper = render(<AdminBuffer params={{}} />);
 
       expect(screen.getAllByTestId('loading-indicator')).toHaveLength(2);

Некоторые файлы не были показаны из-за большого количества измененных файлов