summaryrefslogtreecommitdiff
path: root/spec/frontend/notes/components
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/notes/components')
-rw-r--r--spec/frontend/notes/components/comment_form_spec.js7
-rw-r--r--spec/frontend/notes/components/discussion_actions_spec.js2
-rw-r--r--spec/frontend/notes/components/discussion_counter_spec.js9
-rw-r--r--spec/frontend/notes/components/discussion_filter_spec.js4
-rw-r--r--spec/frontend/notes/components/discussion_notes_spec.js2
-rw-r--r--spec/frontend/notes/components/note_form_spec.js8
-rw-r--r--spec/frontend/notes/components/note_header_spec.js94
-rw-r--r--spec/frontend/notes/components/noteable_discussion_spec.js2
-rw-r--r--spec/frontend/notes/components/notes_app_spec.js2
9 files changed, 94 insertions, 36 deletions
diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js
index a2c7f0b3767..dc68c4371aa 100644
--- a/spec/frontend/notes/components/comment_form_spec.js
+++ b/spec/frontend/notes/components/comment_form_spec.js
@@ -9,12 +9,7 @@ import CommentForm from '~/notes/components/comment_form.vue';
import * as constants from '~/notes/constants';
import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
import { keyboardDownEvent } from '../../issue_show/helpers';
-import {
- loggedOutnoteableData,
- notesDataMock,
- userDataMock,
- noteableDataMock,
-} from '../../notes/mock_data';
+import { loggedOutnoteableData, notesDataMock, userDataMock, noteableDataMock } from '../mock_data';
jest.mock('autosize');
jest.mock('~/commons/nav/user_merge_requests');
diff --git a/spec/frontend/notes/components/discussion_actions_spec.js b/spec/frontend/notes/components/discussion_actions_spec.js
index 5101b81e3ee..44dc148933c 100644
--- a/spec/frontend/notes/components/discussion_actions_spec.js
+++ b/spec/frontend/notes/components/discussion_actions_spec.js
@@ -1,5 +1,5 @@
import { shallowMount, mount } from '@vue/test-utils';
-import { discussionMock } from '../../notes/mock_data';
+import { discussionMock } from '../mock_data';
import DiscussionActions from '~/notes/components/discussion_actions.vue';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
import ResolveDiscussionButton from '~/notes/components/discussion_resolve_button.vue';
diff --git a/spec/frontend/notes/components/discussion_counter_spec.js b/spec/frontend/notes/components/discussion_counter_spec.js
index 77603c16f82..04535aa17c5 100644
--- a/spec/frontend/notes/components/discussion_counter_spec.js
+++ b/spec/frontend/notes/components/discussion_counter_spec.js
@@ -75,15 +75,14 @@ describe('DiscussionCounter component', () => {
});
it.each`
- title | resolved | isActive | icon | groupLength
- ${'not allResolved'} | ${false} | ${false} | ${'check-circle'} | ${3}
- ${'allResolved'} | ${true} | ${true} | ${'check-circle-filled'} | ${1}
- `('renders correctly if $title', ({ resolved, isActive, icon, groupLength }) => {
+ title | resolved | isActive | groupLength
+ ${'not allResolved'} | ${false} | ${false} | ${3}
+ ${'allResolved'} | ${true} | ${true} | ${1}
+ `('renders correctly if $title', ({ resolved, isActive, groupLength }) => {
updateStore({ resolvable: true, resolved });
wrapper = shallowMount(DiscussionCounter, { store, localVue });
expect(wrapper.find(`.is-active`).exists()).toBe(isActive);
- expect(wrapper.find({ name: icon }).exists()).toBe(true);
expect(wrapper.findAll('[role="group"').length).toBe(groupLength);
});
});
diff --git a/spec/frontend/notes/components/discussion_filter_spec.js b/spec/frontend/notes/components/discussion_filter_spec.js
index b8d2d721443..7f042c0e9de 100644
--- a/spec/frontend/notes/components/discussion_filter_spec.js
+++ b/spec/frontend/notes/components/discussion_filter_spec.js
@@ -1,4 +1,4 @@
-import Vue from 'vue';
+import createEventHub from '~/helpers/event_hub_factory';
import Vuex from 'vuex';
import { createLocalVue, mount } from '@vue/test-utils';
@@ -132,7 +132,7 @@ describe('DiscussionFilter component', () => {
});
describe('Merge request tabs', () => {
- eventHub = new Vue();
+ eventHub = createEventHub();
beforeEach(() => {
window.mrTabs = {
diff --git a/spec/frontend/notes/components/discussion_notes_spec.js b/spec/frontend/notes/components/discussion_notes_spec.js
index 81773752037..5a10deefd09 100644
--- a/spec/frontend/notes/components/discussion_notes_spec.js
+++ b/spec/frontend/notes/components/discussion_notes_spec.js
@@ -7,7 +7,7 @@ import PlaceholderNote from '~/vue_shared/components/notes/placeholder_note.vue'
import PlaceholderSystemNote from '~/vue_shared/components/notes/placeholder_system_note.vue';
import SystemNote from '~/vue_shared/components/notes/system_note.vue';
import createStore from '~/notes/stores';
-import { noteableDataMock, discussionMock, notesDataMock } from '../../notes/mock_data';
+import { noteableDataMock, discussionMock, notesDataMock } from '../mock_data';
describe('DiscussionNotes', () => {
let wrapper;
diff --git a/spec/frontend/notes/components/note_form_spec.js b/spec/frontend/notes/components/note_form_spec.js
index bccac03126c..8270c148fb5 100644
--- a/spec/frontend/notes/components/note_form_spec.js
+++ b/spec/frontend/notes/components/note_form_spec.js
@@ -161,18 +161,18 @@ describe('issue_note_form component', () => {
describe('actions', () => {
it('should be possible to cancel', () => {
- // TODO: do not spy on vm
- jest.spyOn(wrapper.vm, 'cancelHandler');
+ const cancelHandler = jest.fn();
wrapper.setProps({
...props,
isEditing: true,
});
+ wrapper.setMethods({ cancelHandler });
return wrapper.vm.$nextTick().then(() => {
- const cancelButton = wrapper.find('.note-edit-cancel');
+ const cancelButton = wrapper.find('[data-testid="cancel"]');
cancelButton.trigger('click');
- expect(wrapper.vm.cancelHandler).toHaveBeenCalled();
+ expect(cancelHandler).toHaveBeenCalledWith(true);
});
});
diff --git a/spec/frontend/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js
index d477de69716..2bb08b60569 100644
--- a/spec/frontend/notes/components/note_header_spec.js
+++ b/spec/frontend/notes/components/note_header_spec.js
@@ -1,7 +1,7 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { nextTick } from 'vue';
import Vuex from 'vuex';
import NoteHeader from '~/notes/components/note_header.vue';
-import GitlabTeamMemberBadge from '~/vue_shared/components/user_avatar/badges/gitlab_team_member_badge.vue';
const localVue = createLocalVue();
localVue.use(Vuex);
@@ -18,6 +18,7 @@ describe('NoteHeader component', () => {
const findActionText = () => wrapper.find({ ref: 'actionText' });
const findTimestampLink = () => wrapper.find({ ref: 'noteTimestampLink' });
const findTimestamp = () => wrapper.find({ ref: 'noteTimestamp' });
+ const findConfidentialIndicator = () => wrapper.find('[data-testid="confidentialIndicator"]');
const findSpinner = () => wrapper.find({ ref: 'spinner' });
const author = {
@@ -140,20 +141,6 @@ describe('NoteHeader component', () => {
});
});
- test.each`
- props | expected | message1 | message2
- ${{ author: { ...author, is_gitlab_employee: true } }} | ${true} | ${'renders'} | ${'true'}
- ${{ author: { ...author, is_gitlab_employee: false } }} | ${false} | ${"doesn't render"} | ${'false'}
- ${{ author }} | ${false} | ${"doesn't render"} | ${'undefined'}
- `(
- '$message1 GitLab team member badge when `is_gitlab_employee` is $message2',
- ({ props, expected }) => {
- createComponent(props);
-
- expect(wrapper.find(GitlabTeamMemberBadge).exists()).toBe(expected);
- },
- );
-
describe('loading spinner', () => {
it('shows spinner when showSpinner is true', () => {
createComponent();
@@ -179,4 +166,81 @@ describe('NoteHeader component', () => {
expect(findTimestamp().exists()).toBe(true);
});
});
+
+ describe('author username link', () => {
+ it('proxies `mouseenter` event to author name link', () => {
+ createComponent({ author });
+
+ const dispatchEvent = jest.spyOn(wrapper.vm.$refs.authorNameLink, 'dispatchEvent');
+
+ wrapper.find({ ref: 'authorUsernameLink' }).trigger('mouseenter');
+
+ expect(dispatchEvent).toHaveBeenCalledWith(new Event('mouseenter'));
+ });
+
+ it('proxies `mouseleave` event to author name link', () => {
+ createComponent({ author });
+
+ const dispatchEvent = jest.spyOn(wrapper.vm.$refs.authorNameLink, 'dispatchEvent');
+
+ wrapper.find({ ref: 'authorUsernameLink' }).trigger('mouseleave');
+
+ expect(dispatchEvent).toHaveBeenCalledWith(new Event('mouseleave'));
+ });
+ });
+
+ describe('when author status tooltip is opened', () => {
+ it('removes `title` attribute from emoji to prevent duplicate tooltips', () => {
+ createComponent({
+ author: {
+ ...author,
+ status_tooltip_html:
+ '"<span class="user-status-emoji has-tooltip" title="foo bar" data-html="true" data-placement="top"><gl-emoji title="basketball and hoop" data-name="basketball" data-unicode-version="6.0">🏀</gl-emoji></span>"',
+ },
+ });
+
+ return nextTick().then(() => {
+ const authorStatus = wrapper.find({ ref: 'authorStatus' });
+ authorStatus.trigger('mouseenter');
+
+ expect(authorStatus.find('gl-emoji').attributes('title')).toBeUndefined();
+ });
+ });
+ });
+
+ describe('when author username link is hovered', () => {
+ it('toggles hover specific CSS classes on author name link', done => {
+ createComponent({ author });
+
+ const authorUsernameLink = wrapper.find({ ref: 'authorUsernameLink' });
+ const authorNameLink = wrapper.find({ ref: 'authorNameLink' });
+
+ authorUsernameLink.trigger('mouseenter');
+
+ nextTick(() => {
+ expect(authorNameLink.classes()).toContain('hover');
+ expect(authorNameLink.classes()).toContain('text-underline');
+
+ authorUsernameLink.trigger('mouseleave');
+
+ nextTick(() => {
+ expect(authorNameLink.classes()).not.toContain('hover');
+ expect(authorNameLink.classes()).not.toContain('text-underline');
+
+ done();
+ });
+ });
+ });
+ });
+
+ describe('with confidentiality indicator', () => {
+ it.each`
+ status | condition
+ ${true} | ${'shows'}
+ ${false} | ${'hides'}
+ `('$condition icon indicator when isConfidential is $status', ({ status }) => {
+ createComponent({ isConfidential: status });
+ expect(findConfidentialIndicator().exists()).toBe(status);
+ });
+ });
});
diff --git a/spec/frontend/notes/components/noteable_discussion_spec.js b/spec/frontend/notes/components/noteable_discussion_spec.js
index b91f599f158..b14ec2a65be 100644
--- a/spec/frontend/notes/components/noteable_discussion_spec.js
+++ b/spec/frontend/notes/components/noteable_discussion_spec.js
@@ -138,7 +138,7 @@ describe('noteable_discussion component', () => {
describe('signout widget', () => {
beforeEach(() => {
- originalGon = Object.assign({}, window.gon);
+ originalGon = { ...window.gon };
window.gon = window.gon || {};
});
diff --git a/spec/frontend/notes/components/notes_app_spec.js b/spec/frontend/notes/components/notes_app_spec.js
index e22dd85f221..fbfba2efb1d 100644
--- a/spec/frontend/notes/components/notes_app_spec.js
+++ b/spec/frontend/notes/components/notes_app_spec.js
@@ -10,7 +10,7 @@ import createStore from '~/notes/stores';
import * as constants from '~/notes/constants';
import '~/behaviors/markdown/render_gfm';
// TODO: use generated fixture (https://gitlab.com/gitlab-org/gitlab-foss/issues/62491)
-import * as mockData from '../../notes/mock_data';
+import * as mockData from '../mock_data';
import * as urlUtility from '~/lib/utils/url_utility';
import OrderedLayout from '~/vue_shared/components/ordered_layout.vue';