diff options
author | Eric Eastwood <contact@ericeastwood.com> | 2017-08-14 02:26:19 -0500 |
---|---|---|
committer | Eric Eastwood <contact@ericeastwood.com> | 2017-09-03 22:03:17 -0500 |
commit | 90c60138db4e1f86026aac5760febe4ba066ca30 (patch) | |
tree | d08764bc1f19556a528bd43f5cc932fa552e7198 /spec/javascripts/sidebar | |
parent | a3af683045e0170d975eab2562a466f88d2692b8 (diff) | |
download | gitlab-ce-90c60138db4e1f86026aac5760febe4ba066ca30.tar.gz |
Move "Move to different project" to sidebar34261-move-move-to-sidebar
Fix https://gitlab.com/gitlab-org/gitlab-ce/issues/34261
Diffstat (limited to 'spec/javascripts/sidebar')
-rw-r--r-- | spec/javascripts/sidebar/mock_data.js | 41 | ||||
-rw-r--r-- | spec/javascripts/sidebar/sidebar_mediator_spec.js | 40 | ||||
-rw-r--r-- | spec/javascripts/sidebar/sidebar_move_issue_spec.js | 142 | ||||
-rw-r--r-- | spec/javascripts/sidebar/sidebar_service_spec.js | 28 | ||||
-rw-r--r-- | spec/javascripts/sidebar/sidebar_store_spec.js | 14 |
5 files changed, 261 insertions, 4 deletions
diff --git a/spec/javascripts/sidebar/mock_data.js b/spec/javascripts/sidebar/mock_data.js index 9fc8667ecc9..e2b6bcabc98 100644 --- a/spec/javascripts/sidebar/mock_data.js +++ b/spec/javascripts/sidebar/mock_data.js @@ -66,17 +66,57 @@ const sidebarMockData = { }, labels: [], }, + '/autocomplete/projects?project_id=15': [ + { + 'id': 0, + 'name_with_namespace': 'No project', + }, { + 'id': 20, + 'name_with_namespace': 'foo / bar', + }, + ], }, 'PUT': { '/gitlab-org/gitlab-shell/issues/5.json': { data: {}, }, }, + 'POST': { + '/gitlab-org/gitlab-shell/issues/5/move': { + id: 123, + iid: 5, + author_id: 1, + description: 'some description', + lock_version: 5, + milestone_id: null, + state: 'opened', + title: 'some title', + updated_by_id: 1, + created_at: '2017-06-27T19:54:42.437Z', + updated_at: '2017-08-18T03:39:49.222Z', + deleted_at: null, + time_estimate: 0, + total_time_spent: 0, + human_time_estimate: null, + human_total_time_spent: null, + branch_name: null, + confidential: false, + assignees: [], + due_date: null, + moved_to_id: null, + project_id: 7, + milestone: null, + labels: [], + web_url: '/root/some-project/issues/5', + }, + }, }; export default { mediator: { endpoint: '/gitlab-org/gitlab-shell/issues/5.json', + moveIssueEndpoint: '/gitlab-org/gitlab-shell/issues/5/move', + projectsAutocompleteEndpoint: '/autocomplete/projects?project_id=15', editable: true, currentUser: { id: 1, @@ -85,6 +125,7 @@ export default { avatar_url: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', }, rootPath: '/', + fullPath: '/gitlab-org/gitlab-shell', }, time: { time_estimate: 3600, diff --git a/spec/javascripts/sidebar/sidebar_mediator_spec.js b/spec/javascripts/sidebar/sidebar_mediator_spec.js index e246f41ee82..3aa8ca5db0d 100644 --- a/spec/javascripts/sidebar/sidebar_mediator_spec.js +++ b/spec/javascripts/sidebar/sidebar_mediator_spec.js @@ -30,7 +30,7 @@ describe('Sidebar mediator', () => { expect(resp.status).toEqual(200); done(); }) - .catch(() => {}); + .catch(done.fail); }); it('fetches the data', () => { @@ -38,4 +38,42 @@ describe('Sidebar mediator', () => { this.mediator.fetch(); expect(this.mediator.service.get).toHaveBeenCalled(); }); + + it('sets moveToProjectId', () => { + const projectId = 7; + spyOn(this.mediator.store, 'setMoveToProjectId').and.callThrough(); + + this.mediator.setMoveToProjectId(projectId); + + expect(this.mediator.store.setMoveToProjectId).toHaveBeenCalledWith(projectId); + }); + + it('fetches autocomplete projects', (done) => { + const searchTerm = 'foo'; + spyOn(this.mediator.service, 'getProjectsAutocomplete').and.callThrough(); + spyOn(this.mediator.store, 'setAutocompleteProjects').and.callThrough(); + + this.mediator.fetchAutocompleteProjects(searchTerm) + .then(() => { + expect(this.mediator.service.getProjectsAutocomplete).toHaveBeenCalledWith(searchTerm); + expect(this.mediator.store.setAutocompleteProjects).toHaveBeenCalled(); + done(); + }) + .catch(done.fail); + }); + + it('moves issue', (done) => { + const moveToProjectId = 7; + this.mediator.store.setMoveToProjectId(moveToProjectId); + spyOn(this.mediator.service, 'moveIssue').and.callThrough(); + spyOn(gl.utils, 'visitUrl'); + + this.mediator.moveIssue() + .then(() => { + expect(this.mediator.service.moveIssue).toHaveBeenCalledWith(moveToProjectId); + expect(gl.utils.visitUrl).toHaveBeenCalledWith('/root/some-project/issues/5'); + done(); + }) + .catch(done.fail); + }); }); diff --git a/spec/javascripts/sidebar/sidebar_move_issue_spec.js b/spec/javascripts/sidebar/sidebar_move_issue_spec.js new file mode 100644 index 00000000000..8b0d51bbcc8 --- /dev/null +++ b/spec/javascripts/sidebar/sidebar_move_issue_spec.js @@ -0,0 +1,142 @@ +import Vue from 'vue'; +import SidebarMediator from '~/sidebar/sidebar_mediator'; +import SidebarStore from '~/sidebar/stores/sidebar_store'; +import SidebarService from '~/sidebar/services/sidebar_service'; +import SidebarMoveIssue from '~/sidebar/lib/sidebar_move_issue'; +import Mock from './mock_data'; + +describe('SidebarMoveIssue', () => { + beforeEach(() => { + Vue.http.interceptors.push(Mock.sidebarMockInterceptor); + this.mediator = new SidebarMediator(Mock.mediator); + this.$content = $(` + <div class="dropdown"> + <div class="js-toggle"></div> + <div class="dropdown-content"></div> + <div class="js-confirm-button"></div> + </div> + `); + this.$toggleButton = this.$content.find('.js-toggle'); + this.$confirmButton = this.$content.find('.js-confirm-button'); + + this.sidebarMoveIssue = new SidebarMoveIssue( + this.mediator, + this.$toggleButton, + this.$confirmButton, + ); + this.sidebarMoveIssue.init(); + }); + + afterEach(() => { + SidebarService.singleton = null; + SidebarStore.singleton = null; + SidebarMediator.singleton = null; + + this.sidebarMoveIssue.destroy(); + + Vue.http.interceptors = _.without(Vue.http.interceptors, Mock.sidebarMockInterceptor); + }); + + describe('init', () => { + it('should initialize the dropdown and listeners', () => { + spyOn(this.sidebarMoveIssue, 'initDropdown'); + spyOn(this.sidebarMoveIssue, 'addEventListeners'); + + this.sidebarMoveIssue.init(); + + expect(this.sidebarMoveIssue.initDropdown).toHaveBeenCalled(); + expect(this.sidebarMoveIssue.addEventListeners).toHaveBeenCalled(); + }); + }); + + describe('destroy', () => { + it('should remove the listeners', () => { + spyOn(this.sidebarMoveIssue, 'removeEventListeners'); + + this.sidebarMoveIssue.destroy(); + + expect(this.sidebarMoveIssue.removeEventListeners).toHaveBeenCalled(); + }); + }); + + describe('initDropdown', () => { + it('should initialize the gl_dropdown', () => { + spyOn($.fn, 'glDropdown'); + + this.sidebarMoveIssue.initDropdown(); + + expect($.fn.glDropdown).toHaveBeenCalled(); + }); + }); + + describe('onConfirmClicked', () => { + it('should move the issue with valid project ID', () => { + spyOn(this.mediator, 'moveIssue').and.returnValue(Promise.resolve()); + this.mediator.setMoveToProjectId(7); + + this.sidebarMoveIssue.onConfirmClicked(); + + expect(this.mediator.moveIssue).toHaveBeenCalled(); + expect(this.$confirmButton.attr('disabled')).toBe('disabled'); + expect(this.$confirmButton.hasClass('is-loading')).toBe(true); + }); + + it('should remove loading state from confirm button on failure', (done) => { + spyOn(window, 'Flash'); + spyOn(this.mediator, 'moveIssue').and.returnValue(Promise.reject()); + this.mediator.setMoveToProjectId(7); + + this.sidebarMoveIssue.onConfirmClicked(); + + expect(this.mediator.moveIssue).toHaveBeenCalled(); + // Wait for the move issue request to fail + setTimeout(() => { + expect(window.Flash).toHaveBeenCalled(); + expect(this.$confirmButton.attr('disabled')).toBe(undefined); + expect(this.$confirmButton.hasClass('is-loading')).toBe(false); + done(); + }); + }); + + it('should not move the issue with id=0', () => { + spyOn(this.mediator, 'moveIssue'); + this.mediator.setMoveToProjectId(0); + + this.sidebarMoveIssue.onConfirmClicked(); + + expect(this.mediator.moveIssue).not.toHaveBeenCalled(); + }); + }); + + it('should set moveToProjectId on dropdown item "No project" click', (done) => { + spyOn(this.mediator, 'setMoveToProjectId'); + + // Open the dropdown + this.$toggleButton.dropdown('toggle'); + + // Wait for the autocomplete request to finish + setTimeout(() => { + this.$content.find('.js-move-issue-dropdown-item').eq(0).trigger('click'); + + expect(this.mediator.setMoveToProjectId).toHaveBeenCalledWith(0); + expect(this.$confirmButton.attr('disabled')).toBe('disabled'); + done(); + }, 0); + }); + + it('should set moveToProjectId on dropdown item click', (done) => { + spyOn(this.mediator, 'setMoveToProjectId'); + + // Open the dropdown + this.$toggleButton.dropdown('toggle'); + + // Wait for the autocomplete request to finish + setTimeout(() => { + this.$content.find('.js-move-issue-dropdown-item').eq(1).trigger('click'); + + expect(this.mediator.setMoveToProjectId).toHaveBeenCalledWith(20); + expect(this.$confirmButton.attr('disabled')).toBe(undefined); + done(); + }, 0); + }); +}); diff --git a/spec/javascripts/sidebar/sidebar_service_spec.js b/spec/javascripts/sidebar/sidebar_service_spec.js index 91a4dd669a7..a4bd8ba8d88 100644 --- a/spec/javascripts/sidebar/sidebar_service_spec.js +++ b/spec/javascripts/sidebar/sidebar_service_spec.js @@ -5,7 +5,11 @@ import Mock from './mock_data'; describe('Sidebar service', () => { beforeEach(() => { Vue.http.interceptors.push(Mock.sidebarMockInterceptor); - this.service = new SidebarService('/gitlab-org/gitlab-shell/issues/5.json'); + this.service = new SidebarService({ + endpoint: '/gitlab-org/gitlab-shell/issues/5.json', + moveIssueEndpoint: '/gitlab-org/gitlab-shell/issues/5/move', + projectsAutocompleteEndpoint: '/autocomplete/projects?project_id=15', + }); }); afterEach(() => { @@ -19,7 +23,7 @@ describe('Sidebar service', () => { expect(resp).toBeDefined(); done(); }) - .catch(() => {}); + .catch(done.fail); }); it('updates the data', (done) => { @@ -28,6 +32,24 @@ describe('Sidebar service', () => { expect(resp).toBeDefined(); done(); }) - .catch(() => {}); + .catch(done.fail); + }); + + it('gets projects for autocomplete', (done) => { + this.service.getProjectsAutocomplete() + .then((resp) => { + expect(resp).toBeDefined(); + done(); + }) + .catch(done.fail); + }); + + it('moves the issue to another project', (done) => { + this.service.moveIssue(123) + .then((resp) => { + expect(resp).toBeDefined(); + done(); + }) + .catch(done.fail); }); }); diff --git a/spec/javascripts/sidebar/sidebar_store_spec.js b/spec/javascripts/sidebar/sidebar_store_spec.js index b3fa156eb64..69eb3839d67 100644 --- a/spec/javascripts/sidebar/sidebar_store_spec.js +++ b/spec/javascripts/sidebar/sidebar_store_spec.js @@ -82,4 +82,18 @@ describe('Sidebar store', () => { expect(this.store.humanTimeEstimate).toEqual(Mock.time.human_time_estimate); expect(this.store.humanTotalTimeSpent).toEqual(Mock.time.human_total_time_spent); }); + + it('set autocomplete projects', () => { + const projects = [{ id: 0 }]; + this.store.setAutocompleteProjects(projects); + + expect(this.store.autocompleteProjects).toEqual(projects); + }); + + it('set move to project ID', () => { + const projectId = 7; + this.store.setMoveToProjectId(projectId); + + expect(this.store.moveToProjectId).toEqual(projectId); + }); }); |