Browse Source

chore(discover): Moves saved query tests from jsx to tsx (#32692)

Moves the remaining jsx tests from saved query to tsx.
edwardgou-sentry 3 years ago
parent
commit
849af56317

+ 0 - 421
tests/js/spec/views/eventsV2/savedQuery/index.spec.jsx

@@ -1,421 +0,0 @@
-import {mountWithTheme} from 'sentry-test/enzyme';
-
-import EventView from 'sentry/utils/discover/eventView';
-import {DisplayModes} from 'sentry/utils/discover/types';
-import DiscoverBanner from 'sentry/views/eventsV2/banner';
-import {ALL_VIEWS} from 'sentry/views/eventsV2/data';
-import SavedQueryButtonGroup from 'sentry/views/eventsV2/savedQuery';
-import * as utils from 'sentry/views/eventsV2/savedQuery/utils';
-
-const SELECTOR_BUTTON_SAVE_AS = 'button[aria-label="Save as"]';
-const SELECTOR_BUTTON_SAVED = '[data-test-id="discover2-savedquery-button-saved"]';
-const SELECTOR_BUTTON_UPDATE = '[data-test-id="discover2-savedquery-button-update"]';
-const SELECTOR_BUTTON_DELETE = '[data-test-id="discover2-savedquery-button-delete"]';
-const SELECTOR_BUTTON_CREATE_ALERT = '[data-test-id="discover2-create-from-discover"]';
-
-function generateWrappedComponent(
-  location,
-  organization,
-  eventView,
-  savedQuery,
-  yAxis,
-  disabled = false
-) {
-  return mountWithTheme(
-    <SavedQueryButtonGroup
-      location={location}
-      organization={organization}
-      eventView={eventView}
-      savedQuery={savedQuery}
-      disabled={disabled}
-      updateCallback={() => {}}
-      yAxis={yAxis}
-    />
-  );
-}
-
-describe('EventsV2 > SaveQueryButtonGroup', function () {
-  // Organization + Location does not affect state in this component
-  const organization = TestStubs.Organization({
-    features: ['discover-query', 'dashboards-edit'],
-  });
-  const location = {
-    pathname: '/organization/eventsv2/',
-    query: {},
-  };
-  const yAxis = ['count()', 'failure_count()'];
-
-  const errorsQuery = {
-    ...ALL_VIEWS.find(view => view.name === 'Errors by Title'),
-    yAxis: 'count()',
-    display: DisplayModes.DEFAULT,
-  };
-  const errorsView = EventView.fromSavedQuery(errorsQuery);
-
-  const errorsViewSaved = EventView.fromSavedQuery(errorsQuery);
-  errorsViewSaved.id = '1';
-
-  const errorsViewModified = EventView.fromSavedQuery(errorsQuery);
-  errorsViewModified.id = '1';
-  errorsViewModified.name = 'Modified Name';
-
-  const savedQuery = {...errorsViewSaved.toNewQuery(), yAxis};
-
-  describe('building on a new query', () => {
-    const mockUtils = jest
-      .spyOn(utils, 'handleCreateQuery')
-      .mockImplementation(() => Promise.resolve(savedQuery));
-
-    beforeEach(() => {
-      mockUtils.mockClear();
-    });
-
-    it('renders disabled buttons when disabled prop is used', () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsView,
-        undefined,
-        yAxis,
-        true
-      );
-
-      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
-      expect(buttonSaveAs.props()['aria-disabled']).toBe(true);
-    });
-
-    it('renders the correct set of buttons', () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsView,
-        undefined,
-        yAxis
-      );
-
-      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
-      const buttonSaved = wrapper.find(SELECTOR_BUTTON_SAVED);
-      const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE);
-      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE);
-
-      expect(buttonSaveAs.exists()).toBe(true);
-      expect(buttonSaved.exists()).toBe(false);
-      expect(buttonUpdate.exists()).toBe(false);
-      expect(buttonDelete.exists()).toBe(false);
-    });
-
-    it('hides the banner when save is complete.', async () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsView,
-        undefined,
-        yAxis
-      );
-
-      // Click on ButtonSaveAs to open dropdown
-      const buttonSaveAs = wrapper.find('DropdownControl').first();
-      buttonSaveAs.simulate('click');
-
-      // Fill in the Input
-      buttonSaveAs
-        .find('ButtonSaveInput')
-        .simulate('change', {target: {value: 'My New Query Name'}}); // currentTarget.value does not work
-      await tick();
-
-      // Click on Save in the Dropdown
-      await buttonSaveAs.find('ButtonSaveDropDown Button').simulate('click');
-
-      // The banner should not render
-      const banner = mountWithTheme(<DiscoverBanner />);
-      expect(banner.find('BannerTitle').exists()).toBe(false);
-    });
-
-    it('saves a well-formed query', async () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsView,
-        undefined,
-        yAxis
-      );
-
-      // Click on ButtonSaveAs to open dropdown
-      const buttonSaveAs = wrapper.find('DropdownControl').first();
-      buttonSaveAs.simulate('click');
-
-      // Fill in the Input
-      buttonSaveAs
-        .find('ButtonSaveInput')
-        .simulate('change', {target: {value: 'My New Query Name'}}); // currentTarget.value does not work
-      await tick();
-
-      // Click on Save in the Dropdown
-      await buttonSaveAs.find('ButtonSaveDropDown Button').simulate('click');
-
-      expect(mockUtils).toHaveBeenCalledWith(
-        expect.anything(), // api
-        organization,
-        expect.objectContaining({
-          ...errorsView,
-          name: 'My New Query Name',
-        }),
-        yAxis,
-        true
-      );
-    });
-
-    it('rejects if query.name is empty', async () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsView,
-        undefined,
-        yAxis
-      );
-
-      // Click on ButtonSaveAs to open dropdown
-      const buttonSaveAs = wrapper.find('DropdownControl').first();
-      buttonSaveAs.simulate('click');
-
-      // Do not fill in Input
-      await tick();
-
-      // Click on Save in the Dropdown
-      buttonSaveAs.find('ButtonSaveDropDown Button').simulate('click');
-
-      // Check that EventView has a name
-      expect(errorsView.name).toBe('Errors by Title');
-
-      expect(mockUtils).not.toHaveBeenCalled();
-    });
-  });
-
-  describe('viewing a saved query', () => {
-    let mockUtils;
-
-    beforeEach(() => {
-      mockUtils = jest
-        .spyOn(utils, 'handleDeleteQuery')
-        .mockImplementation(() => Promise.resolve(savedQuery));
-    });
-
-    afterEach(() => {
-      mockUtils.mockClear();
-    });
-
-    it('renders the correct set of buttons', () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsViewSaved,
-        savedQuery,
-        yAxis
-      );
-
-      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
-      const buttonSaved = wrapper.find(SELECTOR_BUTTON_SAVED);
-      const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE);
-      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE);
-
-      expect(buttonSaveAs.exists()).toBe(false);
-      expect(buttonSaved.exists()).toBe(true);
-      expect(buttonUpdate.exists()).toBe(false);
-      expect(buttonDelete.exists()).toBe(true);
-    });
-
-    it('treats undefined yAxis the same as count() when checking for changes', () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsViewSaved,
-        {...savedQuery, yAxis: undefined},
-        ['count()']
-      );
-
-      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
-      const buttonSaved = wrapper.find(SELECTOR_BUTTON_SAVED);
-      const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE);
-      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE);
-
-      expect(buttonSaveAs.exists()).toBe(false);
-      expect(buttonSaved.exists()).toBe(true);
-      expect(buttonUpdate.exists()).toBe(false);
-      expect(buttonDelete.exists()).toBe(true);
-    });
-
-    it('converts string yAxis values to array when checking for changes', () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsViewSaved,
-        {...savedQuery, yAxis: 'count()'},
-        ['count()']
-      );
-
-      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
-      const buttonSaved = wrapper.find(SELECTOR_BUTTON_SAVED);
-      const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE);
-      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE);
-
-      expect(buttonSaveAs.exists()).toBe(false);
-      expect(buttonSaved.exists()).toBe(true);
-      expect(buttonUpdate.exists()).toBe(false);
-      expect(buttonDelete.exists()).toBe(true);
-    });
-
-    it('deletes the saved query', async () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsViewSaved,
-        savedQuery,
-        yAxis
-      );
-
-      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE).first();
-      await buttonDelete.simulate('click');
-
-      expect(mockUtils).toHaveBeenCalledWith(
-        expect.anything(), // api
-        organization,
-        expect.objectContaining({id: '1'})
-      );
-    });
-  });
-
-  describe('modifying a saved query', () => {
-    let mockUtils;
-
-    it('renders the correct set of buttons', () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsViewModified,
-        errorsViewSaved.toNewQuery(),
-        yAxis
-      );
-
-      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
-      const buttonSaved = wrapper.find(SELECTOR_BUTTON_SAVED);
-      const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE);
-      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE);
-
-      expect(buttonSaveAs.exists()).toBe(true);
-      expect(buttonSaved.exists()).toBe(false);
-      expect(buttonUpdate.exists()).toBe(true);
-      expect(buttonDelete.exists()).toBe(true);
-    });
-
-    describe('updates the saved query', () => {
-      beforeEach(() => {
-        mockUtils = jest
-          .spyOn(utils, 'handleUpdateQuery')
-          .mockImplementation(() => Promise.resolve(savedQuery));
-      });
-
-      afterEach(() => {
-        mockUtils.mockClear();
-      });
-
-      it('accepts a well-formed query', async () => {
-        const wrapper = generateWrappedComponent(
-          location,
-          organization,
-          errorsViewModified,
-          savedQuery,
-          yAxis
-        );
-
-        // Click on Save in the Dropdown
-        const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE).first();
-        await buttonUpdate.simulate('click');
-
-        expect(mockUtils).toHaveBeenCalledWith(
-          expect.anything(), // api
-          organization,
-          expect.objectContaining({
-            ...errorsViewModified,
-          }),
-          yAxis
-        );
-      });
-    });
-
-    describe('creates a separate query', () => {
-      beforeEach(() => {
-        mockUtils = jest
-          .spyOn(utils, 'handleCreateQuery')
-          .mockImplementation(() => Promise.resolve(savedQuery));
-      });
-
-      afterEach(() => {
-        mockUtils.mockClear();
-      });
-
-      it('checks that it is forked from a saved query', async () => {
-        const wrapper = generateWrappedComponent(
-          location,
-          organization,
-          errorsViewModified,
-          savedQuery,
-          yAxis
-        );
-
-        // Click on ButtonSaveAs to open dropdown
-        const buttonSaveAs = wrapper.find('DropdownControl').first();
-        buttonSaveAs.simulate('click');
-
-        // Fill in the Input
-        buttonSaveAs
-          .find('ButtonSaveInput')
-          .simulate('change', {target: {value: 'Forked Query'}});
-        await tick();
-
-        // Click on Save in the Dropdown
-        await buttonSaveAs.find('ButtonSaveDropDown Button').simulate('click');
-
-        expect(mockUtils).toHaveBeenCalledWith(
-          expect.anything(), // api
-          organization,
-          expect.objectContaining({
-            ...errorsViewModified,
-            name: 'Forked Query',
-          }),
-          yAxis,
-          false
-        );
-      });
-    });
-  });
-  describe('create alert from discover', () => {
-    it('renders create alert button when metrics alerts is enabled', () => {
-      const metricAlertOrg = {
-        ...organization,
-        features: ['incidents'],
-      };
-      const wrapper = generateWrappedComponent(
-        location,
-        metricAlertOrg,
-        errorsViewModified,
-        savedQuery,
-        yAxis
-      );
-      const buttonCreateAlert = wrapper.find(SELECTOR_BUTTON_CREATE_ALERT);
-
-      expect(buttonCreateAlert.exists()).toBe(true);
-    });
-    it('does not render create alert button without metric alerts', () => {
-      const wrapper = generateWrappedComponent(
-        location,
-        organization,
-        errorsViewModified,
-        savedQuery,
-        yAxis
-      );
-      const buttonCreateAlert = wrapper.find(SELECTOR_BUTTON_CREATE_ALERT);
-
-      expect(buttonCreateAlert.exists()).toBe(false);
-    });
-  });
-});

+ 425 - 1
tests/js/spec/views/eventsV2/savedQuery/index.spec.tsx

@@ -1,3 +1,4 @@
+import {mountWithTheme} from 'sentry-test/enzyme';
 import {initializeOrg} from 'sentry-test/initializeOrg';
 import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
 
@@ -5,8 +6,16 @@ import {openAddDashboardWidgetModal} from 'sentry/actionCreators/modal';
 import {NewQuery} from 'sentry/types';
 import EventView from 'sentry/utils/discover/eventView';
 import {DisplayModes} from 'sentry/utils/discover/types';
+import DiscoverBanner from 'sentry/views/eventsV2/banner';
 import {ALL_VIEWS} from 'sentry/views/eventsV2/data';
 import SavedQueryButtonGroup from 'sentry/views/eventsV2/savedQuery';
+import * as utils from 'sentry/views/eventsV2/savedQuery/utils';
+
+const SELECTOR_BUTTON_SAVE_AS = 'button[aria-label="Save as"]';
+const SELECTOR_BUTTON_SAVED = '[data-test-id="discover2-savedquery-button-saved"]';
+const SELECTOR_BUTTON_UPDATE = '[data-test-id="discover2-savedquery-button-update"]';
+const SELECTOR_BUTTON_DELETE = '[data-test-id="discover2-savedquery-button-delete"]';
+const SELECTOR_BUTTON_CREATE_ALERT = '[data-test-id="discover2-create-from-discover"]';
 
 jest.mock('sentry/actionCreators/modal');
 
