diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-06 18:09:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-06 18:09:42 +0300 |
commit | a7beadc83470bd9ce23757a019795f49f95a6fff (patch) | |
tree | cb9ddaa8ea3eaf03b75184e682aef520ff46fc3f /spec/javascripts | |
parent | 4279f24a19836d3e74e4aae8bea7acc2dd8222cc (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/javascripts')
-rw-r--r-- | spec/javascripts/issue_show/components/app_spec.js | 568 | ||||
-rw-r--r-- | spec/javascripts/issue_show/components/description_spec.js | 210 | ||||
-rw-r--r-- | spec/javascripts/issue_show/components/edited_spec.js | 49 | ||||
-rw-r--r-- | spec/javascripts/issue_show/components/fields/description_template_spec.js | 43 | ||||
-rw-r--r-- | spec/javascripts/issue_show/components/form_spec.js | 98 | ||||
-rw-r--r-- | spec/javascripts/issue_show/components/title_spec.js | 105 | ||||
-rw-r--r-- | spec/javascripts/issue_show/helpers.js | 1 | ||||
-rw-r--r-- | spec/javascripts/issue_show/mock_data.js | 1 |
8 files changed, 0 insertions, 1075 deletions
diff --git a/spec/javascripts/issue_show/components/app_spec.js b/spec/javascripts/issue_show/components/app_spec.js deleted file mode 100644 index 2d4d3ea28ff..00000000000 --- a/spec/javascripts/issue_show/components/app_spec.js +++ /dev/null @@ -1,568 +0,0 @@ -/* eslint-disable no-unused-vars */ -import Vue from 'vue'; -import MockAdapter from 'axios-mock-adapter'; -import setTimeoutPromise from 'spec/helpers/set_timeout_promise_helper'; -import GLDropdown from '~/gl_dropdown'; -import axios from '~/lib/utils/axios_utils'; -import '~/behaviors/markdown/render_gfm'; -import issuableApp from '~/issue_show/components/app.vue'; -import eventHub from '~/issue_show/event_hub'; -import { initialRequest, secondRequest } from '../mock_data'; - -function formatText(text) { - return text.trim().replace(/\s\s+/g, ' '); -} - -const REALTIME_REQUEST_STACK = [initialRequest, secondRequest]; - -describe('Issuable output', () => { - let mock; - let realtimeRequestCount = 0; - let vm; - - beforeEach(done => { - setFixtures(` - <div> - <div class="detail-page-description content-block"> - <details open> - <summary>One</summary> - </details> - <details> - <summary>Two</summary> - </details> - </div> - <div class="flash-container"></div> - <span id="task_status"></span> - </div> - `); - spyOn(eventHub, '$emit'); - - const IssuableDescriptionComponent = Vue.extend(issuableApp); - - mock = new MockAdapter(axios); - mock - .onGet('/gitlab-org/gitlab-shell/-/issues/9/realtime_changes/realtime_changes') - .reply(() => { - const res = Promise.resolve([200, REALTIME_REQUEST_STACK[realtimeRequestCount]]); - realtimeRequestCount += 1; - return res; - }); - - vm = new IssuableDescriptionComponent({ - propsData: { - canUpdate: true, - canDestroy: true, - endpoint: '/gitlab-org/gitlab-shell/-/issues/9/realtime_changes', - updateEndpoint: gl.TEST_HOST, - issuableRef: '#1', - initialTitleHtml: '', - initialTitleText: '', - initialDescriptionHtml: 'test', - initialDescriptionText: 'test', - lockVersion: 1, - markdownPreviewPath: '/', - markdownDocsPath: '/', - projectNamespace: '/', - projectPath: '/', - issuableTemplateNamesPath: '/issuable-templates-path', - }, - }).$mount(); - - setTimeout(done); - }); - - afterEach(() => { - mock.restore(); - realtimeRequestCount = 0; - - vm.poll.stop(); - vm.$destroy(); - }); - - it('should render a title/description/edited and update title/description/edited on update', done => { - let editedText; - Vue.nextTick() - .then(() => { - editedText = vm.$el.querySelector('.edited-text'); - }) - .then(() => { - expect(document.querySelector('title').innerText).toContain('this is a title (#1)'); - expect(vm.$el.querySelector('.title').innerHTML).toContain('<p>this is a title</p>'); - expect(vm.$el.querySelector('.md').innerHTML).toContain('<p>this is a description!</p>'); - expect(vm.$el.querySelector('.js-task-list-field').value).toContain( - 'this is a description', - ); - - expect(formatText(editedText.innerText)).toMatch(/Edited[\s\S]+?by Some User/); - expect(editedText.querySelector('.author-link').href).toMatch(/\/some_user$/); - expect(editedText.querySelector('time')).toBeTruthy(); - expect(vm.state.lock_version).toEqual(1); - }) - .then(() => { - vm.poll.makeRequest(); - }) - .then(() => new Promise(resolve => setTimeout(resolve))) - .then(() => { - expect(document.querySelector('title').innerText).toContain('2 (#1)'); - expect(vm.$el.querySelector('.title').innerHTML).toContain('<p>2</p>'); - expect(vm.$el.querySelector('.md').innerHTML).toContain('<p>42</p>'); - expect(vm.$el.querySelector('.js-task-list-field').value).toContain('42'); - expect(vm.$el.querySelector('.edited-text')).toBeTruthy(); - expect(formatText(vm.$el.querySelector('.edited-text').innerText)).toMatch( - /Edited[\s\S]+?by Other User/, - ); - - expect(editedText.querySelector('.author-link').href).toMatch(/\/other_user$/); - expect(editedText.querySelector('time')).toBeTruthy(); - expect(vm.state.lock_version).toEqual(2); - }) - .then(done) - .catch(done.fail); - }); - - it('shows actions if permissions are correct', done => { - vm.showForm = true; - - Vue.nextTick(() => { - expect(vm.$el.querySelector('.btn')).not.toBeNull(); - - done(); - }); - }); - - it('does not show actions if permissions are incorrect', done => { - vm.showForm = true; - vm.canUpdate = false; - - Vue.nextTick(() => { - expect(vm.$el.querySelector('.btn')).toBeNull(); - - done(); - }); - }); - - it('does not update formState if form is already open', done => { - vm.updateAndShowForm(); - - vm.state.titleText = 'testing 123'; - - vm.updateAndShowForm(); - - Vue.nextTick(() => { - expect(vm.store.formState.title).not.toBe('testing 123'); - - done(); - }); - }); - - describe('updateIssuable', () => { - it('fetches new data after update', done => { - spyOn(vm, 'updateStoreState').and.callThrough(); - spyOn(vm.service, 'getData').and.callThrough(); - spyOn(vm.service, 'updateIssuable').and.returnValue( - Promise.resolve({ - data: { web_url: window.location.pathname }, - }), - ); - - vm.updateIssuable() - .then(() => { - expect(vm.updateStoreState).toHaveBeenCalled(); - expect(vm.service.getData).toHaveBeenCalled(); - }) - .then(done) - .catch(done.fail); - }); - - it('correctly updates issuable data', done => { - spyOn(vm.service, 'updateIssuable').and.returnValue( - Promise.resolve({ - data: { web_url: window.location.pathname }, - }), - ); - - vm.updateIssuable() - .then(() => { - expect(vm.service.updateIssuable).toHaveBeenCalledWith(vm.formState); - expect(eventHub.$emit).toHaveBeenCalledWith('close.form'); - }) - .then(done) - .catch(done.fail); - }); - - it('does not redirect if issue has not moved', done => { - const visitUrl = spyOnDependency(issuableApp, 'visitUrl'); - spyOn(vm.service, 'updateIssuable').and.returnValue( - Promise.resolve({ - data: { - web_url: window.location.pathname, - confidential: vm.isConfidential, - }, - }), - ); - - vm.updateIssuable(); - - setTimeout(() => { - expect(visitUrl).not.toHaveBeenCalled(); - done(); - }); - }); - - it('redirects if returned web_url has changed', done => { - const visitUrl = spyOnDependency(issuableApp, 'visitUrl'); - spyOn(vm.service, 'updateIssuable').and.returnValue( - Promise.resolve({ - data: { - web_url: '/testing-issue-move', - confidential: vm.isConfidential, - }, - }), - ); - - vm.updateIssuable(); - - setTimeout(() => { - expect(visitUrl).toHaveBeenCalledWith('/testing-issue-move'); - done(); - }); - }); - - describe('shows dialog when issue has unsaved changed', () => { - it('confirms on title change', done => { - vm.showForm = true; - vm.state.titleText = 'title has changed'; - const e = { returnValue: null }; - vm.handleBeforeUnloadEvent(e); - Vue.nextTick(() => { - expect(e.returnValue).not.toBeNull(); - - done(); - }); - }); - - it('confirms on description change', done => { - vm.showForm = true; - vm.state.descriptionText = 'description has changed'; - const e = { returnValue: null }; - vm.handleBeforeUnloadEvent(e); - Vue.nextTick(() => { - expect(e.returnValue).not.toBeNull(); - - done(); - }); - }); - - it('does nothing when nothing has changed', done => { - const e = { returnValue: null }; - vm.handleBeforeUnloadEvent(e); - Vue.nextTick(() => { - expect(e.returnValue).toBeNull(); - - done(); - }); - }); - }); - - describe('error when updating', () => { - it('closes form on error', done => { - spyOn(vm.service, 'updateIssuable').and.callFake(() => Promise.reject()); - vm.updateIssuable(); - - setTimeout(() => { - expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form'); - expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe( - `Error updating issue`, - ); - - done(); - }); - }); - - it('returns the correct error message for issuableType', done => { - spyOn(vm.service, 'updateIssuable').and.callFake(() => Promise.reject()); - vm.issuableType = 'merge request'; - - Vue.nextTick(() => { - vm.updateIssuable(); - - setTimeout(() => { - expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form'); - expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe( - `Error updating merge request`, - ); - - done(); - }); - }); - }); - - it('shows error message from backend if exists', done => { - const msg = 'Custom error message from backend'; - spyOn(vm.service, 'updateIssuable').and.callFake( - // eslint-disable-next-line prefer-promise-reject-errors - () => Promise.reject({ response: { data: { errors: [msg] } } }), - ); - - vm.updateIssuable(); - setTimeout(() => { - expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe( - `${vm.defaultErrorMessage}. ${msg}`, - ); - - done(); - }); - }); - }); - }); - - it('opens reCAPTCHA modal if update rejected as spam', done => { - function mockScriptSrc() { - const recaptchaChild = vm.$children.find( - // eslint-disable-next-line no-underscore-dangle - child => child.$options._componentTag === 'recaptcha-modal', - ); - - recaptchaChild.scriptSrc = '//scriptsrc'; - } - - let modal; - const promise = new Promise(resolve => { - resolve({ - data: { - recaptcha_html: '<div class="g-recaptcha">recaptcha_html</div>', - }, - }); - }); - - spyOn(vm.service, 'updateIssuable').and.returnValue(promise); - - vm.canUpdate = true; - vm.showForm = true; - - vm.$nextTick() - .then(() => mockScriptSrc()) - .then(() => vm.updateIssuable()) - .then(promise) - .then(() => setTimeoutPromise()) - .then(() => { - modal = vm.$el.querySelector('.js-recaptcha-modal'); - - expect(modal.style.display).not.toEqual('none'); - expect(modal.querySelector('.g-recaptcha').textContent).toEqual('recaptcha_html'); - expect(document.body.querySelector('.js-recaptcha-script').src).toMatch('//scriptsrc'); - }) - .then(() => modal.querySelector('.close').click()) - .then(() => vm.$nextTick()) - .then(() => { - expect(modal.style.display).toEqual('none'); - expect(document.body.querySelector('.js-recaptcha-script')).toBeNull(); - }) - .then(done) - .catch(done.fail); - }); - - describe('deleteIssuable', () => { - it('changes URL when deleted', done => { - const visitUrl = spyOnDependency(issuableApp, 'visitUrl'); - spyOn(vm.service, 'deleteIssuable').and.returnValue( - Promise.resolve({ - data: { - web_url: '/test', - }, - }), - ); - - vm.deleteIssuable(); - - setTimeout(() => { - expect(visitUrl).toHaveBeenCalledWith('/test'); - - done(); - }); - }); - - it('stops polling when deleting', done => { - spyOnDependency(issuableApp, 'visitUrl'); - spyOn(vm.poll, 'stop').and.callThrough(); - spyOn(vm.service, 'deleteIssuable').and.returnValue( - Promise.resolve({ - data: { - web_url: '/test', - }, - }), - ); - - vm.deleteIssuable(); - - setTimeout(() => { - expect(vm.poll.stop).toHaveBeenCalledWith(); - - done(); - }); - }); - - it('closes form on error', done => { - spyOn(vm.service, 'deleteIssuable').and.returnValue(Promise.reject()); - - vm.deleteIssuable(); - - setTimeout(() => { - expect(eventHub.$emit).not.toHaveBeenCalledWith('close.form'); - expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe( - 'Error deleting issue', - ); - - done(); - }); - }); - }); - - describe('updateAndShowForm', () => { - it('shows locked warning if form is open & data is different', done => { - vm.$nextTick() - .then(() => { - vm.updateAndShowForm(); - - vm.poll.makeRequest(); - - return new Promise(resolve => { - vm.$watch('formState.lockedWarningVisible', value => { - if (value) resolve(); - }); - }); - }) - .then(() => { - expect(vm.formState.lockedWarningVisible).toEqual(true); - expect(vm.formState.lock_version).toEqual(1); - expect(vm.$el.querySelector('.alert')).not.toBeNull(); - }) - .then(done) - .catch(done.fail); - }); - }); - - describe('requestTemplatesAndShowForm', () => { - beforeEach(() => { - spyOn(vm, 'updateAndShowForm'); - }); - - it('shows the form if template names request is successful', done => { - const mockData = [{ name: 'Bug' }]; - mock.onGet('/issuable-templates-path').reply(() => Promise.resolve([200, mockData])); - - vm.requestTemplatesAndShowForm() - .then(() => { - expect(vm.updateAndShowForm).toHaveBeenCalledWith(mockData); - }) - .then(done) - .catch(done.fail); - }); - - it('shows the form if template names request failed', done => { - mock - .onGet('/issuable-templates-path') - .reply(() => Promise.reject(new Error('something went wrong'))); - - vm.requestTemplatesAndShowForm() - .then(() => { - expect(document.querySelector('.flash-container .flash-text').textContent).toContain( - 'Error updating issue', - ); - - expect(vm.updateAndShowForm).toHaveBeenCalledWith(); - }) - .then(done) - .catch(done.fail); - }); - }); - - describe('show inline edit button', () => { - it('should not render by default', () => { - expect(vm.$el.querySelector('.title-container .note-action-button')).toBeDefined(); - }); - - it('should render if showInlineEditButton', () => { - vm.showInlineEditButton = true; - - expect(vm.$el.querySelector('.title-container .note-action-button')).toBeDefined(); - }); - }); - - describe('updateStoreState', () => { - it('should make a request and update the state of the store', done => { - const data = { foo: 1 }; - spyOn(vm.store, 'updateState'); - spyOn(vm.service, 'getData').and.returnValue(Promise.resolve({ data })); - - vm.updateStoreState() - .then(() => { - expect(vm.service.getData).toHaveBeenCalled(); - expect(vm.store.updateState).toHaveBeenCalledWith(data); - }) - .then(done) - .catch(done.fail); - }); - - it('should show error message if store update fails', done => { - spyOn(vm.service, 'getData').and.returnValue(Promise.reject()); - vm.issuableType = 'merge request'; - - vm.updateStoreState() - .then(() => { - expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe( - `Error updating ${vm.issuableType}`, - ); - }) - .then(done) - .catch(done.fail); - }); - }); - - describe('issueChanged', () => { - beforeEach(() => { - vm.store.formState.title = ''; - vm.store.formState.description = ''; - vm.initialDescriptionText = ''; - vm.initialTitleText = ''; - }); - - it('returns true when title is changed', () => { - vm.store.formState.title = 'RandomText'; - - expect(vm.issueChanged).toBe(true); - }); - - it('returns false when title is empty null', () => { - vm.store.formState.title = null; - - expect(vm.issueChanged).toBe(false); - }); - - it('returns false when `initialTitleText` is null and `formState.title` is empty string', () => { - vm.store.formState.title = ''; - vm.initialTitleText = null; - - expect(vm.issueChanged).toBe(false); - }); - - it('returns true when description is changed', () => { - vm.store.formState.description = 'RandomText'; - - expect(vm.issueChanged).toBe(true); - }); - - it('returns false when description is empty null', () => { - vm.store.formState.title = null; - - expect(vm.issueChanged).toBe(false); - }); - - it('returns false when `initialDescriptionText` is null and `formState.description` is empty string', () => { - vm.store.formState.description = ''; - vm.initialDescriptionText = null; - - expect(vm.issueChanged).toBe(false); - }); - }); -}); diff --git a/spec/javascripts/issue_show/components/description_spec.js b/spec/javascripts/issue_show/components/description_spec.js deleted file mode 100644 index 194f177d837..00000000000 --- a/spec/javascripts/issue_show/components/description_spec.js +++ /dev/null @@ -1,210 +0,0 @@ -import $ from 'jquery'; -import Vue from 'vue'; -import '~/behaviors/markdown/render_gfm'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import Description from '~/issue_show/components/description.vue'; - -describe('Description component', () => { - let vm; - let DescriptionComponent; - const props = { - canUpdate: true, - descriptionHtml: 'test', - descriptionText: 'test', - updatedAt: new Date().toString(), - taskStatus: '', - updateUrl: gl.TEST_HOST, - }; - - 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('animates description changes', done => { - vm.descriptionHtml = 'changed'; - - Vue.nextTick(() => { - expect( - vm.$el.querySelector('.md').classList.contains('issue-realtime-pre-pulse'), - ).toBeTruthy(); - - setTimeout(() => { - expect( - vm.$el.querySelector('.md').classList.contains('issue-realtime-trigger-pulse'), - ).toBeTruthy(); - - done(); - }); - }); - }); - - it('opens reCAPTCHA dialog if update rejected as spam', done => { - let modal; - const recaptchaChild = vm.$children.find( - // eslint-disable-next-line no-underscore-dangle - child => child.$options._componentTag === 'recaptcha-modal', - ); - - recaptchaChild.scriptSrc = '//scriptsrc'; - - vm.taskListUpdateSuccess({ - recaptcha_html: '<div class="g-recaptcha">recaptcha_html</div>', - }); - - vm.$nextTick() - .then(() => { - modal = vm.$el.querySelector('.js-recaptcha-modal'); - - expect(modal.style.display).not.toEqual('none'); - expect(modal.querySelector('.g-recaptcha').textContent).toEqual('recaptcha_html'); - expect(document.body.querySelector('.js-recaptcha-script').src).toMatch('//scriptsrc'); - }) - .then(() => modal.querySelector('.close').click()) - .then(() => vm.$nextTick()) - .then(() => { - expect(modal.style.display).toEqual('none'); - expect(document.body.querySelector('.js-recaptcha-script')).toBeNull(); - }) - .then(done) - .catch(done.fail); - }); - - describe('TaskList', () => { - let TaskList; - - beforeEach(() => { - vm.$destroy(); - vm = mountComponent( - DescriptionComponent, - Object.assign({}, props, { - issuableType: 'issuableType', - }), - ); - TaskList = spyOnDependency(Description, 'TaskList'); - }); - - it('re-inits the TaskList when description changed', done => { - vm.descriptionHtml = 'changed'; - - setTimeout(() => { - expect(TaskList).toHaveBeenCalled(); - done(); - }); - }); - - it('does not re-init the TaskList when canUpdate is false', done => { - vm.canUpdate = false; - vm.descriptionHtml = 'changed'; - - setTimeout(() => { - expect(TaskList).not.toHaveBeenCalled(); - done(); - }); - }); - - it('calls with issuableType dataType', done => { - vm.descriptionHtml = 'changed'; - - setTimeout(() => { - expect(TaskList).toHaveBeenCalledWith({ - dataType: 'issuableType', - fieldName: 'description', - selector: '.detail-page-description', - onSuccess: jasmine.any(Function), - onError: jasmine.any(Function), - lockVersion: 0, - }); - - done(); - }); - }); - }); - - describe('taskStatus', () => { - it('adds full taskStatus', done => { - vm.taskStatus = '1 of 1'; - - setTimeout(() => { - expect(document.querySelector('.issuable-meta #task_status').textContent.trim()).toBe( - '1 of 1', - ); - - done(); - }); - }); - - it('adds short taskStatus', done => { - vm.taskStatus = '1 of 1'; - - setTimeout(() => { - expect(document.querySelector('.issuable-meta #task_status_short').textContent.trim()).toBe( - '1/1 task', - ); - - done(); - }); - }); - - it('clears task status text when no tasks are present', done => { - vm.taskStatus = '0 of 0'; - - setTimeout(() => { - expect(document.querySelector('.issuable-meta #task_status').textContent.trim()).toBe(''); - - done(); - }); - }); - }); - - it('applies syntax highlighting and math when description changed', done => { - spyOn(vm, 'renderGFM').and.callThrough(); - spyOn($.prototype, 'renderGFM').and.callThrough(); - vm.descriptionHtml = 'changed'; - - Vue.nextTick(() => { - setTimeout(() => { - expect(vm.$refs['gfm-content']).toBeDefined(); - expect(vm.renderGFM).toHaveBeenCalled(); - expect($.prototype.renderGFM).toHaveBeenCalled(); - - done(); - }); - }); - }); - - it('sets data-update-url', () => { - expect(vm.$el.querySelector('textarea').dataset.updateUrl).toEqual(gl.TEST_HOST); - }); - - 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.'; - spyOn(vm, '$emit'); - - vm.taskListUpdateError(); - - expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(msg); - expect(vm.$emit).toHaveBeenCalledWith('taskListUpdateFailed'); - }); - }); -}); diff --git a/spec/javascripts/issue_show/components/edited_spec.js b/spec/javascripts/issue_show/components/edited_spec.js deleted file mode 100644 index a1683f060c0..00000000000 --- a/spec/javascripts/issue_show/components/edited_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import Vue from 'vue'; -import edited from '~/issue_show/components/edited.vue'; - -function formatText(text) { - return text.trim().replace(/\s\s+/g, ' '); -} - -describe('edited', () => { - const EditedComponent = Vue.extend(edited); - - it('should render an edited at+by string', () => { - const editedComponent = new EditedComponent({ - propsData: { - updatedAt: '2017-05-15T12:31:04.428Z', - updatedByName: 'Some User', - updatedByPath: '/some_user', - }, - }).$mount(); - - expect(formatText(editedComponent.$el.innerText)).toMatch(/Edited[\s\S]+?by Some User/); - expect(editedComponent.$el.querySelector('.author-link').href).toMatch(/\/some_user$/); - expect(editedComponent.$el.querySelector('time')).toBeTruthy(); - }); - - it('if no updatedAt is provided, no time element will be rendered', () => { - const editedComponent = new EditedComponent({ - propsData: { - updatedByName: 'Some User', - updatedByPath: '/some_user', - }, - }).$mount(); - - expect(formatText(editedComponent.$el.innerText)).toMatch(/Edited by Some User/); - expect(editedComponent.$el.querySelector('.author-link').href).toMatch(/\/some_user$/); - expect(editedComponent.$el.querySelector('time')).toBeFalsy(); - }); - - it('if no updatedByName and updatedByPath is provided, no user element will be rendered', () => { - const editedComponent = new EditedComponent({ - propsData: { - updatedAt: '2017-05-15T12:31:04.428Z', - }, - }).$mount(); - - expect(formatText(editedComponent.$el.innerText)).not.toMatch(/by Some User/); - expect(editedComponent.$el.querySelector('.author-link')).toBeFalsy(); - expect(editedComponent.$el.querySelector('time')).toBeTruthy(); - }); -}); diff --git a/spec/javascripts/issue_show/components/fields/description_template_spec.js b/spec/javascripts/issue_show/components/fields/description_template_spec.js deleted file mode 100644 index 8d77a620d76..00000000000 --- a/spec/javascripts/issue_show/components/fields/description_template_spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import Vue from 'vue'; -import descriptionTemplate from '~/issue_show/components/fields/description_template.vue'; - -describe('Issue description template component', () => { - let vm; - let formState; - - beforeEach(done => { - const Component = Vue.extend(descriptionTemplate); - formState = { - description: 'test', - }; - - vm = new Component({ - propsData: { - formState, - issuableTemplates: [{ name: 'test' }], - projectPath: '/', - projectNamespace: '/', - }, - }).$mount(); - - Vue.nextTick(done); - }); - - it('renders templates as JSON array in data attribute', () => { - expect(vm.$el.querySelector('.js-issuable-selector').getAttribute('data-data')).toBe( - '[{"name":"test"}]', - ); - }); - - it('updates formState when changing template', () => { - vm.issuableTemplate.editor.setValue('test new template'); - - expect(formState.description).toBe('test new template'); - }); - - it('returns formState description with editor getValue', () => { - formState.description = 'testing new template'; - - expect(vm.issuableTemplate.editor.getValue()).toBe('testing new template'); - }); -}); diff --git a/spec/javascripts/issue_show/components/form_spec.js b/spec/javascripts/issue_show/components/form_spec.js deleted file mode 100644 index a111333ac80..00000000000 --- a/spec/javascripts/issue_show/components/form_spec.js +++ /dev/null @@ -1,98 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import formComponent from '~/issue_show/components/form.vue'; -import eventHub from '~/issue_show/event_hub'; - -describe('Inline edit form component', () => { - let vm; - const defaultProps = { - canDestroy: true, - formState: { - title: 'b', - description: 'a', - lockedWarningVisible: false, - }, - issuableType: 'issue', - markdownPreviewPath: '/', - markdownDocsPath: '/', - projectPath: '/', - projectNamespace: '/', - }; - - afterEach(() => { - vm.$destroy(); - }); - - const createComponent = props => { - const Component = Vue.extend(formComponent); - - vm = mountComponent(Component, { - ...defaultProps, - ...props, - }); - }; - - it('does not render template selector if no templates exist', () => { - createComponent(); - - expect(vm.$el.querySelector('.js-issuable-selector-wrap')).toBeNull(); - }); - - it('renders template selector when templates exists', () => { - createComponent({ issuableTemplates: ['test'] }); - - expect(vm.$el.querySelector('.js-issuable-selector-wrap')).not.toBeNull(); - }); - - it('hides locked warning by default', () => { - createComponent(); - - expect(vm.$el.querySelector('.alert')).toBeNull(); - }); - - it('shows locked warning if formState is different', () => { - createComponent({ formState: { ...defaultProps.formState, lockedWarningVisible: true } }); - - expect(vm.$el.querySelector('.alert')).not.toBeNull(); - }); - - it('hides locked warning when currently saving', () => { - createComponent({ - formState: { ...defaultProps.formState, updateLoading: true, lockedWarningVisible: true }, - }); - - expect(vm.$el.querySelector('.alert')).toBeNull(); - }); - - describe('autosave', () => { - let autosaveObj; - let autosave; - - beforeEach(() => { - autosaveObj = { reset: jasmine.createSpy() }; - autosave = spyOnDependency(formComponent, 'Autosave').and.returnValue(autosaveObj); - }); - - it('initialized Autosave on mount', () => { - createComponent(); - - expect(autosave).toHaveBeenCalledTimes(2); - }); - - it('calls reset on autosave when eventHub emits appropriate events', () => { - createComponent(); - - eventHub.$emit('close.form'); - - expect(autosaveObj.reset).toHaveBeenCalledTimes(2); - - eventHub.$emit('delete.issuable'); - - expect(autosaveObj.reset).toHaveBeenCalledTimes(4); - - eventHub.$emit('update.issuable'); - - expect(autosaveObj.reset).toHaveBeenCalledTimes(6); - }); - }); -}); diff --git a/spec/javascripts/issue_show/components/title_spec.js b/spec/javascripts/issue_show/components/title_spec.js deleted file mode 100644 index 9754c8a6755..00000000000 --- a/spec/javascripts/issue_show/components/title_spec.js +++ /dev/null @@ -1,105 +0,0 @@ -import Vue from 'vue'; -import Store from '~/issue_show/stores'; -import titleComponent from '~/issue_show/components/title.vue'; -import eventHub from '~/issue_show/event_hub'; - -describe('Title component', () => { - let vm; - - beforeEach(() => { - const Component = Vue.extend(titleComponent); - const store = new Store({ - titleHtml: '', - descriptionHtml: '', - issuableRef: '', - }); - vm = new Component({ - propsData: { - issuableRef: '#1', - titleHtml: 'Testing <img />', - titleText: 'Testing', - showForm: false, - formState: store.formState, - }, - }).$mount(); - }); - - it('renders title HTML', () => { - expect(vm.$el.querySelector('.title').innerHTML.trim()).toBe('Testing <img>'); - }); - - it('updates page title when changing titleHtml', done => { - spyOn(vm, 'setPageTitle'); - vm.titleHtml = 'test'; - - Vue.nextTick(() => { - expect(vm.setPageTitle).toHaveBeenCalled(); - - done(); - }); - }); - - it('animates title changes', done => { - vm.titleHtml = 'test'; - - Vue.nextTick(() => { - expect( - vm.$el.querySelector('.title').classList.contains('issue-realtime-pre-pulse'), - ).toBeTruthy(); - - setTimeout(() => { - expect( - vm.$el.querySelector('.title').classList.contains('issue-realtime-trigger-pulse'), - ).toBeTruthy(); - - done(); - }); - }); - }); - - it('updates page title after changing title', done => { - vm.titleHtml = 'changed'; - vm.titleText = 'changed'; - - Vue.nextTick(() => { - expect(document.querySelector('title').textContent.trim()).toContain('changed'); - - done(); - }); - }); - - describe('inline edit button', () => { - beforeEach(() => { - spyOn(eventHub, '$emit'); - }); - - it('should not show by default', () => { - expect(vm.$el.querySelector('.btn-edit')).toBeNull(); - }); - - it('should not show if canUpdate is false', () => { - vm.showInlineEditButton = true; - vm.canUpdate = false; - - expect(vm.$el.querySelector('.btn-edit')).toBeNull(); - }); - - it('should show if showInlineEditButton and canUpdate', () => { - vm.showInlineEditButton = true; - vm.canUpdate = true; - - expect(vm.$el.querySelector('.btn-edit')).toBeDefined(); - }); - - it('should trigger open.form event when clicked', () => { - vm.showInlineEditButton = true; - vm.canUpdate = true; - - Vue.nextTick(() => { - vm.$el.querySelector('.btn-edit').click(); - - expect(eventHub.$emit).toHaveBeenCalledWith('open.form'); - }); - }); - }); -}); diff --git a/spec/javascripts/issue_show/helpers.js b/spec/javascripts/issue_show/helpers.js deleted file mode 100644 index 951acfd4e10..00000000000 --- a/spec/javascripts/issue_show/helpers.js +++ /dev/null @@ -1 +0,0 @@ -export * from '../../frontend/issue_show/helpers.js'; diff --git a/spec/javascripts/issue_show/mock_data.js b/spec/javascripts/issue_show/mock_data.js deleted file mode 100644 index 1b391bd1588..00000000000 --- a/spec/javascripts/issue_show/mock_data.js +++ /dev/null @@ -1 +0,0 @@ -export * from '../../frontend/issue_show/mock_data'; |