Commit b7d8b0b3 authored by Axel García's avatar Axel García

Update test pattern for Roadmap empty state

This also removes the usage of v-html, and
requests more data from our backend
parent 2351da48
<script> <script>
/* eslint-disable vue/no-v-html */ import { GlButton, GlSafeHtmlDirective } from '@gitlab/ui';
import { GlButton } from '@gitlab/ui';
import { s__, sprintf } from '~/locale'; import { s__, sprintf } from '~/locale';
import { dateInWords } from '~/lib/utils/datetime_utility'; import { dateInWords } from '~/lib/utils/datetime_utility';
...@@ -11,8 +10,11 @@ export default { ...@@ -11,8 +10,11 @@ export default {
components: { components: {
GlButton, GlButton,
}, },
directives: {
SafeHtml: GlSafeHtmlDirective,
},
mixins: [CommonMixin], mixins: [CommonMixin],
inject: ['newEpicPath', 'listEpicsPath'], inject: ['newEpicPath', 'listEpicsPath', 'epicsDocsPath'],
props: { props: {
presetType: { presetType: {
type: String, type: String,
...@@ -91,8 +93,7 @@ export default { ...@@ -91,8 +93,7 @@ export default {
'GroupRoadmap|To view the roadmap, add a start or due date to one of the %{linkStart}child epics%{linkEnd}.', 'GroupRoadmap|To view the roadmap, add a start or due date to one of the %{linkStart}child epics%{linkEnd}.',
), ),
{ {
linkStart: linkStart: `<a href="${this.epicsDocsPath}#multi-level-child-epics" target="_blank" rel="noopener noreferrer nofollow">`,
'<a href="https://docs.gitlab.com/ee/user/group/epics/#multi-level-child-epics" target="_blank" rel="noopener noreferrer nofollow">',
linkEnd: '</a>', linkEnd: '</a>',
}, },
false, false,
...@@ -117,24 +118,29 @@ export default { ...@@ -117,24 +118,29 @@ export default {
<template> <template>
<div class="row empty-state"> <div class="row empty-state">
<div class="col-12"> <div class="col-12">
<div class="svg-content"><img :src="emptyStateIllustrationPath" /></div> <div class="svg-content">
<img :src="emptyStateIllustrationPath" data-testid="illustration" />
</div>
</div> </div>
<div class="col-12"> <div class="col-12">
<div class="text-content"> <div class="text-content">
<h4 data-testid="default-message">{{ message }}</h4> <h4 data-testid="title">{{ message }}</h4>
<p v-html="subMessage"></p> <p v-safe-html="subMessage" data-testid="sub-title"></p>
<div class="gl-text-center"> <div class="gl-text-center">
<gl-button <gl-button
v-if="!hasFiltersApplied"
:href="newEpicPath" :href="newEpicPath"
variant="success" variant="success"
class="gl-mt-3 gl-sm-mt-0! gl-w-full gl-sm-w-auto!" class="gl-mt-3 gl-sm-mt-0! gl-w-full gl-sm-w-auto!"
data-testid="new-epic-button"
> >
{{ __('New epic') }} {{ __('New epic') }}
</gl-button> </gl-button>
<gl-button <gl-button
:href="listEpicsPath" :href="listEpicsPath"
class="gl-mt-3 gl-sm-mt-0! gl-sm-ml-3 gl-w-full gl-sm-w-auto!" class="gl-mt-3 gl-sm-mt-0! gl-sm-ml-3 gl-w-full gl-sm-w-auto!"
data-testid="list-epics-button"
> >
{{ __('View epics list') }} {{ __('View epics list') }}
</gl-button> </gl-button>
......
...@@ -56,6 +56,7 @@ export default () => { ...@@ -56,6 +56,7 @@ export default () => {
return { return {
newEpicPath: dataset.newEpicPath, newEpicPath: dataset.newEpicPath,
listEpicsPath: dataset.listEpicsPath, listEpicsPath: dataset.listEpicsPath,
epicsDocsPath: dataset.epicsDocsPath,
}; };
}, },
data() { data() {
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
has_filters_applied: 'false', has_filters_applied: 'false',
new_epic_path: new_group_epic_path(@group), new_epic_path: new_group_epic_path(@group),
list_epics_path: group_epics_path(@group), list_epics_path: group_epics_path(@group),
epics_docs_path: help_page_path('user/group/epics/index'),
preset_type: roadmap_layout, preset_type: roadmap_layout,
epics_state: 'all', epics_state: 'all',
sorted_by: roadmap_sort_order, sorted_by: roadmap_sort_order,
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
has_filters_applied: "#{has_filters_applied}", has_filters_applied: "#{has_filters_applied}",
new_epic_path: new_group_epic_path(@group), new_epic_path: new_group_epic_path(@group),
list_epics_path: group_epics_path(@group), list_epics_path: group_epics_path(@group),
epics_docs_path: help_page_path('user/group/epics/index'),
group_labels_endpoint: group_labels_path(@group, format: :json), group_labels_endpoint: group_labels_path(@group, format: :json),
group_milestones_endpoint: group_milestones_path(@group, format: :json), group_milestones_endpoint: group_milestones_path(@group, format: :json),
preset_type: roadmap_layout, preset_type: roadmap_layout,
......
---
title: New epic button in Epic Roadmap empty state should direct the user to a full
epic creation page
merge_request: 45948
author:
type: changed
...@@ -2,21 +2,31 @@ import { shallowMount } from '@vue/test-utils'; ...@@ -2,21 +2,31 @@ import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import EpicsListEmpty from 'ee/roadmap/components/epics_list_empty.vue'; import EpicsListEmpty from 'ee/roadmap/components/epics_list_empty.vue';
import { mockTimeframeInitialDate, mockSvgPath } from 'ee_jest/roadmap/mock_data'; import { mockTimeframeInitialDate, mockSvgPath } from 'ee_jest/roadmap/mock_data';
import { TEST_HOST } from 'helpers/test_constants';
import { PRESET_TYPES } from 'ee/roadmap/constants'; import { PRESET_TYPES } from 'ee/roadmap/constants';
import { getTimeframeForMonthsView } from 'ee/roadmap/utils/roadmap_utils'; import { TEST_HOST } from 'helpers/test_constants';
import {
getTimeframeForQuartersView,
getTimeframeForWeeksView,
getTimeframeForMonthsView,
} from 'ee/roadmap/utils/roadmap_utils';
const TEST_EPICS_PATH = '/epics';
const TEST_NEW_EPIC_PATH = '/epics/new';
const mockTimeframeQuarters = getTimeframeForQuartersView(mockTimeframeInitialDate);
const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate); const mockTimeframeMonths = getTimeframeForMonthsView(mockTimeframeInitialDate);
const mockTimeframeWeeks = getTimeframeForWeeksView(mockTimeframeInitialDate);
describe('~/todos/app.vue', () => { describe('ee/roadmap/components/epics_list_empty.vue', () => {
let wrapper; let wrapper;
const createWrapper = ({ const createWrapper = ({
isChildEpics = false,
hasFiltersApplied = false, hasFiltersApplied = false,
presetType = PRESET_TYPES.MONTHS, presetType = PRESET_TYPES.MONTHS,
timeframeStart = mockTimeframeMonths[0], timeframeStart = mockTimeframeMonths[0],
timeframeEnd = mockTimeframeMonths[mockTimeframeMonths.length - 1], timeframeEnd = mockTimeframeMonths[mockTimeframeMonths.length - 1],
}) => { } = {}) => {
wrapper = extendedWrapper( wrapper = extendedWrapper(
shallowMount(EpicsListEmpty, { shallowMount(EpicsListEmpty, {
propsData: { propsData: {
...@@ -25,27 +35,148 @@ describe('~/todos/app.vue', () => { ...@@ -25,27 +35,148 @@ describe('~/todos/app.vue', () => {
timeframeEnd, timeframeEnd,
emptyStateIllustrationPath: mockSvgPath, emptyStateIllustrationPath: mockSvgPath,
hasFiltersApplied, hasFiltersApplied,
isChildEpics,
}, },
provide: { provide: {
newEpicPath: TEST_HOST, newEpicPath: TEST_NEW_EPIC_PATH,
listEpicsPath: TEST_HOST, listEpicsPath: TEST_EPICS_PATH,
epicsDocsPath: TEST_HOST,
}, },
}), }),
); );
}; };
beforeEach(() => {
createWrapper({});
});
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null; wrapper = null;
}); });
const findDefaultMessage = () => wrapper.findByTestId('default-message'); const findTitle = () => wrapper.findByTestId('title');
const findSubTitle = () => wrapper.findByTestId('sub-title');
const findNewEpicButton = () => wrapper.findByTestId('new-epic-button');
const findListEpicsButton = () => wrapper.findByTestId('list-epics-button');
const findIllustration = () => wrapper.findByTestId('illustration');
it('renders default message', () => { it('renders default message', () => {
expect(findDefaultMessage().text()).toBe(wrapper.vm.message); createWrapper({});
expect(findTitle().text()).toBe(wrapper.vm.message);
});
it('renders empty state message when `hasFiltersApplied` prop is true', () => {
createWrapper({ hasFiltersApplied: true });
expect(findTitle().text()).toBe('Sorry, no epics matched your search');
});
describe('with presetType `QUARTERS`', () => {
it('renders default empty state sub-title when `hasFiltersApplied` props is false', () => {
createWrapper({
presetType: PRESET_TYPES.QUARTERS,
timeframeStart: mockTimeframeQuarters[0],
timeframeEnd: mockTimeframeQuarters[mockTimeframeQuarters.length - 1],
});
expect(findSubTitle().text()).toBe(
'To view the roadmap, add a start or due date to one of your epics in this group or its subgroups; from Jul 1, 2017 to Mar 31, 2019.',
);
});
it('renders empty state sub-title when `hasFiltersApplied` prop is true', () => {
createWrapper({
presetType: PRESET_TYPES.QUARTERS,
timeframeStart: mockTimeframeQuarters[0],
timeframeEnd: mockTimeframeQuarters[mockTimeframeQuarters.length - 1],
hasFiltersApplied: true,
});
expect(findSubTitle().text()).toBe(
'To widen your search, change or remove filters; from Jul 1, 2017 to Mar 31, 2019.',
);
});
});
describe('with presetType `MONTHS`', () => {
it('renders default empty state sub-title when `hasFiltersApplied` props is false', () => {
createWrapper({
presetType: PRESET_TYPES.MONTHS,
});
expect(findSubTitle().text()).toBe(
'To view the roadmap, add a start or due date to one of your epics in this group or its subgroups; from Nov 1, 2017 to Jun 30, 2018.',
);
});
it('renders empty state sub-title when `hasFiltersApplied` prop is true', () => {
createWrapper({
presetType: PRESET_TYPES.MONTHS,
hasFiltersApplied: true,
});
expect(findSubTitle().text()).toBe(
'To widen your search, change or remove filters; from Nov 1, 2017 to Jun 30, 2018.',
);
});
});
describe('with presetType `WEEKS`', () => {
let timeframeEnd;
beforeEach(() => {
timeframeEnd = mockTimeframeWeeks[mockTimeframeWeeks.length - 1];
timeframeEnd.setDate(timeframeEnd.getDate() + 6);
});
it('renders default empty state sub-title when `hasFiltersApplied` props is false', () => {
createWrapper({
presetType: PRESET_TYPES.WEEKS,
timeframeStart: mockTimeframeWeeks[0],
timeframeEnd,
});
expect(findSubTitle().text()).toBe(
'To view the roadmap, add a start or due date to one of your epics in this group or its subgroups; from Dec 17, 2017 to Feb 9, 2018.',
);
});
it('renders empty state sub-title when `hasFiltersApplied` prop is true', () => {
createWrapper({
presetType: PRESET_TYPES.WEEKS,
timeframeStart: mockTimeframeWeeks[0],
timeframeEnd,
hasFiltersApplied: true,
});
expect(findSubTitle().text()).toBe(
'To widen your search, change or remove filters; from Dec 17, 2017 to Feb 15, 2018.',
);
});
});
it('renders empty state sub-title when `isChildEpics` is set to `true`', () => {
createWrapper({ isChildEpics: true });
expect(findSubTitle().text()).toBe(
'To view the roadmap, add a start or due date to one of the child epics.',
);
});
it('renders empty state illustration in image element with provided `emptyStateIllustrationPath`', () => {
createWrapper({});
expect(findIllustration().attributes('src')).toBe(mockSvgPath);
});
it('renders buttons for create and list epics', () => {
createWrapper({});
expect(findNewEpicButton().attributes('href')).toBe(TEST_NEW_EPIC_PATH);
expect(findListEpicsButton().attributes('href')).toBe(TEST_EPICS_PATH);
});
it('does not render new epic button element when `hasFiltersApplied` prop is true', () => {
createWrapper({ hasFiltersApplied: true });
expect(findNewEpicButton().exists()).toBe(false);
}); });
}); });
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