diff options
-rw-r--r-- | app/assets/javascripts/project_label_subscription.js | 11 | ||||
-rw-r--r-- | app/assets/javascripts/prometheus_metrics/prometheus_metrics.js | 17 | ||||
-rw-r--r-- | app/assets/javascripts/protected_branches/protected_branch_edit.js | 40 | ||||
-rw-r--r-- | app/assets/javascripts/protected_tags/protected_tag_edit.js | 31 | ||||
-rw-r--r-- | app/assets/javascripts/right_sidebar.js | 31 | ||||
-rw-r--r-- | app/assets/javascripts/shortcuts.js | 27 | ||||
-rw-r--r-- | app/assets/javascripts/task_list.js | 18 | ||||
-rw-r--r-- | app/assets/javascripts/users/user_tabs.js | 33 | ||||
-rw-r--r-- | app/assets/javascripts/users_select.js | 98 | ||||
-rw-r--r-- | spec/javascripts/collapsed_sidebar_todo_spec.js | 139 | ||||
-rw-r--r-- | spec/javascripts/issue_spec.js | 17 | ||||
-rw-r--r-- | spec/javascripts/merge_request_spec.js | 28 | ||||
-rw-r--r-- | spec/javascripts/notes_spec.js | 26 | ||||
-rw-r--r-- | spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js | 44 | ||||
-rw-r--r-- | spec/javascripts/right_sidebar_spec.js | 26 |
15 files changed, 313 insertions, 273 deletions
diff --git a/app/assets/javascripts/project_label_subscription.js b/app/assets/javascripts/project_label_subscription.js index b65521b278f..64b7dd540f9 100644 --- a/app/assets/javascripts/project_label_subscription.js +++ b/app/assets/javascripts/project_label_subscription.js @@ -1,3 +1,7 @@ +import { __ } from './locale'; +import axios from './lib/utils/axios_utils'; +import flash from './flash'; + export default class ProjectLabelSubscription { constructor(container) { this.$container = $(container); @@ -17,10 +21,7 @@ export default class ProjectLabelSubscription { $btn.addClass('disabled'); $span.toggleClass('hidden'); - $.ajax({ - type: 'POST', - url, - }).done(() => { + axios.post(url).then(() => { let newStatus; let newAction; @@ -45,6 +46,6 @@ export default class ProjectLabelSubscription { return button; }); - }); + }).catch(() => flash(__('There was an error subscribing to this label.'))); } } diff --git a/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js b/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js index 55c93923cc8..59ad5b45855 100644 --- a/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js +++ b/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js @@ -1,3 +1,4 @@ +import axios from '../lib/utils/axios_utils'; import PANEL_STATE from './constants'; import { backOff } from '../lib/utils/common_utils'; @@ -81,24 +82,20 @@ export default class PrometheusMetrics { loadActiveMetrics() { this.showMonitoringMetricsPanelState(PANEL_STATE.LOADING); backOff((next, stop) => { - $.ajax({ - url: this.activeMetricsEndpoint, - dataType: 'json', - global: false, - }) - .done((res) => { - if (res && res.success) { - stop(res); + axios.get(this.activeMetricsEndpoint) + .then(({ data }) => { + if (data && data.success) { + stop(data); } else { this.backOffRequestCounter = this.backOffRequestCounter += 1; if (this.backOffRequestCounter < 3) { next(); } else { - stop(res); + stop(data); } } }) - .fail(stop); + .catch(stop); }) .then((res) => { if (res && res.data && res.data.length) { diff --git a/app/assets/javascripts/protected_branches/protected_branch_edit.js b/app/assets/javascripts/protected_branches/protected_branch_edit.js index 632625da8e7..b51b3e9a6ff 100644 --- a/app/assets/javascripts/protected_branches/protected_branch_edit.js +++ b/app/assets/javascripts/protected_branches/protected_branch_edit.js @@ -1,5 +1,5 @@ -/* eslint-disable no-new */ -import Flash from '../flash'; +import flash from '../flash'; +import axios from '../lib/utils/axios_utils'; import ProtectedBranchAccessDropdown from './protected_branch_access_dropdown'; export default class ProtectedBranchEdit { @@ -38,29 +38,25 @@ export default class ProtectedBranchEdit { this.$allowedToMergeDropdown.disable(); this.$allowedToPushDropdown.disable(); - $.ajax({ - type: 'POST', - url: this.$wrap.data('url'), - dataType: 'json', - data: { - _method: 'PATCH', - protected_branch: { - merge_access_levels_attributes: [{ - id: this.$allowedToMergeDropdown.data('access-level-id'), - access_level: $allowedToMergeInput.val(), - }], - push_access_levels_attributes: [{ - id: this.$allowedToPushDropdown.data('access-level-id'), - access_level: $allowedToPushInput.val(), - }], - }, + axios.patch(this.$wrap.data('url'), { + protected_branch: { + merge_access_levels_attributes: [{ + id: this.$allowedToMergeDropdown.data('access-level-id'), + access_level: $allowedToMergeInput.val(), + }], + push_access_levels_attributes: [{ + id: this.$allowedToPushDropdown.data('access-level-id'), + access_level: $allowedToPushInput.val(), + }], }, - error() { - new Flash('Failed to update branch!', 'alert', document.querySelector('.js-protected-branches-list')); - }, - }).always(() => { + }).then(() => { + this.$allowedToMergeDropdown.enable(); + this.$allowedToPushDropdown.enable(); + }).catch(() => { this.$allowedToMergeDropdown.enable(); this.$allowedToPushDropdown.enable(); + + flash('Failed to update branch!', 'alert', document.querySelector('.js-protected-branches-list')); }); } } diff --git a/app/assets/javascripts/protected_tags/protected_tag_edit.js b/app/assets/javascripts/protected_tags/protected_tag_edit.js index dad0ad25b65..21a258cf93c 100644 --- a/app/assets/javascripts/protected_tags/protected_tag_edit.js +++ b/app/assets/javascripts/protected_tags/protected_tag_edit.js @@ -1,5 +1,5 @@ -/* eslint-disable no-new */ -import Flash from '../flash'; +import flash from '../flash'; +import axios from '../lib/utils/axios_utils'; import ProtectedTagAccessDropdown from './protected_tag_access_dropdown'; export default class ProtectedTagEdit { @@ -28,24 +28,19 @@ export default class ProtectedTagEdit { this.$allowedToCreateDropdownButton.disable(); - $.ajax({ - type: 'POST', - url: this.$wrap.data('url'), - dataType: 'json', - data: { - _method: 'PATCH', - protected_tag: { - create_access_levels_attributes: [{ - id: this.$allowedToCreateDropdownButton.data('access-level-id'), - access_level: $allowedToCreateInput.val(), - }], - }, + axios.patch(this.$wrap.data('url'), { + protected_tag: { + create_access_levels_attributes: [{ + id: this.$allowedToCreateDropdownButton.data('access-level-id'), + access_level: $allowedToCreateInput.val(), + }], }, - error() { - new Flash('Failed to update tag!', 'alert', document.querySelector('.js-protected-tags-list')); - }, - }).always(() => { + }).then(() => { + this.$allowedToCreateDropdownButton.enable(); + }).catch(() => { this.$allowedToCreateDropdownButton.enable(); + + flash('Failed to update tag!', 'alert', document.querySelector('.js-protected-tags-list')); }); } } diff --git a/app/assets/javascripts/right_sidebar.js b/app/assets/javascripts/right_sidebar.js index b830fcf7e80..01c3be5411f 100644 --- a/app/assets/javascripts/right_sidebar.js +++ b/app/assets/javascripts/right_sidebar.js @@ -2,6 +2,8 @@ import _ from 'underscore'; import Cookies from 'js-cookie'; +import flash from './flash'; +import axios from './lib/utils/axios_utils'; function Sidebar(currentUser) { this.toggleTodo = this.toggleTodo.bind(this); @@ -62,7 +64,7 @@ Sidebar.prototype.sidebarToggleClicked = function (e, triggered) { Sidebar.prototype.toggleTodo = function(e) { var $btnText, $this, $todoLoading, ajaxType, url; $this = $(e.currentTarget); - ajaxType = $this.attr('data-delete-path') ? 'DELETE' : 'POST'; + ajaxType = $this.attr('data-delete-path') ? 'delete' : 'post'; if ($this.attr('data-delete-path')) { url = "" + ($this.attr('data-delete-path')); } else { @@ -71,25 +73,14 @@ Sidebar.prototype.toggleTodo = function(e) { $this.tooltip('hide'); - return $.ajax({ - url: url, - type: ajaxType, - dataType: 'json', - data: { - issuable_id: $this.data('issuable-id'), - issuable_type: $this.data('issuable-type') - }, - beforeSend: (function(_this) { - return function() { - $('.js-issuable-todo').disable() - .addClass('is-loading'); - }; - })(this) - }).done((function(_this) { - return function(data) { - return _this.todoUpdateDone(data); - }; - })(this)); + $('.js-issuable-todo').disable().addClass('is-loading'); + + axios[ajaxType](url, { + issuable_id: $this.data('issuable-id'), + issuable_type: $this.data('issuable-type'), + }).then(({ data }) => { + this.todoUpdateDone(data); + }).catch(() => flash(`There was an error ${ajaxType === 'post' ? 'adding a' : 'deleting the'} todo.`)); }; Sidebar.prototype.todoUpdateDone = function(data) { diff --git a/app/assets/javascripts/shortcuts.js b/app/assets/javascripts/shortcuts.js index cd5ab53eace..c5dddd001bb 100644 --- a/app/assets/javascripts/shortcuts.js +++ b/app/assets/javascripts/shortcuts.js @@ -1,5 +1,6 @@ import Cookies from 'js-cookie'; import Mousetrap from 'mousetrap'; +import axios from './lib/utils/axios_utils'; import { refreshCurrentPage, visitUrl } from './lib/utils/url_utility'; import findAndFollowLink from './shortcuts_dashboard_navigation'; @@ -85,21 +86,21 @@ export default class Shortcuts { $modal.modal('toggle'); } - $.ajax({ - url: gon.shortcuts_path, - dataType: 'script', - success() { - if (location && location.length > 0) { - const results = []; - for (let i = 0, len = location.length; i < len; i += 1) { - results.push($(location[i]).show()); - } - return results; + return axios.get(gon.shortcuts_path, { + responseType: 'text', + }).then(({ data }) => { + $.globalEval(data); + + if (location && location.length > 0) { + const results = []; + for (let i = 0, len = location.length; i < len; i += 1) { + results.push($(location[i]).show()); } + return results; + } - $('.hidden-shortcut').show(); - return $('.js-more-help-button').remove(); - }, + $('.hidden-shortcut').show(); + return $('.js-more-help-button').remove(); }); } diff --git a/app/assets/javascripts/task_list.js b/app/assets/javascripts/task_list.js index dcbec40c79e..129a551cbcd 100644 --- a/app/assets/javascripts/task_list.js +++ b/app/assets/javascripts/task_list.js @@ -1,4 +1,5 @@ import 'deckar01-task_list'; +import axios from './lib/utils/axios_utils'; import Flash from './flash'; export default class TaskList { @@ -7,11 +8,11 @@ export default class TaskList { this.dataType = options.dataType; this.fieldName = options.fieldName; this.onSuccess = options.onSuccess || (() => {}); - this.onError = function showFlash(response) { + this.onError = function showFlash(e) { let errorMessages = ''; - if (response.responseJSON) { - errorMessages = response.responseJSON.errors.join(' '); + if (e.response.data && typeof e.response.data === 'object') { + errorMessages = e.response.data.errors.join(' '); } return new Flash(errorMessages || 'Update failed', 'alert'); @@ -38,12 +39,9 @@ export default class TaskList { patchData[this.dataType] = { [this.fieldName]: $target.val(), }; - return $.ajax({ - type: 'PATCH', - url: $target.data('update-url') || $('form.js-issuable-update').attr('action'), - data: patchData, - success: this.onSuccess, - error: this.onError, - }); + + return axios.patch($target.data('update-url') || $('form.js-issuable-update').attr('action'), patchData) + .then(({ data }) => this.onSuccess(data)) + .catch(err => this.onError(err)); } } diff --git a/app/assets/javascripts/users/user_tabs.js b/app/assets/javascripts/users/user_tabs.js index 992baa9a1ef..e13b9839a20 100644 --- a/app/assets/javascripts/users/user_tabs.js +++ b/app/assets/javascripts/users/user_tabs.js @@ -1,6 +1,9 @@ +import axios from '../lib/utils/axios_utils'; import Activities from '../activities'; import ActivityCalendar from './activity_calendar'; import { localTimeAgo } from '../lib/utils/datetime_utility'; +import { __ } from '../locale'; +import flash from '../flash'; /** * UserTabs @@ -131,18 +134,20 @@ export default class UserTabs { } loadTab(action, endpoint) { - return $.ajax({ - beforeSend: () => this.toggleLoading(true), - complete: () => this.toggleLoading(false), - dataType: 'json', - url: endpoint, - success: (data) => { + this.toggleLoading(true); + + return axios.get(endpoint) + .then(({ data }) => { const tabSelector = `div#${action}`; this.$parentEl.find(tabSelector).html(data.html); this.loaded[action] = true; localTimeAgo($('.js-timeago', tabSelector)); - }, - }); + + this.toggleLoading(false); + }) + .catch(() => { + this.toggleLoading(false); + }); } loadActivities() { @@ -158,17 +163,15 @@ export default class UserTabs { utcFormatted = `UTC${utcOffset > 0 ? '+' : ''}${(utcOffset / 3600)}`; } - $.ajax({ - dataType: 'json', - url: calendarPath, - success: (activityData) => { + axios.get(calendarPath) + .then(({ data }) => { $calendarWrap.html(CALENDAR_TEMPLATE); $calendarWrap.find('.calendar-hint').append(`(Timezone: ${utcFormatted})`); // eslint-disable-next-line no-new - new ActivityCalendar('.js-contrib-calendar', activityData, calendarActivitiesPath, utcOffset); - }, - }); + new ActivityCalendar('.js-contrib-calendar', data, calendarActivitiesPath, utcOffset); + }) + .catch(() => flash(__('There was an error loading users activity calendar.'))); // eslint-disable-next-line no-new new Activities(); diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index ab108906732..eaed81cf79e 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -2,6 +2,7 @@ /* global Issuable */ /* global emitSidebarEvent */ import _ from 'underscore'; +import axios from './lib/utils/axios_utils'; // TODO: remove eventHub hack after code splitting refactor window.emitSidebarEvent = window.emitSidebarEvent || $.noop; @@ -177,32 +178,28 @@ function UsersSelect(currentUser, els, options = {}) { $loading.removeClass('hidden').fadeIn(); $dropdown.trigger('loading.gl.dropdown'); - return $.ajax({ - type: 'PUT', - dataType: 'json', - url: issueURL, - data: data - }).done(function(data) { - var user; - $dropdown.trigger('loaded.gl.dropdown'); - $loading.fadeOut(); - if (data.assignee) { - user = { - name: data.assignee.name, - username: data.assignee.username, - avatar: data.assignee.avatar_url - }; - } else { - user = { - name: 'Unassigned', - username: '', - avatar: '' - }; - } - $value.html(assigneeTemplate(user)); - $collapsedSidebar.attr('title', _.escape(user.name)).tooltip('fixTitle'); - return $collapsedSidebar.html(collapsedAssigneeTemplate(user)); - }); + return axios.put(issueURL, data) + .then(({ data }) => { + var user; + $dropdown.trigger('loaded.gl.dropdown'); + $loading.fadeOut(); + if (data.assignee) { + user = { + name: data.assignee.name, + username: data.assignee.username, + avatar: data.assignee.avatar_url + }; + } else { + user = { + name: 'Unassigned', + username: '', + avatar: '' + }; + } + $value.html(assigneeTemplate(user)); + $collapsedSidebar.attr('title', _.escape(user.name)).tooltip('fixTitle'); + return $collapsedSidebar.html(collapsedAssigneeTemplate(user)); + }); }; collapsedAssigneeTemplate = _.template('<% if( avatar ) { %> <a class="author_link" href="/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> </a> <% } else { %> <i class="fa fa-user"></i> <% } %>'); assigneeTemplate = _.template('<% if (username) { %> <a class="author_link bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="avatar avatar-inline s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> No assignee - <a href="#" class="js-assign-yourself"> assign yourself </a> </span> <% } %>'); @@ -660,38 +657,33 @@ UsersSelect.prototype.user = function(user_id, callback) { var url; url = this.buildUrl(this.userPath); url = url.replace(':id', user_id); - return $.ajax({ - url: url, - dataType: "json" - }).done(function(user) { - return callback(user); - }); + return axios.get(url) + .then(({ data }) => { + callback(data); + }); }; // Return users list. Filtered by query // Only active users retrieved UsersSelect.prototype.users = function(query, options, callback) { - var url; - url = this.buildUrl(this.usersPath); - return $.ajax({ - url: url, - data: { - search: query, - per_page: options.perPage || 20, - active: true, - project_id: options.projectId || null, - group_id: options.groupId || null, - skip_ldap: options.skipLdap || null, - todo_filter: options.todoFilter || null, - todo_state_filter: options.todoStateFilter || null, - current_user: options.showCurrentUser || null, - author_id: options.authorId || null, - skip_users: options.skipUsers || null - }, - dataType: "json" - }).done(function(users) { - return callback(users); - }); + const url = this.buildUrl(this.usersPath); + const params = { + search: query, + per_page: options.perPage || 20, + active: true, + project_id: options.projectId || null, + group_id: options.groupId || null, + skip_ldap: options.skipLdap || null, + todo_filter: options.todoFilter || null, + todo_state_filter: options.todoStateFilter || null, + current_user: options.showCurrentUser || null, + author_id: options.authorId || null, + skip_users: options.skipUsers || null + }; + return axios.get(url, { params }) + .then(({ data }) => { + callback(data); + }); }; UsersSelect.prototype.buildUrl = function(url) { diff --git a/spec/javascripts/collapsed_sidebar_todo_spec.js b/spec/javascripts/collapsed_sidebar_todo_spec.js index 5026eaafaca..2abf52a1676 100644 --- a/spec/javascripts/collapsed_sidebar_todo_spec.js +++ b/spec/javascripts/collapsed_sidebar_todo_spec.js @@ -1,10 +1,14 @@ /* eslint-disable no-new */ import _ from 'underscore'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import Sidebar from '~/right_sidebar'; +import timeoutPromise from './helpers/set_timeout_promise_helper'; describe('Issuable right sidebar collapsed todo toggle', () => { const fixtureName = 'issues/open-issue.html.raw'; const jsonFixtureName = 'todos/todos.json'; + let mock; preloadFixtures(fixtureName); preloadFixtures(jsonFixtureName); @@ -19,19 +23,26 @@ describe('Issuable right sidebar collapsed todo toggle', () => { document.querySelector('.js-right-sidebar') .classList.toggle('right-sidebar-collapsed'); - spyOn(jQuery, 'ajax').and.callFake((res) => { - const d = $.Deferred(); + mock = new MockAdapter(axios); + + mock.onPost(`${gl.TEST_HOST}/frontend-fixtures/issues-project/todos`).reply(() => { const response = _.clone(todoData); - if (res.type === 'DELETE') { - delete response.delete_path; - } + return [200, response]; + }); - d.resolve(response); - return d.promise(); + mock.onDelete(/(.*)\/dashboard\/todos\/\d+$/).reply(() => { + const response = _.clone(todoData); + delete response.delete_path; + + return [200, response]; }); }); + afterEach(() => { + mock.restore(); + }); + it('shows add todo button', () => { expect( document.querySelector('.js-issuable-todo.sidebar-collapsed-icon'), @@ -52,71 +63,101 @@ describe('Issuable right sidebar collapsed todo toggle', () => { ).toBe('Add todo'); }); - it('toggle todo state', () => { + it('toggle todo state', (done) => { document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); - expect( - document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'), - ).not.toBeNull(); + setTimeout(() => { + expect( + document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'), + ).not.toBeNull(); - expect( - document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .fa-check-square'), - ).not.toBeNull(); - }); + expect( + document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .fa-check-square'), + ).not.toBeNull(); - it('toggle todo state of expanded todo toggle', () => { - document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); - - expect( - document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(), - ).toBe('Mark done'); + done(); + }); }); - it('toggles todo button tooltip', () => { + it('toggle todo state of expanded todo toggle', (done) => { document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); - expect( - document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('data-original-title'), - ).toBe('Mark done'); - }); - - it('marks todo as done', () => { - document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); + setTimeout(() => { + expect( + document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(), + ).toBe('Mark done'); - expect( - document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'), - ).not.toBeNull(); + done(); + }); + }); + it('toggles todo button tooltip', (done) => { document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); - expect( - document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'), - ).toBeNull(); + setTimeout(() => { + expect( + document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('data-original-title'), + ).toBe('Mark done'); - expect( - document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(), - ).toBe('Add todo'); + done(); + }); }); - it('updates aria-label to mark done', () => { + it('marks todo as done', (done) => { document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); - expect( - document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'), - ).toBe('Mark done'); + timeoutPromise() + .then(() => { + expect( + document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'), + ).not.toBeNull(); + + document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); + }) + .then(timeoutPromise) + .then(() => { + expect( + document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'), + ).toBeNull(); + + expect( + document.querySelector('.issuable-sidebar-header .js-issuable-todo').textContent.trim(), + ).toBe('Add todo'); + }) + .then(done) + .catch(done.fail); }); - it('updates aria-label to add todo', () => { + it('updates aria-label to mark done', (done) => { document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); - expect( - document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'), - ).toBe('Mark done'); + setTimeout(() => { + expect( + document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'), + ).toBe('Mark done'); + done(); + }); + }); + + it('updates aria-label to add todo', (done) => { document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); - expect( - document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'), - ).toBe('Add todo'); + timeoutPromise() + .then(() => { + expect( + document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'), + ).toBe('Mark done'); + + document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click(); + }) + .then(timeoutPromise) + .then(() => { + expect( + document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'), + ).toBe('Add todo'); + }) + .then(done) + .catch(done.fail); }); }); diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js index 5245bf6455c..177962ecf82 100644 --- a/spec/javascripts/issue_spec.js +++ b/spec/javascripts/issue_spec.js @@ -70,23 +70,6 @@ describe('Issue', function() { expect($btn).toHaveText(isIssueInitiallyOpen ? 'Close issue' : 'Reopen issue'); } - describe('task lists', function() { - beforeEach(function() { - loadFixtures('issues/issue-with-task-list.html.raw'); - this.issue = new Issue(); - }); - - it('submits an ajax request on tasklist:changed', function() { - spyOn(jQuery, 'ajax').and.callFake(function(req) { - expect(req.type).toBe('PATCH'); - expect(req.url).toBe(gl.TEST_HOST + '/frontend-fixtures/issues-project/issues/1.json'); // eslint-disable-line prefer-template - expect(req.data.issue.description).not.toBe(null); - }); - - $('.js-task-list-field').trigger('tasklist:changed'); - }); - }); - [true, false].forEach((isIssueInitiallyOpen) => { describe(`with ${isIssueInitiallyOpen ? 'open' : 'closed'} issue`, function() { const action = isIssueInitiallyOpen ? 'close' : 'reopen'; diff --git a/spec/javascripts/merge_request_spec.js b/spec/javascripts/merge_request_spec.js index bae3219b043..bdfd16ac995 100644 --- a/spec/javascripts/merge_request_spec.js +++ b/spec/javascripts/merge_request_spec.js @@ -1,5 +1,6 @@ /* eslint-disable space-before-function-paren, no-return-assign */ - +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import MergeRequest from '~/merge_request'; import CloseReopenReportToggle from '~/close_reopen_report_toggle'; import IssuablesHelper from '~/helpers/issuables_helper'; @@ -7,11 +8,24 @@ import IssuablesHelper from '~/helpers/issuables_helper'; (function() { describe('MergeRequest', function() { describe('task lists', function() { + let mock; + preloadFixtures('merge_requests/merge_request_with_task_list.html.raw'); beforeEach(function() { loadFixtures('merge_requests/merge_request_with_task_list.html.raw'); + + spyOn(axios, 'patch').and.callThrough(); + mock = new MockAdapter(axios); + + mock.onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`).reply(200, {}); + return this.merge = new MergeRequest(); }); + + afterEach(() => { + mock.restore(); + }); + it('modifies the Markdown field', function() { spyOn(jQuery, 'ajax').and.stub(); const changeEvent = document.createEvent('HTMLEvents'); @@ -21,14 +35,14 @@ import IssuablesHelper from '~/helpers/issuables_helper'; }); it('submits an ajax request on tasklist:changed', (done) => { - spyOn(jQuery, 'ajax').and.callFake((req) => { - expect(req.type).toBe('PATCH'); - expect(req.url).toBe(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`); - expect(req.data.merge_request.description).not.toBe(null); + $('.js-task-list-field').trigger('tasklist:changed'); + + setTimeout(() => { + expect(axios.patch).toHaveBeenCalledWith(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`, { + merge_request: { description: '- [ ] Task List Item' }, + }); done(); }); - - $('.js-task-list-field').trigger('tasklist:changed'); }); }); diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index 2fb385bd79f..274d7591c71 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -50,13 +50,24 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; }); describe('task lists', function() { + let mock; + beforeEach(function() { + spyOn(axios, 'patch').and.callThrough(); + mock = new MockAdapter(axios); + + mock.onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`).reply(200, {}); + $('.js-comment-button').on('click', function(e) { e.preventDefault(); }); this.notes = new Notes('', []); }); + afterEach(() => { + mock.restore(); + }); + it('modifies the Markdown field', function() { const changeEvent = document.createEvent('HTMLEvents'); changeEvent.initEvent('change', true, true); @@ -65,14 +76,15 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; expect($('.js-task-list-field.original-task-list').val()).toBe('- [x] Task List Item'); }); - it('submits an ajax request on tasklist:changed', function() { - spyOn(jQuery, 'ajax').and.callFake(function(req) { - expect(req.type).toBe('PATCH'); - expect(req.url).toBe('http://test.host/frontend-fixtures/merge-requests-project/merge_requests/1.json'); - return expect(req.data.note).not.toBe(null); - }); + it('submits an ajax request on tasklist:changed', function(done) { + $('.js-task-list-container').trigger('tasklist:changed'); - $('.js-task-list-field.js-note-text').trigger('tasklist:changed'); + setTimeout(() => { + expect(axios.patch).toHaveBeenCalledWith(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`, { + note: { note: '' }, + }); + done(); + }); }); }); diff --git a/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js b/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js index b24567ffc0c..f6c0f51cf62 100644 --- a/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js +++ b/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js @@ -1,3 +1,5 @@ +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics'; import PANEL_STATE from '~/prometheus_metrics/constants'; import { metrics, missingVarMetrics } from './mock_data'; @@ -102,25 +104,38 @@ describe('PrometheusMetrics', () => { describe('loadActiveMetrics', () => { let prometheusMetrics; + let mock; + + function mockSuccess() { + mock.onGet(prometheusMetrics.activeMetricsEndpoint).reply(200, { + data: metrics, + success: true, + }); + } + + function mockError() { + mock.onGet(prometheusMetrics.activeMetricsEndpoint).networkError(); + } beforeEach(() => { + spyOn(axios, 'get').and.callThrough(); + prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring'); + + mock = new MockAdapter(axios); + }); + + afterEach(() => { + mock.restore(); }); it('should show loader animation while response is being loaded and hide it when request is complete', (done) => { - const deferred = $.Deferred(); - spyOn($, 'ajax').and.returnValue(deferred.promise()); + mockSuccess(); prometheusMetrics.loadActiveMetrics(); expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeFalsy(); - expect($.ajax).toHaveBeenCalledWith({ - url: prometheusMetrics.activeMetricsEndpoint, - dataType: 'json', - global: false, - }); - - deferred.resolve({ data: metrics, success: true }); + expect(axios.get).toHaveBeenCalledWith(prometheusMetrics.activeMetricsEndpoint); setTimeout(() => { expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeTruthy(); @@ -129,14 +144,10 @@ describe('PrometheusMetrics', () => { }); it('should show empty state if response failed to load', (done) => { - const deferred = $.Deferred(); - spyOn($, 'ajax').and.returnValue(deferred.promise()); - spyOn(prometheusMetrics, 'populateActiveMetrics'); + mockError(); prometheusMetrics.loadActiveMetrics(); - deferred.reject(); - setTimeout(() => { expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeTruthy(); expect(prometheusMetrics.$monitoredMetricsEmpty.hasClass('hidden')).toBeFalsy(); @@ -145,14 +156,11 @@ describe('PrometheusMetrics', () => { }); it('should populate metrics list once response is loaded', (done) => { - const deferred = $.Deferred(); - spyOn($, 'ajax').and.returnValue(deferred.promise()); spyOn(prometheusMetrics, 'populateActiveMetrics'); + mockSuccess(); prometheusMetrics.loadActiveMetrics(); - deferred.resolve({ data: metrics, success: true }); - setTimeout(() => { expect(prometheusMetrics.populateActiveMetrics).toHaveBeenCalledWith(metrics); done(); diff --git a/spec/javascripts/right_sidebar_spec.js b/spec/javascripts/right_sidebar_spec.js index 3267e29585b..35bb630bf5d 100644 --- a/spec/javascripts/right_sidebar_spec.js +++ b/spec/javascripts/right_sidebar_spec.js @@ -1,6 +1,8 @@ /* eslint-disable space-before-function-paren, no-var, one-var, one-var-declaration-per-line, new-parens, no-return-assign, new-cap, vars-on-top, max-len */ +import MockAdapter from 'axios-mock-adapter'; import '~/commons/bootstrap'; +import axios from '~/lib/utils/axios_utils'; import Sidebar from '~/right_sidebar'; (function() { @@ -35,16 +37,23 @@ import Sidebar from '~/right_sidebar'; var fixtureName = 'issues/open-issue.html.raw'; preloadFixtures(fixtureName); loadJSONFixtures('todos/todos.json'); + let mock; beforeEach(function() { loadFixtures(fixtureName); - this.sidebar = new Sidebar; + mock = new MockAdapter(axios); + this.sidebar = new Sidebar(); $aside = $('.right-sidebar'); $page = $('.layout-page'); $icon = $aside.find('i'); $toggle = $aside.find('.js-sidebar-toggle'); return $labelsIcon = $aside.find('.sidebar-collapsed-icon'); }); + + afterEach(() => { + mock.restore(); + }); + it('should expand/collapse the sidebar when arrow is clicked', function() { assertSidebarState('expanded'); $toggle.click(); @@ -63,20 +72,19 @@ import Sidebar from '~/right_sidebar'; return assertSidebarState('collapsed'); }); - it('should broadcast todo:toggle event when add todo clicked', function() { + it('should broadcast todo:toggle event when add todo clicked', function(done) { var todos = getJSONFixture('todos/todos.json'); - spyOn(jQuery, 'ajax').and.callFake(function() { - var d = $.Deferred(); - var response = todos; - d.resolve(response); - return d.promise(); - }); + mock.onPost(/(.*)\/todos$/).reply(200, todos); var todoToggleSpy = spyOnEvent(document, 'todo:toggle'); $('.issuable-sidebar-header .js-issuable-todo').click(); - expect(todoToggleSpy.calls.count()).toEqual(1); + setTimeout(() => { + expect(todoToggleSpy.calls.count()).toEqual(1); + + done(); + }); }); it('should not hide collapsed icons', () => { |