Commit 07290d35 authored by Axel García's avatar Axel García Committed by Miguel Rincon

Add test for the new epic button on epic header

Also some refactoring on the test and selectors
parent c3a7d311
......@@ -45,12 +45,7 @@ export default {
return this.isEpicOpen ? __('Open') : __('Closed');
},
actionButtonClass() {
// False positive css classes
// https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/24
// eslint-disable-next-line @gitlab/require-i18n-strings
return `js-btn-epic-action qa-close-reopen-epic-button ${
this.isEpicOpen ? 'btn-close' : 'btn-open'
}`;
return `qa-close-reopen-epic-button ${this.isEpicOpen ? 'btn-close' : 'btn-open'}`;
},
actionButtonText() {
return this.isEpicOpen ? __('Close epic') : __('Reopen epic');
......@@ -88,12 +83,17 @@ export default {
<div
:class="{ 'status-box-open': isEpicOpen, 'status-box-issue-closed': !isEpicOpen }"
class="issuable-status-box status-box"
data-testid="status-box"
>
<gl-icon :name="statusIcon" class="d-block d-sm-none" />
<span class="d-none d-sm-block">{{ statusText }}</span>
</div>
<div class="issuable-meta">
<div v-if="confidential" class="issuable-warning-icon inline">
<div class="issuable-meta" data-testid="author-details">
<div
v-if="confidential"
class="issuable-warning-icon inline"
data-testid="confidential-icon"
>
<gl-icon name="eye-slash" class="icon" />
</div>
{{ __('Opened') }}
......@@ -117,14 +117,16 @@ export default {
</div>
<gl-button
:aria-label="__('Toggle sidebar')"
class="float-right gl-display-block d-sm-none gl-align-self-center gutter-toggle issuable-gutter-toggle js-sidebar-toggle"
type="button"
class="float-right gl-display-block d-sm-none gl-align-self-center gutter-toggle issuable-gutter-toggle"
data-testid="sidebar-toggle"
@click="toggleSidebar({ sidebarCollapsed })"
>
<i class="fa fa-angle-double-left"></i>
</gl-button>
<div
class="detail-page-header-actions gl-display-flex gl-flex-wrap gl-align-items-center gl-w-full gl-w-sm-auto js-issuable-actions"
class="detail-page-header-actions gl-display-flex gl-flex-wrap gl-align-items-center gl-w-full gl-sm-w-auto!"
data-testid="action-buttons"
>
<gl-button
v-if="canUpdate"
......@@ -132,7 +134,8 @@ export default {
:class="actionButtonClass"
category="secondary"
variant="warning"
class="gl-mt-3 gl-mt-sm-0 gl-w-full gl-w-sm-auto"
class="gl-mt-3 gl-sm-mt-0! gl-w-full gl-sm-w-auto!"
data-testid="toggle-status-button"
@click="toggleEpicStatus(isEpicOpen)"
>
{{ actionButtonText }}
......@@ -140,10 +143,10 @@ export default {
<gl-button
v-if="userCanCreate"
:href="newEpicWebUrl"
data-testid="new-epic-button"
class="gl-mt-3 gl-mt-sm-0 gl-ml-sm-3 gl-w-full gl-w-sm-auto"
category="secondary"
variant="success"
class="gl-mt-3 gl-sm-mt-0! gl-sm-ml-3 gl-w-full gl-sm-w-auto!"
data-testid="new-epic-button"
>
{{ __('New epic') }}
</gl-button>
......
import Vue from 'vue';
import Vuex from 'vuex';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import { GlIcon } from '@gitlab/ui';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
......@@ -11,13 +9,10 @@ import { statusType } from 'ee/epic/constants';
import { mockEpicMeta, mockEpicData } from '../mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('EpicHeaderComponent', () => {
let wrapper;
let vm;
let store;
let features = {};
beforeEach(() => {
store = createStore();
......@@ -25,135 +20,159 @@ describe('EpicHeaderComponent', () => {
store.dispatch('setEpicData', mockEpicData);
wrapper = shallowMount(EpicHeader, {
localVue,
store,
provide: {
glFeatures: features,
},
});
vm = wrapper.vm;
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findStatusBox = () => wrapper.find('[data-testid="status-box"]');
const findConfidentialIcon = () => wrapper.find('[data-testid="confidential-icon"]').find(GlIcon);
const findAuthorDetails = () => wrapper.find('[data-testid="author-details"]');
const findActionButtons = () => wrapper.find('[data-testid="action-buttons"]');
const findNewEpicButton = () => wrapper.find('[data-testid="new-epic-button"]');
const findSidebarToggle = () => wrapper.find('[data-testid="sidebar-toggle"]');
describe('computed', () => {
describe('statusIcon', () => {
it('returns string `issue-open-m` when `isEpicOpen` is true', () => {
vm.$store.state.state = statusType.open;
store.state.state = statusType.open;
expect(vm.statusIcon).toBe('issue-open-m');
expect(wrapper.vm.statusIcon).toBe('issue-open-m');
});
it('returns string `mobile-issue-close` when `isEpicOpen` is false', () => {
vm.$store.state.state = statusType.close;
store.state.state = statusType.close;
expect(vm.statusIcon).toBe('mobile-issue-close');
expect(wrapper.vm.statusIcon).toBe('mobile-issue-close');
});
});
describe('statusText', () => {
it('returns string `Open` when `isEpicOpen` is true', () => {
vm.$store.state.state = statusType.open;
store.state.state = statusType.open;
expect(vm.statusText).toBe('Open');
expect(wrapper.vm.statusText).toBe('Open');
});
it('returns string `Closed` when `isEpicOpen` is false', () => {
vm.$store.state.state = statusType.close;
store.state.state = statusType.close;
expect(vm.statusText).toBe('Closed');
expect(wrapper.vm.statusText).toBe('Closed');
});
});
describe('actionButtonClass', () => {
it('returns default button classes along with `btn-close` when `isEpicOpen` is true', () => {
vm.$store.state.state = statusType.open;
it('returns `btn-close` when `isEpicOpen` is true', () => {
store.state.state = statusType.open;
expect(vm.actionButtonClass).toBe(
'js-btn-epic-action qa-close-reopen-epic-button btn-close',
);
expect(wrapper.vm.actionButtonClass).toContain('btn-close');
});
it('returns default button classes along with `btn-open` when `isEpicOpen` is false', () => {
vm.$store.state.state = statusType.close;
it('returns `btn-open` when `isEpicOpen` is false', () => {
store.state.state = statusType.close;
expect(vm.actionButtonClass).toBe(
'js-btn-epic-action qa-close-reopen-epic-button btn-open',
);
expect(wrapper.vm.actionButtonClass).toContain('btn-open');
});
});
describe('actionButtonText', () => {
it('returns string `Close epic` when `isEpicOpen` is true', () => {
vm.$store.state.state = statusType.open;
store.state.state = statusType.open;
expect(vm.actionButtonText).toBe('Close epic');
expect(wrapper.vm.actionButtonText).toBe('Close epic');
});
it('returns string `Reopen epic` when `isEpicOpen` is false', () => {
vm.$store.state.state = statusType.close;
store.state.state = statusType.close;
expect(vm.actionButtonText).toBe('Reopen epic');
expect(wrapper.vm.actionButtonText).toBe('Reopen epic');
});
});
});
describe('template', () => {
it('renders component container element with class `detail-page-header`', () => {
expect(vm.$el.classList.contains('detail-page-header')).toBe(true);
expect(vm.$el.querySelector('.detail-page-header-body')).not.toBeNull();
expect(wrapper.classes()).toContain('detail-page-header');
expect(wrapper.find('.detail-page-header-body').exists()).toBeTruthy();
});
it('renders epic status icon and text elements', () => {
const statusEl = wrapper.find('.issuable-status-box');
const statusBox = findStatusBox();
expect(statusEl.exists()).toBe(true);
expect(statusEl.find(GlIcon).props('name')).toBe('issue-open-m');
expect(statusEl.find('span').text()).toBe('Open');
expect(statusBox.exists()).toBe(true);
expect(statusBox.find(GlIcon).props('name')).toBe('issue-open-m');
expect(statusBox.find('span').text()).toBe('Open');
});
it('renders confidential icon when `confidential` prop is true', () => {
vm.$store.state.confidential = true;
store.state.confidential = true;
return wrapper.vm.$nextTick(() => {
const confidentialIcon = findConfidentialIcon();
return Vue.nextTick(() => {
const iconEl = wrapper.find('.issuable-warning-icon').find(GlIcon);
expect(iconEl.exists()).toBe(true);
expect(iconEl.props('name')).toBe('eye-slash');
expect(confidentialIcon.exists()).toBe(true);
expect(confidentialIcon.props('name')).toBe('eye-slash');
});
});
it('renders epic author details element', () => {
const metaEl = wrapper.find('.issuable-meta');
const epicDetails = findAuthorDetails();
expect(metaEl.exists()).toBe(true);
expect(metaEl.find(TimeagoTooltip).exists()).toBe(true);
expect(metaEl.find(UserAvatarLink).exists()).toBe(true);
expect(epicDetails.exists()).toBe(true);
expect(epicDetails.find(TimeagoTooltip).exists()).toBe(true);
expect(epicDetails.find(UserAvatarLink).exists()).toBe(true);
});
it('renders action buttons element', () => {
const actionsEl = vm.$el.querySelector('.js-issuable-actions');
const actionButtons = findActionButtons();
const toggleStatusButton = actionButtons.find('[data-testid="toggle-status-button"]');
expect(actionsEl).not.toBeNull();
expect(actionsEl.querySelector('.js-btn-epic-action')).not.toBeNull();
expect(actionsEl.querySelector('.js-btn-epic-action').innerText.trim()).toBe('Close epic');
expect(actionButtons.exists()).toBeTruthy();
expect(toggleStatusButton.exists()).toBeTruthy();
expect(toggleStatusButton.text()).toBe('Close epic');
});
it('renders toggle sidebar button element', () => {
const toggleButtonEl = wrapper.find('.js-sidebar-toggle');
const toggleButton = findSidebarToggle();
expect(toggleButtonEl.exists()).toBe(true);
expect(toggleButtonEl.attributes('aria-label')).toBe('Toggle sidebar');
expect(toggleButtonEl.classes()).toEqual(
expect(toggleButton.exists()).toBeTruthy();
expect(toggleButton.attributes('aria-label')).toBe('Toggle sidebar');
expect(toggleButton.classes()).toEqual(
expect.arrayContaining([('d-block', 'd-sm-none', 'gutter-toggle')]),
);
});
it('renders GitLab team member badge when `author.isGitlabEmployee` is `true`', () => {
vm.$store.state.author.isGitlabEmployee = true;
store.state.author.isGitlabEmployee = true;
// Wait for dynamic imports to resolve
return new Promise(setImmediate).then(() => {
expect(vm.$refs.gitlabTeamMemberBadge).not.toBeUndefined();
expect(wrapper.vm.$refs.gitlabTeamMemberBadge).not.toBeUndefined();
});
});
it('does not render new epic button without `createEpicForm` feature flag', () => {
expect(findNewEpicButton().exists()).toBeFalsy();
});
describe('with `createEpicForm` feature flag', () => {
beforeAll(() => {
features = { createEpicForm: true };
});
it('renders new epic button if user can create it', () => {
store.state.canCreate = true;
return wrapper.vm.$nextTick().then(() => {
expect(findNewEpicButton().exists()).toBe(true);
});
});
});
});
......
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