@@ -34,8 +43,42 @@ function mount(
     />
   );
 }
+function generateWrappedComponent(
+  location,
+  organization,
+  router,
+  eventView,
+  savedQuery,
+  yAxis,
+  disabled = false
+) {
+  return mountWithTheme(
+    <SavedQueryButtonGroup
+      location={location}
+      organization={organization}
+      eventView={eventView}
+      savedQuery={savedQuery}
+      disabled={disabled}
+      updateCallback={() => {}}
+      yAxis={yAxis}
+      onIncompatibleAlertQuery={() => undefined}
+      router={router}
+      savedQueryLoading={false}
+    />
+  );
+}
 
 describe('EventsV2 > SaveQueryButtonGroup', function () {
+  const organization = TestStubs.Organization({
+    features: ['discover-query', 'dashboards-edit'],
+  });
+  const location = {
+    pathname: '/organization/eventsv2/',
+    query: {},
+  };
+  const router = {
+    location: {query: {}},
+  };
   const yAxis = ['count()', 'failure_count()'];
 
   const errorsQuery = {
@@ -43,6 +86,7 @@ describe('EventsV2 > SaveQueryButtonGroup', function () {
     yAxis: ['count()'],
     display: DisplayModes.DEFAULT,
   };
+  const errorsView = EventView.fromSavedQuery(errorsQuery);
 
   const errorsViewSaved = EventView.fromSavedQuery(errorsQuery);
   errorsViewSaved.id = '1';
@@ -51,7 +95,387 @@ describe('EventsV2 > SaveQueryButtonGroup', function () {
   errorsViewModified.id = '1';
   errorsViewModified.name = 'Modified Name';
 
-  const savedQuery = {...errorsViewSaved.toNewQuery(), yAxis};
+  const savedQuery = {
+    ...errorsViewSaved.toNewQuery(),
+    yAxis,
+    dateCreated: '',
+    dateUpdated: '',
+    id: '1',
+  };
+
+  describe('building on a new query', () => {
+    const mockUtils = jest
+      .spyOn(utils, 'handleCreateQuery')
+      .mockImplementation(() => Promise.resolve(savedQuery));
+
+    beforeEach(() => {
+      mockUtils.mockClear();
+    });
+
+    it('renders disabled buttons when disabled prop is used', () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsView,
+        undefined,
+        yAxis,
+        true
+      );
+
+      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
+      expect(buttonSaveAs.props()['aria-disabled']).toBe(true);
+    });
+
+    it('renders the correct set of buttons', () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsView,
+        undefined,
+        yAxis
+      );
+
+      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
+      const buttonSaved = wrapper.find(SELECTOR_BUTTON_SAVED);
+      const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE);
+      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE);
+
+      expect(buttonSaveAs.exists()).toBe(true);
+      expect(buttonSaved.exists()).toBe(false);
+      expect(buttonUpdate.exists()).toBe(false);
+      expect(buttonDelete.exists()).toBe(false);
+    });
+
+    it('hides the banner when save is complete.', async () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsView,
+        undefined,
+        yAxis
+      );
+
+      // Click on ButtonSaveAs to open dropdown
+      const buttonSaveAs = wrapper.find('DropdownControl').first();
+      buttonSaveAs.simulate('click');
+
+      // Fill in the Input
+      buttonSaveAs
+        .find('ButtonSaveInput')
+        .simulate('change', {target: {value: 'My New Query Name'}}); // currentTarget.value does not work
+      await tick();
+
+      // Click on Save in the Dropdown
+      await buttonSaveAs.find('ButtonSaveDropDown Button').simulate('click');
+
+      // The banner should not render
+      const banner = mountWithTheme(
+        <DiscoverBanner organization={organization} resultsUrl="" />
+      );
+      expect(banner.find('BannerTitle').exists()).toBe(false);
+    });
+
+    it('saves a well-formed query', async () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsView,
+        undefined,
+        yAxis
+      );
+
+      // Click on ButtonSaveAs to open dropdown
+      const buttonSaveAs = wrapper.find('DropdownControl').first();
+      buttonSaveAs.simulate('click');
+
+      // Fill in the Input
+      buttonSaveAs
+        .find('ButtonSaveInput')
+        .simulate('change', {target: {value: 'My New Query Name'}}); // currentTarget.value does not work
+      await tick();
+
+      // Click on Save in the Dropdown
+      await buttonSaveAs.find('ButtonSaveDropDown Button').simulate('click');
+
+      expect(mockUtils).toHaveBeenCalledWith(
+        expect.anything(), // api
+        organization,
+        expect.objectContaining({
+          ...errorsView,
+          name: 'My New Query Name',
+        }),
+        yAxis,
+        true
+      );
+    });
+
+    it('rejects if query.name is empty', async () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsView,
+        undefined,
+        yAxis
+      );
+
+      // Click on ButtonSaveAs to open dropdown
+      const buttonSaveAs = wrapper.find('DropdownControl').first();
+      buttonSaveAs.simulate('click');
+
+      // Do not fill in Input
+      await tick();
+
+      // Click on Save in the Dropdown
+      buttonSaveAs.find('ButtonSaveDropDown Button').simulate('click');
+
+      // Check that EventView has a name
+      expect(errorsView.name).toBe('Errors by Title');
+
+      expect(mockUtils).not.toHaveBeenCalled();
+    });
+  });
+
+  describe('viewing a saved query', () => {
+    let mockUtils;
+
+    beforeEach(() => {
+      mockUtils = jest
+        .spyOn(utils, 'handleDeleteQuery')
+        .mockImplementation(() => Promise.resolve());
+    });
+
+    afterEach(() => {
+      mockUtils.mockClear();
+    });
+
+    it('renders the correct set of buttons', () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsViewSaved,
+        savedQuery,
+        yAxis
+      );
+
+      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
+      const buttonSaved = wrapper.find(SELECTOR_BUTTON_SAVED);
+      const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE);
+      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE);
+
+      expect(buttonSaveAs.exists()).toBe(false);
+      expect(buttonSaved.exists()).toBe(true);
+      expect(buttonUpdate.exists()).toBe(false);
+      expect(buttonDelete.exists()).toBe(true);
+    });
+
+    it('treats undefined yAxis the same as count() when checking for changes', () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsViewSaved,
+        {...savedQuery, yAxis: undefined},
+        ['count()']
+      );
+
+      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
+      const buttonSaved = wrapper.find(SELECTOR_BUTTON_SAVED);
+      const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE);
+      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE);
+
+      expect(buttonSaveAs.exists()).toBe(false);
+      expect(buttonSaved.exists()).toBe(true);
+      expect(buttonUpdate.exists()).toBe(false);
+      expect(buttonDelete.exists()).toBe(true);
+    });
+
+    it('converts string yAxis values to array when checking for changes', () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsViewSaved,
+        {...savedQuery, yAxis: 'count()'},
+        ['count()']
+      );
+
+      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
+      const buttonSaved = wrapper.find(SELECTOR_BUTTON_SAVED);
+      const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE);
+      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE);
+
+      expect(buttonSaveAs.exists()).toBe(false);
+      expect(buttonSaved.exists()).toBe(true);
+      expect(buttonUpdate.exists()).toBe(false);
+      expect(buttonDelete.exists()).toBe(true);
+    });
+
+    it('deletes the saved query', async () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsViewSaved,
+        savedQuery,
+        yAxis
+      );
+
+      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE).first();
+      await buttonDelete.simulate('click');
+
+      expect(mockUtils).toHaveBeenCalledWith(
+        expect.anything(), // api
+        organization,
+        expect.objectContaining({id: '1'})
+      );
+    });
+  });
+
+  describe('modifying a saved query', () => {
+    let mockUtils;
+
+    it('renders the correct set of buttons', () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsViewModified,
+        errorsViewSaved.toNewQuery(),
+        yAxis
+      );
+
+      const buttonSaveAs = wrapper.find(SELECTOR_BUTTON_SAVE_AS);
+      const buttonSaved = wrapper.find(SELECTOR_BUTTON_SAVED);
+      const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE);
+      const buttonDelete = wrapper.find(SELECTOR_BUTTON_DELETE);
+
+      expect(buttonSaveAs.exists()).toBe(true);
+      expect(buttonSaved.exists()).toBe(false);
+      expect(buttonUpdate.exists()).toBe(true);
+      expect(buttonDelete.exists()).toBe(true);
+    });
+
+    describe('updates the saved query', () => {
+      beforeEach(() => {
+        mockUtils = jest
+          .spyOn(utils, 'handleUpdateQuery')
+          .mockImplementation(() => Promise.resolve(savedQuery));
+      });
+
+      afterEach(() => {
+        mockUtils.mockClear();
+      });
+
+      it('accepts a well-formed query', async () => {
+        const wrapper = generateWrappedComponent(
+          location,
+          organization,
+          router,
+          errorsViewModified,
+          savedQuery,
+          yAxis
+        );
+
+        // Click on Save in the Dropdown
+        const buttonUpdate = wrapper.find(SELECTOR_BUTTON_UPDATE).first();
+        await buttonUpdate.simulate('click');
+
+        expect(mockUtils).toHaveBeenCalledWith(
+          expect.anything(), // api
+          organization,
+          expect.objectContaining({
+            ...errorsViewModified,
+          }),
+          yAxis
+        );
+      });
+    });
+
+    describe('creates a separate query', () => {
+      beforeEach(() => {
+        mockUtils = jest
+          .spyOn(utils, 'handleCreateQuery')
+          .mockImplementation(() => Promise.resolve(savedQuery));
+      });
+
+      afterEach(() => {
+        mockUtils.mockClear();
+      });
+
+      it('checks that it is forked from a saved query', async () => {
+        const wrapper = generateWrappedComponent(
+          location,
+          organization,
+          router,
+          errorsViewModified,
+          savedQuery,
+          yAxis
+        );
+
+        // Click on ButtonSaveAs to open dropdown
+        const buttonSaveAs = wrapper.find('DropdownControl').first();
+        buttonSaveAs.simulate('click');
+
+        // Fill in the Input
+        buttonSaveAs
+          .find('ButtonSaveInput')
+          .simulate('change', {target: {value: 'Forked Query'}});
+        await tick();
+
+        // Click on Save in the Dropdown
+        await buttonSaveAs.find('ButtonSaveDropDown Button').simulate('click');
+
+        expect(mockUtils).toHaveBeenCalledWith(
+          expect.anything(), // api
+          organization,
+          expect.objectContaining({
+            ...errorsViewModified,
+            name: 'Forked Query',
+          }),
+          yAxis,
+          false
+        );
+      });
+    });
+  });
+  describe('create alert from discover', () => {
+    it('renders create alert button when metrics alerts is enabled', () => {
+      const metricAlertOrg = {
+        ...organization,
+        features: ['incidents'],
+      };
+      const wrapper = generateWrappedComponent(
+        location,
+        metricAlertOrg,
+        router,
+        errorsViewModified,
+        savedQuery,
+        yAxis
+      );
+      const buttonCreateAlert = wrapper.find(SELECTOR_BUTTON_CREATE_ALERT);
+
+      expect(buttonCreateAlert.exists()).toBe(true);
+    });
+    it('does not render create alert button without metric alerts', () => {
+      const wrapper = generateWrappedComponent(
+        location,
+        organization,
+        router,
+        errorsViewModified,
+        savedQuery,
+        yAxis
+      );
+      const buttonCreateAlert = wrapper.find(SELECTOR_BUTTON_CREATE_ALERT);
+
+      expect(buttonCreateAlert.exists()).toBe(false);
+    });
+  });
 
   describe('add dashboard widget', () => {
     let initialData;