summaryrefslogtreecommitdiff
path: root/spec/javascripts/sidebar
diff options
context:
space:
mode:
authorEric Eastwood <contact@ericeastwood.com>2017-08-14 02:26:19 -0500
committerEric Eastwood <contact@ericeastwood.com>2017-09-03 22:03:17 -0500
commit90c60138db4e1f86026aac5760febe4ba066ca30 (patch)
treed08764bc1f19556a528bd43f5cc932fa552e7198 /spec/javascripts/sidebar
parenta3af683045e0170d975eab2562a466f88d2692b8 (diff)
downloadgitlab-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.js41
-rw-r--r--spec/javascripts/sidebar/sidebar_mediator_spec.js40
-rw-r--r--spec/javascripts/sidebar/sidebar_move_issue_spec.js142
-rw-r--r--spec/javascripts/sidebar/sidebar_service_spec.js28
-rw-r--r--spec/javascripts/sidebar/sidebar_store_spec.js14
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);
+ });
});