summaryrefslogtreecommitdiff
path: root/spec/frontend/sidebar
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 18:42:06 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 18:42:06 +0000
commit6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch)
tree78be5963ec075d80116a932011d695dd33910b4e /spec/frontend/sidebar
parent1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff)
downloadgitlab-ce-6e4e1050d9dba2b7b2523fdd1768823ab85feef4.tar.gz
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'spec/frontend/sidebar')
-rw-r--r--spec/frontend/sidebar/__snapshots__/confidential_issue_sidebar_spec.js.snap8
-rw-r--r--spec/frontend/sidebar/confidential/__snapshots__/edit_form_spec.js.snap50
-rw-r--r--spec/frontend/sidebar/confidential/edit_form_buttons_spec.js108
-rw-r--r--spec/frontend/sidebar/confidential/edit_form_spec.js11
-rw-r--r--spec/frontend/sidebar/confidential_issue_sidebar_spec.js98
-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
-rw-r--r--spec/frontend/sidebar/todo_spec.js2
12 files changed, 552 insertions, 276 deletions
diff --git a/spec/frontend/sidebar/__snapshots__/confidential_issue_sidebar_spec.js.snap b/spec/frontend/sidebar/__snapshots__/confidential_issue_sidebar_spec.js.snap
index da571af3a0d..4c1ab4a499c 100644
--- a/spec/frontend/sidebar/__snapshots__/confidential_issue_sidebar_spec.js.snap
+++ b/spec/frontend/sidebar/__snapshots__/confidential_issue_sidebar_spec.js.snap
@@ -49,8 +49,6 @@ exports[`Confidential Issue Sidebar Block renders for confidential = false and i
</div>
</div>
-
- <!---->
</div>
`;
@@ -111,8 +109,6 @@ exports[`Confidential Issue Sidebar Block renders for confidential = false and i
</div>
</div>
-
- <!---->
</div>
`;
@@ -164,8 +160,6 @@ exports[`Confidential Issue Sidebar Block renders for confidential = true and is
</div>
</div>
-
- <!---->
</div>
`;
@@ -225,7 +219,5 @@ exports[`Confidential Issue Sidebar Block renders for confidential = true and is
</div>
</div>
-
- <!---->
</div>
`;
diff --git a/spec/frontend/sidebar/confidential/__snapshots__/edit_form_spec.js.snap b/spec/frontend/sidebar/confidential/__snapshots__/edit_form_spec.js.snap
new file mode 100644
index 00000000000..d33f6c7f389
--- /dev/null
+++ b/spec/frontend/sidebar/confidential/__snapshots__/edit_form_spec.js.snap
@@ -0,0 +1,50 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Edit Form Dropdown when confidential renders on or off text based on confidentiality 1`] = `
+<div
+ class="dropdown show"
+ toggleform="function () {}"
+ updateconfidentialattribute="function () {}"
+>
+ <div
+ class="dropdown-menu sidebar-item-warning-message"
+ >
+ <div>
+ <p>
+ <gl-sprintf-stub
+ message="You are going to turn off the confidentiality. This means %{strongStart}everyone%{strongEnd} will be able to see and leave a comment on this %{issuableType}."
+ />
+ </p>
+
+ <edit-form-buttons-stub
+ confidential="true"
+ fullpath=""
+ />
+ </div>
+ </div>
+</div>
+`;
+
+exports[`Edit Form Dropdown when not confidential renders "You are going to turn on the confidentiality." in the 1`] = `
+<div
+ class="dropdown show"
+ toggleform="function () {}"
+ updateconfidentialattribute="function () {}"
+>
+ <div
+ class="dropdown-menu sidebar-item-warning-message"
+ >
+ <div>
+ <p>
+ <gl-sprintf-stub
+ message="You are going to turn on the confidentiality. This means that only team members with %{strongStart}at least Reporter access%{strongEnd} are able to see and leave comments on the %{issuableType}."
+ />
+ </p>
+
+ <edit-form-buttons-stub
+ fullpath=""
+ />
+ </div>
+ </div>
+</div>
+`;
diff --git a/spec/frontend/sidebar/confidential/edit_form_buttons_spec.js b/spec/frontend/sidebar/confidential/edit_form_buttons_spec.js
index 15493d3087f..2f11c6a07c2 100644
--- a/spec/frontend/sidebar/confidential/edit_form_buttons_spec.js
+++ b/spec/frontend/sidebar/confidential/edit_form_buttons_spec.js
@@ -1,10 +1,10 @@
import { shallowMount } from '@vue/test-utils';
import { GlLoadingIcon } from '@gitlab/ui';
+import waitForPromises from 'helpers/wait_for_promises';
import EditFormButtons from '~/sidebar/components/confidential/edit_form_buttons.vue';
import eventHub from '~/sidebar/event_hub';
import createStore from '~/notes/stores';
-import waitForPromises from 'helpers/wait_for_promises';
-import flash from '~/flash';
+import { deprecatedCreateFlash as flash } from '~/flash';
jest.mock('~/sidebar/event_hub', () => ({ $emit: jest.fn() }));
jest.mock('~/flash');
@@ -14,12 +14,7 @@ describe('Edit Form Buttons', () => {
let store;
const findConfidentialToggle = () => wrapper.find('[data-testid="confidential-toggle"]');
- const createComponent = ({
- props = {},
- data = {},
- confidentialApolloSidebar = false,
- resolved = true,
- }) => {
+ const createComponent = ({ props = {}, data = {}, resolved = true }) => {
store = createStore();
if (resolved) {
jest.spyOn(store, 'dispatch').mockResolvedValue();
@@ -38,11 +33,6 @@ describe('Edit Form Buttons', () => {
...data,
};
},
- provide: {
- glFeatures: {
- confidentialApolloSidebar,
- },
- },
store,
});
};
@@ -54,9 +44,11 @@ describe('Edit Form Buttons', () => {
describe('when isLoading', () => {
beforeEach(() => {
- createComponent({});
-
- wrapper.vm.$store.state.noteableData.confidential = false;
+ createComponent({
+ props: {
+ confidential: false,
+ },
+ });
});
it('renders "Applying" in the toggle button', () => {
@@ -78,6 +70,9 @@ describe('Edit Form Buttons', () => {
data: {
isLoading: false,
},
+ props: {
+ confidential: false,
+ },
});
expect(findConfidentialToggle().text()).toBe('Turn On');
@@ -90,70 +85,63 @@ describe('Edit Form Buttons', () => {
data: {
isLoading: false,
},
+ props: {
+ confidential: true,
+ },
});
-
- wrapper.vm.$store.state.noteableData.confidential = true;
});
it('renders on or off text based on confidentiality', () => {
expect(findConfidentialToggle().text()).toBe('Turn Off');
});
-
- describe('when clicking on the confidential toggle', () => {
- it('emits updateConfidentialAttribute', () => {
- findConfidentialToggle().trigger('click');
-
- expect(eventHub.$emit).toHaveBeenCalledWith('updateConfidentialAttribute');
- });
- });
});
- describe('when confidentialApolloSidebar is turned on', () => {
- const isConfidential = true;
+ describe('when succeeds', () => {
+ beforeEach(() => {
+ createComponent({ data: { isLoading: false }, props: { confidential: true } });
+ findConfidentialToggle().trigger('click');
+ });
- describe('when succeeds', () => {
- beforeEach(() => {
- createComponent({ data: { isLoading: false }, confidentialApolloSidebar: true });
- wrapper.vm.$store.state.noteableData.confidential = isConfidential;
- findConfidentialToggle().trigger('click');
+ it('dispatches the correct action', () => {
+ expect(store.dispatch).toHaveBeenCalledWith('updateConfidentialityOnIssuable', {
+ confidential: false,
+ fullPath: '',
});
+ });
- it('dispatches the correct action', () => {
- expect(store.dispatch).toHaveBeenCalledWith('updateConfidentialityOnIssue', {
- confidential: !isConfidential,
- fullPath: '',
- });
+ it('resets loading', () => {
+ return waitForPromises().then(() => {
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
});
+ });
- it('resets loading', () => {
- return waitForPromises().then(() => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
- });
+ it('emits close form', () => {
+ return waitForPromises().then(() => {
+ expect(eventHub.$emit).toHaveBeenCalledWith('closeConfidentialityForm');
});
+ });
- it('emits close form', () => {
- return waitForPromises().then(() => {
- expect(eventHub.$emit).toHaveBeenCalledWith('closeConfidentialityForm');
- });
+ it('emits updateOnConfidentiality event', () => {
+ return waitForPromises().then(() => {
+ expect(eventHub.$emit).toHaveBeenCalledWith('updateIssuableConfidentiality', false);
});
});
+ });
- describe('when fails', () => {
- beforeEach(() => {
- createComponent({
- data: { isLoading: false },
- confidentialApolloSidebar: true,
- resolved: false,
- });
- wrapper.vm.$store.state.noteableData.confidential = isConfidential;
- findConfidentialToggle().trigger('click');
+ describe('when fails', () => {
+ beforeEach(() => {
+ createComponent({
+ data: { isLoading: false },
+ props: { confidential: true },
+ resolved: false,
});
+ findConfidentialToggle().trigger('click');
+ });
- it('calls flash with the correct message', () => {
- expect(flash).toHaveBeenCalledWith(
- 'Something went wrong trying to change the confidentiality of this issue',
- );
- });
+ it('calls flash with the correct message', () => {
+ expect(flash).toHaveBeenCalledWith(
+ 'Something went wrong trying to change the confidentiality of this issue',
+ );
});
});
});
diff --git a/spec/frontend/sidebar/confidential/edit_form_spec.js b/spec/frontend/sidebar/confidential/edit_form_spec.js
index a22bbe5ae0d..56f163eecd1 100644
--- a/spec/frontend/sidebar/confidential/edit_form_spec.js
+++ b/spec/frontend/sidebar/confidential/edit_form_spec.js
@@ -12,6 +12,7 @@ describe('Edit Form Dropdown', () => {
...props,
isLoading: false,
fullPath: '',
+ issuableType: 'issue',
},
});
};
@@ -22,26 +23,26 @@ describe('Edit Form Dropdown', () => {
});
describe('when not confidential', () => {
- it('renders "You are going to turn off the confidentiality." in the ', () => {
+ it('renders "You are going to turn on the confidentiality." in the ', () => {
createComponent({
- isConfidential: false,
+ confidential: false,
toggleForm,
updateConfidentialAttribute,
});
- expect(wrapper.find('p').text()).toContain('You are going to turn on the confidentiality.');
+ expect(wrapper.element).toMatchSnapshot();
});
});
describe('when confidential', () => {
it('renders on or off text based on confidentiality', () => {
createComponent({
- isConfidential: true,
+ confidential: true,
toggleForm,
updateConfidentialAttribute,
});
- expect(wrapper.find('p').text()).toContain('You are going to turn off the confidentiality.');
+ expect(wrapper.element).toMatchSnapshot();
});
});
});
diff --git a/spec/frontend/sidebar/confidential_issue_sidebar_spec.js b/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
index 06cf1e6166c..bc2df9305d0 100644
--- a/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
+++ b/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
@@ -1,13 +1,10 @@
import { shallowMount } from '@vue/test-utils';
import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
+import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import ConfidentialIssueSidebar from '~/sidebar/components/confidential/confidential_issue_sidebar.vue';
import EditForm from '~/sidebar/components/confidential/edit_form.vue';
-import SidebarService from '~/sidebar/services/sidebar_service';
-import createFlash from '~/flash';
-import RecaptchaModal from '~/vue_shared/components/recaptcha_modal.vue';
import createStore from '~/notes/stores';
-import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
-import eventHub from '~/sidebar/event_hub';
+import * as types from '~/notes/stores/mutation_types';
jest.mock('~/flash');
jest.mock('~/sidebar/services/sidebar_service');
@@ -20,32 +17,14 @@ describe('Confidential Issue Sidebar Block', () => {
.fn()
.mockResolvedValue({ data: { issueSetConfidential: { issue: { confidential: true } } } });
- const findRecaptchaModal = () => wrapper.find(RecaptchaModal);
-
- const triggerUpdateConfidentialAttribute = () => {
- wrapper.setData({ edit: true });
- return (
- // wait for edit form to become visible
- wrapper.vm
- .$nextTick()
- .then(() => {
- eventHub.$emit('updateConfidentialAttribute');
- })
- // wait for reCAPTCHA modal to render
- .then(() => wrapper.vm.$nextTick())
- );
- };
-
const createComponent = ({ propsData, data = {} }) => {
const store = createStore();
- const service = new SidebarService();
wrapper = shallowMount(ConfidentialIssueSidebar, {
store,
data() {
return data;
},
propsData: {
- service,
iid: '',
fullPath: '',
...propsData,
@@ -133,61 +112,48 @@ describe('Confidential Issue Sidebar Block', () => {
property: 'confidentiality',
});
});
-
- describe('for successful update', () => {
- beforeEach(() => {
- SidebarService.prototype.update.mockResolvedValue({ data: 'irrelevant' });
+ });
+ describe('computed confidential', () => {
+ beforeEach(() => {
+ createComponent({
+ propsData: {
+ isEditable: true,
+ },
});
+ });
- it('reloads the page', () =>
- triggerUpdateConfidentialAttribute().then(() => {
- expect(window.location.reload).toHaveBeenCalled();
- }));
+ it('returns false when noteableData is not present', () => {
+ wrapper.vm.$store.commit(types.SET_NOTEABLE_DATA, null);
- it('does not show an error message', () =>
- triggerUpdateConfidentialAttribute().then(() => {
- expect(createFlash).not.toHaveBeenCalled();
- }));
+ expect(wrapper.vm.confidential).toBe(false);
});
- describe('for update error', () => {
- beforeEach(() => {
- SidebarService.prototype.update.mockRejectedValue(new Error('updating failed!'));
- });
-
- it('does not reload the page', () =>
- triggerUpdateConfidentialAttribute().then(() => {
- expect(window.location.reload).not.toHaveBeenCalled();
- }));
+ it('returns true when noteableData has confidential attr as true', () => {
+ wrapper.vm.$store.commit(types.SET_NOTEABLE_DATA, {});
+ wrapper.vm.$store.commit(types.SET_ISSUE_CONFIDENTIAL, true);
- it('shows an error message', () =>
- triggerUpdateConfidentialAttribute().then(() => {
- expect(createFlash).toHaveBeenCalled();
- }));
+ expect(wrapper.vm.confidential).toBe(true);
});
- describe('for spam error', () => {
- beforeEach(() => {
- SidebarService.prototype.update.mockRejectedValue({ name: 'SpamError' });
- });
+ it('returns false when noteableData has confidential attr as false', () => {
+ wrapper.vm.$store.commit(types.SET_NOTEABLE_DATA, {});
+ wrapper.vm.$store.commit(types.SET_ISSUE_CONFIDENTIAL, false);
+
+ expect(wrapper.vm.confidential).toBe(false);
+ });
- it('does not reload the page', () =>
- triggerUpdateConfidentialAttribute().then(() => {
- expect(window.location.reload).not.toHaveBeenCalled();
- }));
+ it('returns true when confidential attr is true', () => {
+ wrapper.vm.$store.commit(types.SET_NOTEABLE_DATA, {});
+ wrapper.vm.$store.commit(types.SET_ISSUE_CONFIDENTIAL, true);
- it('does not show an error message', () =>
- triggerUpdateConfidentialAttribute().then(() => {
- expect(createFlash).not.toHaveBeenCalled();
- }));
+ expect(wrapper.vm.confidential).toBe(true);
+ });
- it('shows a reCAPTCHA modal', () => {
- expect(findRecaptchaModal().exists()).toBe(false);
+ it('returns false when confidential attr is false', () => {
+ wrapper.vm.$store.commit(types.SET_NOTEABLE_DATA, {});
+ wrapper.vm.$store.commit(types.SET_ISSUE_CONFIDENTIAL, false);
- return triggerUpdateConfidentialAttribute().then(() => {
- expect(findRecaptchaModal().exists()).toBe(true);
- });
- });
+ expect(wrapper.vm.confidential).toBe(false);
});
});
});
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);
- });
-});
diff --git a/spec/frontend/sidebar/todo_spec.js b/spec/frontend/sidebar/todo_spec.js
index 18b621cd12d..e56a78989eb 100644
--- a/spec/frontend/sidebar/todo_spec.js
+++ b/spec/frontend/sidebar/todo_spec.js
@@ -36,7 +36,7 @@ describe('SidebarTodo', () => {
it.each`
isTodo | iconClass | label | icon
- ${false} | ${''} | ${'Add a To Do'} | ${'todo-add'}
+ ${false} | ${''} | ${'Add a To-Do'} | ${'todo-add'}
${true} | ${'todo-undone'} | ${'Mark as done'} | ${'todo-done'}
`(
'renders proper button when `isTodo` prop is `$isTodo`',