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/sidebar/lock')
-rw-r--r--spec/frontend/sidebar/lock/__snapshots__/edit_form_spec.js.snap79
-rw-r--r--spec/frontend/sidebar/lock/constants.js2
-rw-r--r--spec/frontend/sidebar/lock/edit_form_buttons_spec.js171
-rw-r--r--spec/frontend/sidebar/lock/edit_form_spec.js67
-rw-r--r--spec/frontend/sidebar/lock/issuable_lock_form_spec.js133
-rw-r--r--spec/frontend/sidebar/lock/lock_issue_sidebar_spec.js99
6 files changed, 415 insertions, 136 deletions
diff --git a/spec/frontend/sidebar/lock/__snapshots__/edit_form_spec.js.snap b/spec/frontend/sidebar/lock/__snapshots__/edit_form_spec.js.snap
new file mode 100644
index 00000000000..18d4df297df
--- /dev/null
+++ b/spec/frontend/sidebar/lock/__snapshots__/edit_form_spec.js.snap
@@ -0,0 +1,79 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Edit Form Dropdown In issue page when locked the appropriate warning text is rendered 1`] = `
+<div
+ class="dropdown-menu sidebar-item-warning-message"
+ data-testid="warning-text"
+>
+ <p
+ class="text"
+ >
+ <gl-sprintf-stub
+ message="Unlock this %{issuableDisplayName}? %{strongStart}Everyone%{strongEnd} will be able to comment."
+ />
+ </p>
+
+ <edit-form-buttons-stub
+ islocked="true"
+ issuabledisplayname="issue"
+ />
+</div>
+`;
+
+exports[`Edit Form Dropdown In issue page when unlocked the appropriate warning text is rendered 1`] = `
+<div
+ class="dropdown-menu sidebar-item-warning-message"
+ data-testid="warning-text"
+>
+ <p
+ class="text"
+ >
+ <gl-sprintf-stub
+ message="Lock this %{issuableDisplayName}? Only %{strongStart}project members%{strongEnd} will be able to comment."
+ />
+ </p>
+
+ <edit-form-buttons-stub
+ issuabledisplayname="issue"
+ />
+</div>
+`;
+
+exports[`Edit Form Dropdown In merge request page when locked the appropriate warning text is rendered 1`] = `
+<div
+ class="dropdown-menu sidebar-item-warning-message"
+ data-testid="warning-text"
+>
+ <p
+ class="text"
+ >
+ <gl-sprintf-stub
+ message="Unlock this %{issuableDisplayName}? %{strongStart}Everyone%{strongEnd} will be able to comment."
+ />
+ </p>
+
+ <edit-form-buttons-stub
+ islocked="true"
+ issuabledisplayname="merge request"
+ />
+</div>
+`;
+
+exports[`Edit Form Dropdown In merge request page when unlocked the appropriate warning text is rendered 1`] = `
+<div
+ class="dropdown-menu sidebar-item-warning-message"
+ data-testid="warning-text"
+>
+ <p
+ class="text"
+ >
+ <gl-sprintf-stub
+ message="Lock this %{issuableDisplayName}? Only %{strongStart}project members%{strongEnd} will be able to comment."
+ />
+ </p>
+
+ <edit-form-buttons-stub
+ issuabledisplayname="merge request"
+ />
+</div>
+`;
diff --git a/spec/frontend/sidebar/lock/constants.js b/spec/frontend/sidebar/lock/constants.js
new file mode 100644
index 00000000000..b9f08e9286d
--- /dev/null
+++ b/spec/frontend/sidebar/lock/constants.js
@@ -0,0 +1,2 @@
+export const ISSUABLE_TYPE_ISSUE = 'issue';
+export const ISSUABLE_TYPE_MR = 'merge request';
diff --git a/spec/frontend/sidebar/lock/edit_form_buttons_spec.js b/spec/frontend/sidebar/lock/edit_form_buttons_spec.js
index 66f9237ce97..de1da3456f8 100644
--- a/spec/frontend/sidebar/lock/edit_form_buttons_spec.js
+++ b/spec/frontend/sidebar/lock/edit_form_buttons_spec.js
@@ -1,31 +1,178 @@
import { shallowMount } from '@vue/test-utils';
+import { GlLoadingIcon } from '@gitlab/ui';
import EditFormButtons from '~/sidebar/components/lock/edit_form_buttons.vue';
+import eventHub from '~/sidebar/event_hub';
+import { deprecatedCreateFlash as flash } from '~/flash';
+import createStore from '~/notes/stores';
+import { createStore as createMrStore } from '~/mr_notes/stores';
+import { ISSUABLE_TYPE_ISSUE, ISSUABLE_TYPE_MR } from './constants';
+
+jest.mock('~/sidebar/event_hub', () => ({ $emit: jest.fn() }));
+jest.mock('~/flash');
describe('EditFormButtons', () => {
let wrapper;
+ let store;
+ let issuableType;
+ let issuableDisplayName;
+
+ const setIssuableType = pageType => {
+ issuableType = pageType;
+ issuableDisplayName = issuableType.replace(/_/g, ' ');
+ };
+
+ const findLockToggle = () => wrapper.find('[data-testid="lock-toggle"]');
+ const findGlLoadingIcon = () => wrapper.find(GlLoadingIcon);
- const mountComponent = propsData => shallowMount(EditFormButtons, { propsData });
+ const createComponent = ({ props = {}, data = {}, resolved = true }) => {
+ store = issuableType === ISSUABLE_TYPE_ISSUE ? createStore() : createMrStore();
+
+ if (resolved) {
+ jest.spyOn(store, 'dispatch').mockResolvedValue();
+ } else {
+ jest.spyOn(store, 'dispatch').mockRejectedValue();
+ }
+
+ wrapper = shallowMount(EditFormButtons, {
+ store,
+ provide: {
+ fullPath: '',
+ },
+ propsData: {
+ isLocked: false,
+ issuableDisplayName,
+ ...props,
+ },
+ data() {
+ return {
+ isLoading: false,
+ ...data,
+ };
+ },
+ });
+ };
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
- it('displays "Unlock" when locked', () => {
- wrapper = mountComponent({
- isLocked: true,
- updateLockedAttribute: () => {},
+ describe.each`
+ pageType
+ ${ISSUABLE_TYPE_ISSUE} | ${ISSUABLE_TYPE_MR}
+ `('In $pageType page', ({ pageType }) => {
+ beforeEach(() => {
+ setIssuableType(pageType);
});
- expect(wrapper.text()).toContain('Unlock');
- });
+ describe('when isLoading', () => {
+ beforeEach(() => {
+ createComponent({ data: { isLoading: true } });
+ });
+
+ it('renders "Applying" in the toggle button', () => {
+ expect(findLockToggle().text()).toBe('Applying');
+ });
+
+ it('disables the toggle button', () => {
+ expect(findLockToggle().attributes('disabled')).toBe('disabled');
+ });
- it('displays "Lock" when unlocked', () => {
- wrapper = mountComponent({
- isLocked: false,
- updateLockedAttribute: () => {},
+ it('displays the GlLoadingIcon', () => {
+ expect(findGlLoadingIcon().exists()).toBe(true);
+ });
});
- expect(wrapper.text()).toContain('Lock');
+ describe.each`
+ isLocked | toggleText | statusText
+ ${false} | ${'Lock'} | ${'unlocked'}
+ ${true} | ${'Unlock'} | ${'locked'}
+ `('when $statusText', ({ isLocked, toggleText }) => {
+ beforeEach(() => {
+ createComponent({
+ props: {
+ isLocked,
+ },
+ });
+ });
+
+ it(`toggle button displays "${toggleText}"`, () => {
+ expect(findLockToggle().text()).toContain(toggleText);
+ });
+
+ describe('when toggled', () => {
+ describe(`when resolved`, () => {
+ beforeEach(() => {
+ createComponent({
+ props: {
+ isLocked,
+ },
+ resolved: true,
+ });
+ findLockToggle().trigger('click');
+ });
+
+ it('dispatches the correct action', () => {
+ expect(store.dispatch).toHaveBeenCalledWith('updateLockedAttribute', {
+ locked: !isLocked,
+ fullPath: '',
+ });
+ });
+
+ it('resets loading', async () => {
+ await wrapper.vm.$nextTick().then(() => {
+ expect(findGlLoadingIcon().exists()).toBe(false);
+ });
+ });
+
+ it('emits close form', () => {
+ return wrapper.vm.$nextTick().then(() => {
+ expect(eventHub.$emit).toHaveBeenCalledWith('closeLockForm');
+ });
+ });
+
+ it('does not flash an error message', () => {
+ expect(flash).not.toHaveBeenCalled();
+ });
+ });
+
+ describe(`when not resolved`, () => {
+ beforeEach(() => {
+ createComponent({
+ props: {
+ isLocked,
+ },
+ resolved: false,
+ });
+ findLockToggle().trigger('click');
+ });
+
+ it('dispatches the correct action', () => {
+ expect(store.dispatch).toHaveBeenCalledWith('updateLockedAttribute', {
+ locked: !isLocked,
+ fullPath: '',
+ });
+ });
+
+ it('resets loading', async () => {
+ await wrapper.vm.$nextTick().then(() => {
+ expect(findGlLoadingIcon().exists()).toBe(false);
+ });
+ });
+
+ it('emits close form', () => {
+ return wrapper.vm.$nextTick().then(() => {
+ expect(eventHub.$emit).toHaveBeenCalledWith('closeLockForm');
+ });
+ });
+
+ it('calls flash with the correct message', () => {
+ expect(flash).toHaveBeenCalledWith(
+ `Something went wrong trying to change the locked state of this ${issuableDisplayName}`,
+ );
+ });
+ });
+ });
+ });
});
});
diff --git a/spec/frontend/sidebar/lock/edit_form_spec.js b/spec/frontend/sidebar/lock/edit_form_spec.js
index ec10a999a40..b1c3bfe3ef5 100644
--- a/spec/frontend/sidebar/lock/edit_form_spec.js
+++ b/spec/frontend/sidebar/lock/edit_form_spec.js
@@ -1,37 +1,54 @@
-import Vue from 'vue';
-import editForm from '~/sidebar/components/lock/edit_form.vue';
+import { shallowMount } from '@vue/test-utils';
+import EditForm from '~/sidebar/components/lock/edit_form.vue';
+import { ISSUABLE_TYPE_ISSUE, ISSUABLE_TYPE_MR } from './constants';
-describe('EditForm', () => {
- let vm1;
- let vm2;
+describe('Edit Form Dropdown', () => {
+ let wrapper;
+ let issuableType; // Either ISSUABLE_TYPE_ISSUE or ISSUABLE_TYPE_MR
+ let issuableDisplayName;
- beforeEach(() => {
- const Component = Vue.extend(editForm);
- const toggleForm = () => {};
- const updateLockedAttribute = () => {};
+ const setIssuableType = pageType => {
+ issuableType = pageType;
+ issuableDisplayName = issuableType.replace(/_/g, ' ');
+ };
- vm1 = new Component({
- propsData: {
- isLocked: true,
- toggleForm,
- updateLockedAttribute,
- issuableType: 'issue',
- },
- }).$mount();
+ const findWarningText = () => wrapper.find('[data-testid="warning-text"]');
- vm2 = new Component({
+ const createComponent = ({ props }) => {
+ wrapper = shallowMount(EditForm, {
propsData: {
isLocked: false,
- toggleForm,
- updateLockedAttribute,
- issuableType: 'merge_request',
+ issuableDisplayName,
+ ...props,
},
- }).$mount();
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
});
- it('renders on the appropriate warning text', () => {
- expect(vm1.$el.innerHTML.includes('Unlock this issue?')).toBe(true);
+ describe.each`
+ pageType
+ ${ISSUABLE_TYPE_ISSUE} | ${ISSUABLE_TYPE_MR}
+ `('In $pageType page', ({ pageType }) => {
+ beforeEach(() => {
+ setIssuableType(pageType);
+ });
+
+ describe.each`
+ isLocked | lockStatusText
+ ${false} | ${'unlocked'}
+ ${true} | ${'locked'}
+ `('when $lockStatusText', ({ isLocked }) => {
+ beforeEach(() => {
+ createComponent({ props: { isLocked } });
+ });
- expect(vm2.$el.innerHTML.includes('Lock this merge request?')).toBe(true);
+ it(`the appropriate warning text is rendered`, () => {
+ expect(findWarningText().element).toMatchSnapshot();
+ });
+ });
});
});
diff --git a/spec/frontend/sidebar/lock/issuable_lock_form_spec.js b/spec/frontend/sidebar/lock/issuable_lock_form_spec.js
new file mode 100644
index 00000000000..ab1423a9bbb
--- /dev/null
+++ b/spec/frontend/sidebar/lock/issuable_lock_form_spec.js
@@ -0,0 +1,133 @@
+import { shallowMount } from '@vue/test-utils';
+import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
+import IssuableLockForm from '~/sidebar/components/lock/issuable_lock_form.vue';
+import EditForm from '~/sidebar/components/lock/edit_form.vue';
+import createStore from '~/notes/stores';
+import { createStore as createMrStore } from '~/mr_notes/stores';
+import { ISSUABLE_TYPE_ISSUE, ISSUABLE_TYPE_MR } from './constants';
+
+describe('IssuableLockForm', () => {
+ let wrapper;
+ let store;
+ let issuableType; // Either ISSUABLE_TYPE_ISSUE or ISSUABLE_TYPE_MR
+
+ const setIssuableType = pageType => {
+ issuableType = pageType;
+ };
+
+ const findSidebarCollapseIcon = () => wrapper.find('[data-testid="sidebar-collapse-icon"]');
+ const findLockStatus = () => wrapper.find('[data-testid="lock-status"]');
+ const findEditLink = () => wrapper.find('[data-testid="edit-link"]');
+ const findEditForm = () => wrapper.find(EditForm);
+
+ const initStore = isLocked => {
+ if (issuableType === ISSUABLE_TYPE_ISSUE) {
+ store = createStore();
+ store.getters.getNoteableData.targetType = 'issue';
+ } else {
+ store = createMrStore();
+ }
+ store.getters.getNoteableData.discussion_locked = isLocked;
+ };
+
+ const createComponent = ({ props = {} }) => {
+ wrapper = shallowMount(IssuableLockForm, {
+ store,
+ propsData: {
+ isEditable: true,
+ ...props,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe.each`
+ pageType
+ ${ISSUABLE_TYPE_ISSUE} | ${ISSUABLE_TYPE_MR}
+ `('In $pageType page', ({ pageType }) => {
+ beforeEach(() => {
+ setIssuableType(pageType);
+ });
+
+ describe.each`
+ isLocked
+ ${false} | ${true}
+ `(`renders for isLocked = $isLocked`, ({ isLocked }) => {
+ beforeEach(() => {
+ initStore(isLocked);
+ createComponent({});
+ });
+
+ it('shows the lock status', () => {
+ expect(findLockStatus().text()).toBe(isLocked ? 'Locked' : 'Unlocked');
+ });
+
+ describe('edit form', () => {
+ let isEditable;
+ beforeEach(() => {
+ isEditable = false;
+ createComponent({ props: { isEditable } });
+ });
+
+ describe('when not editable', () => {
+ it('does not display the edit form when opened if not editable', () => {
+ expect(findEditForm().exists()).toBe(false);
+ findSidebarCollapseIcon().trigger('click');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findEditForm().exists()).toBe(false);
+ });
+ });
+ });
+
+ describe('when editable', () => {
+ beforeEach(() => {
+ isEditable = true;
+ createComponent({ props: { isEditable } });
+ });
+
+ it('shows the editable status', () => {
+ expect(findEditLink().exists()).toBe(isEditable);
+ expect(findEditLink().text()).toBe('Edit');
+ });
+
+ describe("when 'Edit' is clicked", () => {
+ it('displays the edit form when editable', () => {
+ expect(findEditForm().exists()).toBe(false);
+ findEditLink().trigger('click');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findEditForm().exists()).toBe(true);
+ });
+ });
+
+ it('tracks the event ', () => {
+ const spy = mockTracking('_category_', wrapper.element, jest.spyOn);
+ triggerEvent(findEditLink().element);
+
+ expect(spy).toHaveBeenCalledWith('_category_', 'click_edit_button', {
+ label: 'right_sidebar',
+ property: 'lock_issue',
+ });
+ });
+ });
+
+ describe('When sidebar is collapsed', () => {
+ it('displays the edit form when opened', () => {
+ expect(findEditForm().exists()).toBe(false);
+ findSidebarCollapseIcon().trigger('click');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findEditForm().exists()).toBe(true);
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/sidebar/lock/lock_issue_sidebar_spec.js b/spec/frontend/sidebar/lock/lock_issue_sidebar_spec.js
deleted file mode 100644
index 00997326d87..00000000000
--- a/spec/frontend/sidebar/lock/lock_issue_sidebar_spec.js
+++ /dev/null
@@ -1,99 +0,0 @@
-import Vue from 'vue';
-import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
-import lockIssueSidebar from '~/sidebar/components/lock/lock_issue_sidebar.vue';
-
-describe('LockIssueSidebar', () => {
- let vm1;
- let vm2;
-
- beforeEach(() => {
- const Component = Vue.extend(lockIssueSidebar);
-
- const mediator = {
- service: {
- update: Promise.resolve(true),
- },
-
- store: {
- isLockDialogOpen: false,
- },
- };
-
- vm1 = new Component({
- propsData: {
- isLocked: true,
- isEditable: true,
- mediator,
- issuableType: 'issue',
- },
- }).$mount();
-
- vm2 = new Component({
- propsData: {
- isLocked: false,
- isEditable: false,
- mediator,
- issuableType: 'merge_request',
- },
- }).$mount();
- });
-
- it('shows if locked and/or editable', () => {
- expect(vm1.$el.innerHTML.includes('Edit')).toBe(true);
-
- expect(vm1.$el.innerHTML.includes('Locked')).toBe(true);
-
- expect(vm2.$el.innerHTML.includes('Unlocked')).toBe(true);
- });
-
- it('displays the edit form when editable', done => {
- expect(vm1.isLockDialogOpen).toBe(false);
-
- vm1.$el.querySelector('.lock-edit').click();
-
- expect(vm1.isLockDialogOpen).toBe(true);
-
- vm1.$nextTick(() => {
- expect(vm1.$el.innerHTML.includes('Unlock this issue?')).toBe(true);
-
- done();
- });
- });
-
- it('tracks an event when "Edit" is clicked', () => {
- const spy = mockTracking('_category_', vm1.$el, jest.spyOn);
- triggerEvent('.lock-edit');
-
- expect(spy).toHaveBeenCalledWith('_category_', 'click_edit_button', {
- label: 'right_sidebar',
- property: 'lock_issue',
- });
- });
-
- it('displays the edit form when opened from collapsed state', done => {
- expect(vm1.isLockDialogOpen).toBe(false);
-
- vm1.$el.querySelector('.sidebar-collapsed-icon').click();
-
- expect(vm1.isLockDialogOpen).toBe(true);
-
- setImmediate(() => {
- expect(vm1.$el.innerHTML.includes('Unlock this issue?')).toBe(true);
-
- done();
- });
- });
-
- it('does not display the edit form when opened from collapsed state if not editable', done => {
- expect(vm2.isLockDialogOpen).toBe(false);
-
- vm2.$el.querySelector('.sidebar-collapsed-icon').click();
-
- Vue.nextTick()
- .then(() => {
- expect(vm2.isLockDialogOpen).toBe(false);
- })
- .then(done)
- .catch(done.fail);
- });
-});