summaryrefslogtreecommitdiff
path: root/spec/javascripts
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-02 18:08:11 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-02 18:08:11 +0000
commit8a7efa45c38ed3200d173d2c3207a8154e583c16 (patch)
tree1bb4d579b95c79aae4946a06fefa089e5549b722 /spec/javascripts
parent53b1f4eaa2a451aaba908a5fee7ce97a930021ac (diff)
downloadgitlab-ce-8a7efa45c38ed3200d173d2c3207a8154e583c16.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/javascripts')
-rw-r--r--spec/javascripts/helpers/init_vue_mr_page_helper.js2
-rw-r--r--spec/javascripts/notes/components/diff_with_note_spec.js89
-rw-r--r--spec/javascripts/notes/components/discussion_filter_spec.js187
-rw-r--r--spec/javascripts/notes/components/discussion_resolve_with_issue_button_spec.js30
-rw-r--r--spec/javascripts/notes/components/note_actions/reply_button_spec.js29
-rw-r--r--spec/javascripts/notes/components/note_actions_spec.js160
-rw-r--r--spec/javascripts/notes/components/note_awards_list_spec.js152
-rw-r--r--spec/javascripts/notes/components/note_body_spec.js57
-rw-r--r--spec/javascripts/notes/components/note_form_spec.js267
-rw-r--r--spec/javascripts/notes/components/note_signed_out_widget_spec.js41
-rw-r--r--spec/javascripts/notes/components/noteable_discussion_spec.js195
-rw-r--r--spec/javascripts/notes/components/noteable_note_spec.js137
-rw-r--r--spec/javascripts/notes/components/toggle_replies_widget_spec.js78
-rw-r--r--spec/javascripts/notes/helpers.js1
-rw-r--r--spec/javascripts/notes/mock_data.js1
-rw-r--r--spec/javascripts/notes/stores/collapse_utils_spec.js37
16 files changed, 1 insertions, 1462 deletions
diff --git a/spec/javascripts/helpers/init_vue_mr_page_helper.js b/spec/javascripts/helpers/init_vue_mr_page_helper.js
index 3fa29cb9136..04f969fcd2d 100644
--- a/spec/javascripts/helpers/init_vue_mr_page_helper.js
+++ b/spec/javascripts/helpers/init_vue_mr_page_helper.js
@@ -1,7 +1,7 @@
import MockAdapter from 'axios-mock-adapter';
import initMRPage from '~/mr_notes/index';
import axios from '~/lib/utils/axios_utils';
-import { userDataMock, notesDataMock, noteableDataMock } from '../notes/mock_data';
+import { userDataMock, notesDataMock, noteableDataMock } from '../../frontend/notes/mock_data';
import diffFileMockData from '../diffs/mock_data/diff_file';
export default function initVueMRPage() {
diff --git a/spec/javascripts/notes/components/diff_with_note_spec.js b/spec/javascripts/notes/components/diff_with_note_spec.js
deleted file mode 100644
index 573aac2c3e0..00000000000
--- a/spec/javascripts/notes/components/diff_with_note_spec.js
+++ /dev/null
@@ -1,89 +0,0 @@
-import Vue from 'vue';
-import { mountComponentWithStore } from 'spec/helpers';
-import DiffWithNote from '~/notes/components/diff_with_note.vue';
-import { createStore } from '~/mr_notes/stores';
-
-const discussionFixture = 'merge_requests/diff_discussion.json';
-const imageDiscussionFixture = 'merge_requests/image_diff_discussion.json';
-
-describe('diff_with_note', () => {
- let store;
- let vm;
- const diffDiscussionMock = getJSONFixture(discussionFixture)[0];
- const diffDiscussion = diffDiscussionMock;
- const Component = Vue.extend(DiffWithNote);
- const props = {
- discussion: diffDiscussion,
- };
- const selectors = {
- get container() {
- return vm.$el;
- },
- get diffTable() {
- return this.container.querySelector('.diff-content table');
- },
- get diffRows() {
- return this.container.querySelectorAll('.diff-content .line_holder');
- },
- get noteRow() {
- return this.container.querySelector('.diff-content .notes_holder');
- },
- };
-
- beforeEach(() => {
- store = createStore();
- store.replaceState({
- ...store.state,
- notes: {
- noteableData: {
- current_user: {},
- },
- },
- });
- });
-
- describe('text diff', () => {
- beforeEach(() => {
- vm = mountComponentWithStore(Component, { props, store });
- });
-
- it('removes trailing "+" char', () => {
- const richText = vm.$el.querySelectorAll('.line_holder')[4].querySelector('.line_content')
- .textContent[0];
-
- expect(richText).not.toEqual('+');
- });
-
- it('removes trailing "-" char', () => {
- const richText = vm.$el.querySelector('#LC13').parentNode.textContent[0];
-
- expect(richText).not.toEqual('-');
- });
-
- it('shows text diff', () => {
- expect(selectors.container).toHaveClass('text-file');
- expect(selectors.diffTable).toExist();
- });
-
- it('shows diff lines', () => {
- expect(selectors.diffRows.length).toBe(12);
- });
-
- it('shows notes row', () => {
- expect(selectors.noteRow).toExist();
- });
- });
-
- describe('image diff', () => {
- beforeEach(() => {
- const imageDiffDiscussionMock = getJSONFixture(imageDiscussionFixture)[0];
- props.discussion = imageDiffDiscussionMock;
- });
-
- it('shows image diff', () => {
- vm = mountComponentWithStore(Component, { props, store });
-
- expect(selectors.diffTable).not.toExist();
- });
- });
-});
diff --git a/spec/javascripts/notes/components/discussion_filter_spec.js b/spec/javascripts/notes/components/discussion_filter_spec.js
deleted file mode 100644
index 7524de36ac5..00000000000
--- a/spec/javascripts/notes/components/discussion_filter_spec.js
+++ /dev/null
@@ -1,187 +0,0 @@
-import Vue from 'vue';
-import createStore from '~/notes/stores';
-import DiscussionFilter from '~/notes/components/discussion_filter.vue';
-import { DISCUSSION_FILTERS_DEFAULT_VALUE, DISCUSSION_FILTER_TYPES } from '~/notes/constants';
-import { mountComponentWithStore } from '../../helpers/vue_mount_component_helper';
-import { discussionFiltersMock, discussionMock } from '../mock_data';
-
-describe('DiscussionFilter component', () => {
- let vm;
- let store;
- let eventHub;
-
- const mountComponent = () => {
- store = createStore();
-
- const discussions = [
- {
- ...discussionMock,
- id: discussionMock.id,
- notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: true }],
- },
- ];
- const Component = Vue.extend(DiscussionFilter);
- const selectedValue = DISCUSSION_FILTERS_DEFAULT_VALUE;
- const props = { filters: discussionFiltersMock, selectedValue };
-
- store.state.discussions = discussions;
- return mountComponentWithStore(Component, {
- el: null,
- store,
- props,
- });
- };
-
- beforeEach(() => {
- window.mrTabs = undefined;
- vm = mountComponent();
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders the all filters', () => {
- expect(vm.$el.querySelectorAll('.dropdown-menu li').length).toEqual(
- discussionFiltersMock.length,
- );
- });
-
- it('renders the default selected item', () => {
- expect(vm.$el.querySelector('#discussion-filter-dropdown').textContent.trim()).toEqual(
- discussionFiltersMock[0].title,
- );
- });
-
- it('updates to the selected item', () => {
- const filterItem = vm.$el.querySelector(
- `.dropdown-menu li[data-filter-type="${DISCUSSION_FILTER_TYPES.HISTORY}"] button`,
- );
- filterItem.click();
-
- expect(vm.currentFilter.title).toEqual(filterItem.textContent.trim());
- });
-
- it('only updates when selected filter changes', () => {
- const filterItem = vm.$el.querySelector(
- `.dropdown-menu li[data-filter-type="${DISCUSSION_FILTER_TYPES.ALL}"] button`,
- );
-
- spyOn(vm, 'filterDiscussion');
- filterItem.click();
-
- expect(vm.filterDiscussion).not.toHaveBeenCalled();
- });
-
- it('disables commenting when "Show history only" filter is applied', () => {
- const filterItem = vm.$el.querySelector(
- `.dropdown-menu li[data-filter-type="${DISCUSSION_FILTER_TYPES.HISTORY}"] button`,
- );
- filterItem.click();
-
- expect(vm.$store.state.commentsDisabled).toBe(true);
- });
-
- it('enables commenting when "Show history only" filter is not applied', () => {
- const filterItem = vm.$el.querySelector(
- `.dropdown-menu li[data-filter-type="${DISCUSSION_FILTER_TYPES.ALL}"] button`,
- );
- filterItem.click();
-
- expect(vm.$store.state.commentsDisabled).toBe(false);
- });
-
- it('renders a dropdown divider for the default filter', () => {
- const defaultFilter = vm.$el.querySelector(
- `.dropdown-menu li[data-filter-type="${DISCUSSION_FILTER_TYPES.ALL}"]`,
- );
-
- expect(defaultFilter.lastChild.classList).toContain('dropdown-divider');
- });
-
- describe('Merge request tabs', () => {
- eventHub = new Vue();
-
- beforeEach(() => {
- window.mrTabs = {
- eventHub,
- currentTab: 'show',
- };
-
- vm = mountComponent();
- });
-
- afterEach(() => {
- window.mrTabs = undefined;
- });
-
- it('only renders when discussion tab is active', done => {
- eventHub.$emit('MergeRequestTabChange', 'commit');
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector).toBeUndefined();
- done();
- });
- });
- });
-
- describe('URL with Links to notes', () => {
- afterEach(() => {
- window.location.hash = '';
- });
-
- it('updates the filter when the URL links to a note', done => {
- window.location.hash = `note_${discussionMock.notes[0].id}`;
- vm.currentValue = discussionFiltersMock[2].value;
- vm.handleLocationHash();
-
- vm.$nextTick(() => {
- expect(vm.currentValue).toEqual(DISCUSSION_FILTERS_DEFAULT_VALUE);
- done();
- });
- });
-
- it('does not update the filter when the current filter is "Show all activity"', done => {
- window.location.hash = `note_${discussionMock.notes[0].id}`;
- vm.handleLocationHash();
-
- vm.$nextTick(() => {
- expect(vm.currentValue).toEqual(DISCUSSION_FILTERS_DEFAULT_VALUE);
- done();
- });
- });
-
- it('only updates filter when the URL links to a note', done => {
- window.location.hash = `testing123`;
- vm.handleLocationHash();
-
- vm.$nextTick(() => {
- expect(vm.currentValue).toEqual(DISCUSSION_FILTERS_DEFAULT_VALUE);
- done();
- });
- });
-
- it('fetches discussions when there is a hash', done => {
- window.location.hash = `note_${discussionMock.notes[0].id}`;
- vm.currentValue = discussionFiltersMock[2].value;
- spyOn(vm, 'selectFilter');
- vm.handleLocationHash();
-
- vm.$nextTick(() => {
- expect(vm.selectFilter).toHaveBeenCalled();
- done();
- });
- });
-
- it('does not fetch discussions when there is no hash', done => {
- window.location.hash = '';
- spyOn(vm, 'selectFilter');
- vm.handleLocationHash();
-
- vm.$nextTick(() => {
- expect(vm.selectFilter).not.toHaveBeenCalled();
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/notes/components/discussion_resolve_with_issue_button_spec.js b/spec/javascripts/notes/components/discussion_resolve_with_issue_button_spec.js
deleted file mode 100644
index 4348445f7ca..00000000000
--- a/spec/javascripts/notes/components/discussion_resolve_with_issue_button_spec.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import { GlButton } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import { TEST_HOST } from 'spec/test_constants';
-import ResolveWithIssueButton from '~/notes/components/discussion_resolve_with_issue_button.vue';
-
-const localVue = createLocalVue();
-
-describe('ResolveWithIssueButton', () => {
- let wrapper;
- const url = `${TEST_HOST}/hello-world/`;
-
- beforeEach(() => {
- wrapper = shallowMount(ResolveWithIssueButton, {
- localVue,
- propsData: {
- url,
- },
- });
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('it should have a link with the provided link property as href', () => {
- const button = wrapper.find(GlButton);
-
- expect(button.attributes().href).toBe(url);
- });
-});
diff --git a/spec/javascripts/notes/components/note_actions/reply_button_spec.js b/spec/javascripts/notes/components/note_actions/reply_button_spec.js
deleted file mode 100644
index 720ab10b270..00000000000
--- a/spec/javascripts/notes/components/note_actions/reply_button_spec.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import Vuex from 'vuex';
-import { createLocalVue, mount } from '@vue/test-utils';
-import ReplyButton from '~/notes/components/note_actions/reply_button.vue';
-
-const localVue = createLocalVue();
-localVue.use(Vuex);
-
-describe('ReplyButton', () => {
- let wrapper;
-
- beforeEach(() => {
- wrapper = mount(localVue.extend(ReplyButton), {
- localVue,
- });
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('emits startReplying on click', () => {
- const button = wrapper.find({ ref: 'button' });
-
- button.trigger('click');
-
- expect(wrapper.emitted().startReplying).toBeTruthy();
- expect(wrapper.emitted().startReplying.length).toBe(1);
- });
-});
diff --git a/spec/javascripts/notes/components/note_actions_spec.js b/spec/javascripts/notes/components/note_actions_spec.js
deleted file mode 100644
index 5d13f587ca7..00000000000
--- a/spec/javascripts/notes/components/note_actions_spec.js
+++ /dev/null
@@ -1,160 +0,0 @@
-import Vue from 'vue';
-import { shallowMount, createLocalVue, createWrapper } from '@vue/test-utils';
-import { TEST_HOST } from 'spec/test_constants';
-import createStore from '~/notes/stores';
-import noteActions from '~/notes/components/note_actions.vue';
-import { userDataMock } from '../mock_data';
-
-describe('noteActions', () => {
- let wrapper;
- let store;
- let props;
-
- const shallowMountNoteActions = propsData => {
- const localVue = createLocalVue();
- return shallowMount(localVue.extend(noteActions), {
- store,
- propsData,
- localVue,
- });
- };
-
- beforeEach(() => {
- store = createStore();
- props = {
- accessLevel: 'Maintainer',
- authorId: 26,
- canDelete: true,
- canEdit: true,
- canAwardEmoji: true,
- canReportAsAbuse: true,
- noteId: '539',
- noteUrl: `${TEST_HOST}/group/project/-/merge_requests/1#note_1`,
- reportAbusePath: `${TEST_HOST}/abuse_reports/new?ref_url=http%3A%2F%2Flocalhost%3A3000%2Fgitlab-org%2Fgitlab-ce%2Fissues%2F7%23note_539&user_id=26`,
- showReply: false,
- };
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('user is logged in', () => {
- beforeEach(() => {
- store.dispatch('setUserData', userDataMock);
-
- wrapper = shallowMountNoteActions(props);
- });
-
- it('should render access level badge', () => {
- expect(
- wrapper
- .find('.note-role')
- .text()
- .trim(),
- ).toEqual(props.accessLevel);
- });
-
- it('should render emoji link', () => {
- expect(wrapper.find('.js-add-award').exists()).toBe(true);
- expect(wrapper.find('.js-add-award').attributes('data-position')).toBe('right');
- });
-
- describe('actions dropdown', () => {
- it('should be possible to edit the comment', () => {
- expect(wrapper.find('.js-note-edit').exists()).toBe(true);
- });
-
- it('should be possible to report abuse to admin', () => {
- expect(wrapper.find(`a[href="${props.reportAbusePath}"]`).exists()).toBe(true);
- });
-
- it('should be possible to copy link to a note', () => {
- expect(wrapper.find('.js-btn-copy-note-link').exists()).toBe(true);
- });
-
- it('should not show copy link action when `noteUrl` prop is empty', done => {
- wrapper.setProps({
- ...props,
- noteUrl: '',
- });
-
- Vue.nextTick()
- .then(() => {
- expect(wrapper.find('.js-btn-copy-note-link').exists()).toBe(false);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('should be possible to delete comment', () => {
- expect(wrapper.find('.js-note-delete').exists()).toBe(true);
- });
-
- it('closes tooltip when dropdown opens', done => {
- wrapper.find('.more-actions-toggle').trigger('click');
-
- const rootWrapper = createWrapper(wrapper.vm.$root);
- Vue.nextTick()
- .then(() => {
- const emitted = Object.keys(rootWrapper.emitted());
-
- expect(emitted).toEqual(['bv::hide::tooltip']);
- done();
- })
- .catch(done.fail);
- });
- });
- });
-
- describe('user is not logged in', () => {
- beforeEach(() => {
- store.dispatch('setUserData', {});
- wrapper = shallowMountNoteActions({
- ...props,
- canDelete: false,
- canEdit: false,
- canAwardEmoji: false,
- canReportAsAbuse: false,
- });
- });
-
- it('should not render emoji link', () => {
- expect(wrapper.find('.js-add-award').exists()).toBe(false);
- });
-
- it('should not render actions dropdown', () => {
- expect(wrapper.find('.more-actions').exists()).toBe(false);
- });
- });
-
- describe('for showReply = true', () => {
- beforeEach(() => {
- wrapper = shallowMountNoteActions({
- ...props,
- showReply: true,
- });
- });
-
- it('shows a reply button', () => {
- const replyButton = wrapper.find({ ref: 'replyButton' });
-
- expect(replyButton.exists()).toBe(true);
- });
- });
-
- describe('for showReply = false', () => {
- beforeEach(() => {
- wrapper = shallowMountNoteActions({
- ...props,
- showReply: false,
- });
- });
-
- it('does not show a reply button', () => {
- const replyButton = wrapper.find({ ref: 'replyButton' });
-
- expect(replyButton.exists()).toBe(false);
- });
- });
-});
diff --git a/spec/javascripts/notes/components/note_awards_list_spec.js b/spec/javascripts/notes/components/note_awards_list_spec.js
deleted file mode 100644
index 90aa1684272..00000000000
--- a/spec/javascripts/notes/components/note_awards_list_spec.js
+++ /dev/null
@@ -1,152 +0,0 @@
-import Vue from 'vue';
-import createStore from '~/notes/stores';
-import awardsNote from '~/notes/components/note_awards_list.vue';
-import { noteableDataMock, notesDataMock } from '../mock_data';
-
-describe('note_awards_list component', () => {
- let store;
- let vm;
- let awardsMock;
-
- beforeEach(() => {
- const Component = Vue.extend(awardsNote);
-
- store = createStore();
- store.dispatch('setNoteableData', noteableDataMock);
- store.dispatch('setNotesData', notesDataMock);
- awardsMock = [
- {
- name: 'flag_tz',
- user: { id: 1, name: 'Administrator', username: 'root' },
- },
- {
- name: 'cartwheel_tone3',
- user: { id: 12, name: 'Bobbie Stehr', username: 'erin' },
- },
- ];
-
- vm = new Component({
- store,
- propsData: {
- awards: awardsMock,
- noteAuthorId: 2,
- noteId: '545',
- canAwardEmoji: true,
- toggleAwardPath: '/gitlab-org/gitlab-foss/notes/545/toggle_award_emoji',
- },
- }).$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('should render awarded emojis', () => {
- expect(vm.$el.querySelector('.js-awards-block button [data-name="flag_tz"]')).toBeDefined();
- expect(
- vm.$el.querySelector('.js-awards-block button [data-name="cartwheel_tone3"]'),
- ).toBeDefined();
- });
-
- it('should be possible to remove awarded emoji', () => {
- spyOn(vm, 'handleAward').and.callThrough();
- spyOn(vm, 'toggleAwardRequest').and.callThrough();
- vm.$el.querySelector('.js-awards-block button').click();
-
- expect(vm.handleAward).toHaveBeenCalledWith('flag_tz');
- expect(vm.toggleAwardRequest).toHaveBeenCalled();
- });
-
- it('should be possible to add new emoji', () => {
- expect(vm.$el.querySelector('.js-add-award')).toBeDefined();
- });
-
- describe('when the user name contains special HTML characters', () => {
- const createAwardEmoji = (_, index) => ({
- name: 'art',
- user: { id: index, name: `&<>"\`'-${index}`, username: `user-${index}` },
- });
-
- const mountComponent = () => {
- const Component = Vue.extend(awardsNote);
- vm = new Component({
- store,
- propsData: {
- awards: awardsMock,
- noteAuthorId: 0,
- noteId: '545',
- canAwardEmoji: true,
- toggleAwardPath: '/gitlab-org/gitlab-foss/notes/545/toggle_award_emoji',
- },
- }).$mount();
- };
-
- const findTooltip = () =>
- vm.$el.querySelector('[data-original-title]').getAttribute('data-original-title');
-
- it('should only escape & and " characters', () => {
- awardsMock = [...new Array(1)].map(createAwardEmoji);
- mountComponent();
- const escapedName = awardsMock[0].user.name.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
-
- expect(vm.$el.querySelector('[data-original-title]').outerHTML).toContain(escapedName);
- });
-
- it('should not escape special HTML characters twice when only 1 person awarded', () => {
- awardsMock = [...new Array(1)].map(createAwardEmoji);
- mountComponent();
-
- awardsMock.forEach(award => {
- expect(findTooltip()).toContain(award.user.name);
- });
- });
-
- it('should not escape special HTML characters twice when 2 people awarded', () => {
- awardsMock = [...new Array(2)].map(createAwardEmoji);
- mountComponent();
-
- awardsMock.forEach(award => {
- expect(findTooltip()).toContain(award.user.name);
- });
- });
-
- it('should not escape special HTML characters twice when more than 10 people awarded', () => {
- awardsMock = [...new Array(11)].map(createAwardEmoji);
- mountComponent();
-
- // Testing only the first 10 awards since 11 onward will not be displayed.
- awardsMock.slice(0, 10).forEach(award => {
- expect(findTooltip()).toContain(award.user.name);
- });
- });
- });
-
- describe('when the user cannot award emoji', () => {
- beforeEach(() => {
- const Component = Vue.extend(awardsNote);
-
- vm = new Component({
- store,
- propsData: {
- awards: awardsMock,
- noteAuthorId: 2,
- noteId: '545',
- canAwardEmoji: false,
- toggleAwardPath: '/gitlab-org/gitlab-foss/notes/545/toggle_award_emoji',
- },
- }).$mount();
- });
-
- it('should not be possible to remove awarded emoji', () => {
- spyOn(vm, 'toggleAwardRequest').and.callThrough();
-
- vm.$el.querySelector('.js-awards-block button').click();
-
- expect(vm.toggleAwardRequest).not.toHaveBeenCalled();
- });
-
- it('should not be possible to add new emoji', () => {
- expect(vm.$el.querySelector('.js-add-award')).toBeNull();
- });
- });
-});
diff --git a/spec/javascripts/notes/components/note_body_spec.js b/spec/javascripts/notes/components/note_body_spec.js
deleted file mode 100644
index efad0785afe..00000000000
--- a/spec/javascripts/notes/components/note_body_spec.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import Vue from 'vue';
-import createStore from '~/notes/stores';
-import noteBody from '~/notes/components/note_body.vue';
-import { noteableDataMock, notesDataMock, note } from '../mock_data';
-
-describe('issue_note_body component', () => {
- let store;
- let vm;
-
- beforeEach(() => {
- const Component = Vue.extend(noteBody);
-
- store = createStore();
- store.dispatch('setNoteableData', noteableDataMock);
- store.dispatch('setNotesData', notesDataMock);
-
- vm = new Component({
- store,
- propsData: {
- note,
- canEdit: true,
- canAwardEmoji: true,
- },
- }).$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('should render the note', () => {
- expect(vm.$el.querySelector('.note-text').innerHTML).toEqual(note.note_html);
- });
-
- it('should render awards list', () => {
- expect(vm.$el.querySelector('.js-awards-block button [data-name="baseball"]')).not.toBeNull();
- expect(vm.$el.querySelector('.js-awards-block button [data-name="bath_tone3"]')).not.toBeNull();
- });
-
- describe('isEditing', () => {
- beforeEach(done => {
- vm.isEditing = true;
- Vue.nextTick(done);
- });
-
- it('renders edit form', () => {
- expect(vm.$el.querySelector('textarea.js-task-list-field')).not.toBeNull();
- });
-
- it('adds autosave', () => {
- const autosaveKey = `autosave/Note/${note.noteable_type}/${note.id}`;
-
- expect(vm.autosave).toExist();
- expect(vm.autosave.key).toEqual(autosaveKey);
- });
- });
-});
diff --git a/spec/javascripts/notes/components/note_form_spec.js b/spec/javascripts/notes/components/note_form_spec.js
deleted file mode 100644
index 8ab8bce9027..00000000000
--- a/spec/javascripts/notes/components/note_form_spec.js
+++ /dev/null
@@ -1,267 +0,0 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import createStore from '~/notes/stores';
-import NoteForm from '~/notes/components/note_form.vue';
-import MarkdownField from '~/vue_shared/components/markdown/field.vue';
-import { noteableDataMock, notesDataMock } from '../mock_data';
-
-describe('issue_note_form component', () => {
- const dummyAutosaveKey = 'some-autosave-key';
- const dummyDraft = 'dummy draft content';
-
- let store;
- let wrapper;
- let props;
-
- const createComponentWrapper = () => {
- const localVue = createLocalVue();
- return shallowMount(localVue.extend(NoteForm), {
- store,
- propsData: props,
- // see https://gitlab.com/gitlab-org/gitlab-foss/issues/56317 for the following
- localVue,
- });
- };
-
- beforeEach(() => {
- spyOnDependency(NoteForm, 'getDraft').and.callFake(key => {
- if (key === dummyAutosaveKey) {
- return dummyDraft;
- }
-
- return null;
- });
-
- store = createStore();
- store.dispatch('setNoteableData', noteableDataMock);
- store.dispatch('setNotesData', notesDataMock);
-
- props = {
- isEditing: false,
- noteBody: 'Magni suscipit eius consectetur enim et ex et commodi.',
- noteId: '545',
- };
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('noteHash', () => {
- beforeEach(() => {
- wrapper = createComponentWrapper();
- });
-
- it('returns note hash string based on `noteId`', () => {
- expect(wrapper.vm.noteHash).toBe(`#note_${props.noteId}`);
- });
-
- it('return note hash as `#` when `noteId` is empty', done => {
- wrapper.setProps({
- ...props,
- noteId: '',
- });
-
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(wrapper.vm.noteHash).toBe('#');
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('conflicts editing', () => {
- beforeEach(() => {
- wrapper = createComponentWrapper();
- });
-
- it('should show conflict message if note changes outside the component', done => {
- wrapper.setProps({
- ...props,
- isEditing: true,
- noteBody: 'Foo',
- });
-
- const message =
- 'This comment has changed since you started editing, please review the updated comment to ensure information is not lost.';
-
- wrapper.vm
- .$nextTick()
- .then(() => {
- const conflictWarning = wrapper.find('.js-conflict-edit-warning');
-
- expect(conflictWarning.exists()).toBe(true);
- expect(
- conflictWarning
- .text()
- .replace(/\s+/g, ' ')
- .trim(),
- ).toBe(message);
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('form', () => {
- beforeEach(() => {
- wrapper = createComponentWrapper();
- });
-
- it('should render text area with placeholder', () => {
- const textarea = wrapper.find('textarea');
-
- expect(textarea.attributes('placeholder')).toEqual(
- 'Write a comment or drag your files hereā€¦',
- );
- });
-
- it('should link to markdown docs', () => {
- const { markdownDocsPath } = notesDataMock;
- const markdownField = wrapper.find(MarkdownField);
- const markdownFieldProps = markdownField.props();
-
- expect(markdownFieldProps.markdownDocsPath).toBe(markdownDocsPath);
- });
-
- describe('keyboard events', () => {
- let textarea;
-
- beforeEach(() => {
- textarea = wrapper.find('textarea');
- textarea.setValue('Foo');
- });
-
- describe('up', () => {
- it('should ender edit mode', () => {
- // TODO: do not spy on vm
- spyOn(wrapper.vm, 'editMyLastNote').and.callThrough();
-
- textarea.trigger('keydown.up');
-
- expect(wrapper.vm.editMyLastNote).toHaveBeenCalled();
- });
- });
-
- describe('enter', () => {
- it('should save note when cmd+enter is pressed', () => {
- textarea.trigger('keydown.enter', { metaKey: true });
-
- const { handleFormUpdate } = wrapper.emitted();
-
- expect(handleFormUpdate.length).toBe(1);
- });
-
- it('should save note when ctrl+enter is pressed', () => {
- textarea.trigger('keydown.enter', { ctrlKey: true });
-
- const { handleFormUpdate } = wrapper.emitted();
-
- expect(handleFormUpdate.length).toBe(1);
- });
- });
- });
-
- describe('actions', () => {
- it('should be possible to cancel', done => {
- // TODO: do not spy on vm
- spyOn(wrapper.vm, 'cancelHandler').and.callThrough();
- wrapper.setProps({
- ...props,
- isEditing: true,
- });
-
- wrapper.vm
- .$nextTick()
- .then(() => {
- const cancelButton = wrapper.find('.note-edit-cancel');
- cancelButton.trigger('click');
-
- expect(wrapper.vm.cancelHandler).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('should be possible to update the note', done => {
- wrapper.setProps({
- ...props,
- isEditing: true,
- });
-
- wrapper.vm
- .$nextTick()
- .then(() => {
- const textarea = wrapper.find('textarea');
- textarea.setValue('Foo');
- const saveButton = wrapper.find('.js-vue-issue-save');
- saveButton.trigger('click');
-
- expect(wrapper.vm.isSubmitting).toEqual(true);
- })
- .then(done)
- .catch(done.fail);
- });
- });
- });
-
- describe('with autosaveKey', () => {
- describe('with draft', () => {
- beforeEach(done => {
- Object.assign(props, {
- noteBody: '',
- autosaveKey: dummyAutosaveKey,
- });
- wrapper = createComponentWrapper();
-
- wrapper.vm
- .$nextTick()
- .then(done)
- .catch(done.fail);
- });
-
- it('displays the draft in textarea', () => {
- const textarea = wrapper.find('textarea');
-
- expect(textarea.element.value).toBe(dummyDraft);
- });
- });
-
- describe('without draft', () => {
- beforeEach(done => {
- Object.assign(props, {
- noteBody: '',
- autosaveKey: 'some key without draft',
- });
- wrapper = createComponentWrapper();
-
- wrapper.vm
- .$nextTick()
- .then(done)
- .catch(done.fail);
- });
-
- it('leaves the textarea empty', () => {
- const textarea = wrapper.find('textarea');
-
- expect(textarea.element.value).toBe('');
- });
- });
-
- it('updates the draft if textarea content changes', () => {
- const updateDraftSpy = spyOnDependency(NoteForm, 'updateDraft').and.stub();
- Object.assign(props, {
- noteBody: '',
- autosaveKey: dummyAutosaveKey,
- });
- wrapper = createComponentWrapper();
- const textarea = wrapper.find('textarea');
- const dummyContent = 'some new content';
-
- textarea.setValue(dummyContent);
-
- expect(updateDraftSpy).toHaveBeenCalledWith(dummyAutosaveKey, dummyContent);
- });
- });
-});
diff --git a/spec/javascripts/notes/components/note_signed_out_widget_spec.js b/spec/javascripts/notes/components/note_signed_out_widget_spec.js
deleted file mode 100644
index e217a2caa73..00000000000
--- a/spec/javascripts/notes/components/note_signed_out_widget_spec.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import Vue from 'vue';
-import noteSignedOut from '~/notes/components/note_signed_out_widget.vue';
-import createStore from '~/notes/stores';
-import { notesDataMock } from '../mock_data';
-
-describe('note_signed_out_widget component', () => {
- let store;
- let vm;
-
- beforeEach(() => {
- const Component = Vue.extend(noteSignedOut);
- store = createStore();
- store.dispatch('setNotesData', notesDataMock);
-
- vm = new Component({
- store,
- }).$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('should render sign in link provided in the store', () => {
- expect(vm.$el.querySelector(`a[href="${notesDataMock.newSessionPath}"]`).textContent).toEqual(
- 'sign in',
- );
- });
-
- it('should render register link provided in the store', () => {
- expect(vm.$el.querySelector(`a[href="${notesDataMock.registerPath}"]`).textContent).toEqual(
- 'register',
- );
- });
-
- it('should render information text', () => {
- expect(vm.$el.textContent.replace(/\s+/g, ' ').trim()).toEqual(
- 'Please register or sign in to reply',
- );
- });
-});
diff --git a/spec/javascripts/notes/components/noteable_discussion_spec.js b/spec/javascripts/notes/components/noteable_discussion_spec.js
deleted file mode 100644
index ee84fd2b091..00000000000
--- a/spec/javascripts/notes/components/noteable_discussion_spec.js
+++ /dev/null
@@ -1,195 +0,0 @@
-import { mount, createLocalVue } from '@vue/test-utils';
-import createStore from '~/notes/stores';
-import noteableDiscussion from '~/notes/components/noteable_discussion.vue';
-import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
-import ResolveWithIssueButton from '~/notes/components/discussion_resolve_with_issue_button.vue';
-import NoteForm from '~/notes/components/note_form.vue';
-import '~/behaviors/markdown/render_gfm';
-import {
- noteableDataMock,
- discussionMock,
- notesDataMock,
- loggedOutnoteableData,
- userDataMock,
-} from '../mock_data';
-import mockDiffFile from '../../diffs/mock_data/diff_file';
-import { trimText } from '../../helpers/text_helper';
-
-const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json';
-
-const localVue = createLocalVue();
-
-describe('noteable_discussion component', () => {
- let store;
- let wrapper;
- let originalGon;
-
- preloadFixtures(discussionWithTwoUnresolvedNotes);
-
- beforeEach(() => {
- window.mrTabs = {};
- store = createStore();
- store.dispatch('setNoteableData', noteableDataMock);
- store.dispatch('setNotesData', notesDataMock);
-
- wrapper = mount(localVue.extend(noteableDiscussion), {
- store,
- propsData: { discussion: discussionMock },
- localVue,
- });
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('should not render thread header for non diff threads', () => {
- expect(wrapper.find('.discussion-header').exists()).toBe(false);
- });
-
- it('should render thread header', done => {
- const discussion = { ...discussionMock };
- discussion.diff_file = mockDiffFile;
- discussion.diff_discussion = true;
-
- wrapper.setProps({ discussion });
-
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(wrapper.find('.discussion-header').exists()).toBe(true);
- })
- .then(done)
- .catch(done.fail);
- });
-
- describe('actions', () => {
- it('should toggle reply form', done => {
- const replyPlaceholder = wrapper.find(ReplyPlaceholder);
-
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(wrapper.vm.isReplying).toEqual(false);
-
- replyPlaceholder.vm.$emit('onClick');
- })
- .then(() => wrapper.vm.$nextTick())
- .then(() => {
- expect(wrapper.vm.isReplying).toEqual(true);
-
- const noteForm = wrapper.find(NoteForm);
-
- expect(noteForm.exists()).toBe(true);
-
- const noteFormProps = noteForm.props();
-
- expect(noteFormProps.discussion).toBe(discussionMock);
- expect(noteFormProps.isEditing).toBe(false);
- expect(noteFormProps.line).toBe(null);
- expect(noteFormProps.saveButtonTitle).toBe('Comment');
- expect(noteFormProps.autosaveKey).toBe(`Note/Issue/${discussionMock.id}/Reply`);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('does not render jump to thread button', () => {
- expect(wrapper.find('*[data-original-title="Jump to next unresolved thread"]').exists()).toBe(
- false,
- );
- });
- });
-
- describe('for resolved thread', () => {
- beforeEach(() => {
- const discussion = getJSONFixture(discussionWithTwoUnresolvedNotes)[0];
- wrapper.setProps({ discussion });
- });
-
- it('does not display a button to resolve with issue', () => {
- const button = wrapper.find(ResolveWithIssueButton);
-
- expect(button.exists()).toBe(false);
- });
- });
-
- describe('for unresolved thread', () => {
- beforeEach(done => {
- const discussion = {
- ...getJSONFixture(discussionWithTwoUnresolvedNotes)[0],
- expanded: true,
- };
- discussion.notes = discussion.notes.map(note => ({
- ...note,
- resolved: false,
- current_user: {
- ...note.current_user,
- can_resolve: true,
- },
- }));
-
- wrapper.setProps({ discussion });
-
- wrapper.vm
- .$nextTick()
- .then(done)
- .catch(done.fail);
- });
-
- it('displays a button to resolve with issue', () => {
- const button = wrapper.find(ResolveWithIssueButton);
-
- expect(button.exists()).toBe(true);
- });
- });
-
- describe('signout widget', () => {
- beforeEach(() => {
- originalGon = Object.assign({}, window.gon);
- window.gon = window.gon || {};
- });
-
- afterEach(() => {
- wrapper.destroy();
- window.gon = originalGon;
- });
-
- describe('user is logged in', () => {
- beforeEach(() => {
- window.gon.current_user_id = userDataMock.id;
- store.dispatch('setUserData', userDataMock);
-
- wrapper = mount(localVue.extend(noteableDiscussion), {
- store,
- propsData: { discussion: discussionMock },
- localVue,
- });
- });
-
- it('should not render signed out widget', () => {
- expect(Boolean(wrapper.vm.isLoggedIn)).toBe(true);
- expect(trimText(wrapper.text())).not.toContain('Please register or sign in to reply');
- });
- });
-
- describe('user is not logged in', () => {
- beforeEach(() => {
- window.gon.current_user_id = null;
- store.dispatch('setNoteableData', loggedOutnoteableData);
- store.dispatch('setNotesData', notesDataMock);
-
- wrapper = mount(localVue.extend(noteableDiscussion), {
- store,
- propsData: { discussion: discussionMock },
- localVue,
- });
- });
-
- it('should render signed out widget', () => {
- expect(Boolean(wrapper.vm.isLoggedIn)).toBe(false);
- expect(trimText(wrapper.text())).toContain('Please register or sign in to reply');
- });
- });
- });
-});
diff --git a/spec/javascripts/notes/components/noteable_note_spec.js b/spec/javascripts/notes/components/noteable_note_spec.js
deleted file mode 100644
index 1906dae7800..00000000000
--- a/spec/javascripts/notes/components/noteable_note_spec.js
+++ /dev/null
@@ -1,137 +0,0 @@
-import { escape } from 'lodash';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import createStore from '~/notes/stores';
-import issueNote from '~/notes/components/noteable_note.vue';
-import NoteHeader from '~/notes/components/note_header.vue';
-import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
-import NoteActions from '~/notes/components/note_actions.vue';
-import NoteBody from '~/notes/components/note_body.vue';
-import { noteableDataMock, notesDataMock, note } from '../mock_data';
-
-describe('issue_note', () => {
- let store;
- let wrapper;
-
- beforeEach(() => {
- store = createStore();
- store.dispatch('setNoteableData', noteableDataMock);
- store.dispatch('setNotesData', notesDataMock);
-
- const localVue = createLocalVue();
- wrapper = shallowMount(localVue.extend(issueNote), {
- store,
- propsData: {
- note,
- },
- localVue,
- });
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('should render user information', () => {
- const { author } = note;
- const avatar = wrapper.find(UserAvatarLink);
- const avatarProps = avatar.props();
-
- expect(avatarProps.linkHref).toBe(author.path);
- expect(avatarProps.imgSrc).toBe(author.avatar_url);
- expect(avatarProps.imgAlt).toBe(author.name);
- expect(avatarProps.imgSize).toBe(40);
- });
-
- it('should render note header content', () => {
- const noteHeader = wrapper.find(NoteHeader);
- const noteHeaderProps = noteHeader.props();
-
- expect(noteHeaderProps.author).toEqual(note.author);
- expect(noteHeaderProps.createdAt).toEqual(note.created_at);
- expect(noteHeaderProps.noteId).toEqual(note.id);
- });
-
- it('should render note actions', () => {
- const { author } = note;
- const noteActions = wrapper.find(NoteActions);
- const noteActionsProps = noteActions.props();
-
- expect(noteActionsProps.authorId).toBe(author.id);
- expect(noteActionsProps.noteId).toBe(note.id);
- expect(noteActionsProps.noteUrl).toBe(note.noteable_note_url);
- expect(noteActionsProps.accessLevel).toBe(note.human_access);
- expect(noteActionsProps.canEdit).toBe(note.current_user.can_edit);
- expect(noteActionsProps.canAwardEmoji).toBe(note.current_user.can_award_emoji);
- expect(noteActionsProps.canDelete).toBe(note.current_user.can_edit);
- expect(noteActionsProps.canReportAsAbuse).toBe(true);
- expect(noteActionsProps.canResolve).toBe(false);
- expect(noteActionsProps.reportAbusePath).toBe(note.report_abuse_path);
- expect(noteActionsProps.resolvable).toBe(false);
- expect(noteActionsProps.isResolved).toBe(false);
- expect(noteActionsProps.isResolving).toBe(false);
- expect(noteActionsProps.resolvedBy).toEqual({});
- });
-
- it('should render issue body', () => {
- const noteBody = wrapper.find(NoteBody);
- const noteBodyProps = noteBody.props();
-
- expect(noteBodyProps.note).toEqual(note);
- expect(noteBodyProps.line).toBe(null);
- expect(noteBodyProps.canEdit).toBe(note.current_user.can_edit);
- expect(noteBodyProps.isEditing).toBe(false);
- expect(noteBodyProps.helpPagePath).toBe('');
- });
-
- it('prevents note preview xss', done => {
- const imgSrc = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
- const noteBody = `<img src="${imgSrc}" onload="alert(1)" />`;
- const alertSpy = spyOn(window, 'alert');
- store.hotUpdate({
- actions: {
- updateNote() {},
- },
- });
- const noteBodyComponent = wrapper.find(NoteBody);
-
- noteBodyComponent.vm.$emit('handleFormUpdate', noteBody, null, () => {});
-
- setTimeout(() => {
- expect(alertSpy).not.toHaveBeenCalled();
- expect(wrapper.vm.note.note_html).toEqual(escape(noteBody));
- done();
- }, 0);
- });
-
- describe('cancel edit', () => {
- it('restores content of updated note', done => {
- const updatedText = 'updated note text';
- store.hotUpdate({
- actions: {
- updateNote() {},
- },
- });
- const noteBody = wrapper.find(NoteBody);
- noteBody.vm.resetAutoSave = () => {};
-
- noteBody.vm.$emit('handleFormUpdate', updatedText, null, () => {});
-
- wrapper.vm
- .$nextTick()
- .then(() => {
- const noteBodyProps = noteBody.props();
-
- expect(noteBodyProps.note.note_html).toBe(updatedText);
- noteBody.vm.$emit('cancelForm');
- })
- .then(() => wrapper.vm.$nextTick())
- .then(() => {
- const noteBodyProps = noteBody.props();
-
- expect(noteBodyProps.note.note_html).toBe(note.note_html);
- })
- .then(done)
- .catch(done.fail);
- });
- });
-});
diff --git a/spec/javascripts/notes/components/toggle_replies_widget_spec.js b/spec/javascripts/notes/components/toggle_replies_widget_spec.js
deleted file mode 100644
index 8485ec0262f..00000000000
--- a/spec/javascripts/notes/components/toggle_replies_widget_spec.js
+++ /dev/null
@@ -1,78 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import toggleRepliesWidget from '~/notes/components/toggle_replies_widget.vue';
-import { note } from '../mock_data';
-
-const deepCloneObject = obj => JSON.parse(JSON.stringify(obj));
-
-describe('toggle replies widget for notes', () => {
- let vm;
- let ToggleRepliesWidget;
- const noteFromOtherUser = deepCloneObject(note);
- noteFromOtherUser.author.username = 'fatihacet';
-
- const noteFromAnotherUser = deepCloneObject(note);
- noteFromAnotherUser.author.username = 'mgreiling';
- noteFromAnotherUser.author.name = 'Mike Greiling';
-
- const replies = [note, note, note, noteFromOtherUser, noteFromAnotherUser];
-
- beforeEach(() => {
- ToggleRepliesWidget = Vue.extend(toggleRepliesWidget);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('collapsed state', () => {
- beforeEach(() => {
- vm = mountComponent(ToggleRepliesWidget, {
- replies,
- collapsed: true,
- });
- });
-
- it('should render the collapsed', () => {
- const vmTextContent = vm.$el.textContent.replace(/\s\s+/g, ' ');
-
- expect(vm.$el.classList.contains('collapsed')).toEqual(true);
- expect(vm.$el.querySelectorAll('.user-avatar-link').length).toEqual(3);
- expect(vm.$el.querySelector('time')).not.toBeNull();
- expect(vmTextContent).toContain('5 replies');
- expect(vmTextContent).toContain(`Last reply by ${noteFromAnotherUser.author.name}`);
- });
-
- it('should emit toggle event when the replies text clicked', () => {
- const spy = spyOn(vm, '$emit');
-
- vm.$el.querySelector('.js-replies-text').click();
-
- expect(spy).toHaveBeenCalledWith('toggle');
- });
- });
-
- describe('expanded state', () => {
- beforeEach(() => {
- vm = mountComponent(ToggleRepliesWidget, {
- replies,
- collapsed: false,
- });
- });
-
- it('should render expanded state', () => {
- const vmTextContent = vm.$el.textContent.replace(/\s\s+/g, ' ');
-
- expect(vm.$el.querySelector('.collapse-replies-btn')).not.toBeNull();
- expect(vmTextContent).toContain('Collapse replies');
- });
-
- it('should emit toggle event when the collapse replies text called', () => {
- const spy = spyOn(vm, '$emit');
-
- vm.$el.querySelector('.js-collapse-replies').click();
-
- expect(spy).toHaveBeenCalledWith('toggle');
- });
- });
-});
diff --git a/spec/javascripts/notes/helpers.js b/spec/javascripts/notes/helpers.js
deleted file mode 100644
index 7bcba609311..00000000000
--- a/spec/javascripts/notes/helpers.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from '../../frontend/notes/helpers.js';
diff --git a/spec/javascripts/notes/mock_data.js b/spec/javascripts/notes/mock_data.js
deleted file mode 100644
index 89e4553092a..00000000000
--- a/spec/javascripts/notes/mock_data.js
+++ /dev/null
@@ -1 +0,0 @@
-export * from '../../frontend/notes/mock_data.js';
diff --git a/spec/javascripts/notes/stores/collapse_utils_spec.js b/spec/javascripts/notes/stores/collapse_utils_spec.js
deleted file mode 100644
index d3019f4b9a4..00000000000
--- a/spec/javascripts/notes/stores/collapse_utils_spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import {
- isDescriptionSystemNote,
- getTimeDifferenceMinutes,
- collapseSystemNotes,
-} from '~/notes/stores/collapse_utils';
-import { notesWithDescriptionChanges, collapsedSystemNotes } from '../mock_data';
-
-describe('Collapse utils', () => {
- const mockSystemNote = {
- note: 'changed the description',
- note_html: '<p dir="auto">changed the description</p>',
- system: true,
- created_at: '2018-05-14T21:28:00.000Z',
- };
-
- it('checks if a system note is of a description type', () => {
- expect(isDescriptionSystemNote(mockSystemNote)).toEqual(true);
- });
-
- it('returns false when a system note is not a description type', () => {
- expect(isDescriptionSystemNote(Object.assign({}, mockSystemNote, { note: 'foo' }))).toEqual(
- false,
- );
- });
-
- it('gets the time difference between two notes', () => {
- const anotherSystemNote = {
- created_at: '2018-05-14T21:33:00.000Z',
- };
-
- expect(getTimeDifferenceMinutes(mockSystemNote, anotherSystemNote)).toEqual(5);
- });
-
- it('collapses all description system notes made within 10 minutes or less from each other', () => {
- expect(collapseSystemNotes(notesWithDescriptionChanges)).toEqual(collapsedSystemNotes);
- });
-});