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/notes/mixins/discussion_navigation_spec.js')
-rw-r--r--spec/frontend/notes/mixins/discussion_navigation_spec.js178
1 files changed, 178 insertions, 0 deletions
diff --git a/spec/frontend/notes/mixins/discussion_navigation_spec.js b/spec/frontend/notes/mixins/discussion_navigation_spec.js
new file mode 100644
index 00000000000..4e5325b8bc3
--- /dev/null
+++ b/spec/frontend/notes/mixins/discussion_navigation_spec.js
@@ -0,0 +1,178 @@
+import Vuex from 'vuex';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import * as utils from '~/lib/utils/common_utils';
+import discussionNavigation from '~/notes/mixins/discussion_navigation';
+import eventHub from '~/notes/event_hub';
+import notesModule from '~/notes/stores/modules';
+import { setHTMLFixture } from 'helpers/fixtures';
+
+const discussion = (id, index) => ({
+ id,
+ resolvable: index % 2 === 0,
+ active: true,
+ notes: [{}],
+ diff_discussion: true,
+});
+const createDiscussions = () => [...'abcde'].map(discussion);
+const createComponent = () => ({
+ mixins: [discussionNavigation],
+ render() {
+ return this.$slots.default;
+ },
+});
+
+describe('Discussion navigation mixin', () => {
+ const localVue = createLocalVue();
+ localVue.use(Vuex);
+
+ let wrapper;
+ let store;
+ let expandDiscussion;
+
+ beforeEach(() => {
+ setHTMLFixture(
+ [...'abcde']
+ .map(
+ id =>
+ `<ul class="notes" data-discussion-id="${id}"></ul>
+ <div class="discussion" data-discussion-id="${id}"></div>`,
+ )
+ .join(''),
+ );
+
+ jest.spyOn(utils, 'scrollToElement');
+
+ expandDiscussion = jest.fn();
+ const { actions, ...notesRest } = notesModule();
+ store = new Vuex.Store({
+ modules: {
+ notes: {
+ ...notesRest,
+ actions: { ...actions, expandDiscussion },
+ },
+ },
+ });
+ store.state.notes.discussions = createDiscussions();
+
+ wrapper = shallowMount(createComponent(), { store, localVue });
+ });
+
+ afterEach(() => {
+ wrapper.vm.$destroy();
+ jest.clearAllMocks();
+ });
+
+ const findDiscussion = (selector, id) =>
+ document.querySelector(`${selector}[data-discussion-id="${id}"]`);
+
+ describe('cycle through discussions', () => {
+ beforeEach(() => {
+ // eslint-disable-next-line new-cap
+ window.mrTabs = { eventHub: new localVue(), tabShown: jest.fn() };
+ });
+
+ describe.each`
+ fn | args | currentId | expected
+ ${'jumpToNextDiscussion'} | ${[]} | ${null} | ${'a'}
+ ${'jumpToNextDiscussion'} | ${[]} | ${'a'} | ${'c'}
+ ${'jumpToNextDiscussion'} | ${[]} | ${'e'} | ${'a'}
+ ${'jumpToPreviousDiscussion'} | ${[]} | ${null} | ${'e'}
+ ${'jumpToPreviousDiscussion'} | ${[]} | ${'e'} | ${'c'}
+ ${'jumpToPreviousDiscussion'} | ${[]} | ${'c'} | ${'a'}
+ ${'jumpToNextRelativeDiscussion'} | ${[null]} | ${null} | ${'a'}
+ ${'jumpToNextRelativeDiscussion'} | ${['a']} | ${null} | ${'c'}
+ ${'jumpToNextRelativeDiscussion'} | ${['e']} | ${'c'} | ${'a'}
+ `('$fn (args = $args, currentId = $currentId)', ({ fn, args, currentId, expected }) => {
+ beforeEach(() => {
+ store.state.notes.currentDiscussionId = currentId;
+ });
+
+ describe('on `show` active tab', () => {
+ beforeEach(() => {
+ window.mrTabs.currentAction = 'show';
+ wrapper.vm[fn](...args);
+ });
+
+ it('sets current discussion', () => {
+ expect(store.state.notes.currentDiscussionId).toEqual(expected);
+ });
+
+ it('expands discussion', () => {
+ expect(expandDiscussion).toHaveBeenCalled();
+ });
+
+ it('scrolls to element', () => {
+ expect(utils.scrollToElement).toHaveBeenCalledWith(
+ findDiscussion('div.discussion', expected),
+ );
+ });
+ });
+
+ describe('on `diffs` active tab', () => {
+ beforeEach(() => {
+ window.mrTabs.currentAction = 'diffs';
+ wrapper.vm[fn](...args);
+ });
+
+ it('sets current discussion', () => {
+ expect(store.state.notes.currentDiscussionId).toEqual(expected);
+ });
+
+ it('expands discussion', () => {
+ expect(expandDiscussion).toHaveBeenCalled();
+ });
+
+ it('scrolls when scrollToDiscussion is emitted', () => {
+ expect(utils.scrollToElement).not.toHaveBeenCalled();
+
+ eventHub.$emit('scrollToDiscussion');
+
+ expect(utils.scrollToElement).toHaveBeenCalledWith(findDiscussion('ul.notes', expected));
+ });
+ });
+
+ describe('on `other` active tab', () => {
+ beforeEach(() => {
+ window.mrTabs.currentAction = 'other';
+ wrapper.vm[fn](...args);
+ });
+
+ it('sets current discussion', () => {
+ expect(store.state.notes.currentDiscussionId).toEqual(expected);
+ });
+
+ it('does not expand discussion yet', () => {
+ expect(expandDiscussion).not.toHaveBeenCalled();
+ });
+
+ it('shows mrTabs', () => {
+ expect(window.mrTabs.tabShown).toHaveBeenCalledWith('show');
+ });
+
+ describe('when tab is changed', () => {
+ beforeEach(() => {
+ window.mrTabs.eventHub.$emit('MergeRequestTabChange');
+
+ jest.runAllTimers();
+ });
+
+ it('expands discussion', () => {
+ expect(expandDiscussion).toHaveBeenCalledWith(
+ expect.anything(),
+ {
+ discussionId: expected,
+ },
+ undefined,
+ );
+ });
+
+ it('scrolls to discussion', () => {
+ expect(utils.scrollToElement).toHaveBeenCalledWith(
+ findDiscussion('div.discussion', expected),
+ );
+ });
+ });
+ });
+ });
+ });
+});