Commit 8d3cf014 authored by Miguel Rincon's avatar Miguel Rincon

Move environment dropdowns tests to header specs

As the header was separated from the dashboard, we should move our
tests as well to the header specs.

It was also an opportunity to clean up some duplicated tests.
parent f21b86f0
......@@ -254,16 +254,8 @@ export default {
{{ __('Environment') }}
</gl-dropdown-header>
<gl-dropdown-divider />
<gl-search-box-by-type
ref="monitorEnvironmentsDropdownSearch"
class="m-2"
@input="debouncedEnvironmentsSearch"
/>
<gl-loading-icon
v-if="environmentsLoading"
ref="monitorEnvironmentsDropdownLoading"
:inline="true"
/>
<gl-search-box-by-type class="m-2" @input="debouncedEnvironmentsSearch" />
<gl-loading-icon v-if="environmentsLoading" :inline="true" />
<div v-else class="flex-fill overflow-auto">
<gl-dropdown-item
v-for="environment in filteredEnvironments"
......
import { shallowMount } from '@vue/test-utils';
import { createStore } from '~/monitoring/stores';
import * as types from '~/monitoring/stores/mutation_types';
import { GlDropdownItem, GlSearchBoxByType, GlLoadingIcon } from '@gitlab/ui';
import DashboardHeader from '~/monitoring/components/dashboard_header.vue';
import DuplicateDashboardModal from '~/monitoring/components/duplicate_dashboard_modal.vue';
import CreateDashboardModal from '~/monitoring/components/create_dashboard_modal.vue';
import { setupAllDashboards } from '../store_utils';
import { setupAllDashboards, setupStoreWithDashboard, setupStoreWithData } from '../store_utils';
import {
environmentData,
dashboardGitResponse,
selfMonitoringDashboardGitResponse,
dashboardHeaderProps,
} from '../mock_data';
import { redirectTo } from '~/lib/utils/url_utility';
const mockProjectPath = 'https://path/to/project';
jest.mock('~/lib/utils/url_utility', () => ({
redirectTo: jest.fn(),
queryToObject: jest.fn(),
......@@ -21,6 +26,12 @@ describe('Dashboard header', () => {
let store;
let wrapper;
const findEnvsDropdown = () => wrapper.find({ ref: 'monitorEnvironmentsDropdown' });
const findEnvsDropdownItems = () => findEnvsDropdown().findAll(GlDropdownItem);
const findEnvsDropdownSearch = () => findEnvsDropdown().find(GlSearchBoxByType);
const findEnvsDropdownSearchMsg = () => wrapper.find({ ref: 'monitorEnvironmentsDropdownMsg' });
const findEnvsDropdownLoadingIcon = () => findEnvsDropdown().find(GlLoadingIcon);
const findActionsMenu = () => wrapper.find('[data-testid="actions-menu"]');
const findCreateDashboardMenuItem = () =>
findActionsMenu().find('[data-testid="action-create-dashboard"]');
......@@ -29,6 +40,10 @@ describe('Dashboard header', () => {
const findDuplicateDashboardModal = () => wrapper.find(DuplicateDashboardModal);
const findCreateDashboardModal = () => wrapper.find('[data-testid="create-dashboard-modal"]');
const setSearchTerm = searchTerm => {
store.commit(`monitoringDashboard/${types.SET_ENVIRONMENTS_FILTER}`, searchTerm);
};
const createShallowWrapper = (props = {}, options = {}) => {
wrapper = shallowMount(DashboardHeader, {
propsData: { ...dashboardHeaderProps, ...props },
......@@ -45,6 +60,113 @@ describe('Dashboard header', () => {
wrapper.destroy();
});
describe('environments dropdown', () => {
beforeEach(() => {
createShallowWrapper();
});
it('shows the environments dropdown', () => {
expect(findEnvsDropdown().exists()).toBe(true);
});
it('renders a search input', () => {
expect(findEnvsDropdownSearch().exists()).toBe(true);
});
describe('when environments data is not loaded', () => {
beforeEach(() => {
setupStoreWithDashboard(store);
return wrapper.vm.$nextTick();
});
it('there are no environments listed', () => {
expect(findEnvsDropdownItems().length).toBe(0);
});
});
describe('when environments data is loaded', () => {
const currentDashboard = dashboardGitResponse[0].path;
beforeEach(() => {
setupStoreWithData(store);
store.state.monitoringDashboard.projectPath = mockProjectPath;
store.state.monitoringDashboard.currentDashboard = currentDashboard;
return wrapper.vm.$nextTick();
});
it('renders dropdown items with the environment name', () => {
const path = `${mockProjectPath}/-/metrics/${encodeURIComponent(currentDashboard)}`;
findEnvsDropdownItems().wrappers.forEach((itemWrapper, index) => {
const { name, id } = environmentData[index];
const idParam = encodeURIComponent(id);
expect(itemWrapper.text()).toBe(name);
expect(itemWrapper.attributes('href')).toBe(`${path}?environment=${idParam}`);
});
});
// Note: This test is not working, .active does not show the active environment
// https://gitlab.com/gitlab-org/gitlab/-/issues/230615
// eslint-disable-next-line jest/no-disabled-tests
it.skip('renders the environments dropdown with a single active element', () => {
const activeItem = findEnvsDropdownItems().wrappers.filter(itemWrapper =>
itemWrapper.find('.active').exists(),
);
expect(activeItem.length).toBe(1);
});
it('filters rendered dropdown items', () => {
const searchTerm = 'production';
const resultEnvs = environmentData.filter(({ name }) => name.indexOf(searchTerm) !== -1);
setSearchTerm(searchTerm);
return wrapper.vm.$nextTick().then(() => {
expect(findEnvsDropdownItems().length).toBe(resultEnvs.length);
});
});
it('does not filter dropdown items if search term is empty string', () => {
const searchTerm = '';
setSearchTerm(searchTerm);
return wrapper.vm.$nextTick(() => {
expect(findEnvsDropdownItems().length).toBe(environmentData.length);
});
});
it("shows error message if search term doesn't match", () => {
const searchTerm = 'does-not-exist';
setSearchTerm(searchTerm);
return wrapper.vm.$nextTick(() => {
expect(findEnvsDropdownSearchMsg().isVisible()).toBe(true);
});
});
it('shows loading element when environments fetch is still loading', () => {
store.commit(`monitoringDashboard/${types.REQUEST_ENVIRONMENTS_DATA}`);
return wrapper.vm
.$nextTick()
.then(() => {
expect(findEnvsDropdownLoadingIcon().exists()).toBe(true);
})
.then(() => {
store.commit(
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
environmentData,
);
})
.then(() => {
expect(findEnvsDropdownLoadingIcon().exists()).toBe(false);
});
});
});
});
describe('when a dashboard has been duplicated in the duplicate dashboard modal', () => {
beforeEach(() => {
store.state.monitoringDashboard.projectPath = 'root/sandbox';
......@@ -81,7 +203,7 @@ describe('Dashboard header', () => {
});
it('is rendered if projectPath is set in store', () => {
store.state.monitoringDashboard.projectPath = 'https://path/to/project';
store.state.monitoringDashboard.projectPath = mockProjectPath;
return wrapper.vm.$nextTick().then(() => {
expect(findActionsMenu().exists()).toBe(true);
......@@ -93,7 +215,7 @@ describe('Dashboard header', () => {
});
it('contains a modal', () => {
store.state.monitoringDashboard.projectPath = 'https://path/to/project';
store.state.monitoringDashboard.projectPath = mockProjectPath;
return wrapper.vm.$nextTick().then(() => {
expect(findActionsMenu().contains(CreateDashboardModal)).toBe(true);
......@@ -111,7 +233,7 @@ describe('Dashboard header', () => {
'when the selected dashboard can be duplicated',
dashboardPath => {
it('contains a "Create New" menu item and a "Duplicate Dashboard" menu item', () => {
store.state.monitoringDashboard.projectPath = 'https://path/to/project';
store.state.monitoringDashboard.projectPath = mockProjectPath;
setupAllDashboards(store, dashboardPath);
return wrapper.vm.$nextTick().then(() => {
......@@ -131,7 +253,7 @@ describe('Dashboard header', () => {
'when the selected dashboard cannot be duplicated',
dashboardPath => {
it('contains a "Create New" menu item and no "Duplicate Dashboard" menu item', () => {
store.state.monitoringDashboard.projectPath = 'https://path/to/project';
store.state.monitoringDashboard.projectPath = mockProjectPath;
setupAllDashboards(store, dashboardPath);
return wrapper.vm.$nextTick().then(() => {
......@@ -144,10 +266,8 @@ describe('Dashboard header', () => {
});
describe('actions menu modals', () => {
const url = 'https://path/to/project';
beforeEach(() => {
store.state.monitoringDashboard.projectPath = url;
store.state.monitoringDashboard.projectPath = mockProjectPath;
setupAllDashboards(store);
createShallowWrapper();
......@@ -166,7 +286,7 @@ describe('Dashboard header', () => {
});
it('"Create new dashboard" modal contains correct buttons', () => {
expect(findCreateDashboardModal().props('projectPath')).toBe(url);
expect(findCreateDashboardModal().props('projectPath')).toBe(mockProjectPath);
});
it('"Duplicate Dashboard" opens up a modal', () => {
......
import { shallowMount, mount } from '@vue/test-utils';
import Tracking from '~/tracking';
import { ESC_KEY, ESC_KEY_IE11 } from '~/lib/utils/keys';
import { GlModal, GlDropdownItem, GlDeprecatedButton, GlIcon } from '@gitlab/ui';
import { GlModal, GlDeprecatedButton, GlIcon } from '@gitlab/ui';
import { objectToQuery } from '~/lib/utils/url_utility';
import VueDraggable from 'vuedraggable';
import MockAdapter from 'axios-mock-adapter';
......@@ -29,7 +29,7 @@ import {
setupStoreWithDataForPanelCount,
setupStoreWithLinks,
} from '../store_utils';
import { environmentData, dashboardGitResponse, storeVariables } from '../mock_data';
import { dashboardGitResponse, storeVariables } from '../mock_data';
import {
metricsDashboardViewModel,
metricsDashboardPanelCount,
......@@ -46,12 +46,6 @@ describe('Dashboard', () => {
let mock;
const findDashboardHeader = () => wrapper.find(DashboardHeader);
const findEnvironmentsDropdown = () =>
findDashboardHeader().find({ ref: 'monitorEnvironmentsDropdown' });
const findAllEnvironmentsDropdownItems = () => findEnvironmentsDropdown().findAll(GlDropdownItem);
const setSearchTerm = searchTerm => {
store.commit(`monitoringDashboard/${types.SET_ENVIRONMENTS_FILTER}`, searchTerm);
};
const createShallowWrapper = (props = {}, options = {}) => {
wrapper = shallowMount(Dashboard, {
......@@ -90,28 +84,6 @@ describe('Dashboard', () => {
}
});
describe('no metrics are available yet', () => {
beforeEach(() => {
createShallowWrapper();
});
it('shows the environment selector', () => {
expect(findEnvironmentsDropdown().exists()).toBe(true);
});
});
describe('no data found', () => {
beforeEach(() => {
createShallowWrapper();
return wrapper.vm.$nextTick();
});
it('shows the environment selector dropdown', () => {
expect(findEnvironmentsDropdown().exists()).toBe(true);
});
});
describe('request information to the server', () => {
it('calls to set time range and fetch data', () => {
createShallowWrapper({ hasMetrics: true });
......@@ -149,17 +121,14 @@ describe('Dashboard', () => {
});
it('fetches the metrics data with proper time window', () => {
jest.spyOn(store, 'dispatch');
createMountedWrapper({ hasMetrics: true });
store.commit(
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
environmentData,
);
return wrapper.vm.$nextTick().then(() => {
expect(store.dispatch).toHaveBeenCalled();
expect(store.dispatch).toHaveBeenCalledWith('monitoringDashboard/fetchData', undefined);
expect(store.dispatch).toHaveBeenCalledWith(
'monitoringDashboard/setTimeRange',
expect.objectContaining({ duration: { seconds: 28800 } }),
);
});
});
});
......@@ -500,21 +469,6 @@ describe('Dashboard', () => {
return wrapper.vm.$nextTick();
});
it('renders the environments dropdown with a number of environments', () => {
expect(findAllEnvironmentsDropdownItems().length).toEqual(environmentData.length);
findAllEnvironmentsDropdownItems().wrappers.forEach((itemWrapper, index) => {
const anchorEl = itemWrapper.find('a');
if (anchorEl.exists()) {
const href = anchorEl.attributes('href');
const currentDashboard = encodeURIComponent(dashboardGitResponse[0].path);
const environmentId = encodeURIComponent(environmentData[index].id);
const url = `${TEST_HOST}/-/metrics/${currentDashboard}?environment=${environmentId}`;
expect(href).toBe(url);
}
});
});
it('it does not show loading icons in any group', () => {
setupStoreWithData(store);
......@@ -524,16 +478,6 @@ describe('Dashboard', () => {
});
});
});
// Note: This test is not working, .active does not show the active environment
// eslint-disable-next-line jest/no-disabled-tests
it.skip('renders the environments dropdown with a single active element', () => {
const activeItem = findAllEnvironmentsDropdownItems().wrappers.filter(itemWrapper =>
itemWrapper.find('.active').exists(),
);
expect(activeItem.length).toBe(1);
});
});
describe('star dashboards', () => {
......@@ -615,16 +559,6 @@ describe('Dashboard', () => {
});
});
it('hides the environments dropdown list when there is no environments', () => {
createMountedWrapper({ hasMetrics: true });
setupStoreWithDashboard(store);
return wrapper.vm.$nextTick().then(() => {
expect(findAllEnvironmentsDropdownItems()).toHaveLength(0);
});
});
it('renders the datetimepicker dropdown', () => {
createMountedWrapper({ hasMetrics: true });
......@@ -811,100 +745,6 @@ describe('Dashboard', () => {
});
});
describe('searchable environments dropdown', () => {
beforeEach(() => {
createMountedWrapper({ hasMetrics: true }, { attachToDocument: true });
setupStoreWithData(store);
return wrapper.vm.$nextTick();
});
afterEach(() => {
wrapper.destroy();
});
it('renders a search input', () => {
expect(
wrapper
.find(DashboardHeader)
.find({ ref: 'monitorEnvironmentsDropdownSearch' })
.exists(),
).toBe(true);
});
it('renders dropdown items', () => {
findAllEnvironmentsDropdownItems().wrappers.forEach((itemWrapper, index) => {
const anchorEl = itemWrapper.find('a');
if (anchorEl.exists()) {
expect(anchorEl.text()).toBe(environmentData[index].name);
}
});
});
it('filters rendered dropdown items', () => {
const searchTerm = 'production';
const resultEnvs = environmentData.filter(({ name }) => name.indexOf(searchTerm) !== -1);
setSearchTerm(searchTerm);
return wrapper.vm.$nextTick().then(() => {
expect(findAllEnvironmentsDropdownItems().length).toEqual(resultEnvs.length);
});
});
it('does not filter dropdown items if search term is empty string', () => {
const searchTerm = '';
setSearchTerm(searchTerm);
return wrapper.vm.$nextTick(() => {
expect(findAllEnvironmentsDropdownItems().length).toEqual(environmentData.length);
});
});
it("shows error message if search term doesn't match", () => {
const searchTerm = 'does-not-exist';
setSearchTerm(searchTerm);
return wrapper.vm.$nextTick(() => {
expect(
wrapper
.find(DashboardHeader)
.find({ ref: 'monitorEnvironmentsDropdownMsg' })
.isVisible(),
).toBe(true);
});
});
it('shows loading element when environments fetch is still loading', () => {
store.commit(`monitoringDashboard/${types.REQUEST_ENVIRONMENTS_DATA}`);
return wrapper.vm
.$nextTick()
.then(() => {
expect(
wrapper
.find(DashboardHeader)
.find({ ref: 'monitorEnvironmentsDropdownLoading' })
.exists(),
).toBe(true);
})
.then(() => {
store.commit(
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
environmentData,
);
})
.then(() => {
expect(
wrapper
.find(DashboardHeader)
.find({ ref: 'monitorEnvironmentsDropdownLoading' })
.exists(),
).toBe(false);
});
});
});
describe('drag and drop function', () => {
const findDraggables = () => wrapper.findAll(VueDraggable);
const findEnabledDraggables = () => findDraggables().filter(f => !f.attributes('disabled'));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment