diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-12 21:09:34 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-12 21:09:34 +0300 |
commit | 949ed51c6d20ba24e1f508cae9a65b86114bff62 (patch) | |
tree | 9308fe87e6d61b35eb3b2d101c47e89b9054655f /spec/frontend/notes | |
parent | c0b17cee8be646588b14db49ad6d91b8cc818f97 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/notes')
-rw-r--r-- | spec/frontend/notes/mixins/discussion_navigation_spec.js | 106 |
1 files changed, 65 insertions, 41 deletions
diff --git a/spec/frontend/notes/mixins/discussion_navigation_spec.js b/spec/frontend/notes/mixins/discussion_navigation_spec.js index 81e4ed3ebe7..b6a2b318ec3 100644 --- a/spec/frontend/notes/mixins/discussion_navigation_spec.js +++ b/spec/frontend/notes/mixins/discussion_navigation_spec.js @@ -1,7 +1,7 @@ import { shallowMount } from '@vue/test-utils'; import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; -import { setHTMLFixture } from 'helpers/fixtures'; +import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import createEventHub from '~/helpers/event_hub_factory'; import * as utils from '~/lib/utils/common_utils'; import discussionNavigation from '~/notes/mixins/discussion_navigation'; @@ -10,14 +10,15 @@ import notesModule from '~/notes/stores/modules'; let scrollToFile; const discussion = (id, index) => ({ id, - resolvable: index % 2 === 0, + resolvable: index % 2 === 0, // discussions 'b' and 'd' are not resolvable active: true, notes: [{}], diff_discussion: true, position: { new_line: 1, old_line: 1 }, diff_file: { file_path: 'test.js' }, }); -const createDiscussions = () => [...'abcde'].map(discussion); +const mockDiscussionIds = [...'abcde']; +const createDiscussions = () => mockDiscussionIds.map(discussion); const createComponent = () => ({ mixins: [discussionNavigation], render() { @@ -32,22 +33,25 @@ describe('Discussion navigation mixin', () => { let store; let expandDiscussion; + const findDiscussionEl = (id) => document.querySelector(`div[data-discussion-id="${id}"]`); + beforeEach(() => { setHTMLFixture( `<div class="tab-pane notes"> - ${[...'abcde'] + ${mockDiscussionIds .map( - (id) => + (id, index) => `<ul class="notes" data-discussion-id="${id}"></ul> - <div class="discussion" data-discussion-id="${id}"></div>`, + <div class="discussion" data-discussion-id="${id}" ${ + discussion(id, index).resolvable + ? 'data-discussion-resolvable="true"' + : 'data-discussion-resolved="true"' + }></div>`, ) .join('')} </div>`, ); - jest.spyOn(utils, 'scrollToElementWithContext'); - jest.spyOn(utils, 'scrollToElement'); - expandDiscussion = jest.fn(); scrollToFile = jest.fn(); const { actions, ...notesRest } = notesModule(); @@ -70,8 +74,8 @@ describe('Discussion navigation mixin', () => { }); afterEach(() => { - wrapper.vm.$destroy(); jest.clearAllMocks(); + resetHTMLFixture(); }); describe('jumpToFirstUnresolvedDiscussion method', () => { @@ -105,41 +109,61 @@ describe('Discussion navigation mixin', () => { describe('cycle through discussions', () => { beforeEach(() => { window.mrTabs = { eventHub: createEventHub(), tabShown: jest.fn() }; - }); - describe.each` - fn | args | currentId - ${'jumpToNextDiscussion'} | ${[]} | ${null} - ${'jumpToNextDiscussion'} | ${[]} | ${'a'} - ${'jumpToNextDiscussion'} | ${[]} | ${'e'} - ${'jumpToPreviousDiscussion'} | ${[]} | ${null} - ${'jumpToPreviousDiscussion'} | ${[]} | ${'e'} - ${'jumpToPreviousDiscussion'} | ${[]} | ${'c'} - `('$fn (args = $args, currentId = $currentId)', ({ fn, args, currentId }) => { - beforeEach(() => { - store.state.notes.currentDiscussionId = currentId; + // Since we cannot actually scroll on the window, we have to mock each + // discussion's `getBoundingClientRect` to replicate the scroll position: + // a is at 100, b is at 200, c is at 300, d is at 400, e is at 500. + mockDiscussionIds.forEach((id, index) => { + jest + .spyOn(findDiscussionEl(id), 'getBoundingClientRect') + .mockReturnValue({ y: (index + 1) * 100 }); }); - describe('on `show` active tab', () => { - beforeEach(async () => { - window.mrTabs.currentAction = 'show'; - wrapper.vm[fn](...args); - - await nextTick(); - }); - - it('expands discussion', async () => { - await nextTick(); - - expect(expandDiscussion).toHaveBeenCalled(); - }); - - it('scrolls to element', async () => { - await nextTick(); + jest.spyOn(utils, 'scrollToElement'); + }); - expect(utils.scrollToElement).toHaveBeenCalled(); + describe.each` + fn | currentScrollPosition | expectedId + ${'jumpToNextDiscussion'} | ${null} | ${'a'} + ${'jumpToNextDiscussion'} | ${100} | ${'c'} + ${'jumpToNextDiscussion'} | ${200} | ${'c'} + ${'jumpToNextDiscussion'} | ${500} | ${'a'} + ${'jumpToPreviousDiscussion'} | ${null} | ${'e'} + ${'jumpToPreviousDiscussion'} | ${100} | ${'e'} + ${'jumpToPreviousDiscussion'} | ${200} | ${'a'} + ${'jumpToPreviousDiscussion'} | ${500} | ${'c'} + `( + '$fn (currentScrollPosition = $currentScrollPosition)', + ({ fn, currentScrollPosition, expectedId }) => { + describe('on `show` active tab', () => { + beforeEach(async () => { + window.mrTabs.currentAction = 'show'; + + // Set `document.body.scrollHeight` higher than `window.innerHeight` (which is 768) + // to prevent `hasReachedPageEnd` from always returning true + jest.spyOn(document.body, 'scrollHeight', 'get').mockReturnValue(1000); + // Mock current scroll position + jest.spyOn(utils, 'contentTop').mockReturnValue(currentScrollPosition); + + wrapper.vm[fn](); + + await nextTick(); + }); + + it('expands discussion', () => { + expect(expandDiscussion).toHaveBeenCalledWith(expect.any(Object), { + discussionId: expectedId, + }); + }); + + it(`scrolls to discussion element with id "${expectedId}"`, () => { + expect(utils.scrollToElement).toHaveBeenLastCalledWith( + findDiscussionEl(expectedId), + undefined, + ); + }); }); - }); - }); + }, + ); }); }); |