summaryrefslogtreecommitdiff
path: root/spec/frontend/notes
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-01-22 12:08:40 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-01-22 12:08:40 +0000
commitbe3e24ea3c9f497efde85900df298ce9bc42fce8 (patch)
treefd0de9443253a1b21ca9a2741dc34ba3aef795be /spec/frontend/notes
parent001243986195143c395a9811d8254bbf1b9ebfa1 (diff)
downloadgitlab-ce-be3e24ea3c9f497efde85900df298ce9bc42fce8.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/notes')
-rw-r--r--spec/frontend/notes/components/discussion_filter_note_spec.js89
-rw-r--r--spec/frontend/notes/components/note_attachment_spec.js58
-rw-r--r--spec/frontend/notes/components/note_header_spec.js210
3 files changed, 171 insertions, 186 deletions
diff --git a/spec/frontend/notes/components/discussion_filter_note_spec.js b/spec/frontend/notes/components/discussion_filter_note_spec.js
index 6b5f42a84e8..4701108d315 100644
--- a/spec/frontend/notes/components/discussion_filter_note_spec.js
+++ b/spec/frontend/notes/components/discussion_filter_note_spec.js
@@ -1,93 +1,40 @@
-import Vue from 'vue';
+import { shallowMount } from '@vue/test-utils';
import DiscussionFilterNote from '~/notes/components/discussion_filter_note.vue';
import eventHub from '~/notes/event_hub';
-import mountComponent from '../../helpers/vue_mount_component_helper';
-
describe('DiscussionFilterNote component', () => {
- let vm;
+ let wrapper;
const createComponent = () => {
- const Component = Vue.extend(DiscussionFilterNote);
-
- return mountComponent(Component);
+ wrapper = shallowMount(DiscussionFilterNote);
};
beforeEach(() => {
- vm = createComponent();
+ createComponent();
});
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
+ wrapper = null;
});
- describe('computed', () => {
- describe('timelineContent', () => {
- it('returns string containing instruction for switching feed type', () => {
- expect(vm.timelineContent).toBe(
- "You're only seeing <b>other activity</b> in the feed. To add a comment, switch to one of the following options.",
- );
- });
- });
+ it('timelineContent renders a string containing instruction for switching feed type', () => {
+ expect(wrapper.find({ ref: 'timelineContent' }).html()).toBe(
+ "<div>You're only seeing <b>other activity</b> in the feed. To add a comment, switch to one of the following options.</div>",
+ );
});
- describe('methods', () => {
- describe('selectFilter', () => {
- it('emits `dropdownSelect` event on `eventHub` with provided param', () => {
- jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ it('emits `dropdownSelect` event with 0 parameter on clicking Show all activity button', () => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ wrapper.find({ ref: 'showAllActivity' }).vm.$emit('click');
- vm.selectFilter(1);
-
- expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 1);
- });
- });
+ expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 0);
});
- describe('template', () => {
- it('renders component container element', () => {
- expect(vm.$el.classList.contains('discussion-filter-note')).toBe(true);
- });
-
- it('renders comment icon element', () => {
- expect(vm.$el.querySelector('.timeline-icon svg use').getAttribute('xlink:href')).toContain(
- 'comment',
- );
- });
-
- it('renders filter information note', () => {
- expect(vm.$el.querySelector('.timeline-content').innerText.trim()).toContain(
- "You're only seeing other activity in the feed. To add a comment, switch to one of the following options.",
- );
- });
-
- it('renders filter buttons', () => {
- const buttonsContainerEl = vm.$el.querySelector('.discussion-filter-actions');
-
- expect(buttonsContainerEl.querySelector('button:first-child').innerText.trim()).toContain(
- 'Show all activity',
- );
-
- expect(buttonsContainerEl.querySelector('button:last-child').innerText.trim()).toContain(
- 'Show comments only',
- );
- });
-
- it('clicking `Show all activity` button calls `selectFilter("all")` method', () => {
- const showAllBtn = vm.$el.querySelector('.discussion-filter-actions button:first-child');
- jest.spyOn(vm, 'selectFilter').mockImplementation(() => {});
-
- showAllBtn.dispatchEvent(new Event('click'));
-
- expect(vm.selectFilter).toHaveBeenCalledWith(0);
- });
-
- it('clicking `Show comments only` button calls `selectFilter("comments")` method', () => {
- const showAllBtn = vm.$el.querySelector('.discussion-filter-actions button:last-child');
- jest.spyOn(vm, 'selectFilter').mockImplementation(() => {});
-
- showAllBtn.dispatchEvent(new Event('click'));
+ it('emits `dropdownSelect` event with 1 parameter on clicking Show comments only button', () => {
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
+ wrapper.find({ ref: 'showComments' }).vm.$emit('click');
- expect(vm.selectFilter).toHaveBeenCalledWith(1);
- });
+ expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 1);
});
});
diff --git a/spec/frontend/notes/components/note_attachment_spec.js b/spec/frontend/notes/components/note_attachment_spec.js
index b14a518b622..9d1051676e1 100644
--- a/spec/frontend/notes/components/note_attachment_spec.js
+++ b/spec/frontend/notes/components/note_attachment_spec.js
@@ -1,23 +1,45 @@
-import Vue from 'vue';
-import noteAttachment from '~/notes/components/note_attachment.vue';
-
-describe('issue note attachment', () => {
- it('should render properly', () => {
- const props = {
- attachment: {
- filename: 'dk.png',
- image: true,
- url: '/dk.png',
+import { shallowMount } from '@vue/test-utils';
+import NoteAttachment from '~/notes/components/note_attachment.vue';
+
+describe('Issue note attachment', () => {
+ let wrapper;
+
+ const findImage = () => wrapper.find({ ref: 'attachmentImage' });
+ const findUrl = () => wrapper.find({ ref: 'attachmentUrl' });
+
+ const createComponent = attachment => {
+ wrapper = shallowMount(NoteAttachment, {
+ propsData: {
+ attachment,
},
- };
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('renders attachment image if it is passed in attachment prop', () => {
+ createComponent({
+ image: 'test-image',
+ });
+
+ expect(findImage().exists()).toBe(true);
+ });
+
+ it('renders attachment url if it is passed in attachment prop', () => {
+ createComponent({
+ url: 'test-url',
+ });
+
+ expect(findUrl().exists()).toBe(true);
+ });
- const Component = Vue.extend(noteAttachment);
- const vm = new Component({
- propsData: props,
- }).$mount();
+ it('does not render image and url if attachment object is empty', () => {
+ createComponent({});
- expect(vm.$el.classList.contains('note-attachment')).toBeTruthy();
- expect(vm.$el.querySelector('img').src).toContain(props.attachment.url);
- expect(vm.$el.querySelector('a').href).toContain(props.attachment.url);
+ expect(findImage().exists()).toBe(false);
+ expect(findUrl().exists()).toBe(false);
});
});
diff --git a/spec/frontend/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js
index 9b432387654..6544ad3e1fe 100644
--- a/spec/frontend/notes/components/note_header_spec.js
+++ b/spec/frontend/notes/components/note_header_spec.js
@@ -1,125 +1,141 @@
-import Vue from 'vue';
-import noteHeader from '~/notes/components/note_header.vue';
-import createStore from '~/notes/stores';
-
-describe('note_header component', () => {
- let store;
- let vm;
- let Component;
-
- beforeEach(() => {
- Component = Vue.extend(noteHeader);
- store = createStore();
- });
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import NoteHeader from '~/notes/components/note_header.vue';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+const actions = {
+ setTargetNoteHash: jest.fn(),
+};
+
+describe('NoteHeader component', () => {
+ let wrapper;
+
+ const findActionsWrapper = () => wrapper.find({ ref: 'discussionActions' });
+ const findChevronIcon = () => wrapper.find({ ref: 'chevronIcon' });
+ const findActionText = () => wrapper.find({ ref: 'actionText' });
+ const findTimestamp = () => wrapper.find({ ref: 'noteTimestamp' });
+
+ const createComponent = props => {
+ wrapper = shallowMount(NoteHeader, {
+ localVue,
+ store: new Vuex.Store({
+ actions,
+ }),
+ propsData: {
+ ...props,
+ actionTextHtml: '',
+ noteId: '1394',
+ },
+ });
+ };
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
+ wrapper = null;
});
- describe('individual note', () => {
- beforeEach(() => {
- vm = new Component({
- store,
- propsData: {
- actionText: 'commented',
- actionTextHtml: '',
- author: {
- avatar_url: null,
- id: 1,
- name: 'Root',
- path: '/root',
- state: 'active',
- username: 'root',
- },
- createdAt: '2017-08-02T10:51:58.559Z',
- includeToggle: false,
- noteId: '1394',
- expanded: true,
- },
- }).$mount();
+ it('does not render discussion actions when includeToggle is false', () => {
+ createComponent({
+ includeToggle: false,
});
- it('should render user information', () => {
- expect(vm.$el.querySelector('.note-header-author-name').textContent.trim()).toEqual('Root');
- expect(vm.$el.querySelector('.note-header-info a').getAttribute('href')).toEqual('/root');
- expect(vm.$el.querySelector('.note-header-info a').dataset.userId).toEqual('1');
- expect(vm.$el.querySelector('.note-header-info a').dataset.username).toEqual('root');
- expect(vm.$el.querySelector('.note-header-info a').classList).toContain('js-user-link');
+ expect(findActionsWrapper().exists()).toBe(false);
+ });
+
+ describe('when includes a toggle', () => {
+ it('renders discussion actions', () => {
+ createComponent({
+ includeToggle: true,
+ });
+
+ expect(findActionsWrapper().exists()).toBe(true);
});
- it('should render timestamp link', () => {
- expect(vm.$el.querySelector('a[href="#note_1394"]')).toBeDefined();
+ it('emits toggleHandler event on button click', () => {
+ createComponent({
+ includeToggle: true,
+ });
+
+ wrapper.find('.note-action-button').trigger('click');
+ expect(wrapper.emitted('toggleHandler')).toBeDefined();
+ expect(wrapper.emitted('toggleHandler')).toHaveLength(1);
});
- it('should not render user information when prop `author` is empty object', done => {
- vm.author = {};
- Vue.nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.note-header-author-name')).toBeNull();
- })
- .then(done)
- .catch(done.fail);
+ it('has chevron-up icon if expanded prop is true', () => {
+ createComponent({
+ includeToggle: true,
+ expanded: true,
+ });
+
+ expect(findChevronIcon().classes()).toContain('fa-chevron-up');
});
- });
- describe('discussion', () => {
- beforeEach(() => {
- vm = new Component({
- store,
- propsData: {
- actionText: 'started a discussion',
- actionTextHtml: '',
- author: {
- avatar_url: null,
- id: 1,
- name: 'Root',
- path: '/root',
- state: 'active',
- username: 'root',
- },
- createdAt: '2017-08-02T10:51:58.559Z',
- includeToggle: true,
- noteId: '1395',
- expanded: true,
- },
- }).$mount();
+ it('has chevron-down icon if expanded prop is false', () => {
+ createComponent({
+ includeToggle: true,
+ expanded: false,
+ });
+
+ expect(findChevronIcon().classes()).toContain('fa-chevron-down');
});
+ });
- it('should render toggle button', () => {
- expect(vm.$el.querySelector('.js-vue-toggle-button')).toBeDefined();
+ it('renders an author link if author is passed to props', () => {
+ createComponent({
+ author: {
+ avatar_url: null,
+ id: 1,
+ name: 'Root',
+ path: '/root',
+ state: 'active',
+ username: 'root',
+ },
});
- it('emits toggle event on click', done => {
- jest.spyOn(vm, '$emit').mockImplementation(() => {});
+ expect(wrapper.find('.js-user-link').exists()).toBe(true);
+ });
- vm.$el.querySelector('.js-vue-toggle-button').click();
+ it('renders deleted user text if author is not passed as a prop', () => {
+ createComponent();
- Vue.nextTick(() => {
- expect(vm.$emit).toHaveBeenCalledWith('toggleHandler');
- done();
- });
- });
+ expect(wrapper.text()).toContain('A deleted user');
+ });
+
+ it('does not render created at information if createdAt is not passed as a prop', () => {
+ createComponent();
- it('renders up arrow when open', done => {
- vm.expanded = true;
+ expect(findActionText().exists()).toBe(false);
+ expect(findTimestamp().exists()).toBe(false);
+ });
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.js-vue-toggle-button i').classList).toContain(
- 'fa-chevron-up',
- );
- done();
+ describe('when createdAt is passed as a prop', () => {
+ it('renders action text and a timestamp', () => {
+ createComponent({
+ createdAt: '2017-08-02T10:51:58.559Z',
});
+
+ expect(findActionText().exists()).toBe(true);
+ expect(findTimestamp().exists()).toBe(true);
});
- it('renders down arrow when closed', done => {
- vm.expanded = false;
+ it('renders correct actionText if passed', () => {
+ createComponent({
+ createdAt: '2017-08-02T10:51:58.559Z',
+ actionText: 'Test action text',
+ });
+
+ expect(findActionText().text()).toBe('Test action text');
+ });
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.js-vue-toggle-button i').classList).toContain(
- 'fa-chevron-down',
- );
- done();
+ it('calls an action when timestamp is clicked', () => {
+ createComponent({
+ createdAt: '2017-08-02T10:51:58.559Z',
});
+ findTimestamp().trigger('click');
+
+ expect(actions.setTargetNoteHash).toHaveBeenCalled();
});
});
});