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/issues/show/components/description_spec.js')
-rw-r--r--spec/frontend/issues/show/components/description_spec.js187
1 files changed, 187 insertions, 0 deletions
diff --git a/spec/frontend/issues/show/components/description_spec.js b/spec/frontend/issues/show/components/description_spec.js
new file mode 100644
index 00000000000..d39e00b9c9e
--- /dev/null
+++ b/spec/frontend/issues/show/components/description_spec.js
@@ -0,0 +1,187 @@
+import $ from 'jquery';
+import Vue from 'vue';
+import '~/behaviors/markdown/render_gfm';
+import { TEST_HOST } from 'helpers/test_constants';
+import mountComponent from 'helpers/vue_mount_component_helper';
+import Description from '~/issues/show/components/description.vue';
+import TaskList from '~/task_list';
+import { descriptionProps as props } from '../mock_data/mock_data';
+
+jest.mock('~/task_list');
+
+describe('Description component', () => {
+ let vm;
+ let DescriptionComponent;
+
+ beforeEach(() => {
+ DescriptionComponent = Vue.extend(Description);
+
+ if (!document.querySelector('.issuable-meta')) {
+ const metaData = document.createElement('div');
+ metaData.classList.add('issuable-meta');
+ metaData.innerHTML =
+ '<div class="flash-container"></div><span id="task_status"></span><span id="task_status_short"></span>';
+
+ document.body.appendChild(metaData);
+ }
+
+ vm = mountComponent(DescriptionComponent, props);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ afterAll(() => {
+ $('.issuable-meta .flash-container').remove();
+ });
+
+ it('doesnt animate first description changes', () => {
+ vm.descriptionHtml = 'changed';
+
+ return vm.$nextTick().then(() => {
+ expect(
+ vm.$el.querySelector('.md').classList.contains('issue-realtime-pre-pulse'),
+ ).toBeFalsy();
+ jest.runAllTimers();
+ return vm.$nextTick();
+ });
+ });
+
+ it('animates description changes on live update', () => {
+ vm.descriptionHtml = 'changed';
+ return vm
+ .$nextTick()
+ .then(() => {
+ vm.descriptionHtml = 'changed second time';
+ return vm.$nextTick();
+ })
+ .then(() => {
+ expect(
+ vm.$el.querySelector('.md').classList.contains('issue-realtime-pre-pulse'),
+ ).toBeTruthy();
+ jest.runAllTimers();
+ return vm.$nextTick();
+ })
+ .then(() => {
+ expect(
+ vm.$el.querySelector('.md').classList.contains('issue-realtime-trigger-pulse'),
+ ).toBeTruthy();
+ });
+ });
+
+ it('applies syntax highlighting and math when description changed', () => {
+ const vmSpy = jest.spyOn(vm, 'renderGFM');
+ const prototypeSpy = jest.spyOn($.prototype, 'renderGFM');
+ vm.descriptionHtml = 'changed';
+
+ return vm.$nextTick().then(() => {
+ expect(vm.$refs['gfm-content']).toBeDefined();
+ expect(vmSpy).toHaveBeenCalled();
+ expect(prototypeSpy).toHaveBeenCalled();
+ expect($.prototype.renderGFM).toHaveBeenCalled();
+ });
+ });
+
+ it('sets data-update-url', () => {
+ expect(vm.$el.querySelector('textarea').dataset.updateUrl).toEqual(TEST_HOST);
+ });
+
+ describe('TaskList', () => {
+ beforeEach(() => {
+ vm.$destroy();
+ TaskList.mockClear();
+ vm = mountComponent(DescriptionComponent, { ...props, issuableType: 'issuableType' });
+ });
+
+ it('re-inits the TaskList when description changed', () => {
+ vm.descriptionHtml = 'changed';
+
+ expect(TaskList).toHaveBeenCalled();
+ });
+
+ it('does not re-init the TaskList when canUpdate is false', () => {
+ vm.canUpdate = false;
+ vm.descriptionHtml = 'changed';
+
+ expect(TaskList).toHaveBeenCalledTimes(1);
+ });
+
+ it('calls with issuableType dataType', () => {
+ vm.descriptionHtml = 'changed';
+
+ expect(TaskList).toHaveBeenCalledWith({
+ dataType: 'issuableType',
+ fieldName: 'description',
+ selector: '.detail-page-description',
+ onUpdate: expect.any(Function),
+ onSuccess: expect.any(Function),
+ onError: expect.any(Function),
+ lockVersion: 0,
+ });
+ });
+ });
+
+ describe('taskStatus', () => {
+ it('adds full taskStatus', () => {
+ vm.taskStatus = '1 of 1';
+
+ return vm.$nextTick().then(() => {
+ expect(document.querySelector('.issuable-meta #task_status').textContent.trim()).toBe(
+ '1 of 1',
+ );
+ });
+ });
+
+ it('adds short taskStatus', () => {
+ vm.taskStatus = '1 of 1';
+
+ return vm.$nextTick().then(() => {
+ expect(document.querySelector('.issuable-meta #task_status_short').textContent.trim()).toBe(
+ '1/1 task',
+ );
+ });
+ });
+
+ it('clears task status text when no tasks are present', () => {
+ vm.taskStatus = '0 of 0';
+
+ return vm.$nextTick().then(() => {
+ expect(document.querySelector('.issuable-meta #task_status').textContent.trim()).toBe('');
+ });
+ });
+ });
+
+ describe('taskListUpdateStarted', () => {
+ it('emits event to parent', () => {
+ const spy = jest.spyOn(vm, '$emit');
+
+ vm.taskListUpdateStarted();
+
+ expect(spy).toHaveBeenCalledWith('taskListUpdateStarted');
+ });
+ });
+
+ describe('taskListUpdateSuccess', () => {
+ it('emits event to parent', () => {
+ const spy = jest.spyOn(vm, '$emit');
+
+ vm.taskListUpdateSuccess();
+
+ expect(spy).toHaveBeenCalledWith('taskListUpdateSucceeded');
+ });
+ });
+
+ describe('taskListUpdateError', () => {
+ it('should create flash notification and emit an event to parent', () => {
+ const msg =
+ 'Someone edited this issue at the same time you did. The description has been updated and you will need to make your changes again.';
+ const spy = jest.spyOn(vm, '$emit');
+
+ vm.taskListUpdateError();
+
+ expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(msg);
+ expect(spy).toHaveBeenCalledWith('taskListUpdateFailed');
+ });
+ });
+});