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

ref(tests): use MockApiClient instead of Client (#52272)

Seems like the majority of codebase uses MockApiClient instead of Client
and having two separate usage patterns is confusing (all Client imports
seem a few years old)

Tbqh, I would like to see us remove the separate mock client
implementation in the future and rely on something like fetch-mock or
similar where we mock the responses and keep the implementation close to
the actual fetch schema. As it currently stands, the separate
implementation of MockApiClient also risks falling out of sync with the
Client and we risk testing code that will run differently in prod.
Jonas 1 год назад
Родитель
Сommit
65c1ea2f13

+ 5 - 3
static/app/__mocks__/api.tsx

@@ -32,7 +32,7 @@ interface MatchCallable {
 }
 
 type AsyncDelay = undefined | number;
-type ResponseType = ApiNamespace.ResponseMeta & {
+interface ResponseType extends ApiNamespace.ResponseMeta {
   body: any;
   callCount: 0;
   headers: Record<string, string>;
@@ -49,7 +49,7 @@ type ResponseType = ApiNamespace.ResponseMeta & {
    * This will override `MockApiClient.asyncDelay` for this request.
    */
   asyncDelay?: AsyncDelay;
-};
+}
 
 type MockResponse = [resp: ResponseType, mock: jest.Mock];
 
@@ -171,7 +171,9 @@ class Client implements ApiNamespace.Client {
    * In the real client, this clears in-flight responses. It's NOT
    * clearMockResponses. You probably don't want to call this from a test.
    */
-  clear() {}
+  clear() {
+    Object.values(this.activeRequests).forEach(r => r.cancel());
+  }
 
   wrapCallback<T extends any[]>(
     _id: string,

+ 1 - 2
static/app/actionCreators/events.spec.tsx

@@ -1,8 +1,7 @@
 import {doEventsRequest} from 'sentry/actionCreators/events';
-import {Client} from 'sentry/api';
 
 describe('Events ActionCreator', function () {
-  const api = new Client();
+  const api = new MockApiClient();
   const organization = TestStubs.Organization();
   const project = TestStubs.Project();
   const opts = {

+ 5 - 12
static/app/actionCreators/group.spec.tsx

@@ -1,14 +1,7 @@
 import {bulkUpdate, mergeGroups, paramsToQueryArgs} from 'sentry/actionCreators/group';
-import {Client} from 'sentry/api';
 import GroupStore from 'sentry/stores/groupStore';
 
 describe('group', () => {
-  let api: Client;
-
-  beforeEach(function () {
-    api = new MockApiClient();
-  });
-
   describe('paramsToQueryArgs()', function () {
     it('should convert itemIds properties to id array', function () {
       expect(
@@ -92,7 +85,7 @@ describe('group', () => {
       });
 
       bulkUpdate(
-        api,
+        new MockApiClient(),
         {
           orgId: '1337',
           projectId: '1337',
@@ -117,7 +110,7 @@ describe('group', () => {
       });
 
       bulkUpdate(
-        api,
+        new MockApiClient(),
         {
           orgId: '1337',
           projectId: '1337',
@@ -142,7 +135,7 @@ describe('group', () => {
       });
 
       bulkUpdate(
-        api,
+        new MockApiClient(),
         {
           orgId: '1337',
           project: [99],
@@ -174,7 +167,7 @@ describe('group', () => {
       });
 
       mergeGroups(
-        api,
+        new MockApiClient(),
         {
           orgId: '1337',
           projectId: '1337',
@@ -198,7 +191,7 @@ describe('group', () => {
       });
 
       mergeGroups(
-        api,
+        new MockApiClient(),
         {
           orgId: '1337',
           projectId: '1337',

+ 1 - 2
static/app/actionCreators/projects.spec.tsx

@@ -1,10 +1,9 @@
 import {initializeOrg} from 'sentry-test/initializeOrg';
 
 import {_debouncedLoadStats} from 'sentry/actionCreators/projects';
-import {Client} from 'sentry/api';
 
 describe('Projects ActionCreators', function () {
-  const api = new Client();
+  const api = new MockApiClient();
   const {organization, project} = initializeOrg();
 
   it('loadStatsForProject', function () {

+ 2 - 2
static/app/api.spec.tsx

@@ -1,4 +1,4 @@
-import {Client, Request} from 'sentry/api';
+import {Request} from 'sentry/api';
 import {PROJECT_MOVED} from 'sentry/constants/apiErrorCodes';
 
 jest.unmock('sentry/api');
@@ -7,7 +7,7 @@ describe('api', function () {
   let api;
 
   beforeEach(function () {
-    api = new Client();
+    api = new MockApiClient();
   });
 
   describe('Client', function () {

+ 6 - 7
static/app/components/assigneeSelector.spec.jsx

@@ -1,7 +1,6 @@
 import {act, render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
 
 import {openInviteMembersModal} from 'sentry/actionCreators/modal';
-import {Client} from 'sentry/api';
 import AssigneeSelectorComponent from 'sentry/components/assigneeSelector';
 import {putSessionUserFirst} from 'sentry/components/assigneeSelectorDropdown';
 import ConfigStore from 'sentry/stores/configStore';
@@ -88,7 +87,7 @@ describe('AssigneeSelector', () => {
     jest.spyOn(ProjectsStore, 'getAll').mockImplementation(() => [PROJECT_1]);
     jest.spyOn(GroupStore, 'get').mockImplementation(() => GROUP_1);
 
-    assignMock = Client.addMockResponse({
+    assignMock = MockApiClient.addMockResponse({
       method: 'PUT',
       url: `/issues/${GROUP_1.id}/`,
       body: {
@@ -97,7 +96,7 @@ describe('AssigneeSelector', () => {
       },
     });
 
-    assignGroup2Mock = Client.addMockResponse({
+    assignGroup2Mock = MockApiClient.addMockResponse({
       method: 'PUT',
       url: `/issues/${GROUP_2.id}/`,
       body: {
@@ -118,7 +117,7 @@ describe('AssigneeSelector', () => {
   };
 
   afterEach(() => {
-    Client.clearMockResponses();
+    MockApiClient.clearMockResponses();
   });
 
   describe('render with props', () => {
@@ -218,8 +217,8 @@ describe('AssigneeSelector', () => {
   });
 
   it('successfully assigns teams', async () => {
-    Client.clearMockResponses();
-    assignMock = Client.addMockResponse({
+    MockApiClient.clearMockResponses();
+    assignMock = MockApiClient.addMockResponse({
       method: 'PUT',
       url: `/issues/${GROUP_1.id}/`,
       body: {
@@ -329,7 +328,7 @@ describe('AssigneeSelector', () => {
     render(<AssigneeSelectorComponent id={GROUP_2.id} />);
     act(() => MemberListStore.loadInitialData([USER_1, USER_2, USER_3, USER_4]));
 
-    assignMock = Client.addMockResponse({
+    assignMock = MockApiClient.addMockResponse({
       method: 'PUT',
       url: `/issues/${GROUP_2.id}/`,
       statusCode: 400,

+ 0 - 2
static/app/components/discover/transactionsList.spec.jsx

@@ -1,7 +1,6 @@
 import {initializeOrg} from 'sentry-test/initializeOrg';
 import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
 
-import {Client} from 'sentry/api';
 import TransactionsList from 'sentry/components/discover/transactionsList';
 import {t} from 'sentry/locale';
 import EventView from 'sentry/utils/discover/eventView';
@@ -35,7 +34,6 @@ describe('TransactionsList', function () {
   };
 
   beforeEach(function () {
-    api = new Client();
     location = {
       pathname: '/',
       query: {},

+ 1 - 2
static/app/components/events/interfaces/spans/spanTreeModel.spec.tsx

@@ -1,6 +1,5 @@
 import {waitFor} from 'sentry-test/reactTestingLibrary';
 
-import {Client} from 'sentry/api';
 import SpanTreeModel from 'sentry/components/events/interfaces/spans/spanTreeModel';
 import {EnhancedProcessedSpanType} from 'sentry/components/events/interfaces/spans/types';
 import {
@@ -13,7 +12,7 @@ import {assert} from 'sentry/types/utils';
 import {generateEventSlug} from 'sentry/utils/discover/urls';
 
 describe('SpanTreeModel', () => {
-  const api: Client = new Client();
+  const api = new MockApiClient();
 
   const event = {
     id: '2b658a829a21496b87fd1f14a61abf65',

+ 5 - 6
static/app/components/group/sentryAppExternalIssueForm.spec.jsx

@@ -2,7 +2,6 @@ import selectEvent from 'react-select-event';
 
 import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
 
-import {Client} from 'sentry/api';
 import SentryAppExternalIssueForm from 'sentry/components/group/sentryAppExternalIssueForm';
 import {addQueryParamsToExistingUrl} from 'sentry/utils/queryString';
 
@@ -39,7 +38,7 @@ describe('SentryAppExternalIssueForm', () => {
           appName={sentryApp.name}
           config={component.schema.create}
           action="create"
-          api={new Client()}
+          api={new MockApiClient()}
         />
       );
 
@@ -89,7 +88,7 @@ describe('SentryAppExternalIssueForm', () => {
           appName={sentryApp.name}
           config={component.schema.create}
           action="create"
-          api={new Client()}
+          api={new MockApiClient()}
         />
       );
       expect(screen.getByRole('textbox', {name: 'Title'})).toHaveValue(`${group.title}`);
@@ -112,7 +111,7 @@ describe('SentryAppExternalIssueForm', () => {
           appName={sentryApp.name}
           config={component.schema.link}
           action="link"
-          api={new Client()}
+          api={new MockApiClient()}
         />
       );
 
@@ -173,7 +172,7 @@ describe('SentryAppExternalIssueForm Async Field', () => {
         appName={sentryApp.name}
         config={component.schema.create}
         action="create"
-        api={new Client()}
+        api={new MockApiClient()}
       />
     );
 
@@ -238,7 +237,7 @@ describe('SentryAppExternalIssueForm Dependent fields', () => {
         appName={sentryApp.name}
         config={component.schema.create}
         action="create"
-        api={new Client()}
+        api={new MockApiClient()}
       />
     );
 

+ 1 - 2
static/app/components/modals/dashboardWidgetQuerySelectorModal.spec.tsx

@@ -1,14 +1,13 @@
 import {initializeOrg} from 'sentry-test/initializeOrg';
 import {render, screen} from 'sentry-test/reactTestingLibrary';
 
-import {Client} from 'sentry/api';
 import DashboardWidgetQuerySelectorModal from 'sentry/components/modals/dashboardWidgetQuerySelectorModal';
 import {t} from 'sentry/locale';
 import {DisplayType} from 'sentry/views/dashboards/types';
 
 const stubEl: any = (props: any) => <div>{props.children}</div>;
 
-const api: Client = new Client();
+const api = new MockApiClient();
 
 function renderModal({initialData, widget}) {
   return render(

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