Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js')
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js182
1 files changed, 182 insertions, 0 deletions
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js
new file mode 100644
index 00000000000..c8ccd4c88a5
--- /dev/null
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js
@@ -0,0 +1,182 @@
+import { GlAlert, GlFormInput, GlForm } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
+import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue';
+import { createStore } from '~/boards/stores';
+import createFlash from '~/flash';
+
+const TEST_TITLE = 'New item title';
+const TEST_ISSUE_A = {
+ id: 'gid://gitlab/Issue/1',
+ iid: 8,
+ title: 'Issue 1',
+ referencePath: 'h/b#1',
+};
+const TEST_ISSUE_B = {
+ id: 'gid://gitlab/Issue/2',
+ iid: 9,
+ title: 'Issue 2',
+ referencePath: 'h/b#2',
+};
+
+jest.mock('~/flash');
+
+describe('~/boards/components/sidebar/board_sidebar_title.vue', () => {
+ let wrapper;
+ let store;
+
+ afterEach(() => {
+ localStorage.clear();
+ wrapper.destroy();
+ store = null;
+ wrapper = null;
+ });
+
+ const createWrapper = (item = TEST_ISSUE_A) => {
+ store = createStore();
+ store.state.boardItems = { [item.id]: { ...item } };
+ store.dispatch('setActiveId', { id: item.id });
+
+ wrapper = shallowMount(BoardSidebarTitle, {
+ store,
+ provide: {
+ canUpdate: true,
+ },
+ stubs: {
+ 'board-editable-item': BoardEditableItem,
+ },
+ });
+ };
+
+ const findForm = () => wrapper.find(GlForm);
+ const findAlert = () => wrapper.find(GlAlert);
+ const findFormInput = () => wrapper.find(GlFormInput);
+ const findEditableItem = () => wrapper.find(BoardEditableItem);
+ const findCancelButton = () => wrapper.find('[data-testid="cancel-button"]');
+ const findTitle = () => wrapper.find('[data-testid="item-title"]');
+ const findCollapsed = () => wrapper.find('[data-testid="collapsed-content"]');
+
+ it('renders title and reference', () => {
+ createWrapper();
+
+ expect(findTitle().text()).toContain(TEST_ISSUE_A.title);
+ expect(findCollapsed().text()).toContain(TEST_ISSUE_A.referencePath);
+ });
+
+ it('does not render alert', () => {
+ createWrapper();
+
+ expect(findAlert().exists()).toBe(false);
+ });
+
+ describe('when new title is submitted', () => {
+ beforeEach(async () => {
+ createWrapper();
+
+ jest.spyOn(wrapper.vm, 'setActiveItemTitle').mockImplementation(() => {
+ store.state.boardItems[TEST_ISSUE_A.id].title = TEST_TITLE;
+ });
+ findFormInput().vm.$emit('input', TEST_TITLE);
+ findForm().vm.$emit('submit', { preventDefault: () => {} });
+ await wrapper.vm.$nextTick();
+ });
+
+ it('collapses sidebar and renders new title', () => {
+ expect(findCollapsed().isVisible()).toBe(true);
+ expect(findTitle().text()).toContain(TEST_TITLE);
+ });
+
+ it('commits change to the server', () => {
+ expect(wrapper.vm.setActiveItemTitle).toHaveBeenCalledWith({
+ title: TEST_TITLE,
+ projectPath: 'h/b',
+ });
+ });
+ });
+
+ describe('when submitting and invalid title', () => {
+ beforeEach(async () => {
+ createWrapper();
+
+ jest.spyOn(wrapper.vm, 'setActiveItemTitle').mockImplementation(() => {});
+ findFormInput().vm.$emit('input', '');
+ findForm().vm.$emit('submit', { preventDefault: () => {} });
+ await wrapper.vm.$nextTick();
+ });
+
+ it('commits change to the server', () => {
+ expect(wrapper.vm.setActiveItemTitle).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when abandoning the form without saving', () => {
+ beforeEach(async () => {
+ createWrapper();
+
+ wrapper.vm.$refs.sidebarItem.expand();
+ findFormInput().vm.$emit('input', TEST_TITLE);
+ findEditableItem().vm.$emit('off-click');
+ await wrapper.vm.$nextTick();
+ });
+
+ it('does not collapses sidebar and shows alert', () => {
+ expect(findCollapsed().isVisible()).toBe(false);
+ expect(findAlert().exists()).toBe(true);
+ expect(localStorage.getItem(`${TEST_ISSUE_A.id}/item-title-pending-changes`)).toBe(
+ TEST_TITLE,
+ );
+ });
+ });
+
+ describe('when accessing the form with pending changes', () => {
+ beforeAll(() => {
+ localStorage.setItem(`${TEST_ISSUE_A.id}/item-title-pending-changes`, TEST_TITLE);
+
+ createWrapper();
+ });
+
+ it('sets title, expands item and shows alert', async () => {
+ expect(wrapper.vm.title).toBe(TEST_TITLE);
+ expect(findCollapsed().isVisible()).toBe(false);
+ expect(findAlert().exists()).toBe(true);
+ });
+ });
+
+ describe('when cancel button is clicked', () => {
+ beforeEach(async () => {
+ createWrapper(TEST_ISSUE_B);
+
+ jest.spyOn(wrapper.vm, 'setActiveItemTitle').mockImplementation(() => {
+ store.state.boardItems[TEST_ISSUE_B.id].title = TEST_TITLE;
+ });
+ findFormInput().vm.$emit('input', TEST_TITLE);
+ findCancelButton().vm.$emit('click');
+ await wrapper.vm.$nextTick();
+ });
+
+ it('collapses sidebar and render former title', () => {
+ expect(wrapper.vm.setActiveItemTitle).not.toHaveBeenCalled();
+ expect(findCollapsed().isVisible()).toBe(true);
+ expect(findTitle().text()).toBe(TEST_ISSUE_B.title);
+ });
+ });
+
+ describe('when the mutation fails', () => {
+ beforeEach(async () => {
+ createWrapper(TEST_ISSUE_B);
+
+ jest.spyOn(wrapper.vm, 'setActiveItemTitle').mockImplementation(() => {
+ throw new Error(['failed mutation']);
+ });
+ findFormInput().vm.$emit('input', 'Invalid title');
+ findForm().vm.$emit('submit', { preventDefault: () => {} });
+ await wrapper.vm.$nextTick();
+ });
+
+ it('collapses sidebar and renders former item title', () => {
+ expect(findCollapsed().isVisible()).toBe(true);
+ expect(findTitle().text()).toContain(TEST_ISSUE_B.title);
+ expect(createFlash).toHaveBeenCalled();
+ });
+ });
+});