Commit 8b614521 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent f864f8a7
12.6.0-pre 12.7.0-pre
...@@ -14,7 +14,7 @@ module ChatMessage ...@@ -14,7 +14,7 @@ module ChatMessage
obj_attr = HashWithIndifferentAccess.new(obj_attr) obj_attr = HashWithIndifferentAccess.new(obj_attr)
@title = obj_attr[:title] @title = obj_attr[:title]
@wiki_page_url = obj_attr[:url] @wiki_page_url = obj_attr[:url]
@description = obj_attr[:content] @description = obj_attr[:message]
@action = @action =
case obj_attr[:action] case obj_attr[:action]
......
...@@ -21,6 +21,7 @@ module ErrorTracking ...@@ -21,6 +21,7 @@ module ErrorTracking
:project_slug, :project_slug,
:short_id, :short_id,
:status, :status,
:tags,
:title, :title,
:type, :type,
:user_count :user_count
......
---
title: Add tags to sentry detailed error response
merge_request: 22068
author:
type: added
---
title: Add modsecurity_enabled setting to managed ingress
merge_request: 21968
author:
type: added
---
title: Include commit message instead of entire page content in Wiki chat notifications
merge_request: 21722
author: Ville Skyttä
type: changed
...@@ -59,12 +59,6 @@ def subject_starts_with_capital?(subject) ...@@ -59,12 +59,6 @@ def subject_starts_with_capital?(subject)
first_char.upcase == first_char first_char.upcase == first_char
end end
def ce_upstream?
return unless gitlab_danger.ci?
gitlab.mr_labels.any? { |label| label == 'CE upstream' }
end
def too_many_changed_lines?(commit) def too_many_changed_lines?(commit)
commit.diff_parent.stats[:total][:files] > 3 && commit.diff_parent.stats[:total][:files] > 3 &&
lines_changed_in_commit(commit) >= 30 lines_changed_in_commit(commit) >= 30
...@@ -291,11 +285,11 @@ def lint_commits(commits) ...@@ -291,11 +285,11 @@ def lint_commits(commits)
end end
end end
if count_filtered_commits(git.commits) > 10 && !ce_upstream? lint_commits(git.commits)
warn(
if count_filtered_commits(git.commits) > 10
fail(
'This merge request includes more than 10 commits. ' \ 'This merge request includes more than 10 commits. ' \
'Please rebase these commits into a smaller number of commits.' 'Please rebase these commits into a smaller number of commits.'
) )
else
lint_commits(git.commits)
end end
# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddModsecurityEnabledToIngressApplication < ActiveRecord::Migration[5.2]
DOWNTIME = false
def up
add_column :clusters_applications_ingress, :modsecurity_enabled, :boolean
end
def down
remove_column :clusters_applications_ingress, :modsecurity_enabled
end
end
...@@ -1163,6 +1163,7 @@ ActiveRecord::Schema.define(version: 2019_12_18_225624) do ...@@ -1163,6 +1163,7 @@ ActiveRecord::Schema.define(version: 2019_12_18_225624) do
t.text "status_reason" t.text "status_reason"
t.string "external_ip" t.string "external_ip"
t.string "external_hostname" t.string "external_hostname"
t.boolean "modsecurity_enabled"
t.index ["cluster_id"], name: "index_clusters_applications_ingress_on_cluster_id", unique: true t.index ["cluster_id"], name: "index_clusters_applications_ingress_on_cluster_id", unique: true
end end
......
...@@ -31,11 +31,11 @@ export default new MyThing(); ...@@ -31,11 +31,11 @@ export default new MyThing();
export default class MyThing { export default class MyThing {
constructor() { constructor() {
if (!this.prototype.singleton) { if (!MyThing.prototype.singleton) {
this.init(); this.init();
this.prototype.singleton = this; MyThing.prototype.singleton = this;
} }
return this.prototype.singleton; return MyThing.prototype.singleton;
} }
init() { init() {
......
...@@ -26,6 +26,7 @@ module Gitlab ...@@ -26,6 +26,7 @@ module Gitlab
:project_slug, :project_slug,
:short_id, :short_id,
:status, :status,
:tags,
:title, :title,
:type, :type,
:user_count :user_count
......
...@@ -36,6 +36,7 @@ module Sentry ...@@ -36,6 +36,7 @@ module Sentry
id: issue.fetch('id'), id: issue.fetch('id'),
first_seen: issue.fetch('firstSeen', nil), first_seen: issue.fetch('firstSeen', nil),
last_seen: issue.fetch('lastSeen', nil), last_seen: issue.fetch('lastSeen', nil),
tags: extract_tags(issue),
title: issue.fetch('title', nil), title: issue.fetch('title', nil),
type: issue.fetch('type', nil), type: issue.fetch('type', nil),
user_count: issue.fetch('userCount', nil), user_count: issue.fetch('userCount', nil),
...@@ -57,6 +58,13 @@ module Sentry ...@@ -57,6 +58,13 @@ module Sentry
last_release_short_version: issue.dig('lastRelease', 'shortVersion') last_release_short_version: issue.dig('lastRelease', 'shortVersion')
) )
end end
def extract_tags(issue)
{
level: issue.fetch('level', nil),
logger: issue.fetch('logger', nil)
}
end
end end
end end
end end
...@@ -18,6 +18,12 @@ FactoryBot.define do ...@@ -18,6 +18,12 @@ FactoryBot.define do
project_slug { 'project_name' } project_slug { 'project_name' }
short_id { 'ID' } short_id { 'ID' }
status { 'unresolved' } status { 'unresolved' }
tags do
{
level: 'error',
logger: 'rails'
}
end
frequency do frequency do
[ [
[Time.now.to_i, 10] [Time.now.to_i, 10]
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"external_base_url", "external_base_url",
"last_seen", "last_seen",
"message", "message",
"tags",
"type", "type",
"title", "title",
"project_id", "project_id",
...@@ -20,23 +21,38 @@ ...@@ -20,23 +21,38 @@
"last_release_short_version" "last_release_short_version"
], ],
"properties" : { "properties" : {
"id": { "type": "string"}, "id": { "type": "string" },
"first_seen": { "type": "string", "format": "date-time" }, "first_seen": { "type": "string", "format": "date-time" },
"last_seen": { "type": "string", "format": "date-time" }, "last_seen": { "type": "string", "format": "date-time" },
"type": { "type": "string" }, "type": { "type": "string" },
"message": { "type": "string" }, "message": { "type": "string" },
"culprit": { "type": "string" }, "culprit": { "type": "string" },
"count": { "type": "integer"}, "count": { "type": "integer" },
"external_url": { "type": "string" }, "external_url": { "type": "string" },
"external_base_url": { "type": "string" }, "external_base_url": { "type": "string" },
"user_count": { "type": "integer"}, "user_count": { "type": "integer"},
"title": { "type": "string"}, "tags": {
"project_id": { "type": "string"}, "type": "object",
"project_name": { "type": "string"}, "required" : [
"project_slug": { "type": "string"}, "level",
"short_id": { "type": "string"}, "logger"
"status": { "type": "string"}, ],
"frequency": { "type": "array"}, "properties": {
"level": {
"type": "string"
},
"logger": {
"type": "string"
}
}
},
"title": { "type": "string" },
"project_id": { "type": "string" },
"project_name": { "type": "string" },
"project_slug": { "type": "string" },
"short_id": { "type": "string" },
"status": { "type": "string" },
"frequency": { "type": "array" },
"gitlab_issue": { "type": ["string", "null"] }, "gitlab_issue": { "type": ["string", "null"] },
"first_release_last_commit": { "type": ["string", "null"] }, "first_release_last_commit": { "type": ["string", "null"] },
"last_release_last_commit": { "type": ["string", "null"] }, "last_release_last_commit": { "type": ["string", "null"] },
......
import BindInOut from '~/behaviors/bind_in_out';
import ClassSpecHelper from '../helpers/class_spec_helper';
describe('BindInOut', () => {
let testContext;
beforeEach(() => {
testContext = {};
});
describe('constructor', () => {
beforeEach(() => {
testContext.in = {};
testContext.out = {};
testContext.bindInOut = new BindInOut(testContext.in, testContext.out);
});
it('should set .in', () => {
expect(testContext.bindInOut.in).toBe(testContext.in);
});
it('should set .out', () => {
expect(testContext.bindInOut.out).toBe(testContext.out);
});
it('should set .eventWrapper', () => {
expect(testContext.bindInOut.eventWrapper).toEqual({});
});
describe('if .in is an input', () => {
beforeEach(() => {
testContext.bindInOut = new BindInOut({ tagName: 'INPUT' });
});
it('should set .eventType to keyup ', () => {
expect(testContext.bindInOut.eventType).toEqual('keyup');
});
});
describe('if .in is a textarea', () => {
beforeEach(() => {
testContext.bindInOut = new BindInOut({ tagName: 'TEXTAREA' });
});
it('should set .eventType to keyup ', () => {
expect(testContext.bindInOut.eventType).toEqual('keyup');
});
});
describe('if .in is not an input or textarea', () => {
beforeEach(() => {
testContext.bindInOut = new BindInOut({ tagName: 'SELECT' });
});
it('should set .eventType to change ', () => {
expect(testContext.bindInOut.eventType).toEqual('change');
});
});
});
describe('addEvents', () => {
beforeEach(() => {
testContext.in = {
addEventListener: jest.fn(),
};
testContext.bindInOut = new BindInOut(testContext.in);
testContext.addEvents = testContext.bindInOut.addEvents();
});
it('should set .eventWrapper.updateOut', () => {
expect(testContext.bindInOut.eventWrapper.updateOut).toEqual(expect.any(Function));
});
it('should call .addEventListener', () => {
expect(testContext.in.addEventListener).toHaveBeenCalledWith(
testContext.bindInOut.eventType,
testContext.bindInOut.eventWrapper.updateOut,
);
});
it('should return the instance', () => {
expect(testContext.addEvents).toBe(testContext.bindInOut);
});
});
describe('updateOut', () => {
beforeEach(() => {
testContext.in = { value: 'the-value' };
testContext.out = { textContent: 'not-the-value' };
testContext.bindInOut = new BindInOut(testContext.in, testContext.out);
testContext.updateOut = testContext.bindInOut.updateOut();
});
it('should set .out.textContent to .in.value', () => {
expect(testContext.out.textContent).toBe(testContext.in.value);
});
it('should return the instance', () => {
expect(testContext.updateOut).toBe(testContext.bindInOut);
});
});
describe('removeEvents', () => {
beforeEach(() => {
testContext.in = {
removeEventListener: jest.fn(),
};
testContext.updateOut = () => {};
testContext.bindInOut = new BindInOut(testContext.in);
testContext.bindInOut.eventWrapper.updateOut = testContext.updateOut;
testContext.removeEvents = testContext.bindInOut.removeEvents();
});
it('should call .removeEventListener', () => {
expect(testContext.in.removeEventListener).toHaveBeenCalledWith(
testContext.bindInOut.eventType,
testContext.updateOut,
);
});
it('should return the instance', () => {
expect(testContext.removeEvents).toBe(testContext.bindInOut);
});
});
describe('initAll', () => {
beforeEach(() => {
testContext.ins = [0, 1, 2];
testContext.instances = [];
jest.spyOn(document, 'querySelectorAll').mockReturnValue(testContext.ins);
jest.spyOn(Array.prototype, 'map');
jest.spyOn(BindInOut, 'init').mockImplementation(() => {});
testContext.initAll = BindInOut.initAll();
});
ClassSpecHelper.itShouldBeAStaticMethod(BindInOut, 'initAll');
it('should call .querySelectorAll', () => {
expect(document.querySelectorAll).toHaveBeenCalledWith('*[data-bind-in]');
});
it('should call .map', () => {
expect(Array.prototype.map).toHaveBeenCalledWith(expect.any(Function));
});
it('should call .init for each element', () => {
expect(BindInOut.init.mock.calls.length).toEqual(3);
});
it('should return an array of instances', () => {
expect(testContext.initAll).toEqual(expect.any(Array));
});
});
describe('init', () => {
beforeEach(() => {
// eslint-disable-next-line func-names
jest.spyOn(BindInOut.prototype, 'addEvents').mockImplementation(function() {
return this;
});
// eslint-disable-next-line func-names
jest.spyOn(BindInOut.prototype, 'updateOut').mockImplementation(function() {
return this;
});
testContext.init = BindInOut.init({}, {});
});
ClassSpecHelper.itShouldBeAStaticMethod(BindInOut, 'init');
it('should call .addEvents', () => {
expect(BindInOut.prototype.addEvents).toHaveBeenCalled();
});
it('should call .updateOut', () => {
expect(BindInOut.prototype.updateOut).toHaveBeenCalled();
});
describe('if no anOut is provided', () => {
beforeEach(() => {
testContext.anIn = { dataset: { bindIn: 'the-data-bind-in' } };
jest.spyOn(document, 'querySelector').mockImplementation(() => {});
BindInOut.init(testContext.anIn);
});
it('should call .querySelector', () => {
expect(document.querySelector).toHaveBeenCalledWith(
`*[data-bind-out="${testContext.anIn.dataset.bindIn}"]`,
);
});
});
});
});
import $ from 'jquery'; import $ from 'jquery';
import '~/commons/bootstrap'; import '~/commons/bootstrap';
describe('Bootstrap jQuery extensions', function() { describe('Bootstrap jQuery extensions', () => {
describe('disable', function() { describe('disable', () => {
beforeEach(function() { beforeEach(() => {
return setFixtures('<input type="text" />'); setFixtures('<input type="text" />');
}); });
it('adds the disabled attribute', function() { it('adds the disabled attribute', () => {
const $input = $('input').first(); const $input = $('input').first();
$input.disable(); $input.disable();
expect($input).toHaveAttr('disabled', 'disabled'); expect($input).toHaveAttr('disabled', 'disabled');
}); });
return it('adds the disabled class', function() {
it('adds the disabled class', () => {
const $input = $('input').first(); const $input = $('input').first();
$input.disable(); $input.disable();
expect($input).toHaveClass('disabled'); expect($input).toHaveClass('disabled');
}); });
}); });
return describe('enable', function() {
beforeEach(function() { describe('enable', () => {
return setFixtures('<input type="text" disabled="disabled" class="disabled" />'); beforeEach(() => {
setFixtures('<input type="text" disabled="disabled" class="disabled" />');
}); });
it('removes the disabled attribute', function() { it('removes the disabled attribute', () => {
const $input = $('input').first(); const $input = $('input').first();
$input.enable(); $input.enable();
expect($input).not.toHaveAttr('disabled'); expect($input).not.toHaveAttr('disabled');
}); });
return it('removes the disabled class', function() {
it('removes the disabled class', () => {
const $input = $('input').first(); const $input = $('input').first();
$input.enable(); $input.enable();
......
...@@ -15,7 +15,7 @@ describe('branches delete modal', () => { ...@@ -15,7 +15,7 @@ describe('branches delete modal', () => {
</div> </div>
`); `);
$deleteButton = $('.js-delete-branch'); $deleteButton = $('.js-delete-branch');
submitSpy = jasmine.createSpy('submit').and.callFake(event => event.preventDefault()); submitSpy = jest.fn(event => event.preventDefault());
$('#modal-delete-branch form').on('submit', submitSpy); $('#modal-delete-branch form').on('submit', submitSpy);
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new DeleteModal(); new DeleteModal();
......
...@@ -5,7 +5,7 @@ describe('breakpoints', () => { ...@@ -5,7 +5,7 @@ describe('breakpoints', () => {
const size = breakpoints[key]; const size = breakpoints[key];
it(`returns ${key} when larger than ${size}`, () => { it(`returns ${key} when larger than ${size}`, () => {
spyOn(bp, 'windowWidth').and.returnValue(size + 10); jest.spyOn(bp, 'windowWidth').mockReturnValue(size + 10);
expect(bp.getBreakpointSize()).toBe(key); expect(bp.getBreakpointSize()).toBe(key);
}); });
...@@ -13,13 +13,13 @@ describe('breakpoints', () => { ...@@ -13,13 +13,13 @@ describe('breakpoints', () => {
describe('isDesktop', () => { describe('isDesktop', () => {
it('returns true when screen size is medium', () => { it('returns true when screen size is medium', () => {
spyOn(bp, 'windowWidth').and.returnValue(breakpoints.md + 10); jest.spyOn(bp, 'windowWidth').mockReturnValue(breakpoints.md + 10);
expect(bp.isDesktop()).toBe(true); expect(bp.isDesktop()).toBe(true);
}); });
it('returns false when screen size is small', () => { it('returns false when screen size is small', () => {
spyOn(bp, 'windowWidth').and.returnValue(breakpoints.sm + 10); jest.spyOn(bp, 'windowWidth').mockReturnValue(breakpoints.sm + 10);
expect(bp.isDesktop()).toBe(false); expect(bp.isDesktop()).toBe(false);
}); });
......
...@@ -34,10 +34,10 @@ describe('Diff settiings dropdown component', () => { ...@@ -34,10 +34,10 @@ describe('Diff settiings dropdown component', () => {
beforeEach(() => { beforeEach(() => {
actions = { actions = {
setInlineDiffViewType: jasmine.createSpy('setInlineDiffViewType'), setInlineDiffViewType: jest.fn(),
setParallelDiffViewType: jasmine.createSpy('setParallelDiffViewType'), setParallelDiffViewType: jest.fn(),
setRenderTreeList: jasmine.createSpy('setRenderTreeList'), setRenderTreeList: jest.fn(),
setShowWhitespace: jasmine.createSpy('setShowWhitespace'), setShowWhitespace: jest.fn(),
}; };
}); });
...@@ -51,7 +51,7 @@ describe('Diff settiings dropdown component', () => { ...@@ -51,7 +51,7 @@ describe('Diff settiings dropdown component', () => {
vm.find('.js-list-view').trigger('click'); vm.find('.js-list-view').trigger('click');
expect(actions.setRenderTreeList).toHaveBeenCalledWith(jasmine.anything(), false, undefined); expect(actions.setRenderTreeList).toHaveBeenCalledWith(expect.anything(), false, undefined);
}); });
it('tree view button dispatches setRenderTreeList with true', () => { it('tree view button dispatches setRenderTreeList with true', () => {
...@@ -59,7 +59,7 @@ describe('Diff settiings dropdown component', () => { ...@@ -59,7 +59,7 @@ describe('Diff settiings dropdown component', () => {
vm.find('.js-tree-view').trigger('click'); vm.find('.js-tree-view').trigger('click');
expect(actions.setRenderTreeList).toHaveBeenCalledWith(jasmine.anything(), true, undefined); expect(actions.setRenderTreeList).toHaveBeenCalledWith(expect.anything(), true, undefined);
}); });
it('sets list button as active when renderTreeList is false', () => { it('sets list button as active when renderTreeList is false', () => {
...@@ -155,7 +155,7 @@ describe('Diff settiings dropdown component', () => { ...@@ -155,7 +155,7 @@ describe('Diff settiings dropdown component', () => {
checkbox.trigger('change'); checkbox.trigger('change');
expect(actions.setShowWhitespace).toHaveBeenCalledWith( expect(actions.setShowWhitespace).toHaveBeenCalledWith(
jasmine.anything(), expect.anything(),
{ {
showWhitespace: true, showWhitespace: true,
pushState: true, pushState: true,
......
import * as constants from '~/droplab/constants'; import * as constants from '~/droplab/constants';
describe('constants', function() { describe('constants', () => {
describe('DATA_TRIGGER', function() { describe('DATA_TRIGGER', () => {
it('should be `data-dropdown-trigger`', function() { it('should be `data-dropdown-trigger`', () => {
expect(constants.DATA_TRIGGER).toBe('data-dropdown-trigger'); expect(constants.DATA_TRIGGER).toBe('data-dropdown-trigger');
}); });
}); });
describe('DATA_DROPDOWN', function() { describe('DATA_DROPDOWN', () => {
it('should be `data-dropdown`', function() { it('should be `data-dropdown`', () => {
expect(constants.DATA_DROPDOWN).toBe('data-dropdown'); expect(constants.DATA_DROPDOWN).toBe('data-dropdown');
}); });
}); });
describe('SELECTED_CLASS', function() { describe('SELECTED_CLASS', () => {
it('should be `droplab-item-selected`', function() { it('should be `droplab-item-selected`', () => {
expect(constants.SELECTED_CLASS).toBe('droplab-item-selected'); expect(constants.SELECTED_CLASS).toBe('droplab-item-selected');
}); });
}); });
describe('ACTIVE_CLASS', function() { describe('ACTIVE_CLASS', () => {
it('should be `droplab-item-active`', function() { it('should be `droplab-item-active`', () => {
expect(constants.ACTIVE_CLASS).toBe('droplab-item-active'); expect(constants.ACTIVE_CLASS).toBe('droplab-item-active');
}); });
}); });
describe('TEMPLATE_REGEX', function() { describe('TEMPLATE_REGEX', () => {
it('should be a handlebars templating syntax regex', function() { it('should be a handlebars templating syntax regex', () => {
expect(constants.TEMPLATE_REGEX).toEqual(/\{\{(.+?)\}\}/g); expect(constants.TEMPLATE_REGEX).toEqual(/\{\{(.+?)\}\}/g);
}); });
}); });
describe('IGNORE_CLASS', function() { describe('IGNORE_CLASS', () => {
it('should be `droplab-item-ignore`', function() { it('should be `droplab-item-ignore`', () => {
expect(constants.IGNORE_CLASS).toBe('droplab-item-ignore'); expect(constants.IGNORE_CLASS).toBe('droplab-item-ignore');
}); });
}); });
......
...@@ -28,10 +28,10 @@ describe('AjaxFilter', () => { ...@@ -28,10 +28,10 @@ describe('AjaxFilter', () => {
let ajaxSpy; let ajaxSpy;
beforeEach(() => { beforeEach(() => {
spyOn(AjaxCache, 'retrieve').and.callFake(url => ajaxSpy(url)); jest.spyOn(AjaxCache, 'retrieve').mockImplementation(url => ajaxSpy(url));
spyOn(AjaxFilter, '_loadData'); jest.spyOn(AjaxFilter, '_loadData').mockImplementation(() => {});
dummyConfig.onLoadingFinished = jasmine.createSpy('spy'); dummyConfig.onLoadingFinished = jest.fn();
const dynamicList = document.createElement('div'); const dynamicList = document.createElement('div');
dynamicList.dataset.dynamic = true; dynamicList.dataset.dynamic = true;
...@@ -46,7 +46,7 @@ describe('AjaxFilter', () => { ...@@ -46,7 +46,7 @@ describe('AjaxFilter', () => {
AjaxFilter.trigger() AjaxFilter.trigger()
.then(() => { .then(() => {
expect(dummyConfig.onLoadingFinished.calls.count()).toBe(1); expect(dummyConfig.onLoadingFinished.mock.calls.length).toBe(1);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
...@@ -63,7 +63,7 @@ describe('AjaxFilter', () => { ...@@ -63,7 +63,7 @@ describe('AjaxFilter', () => {
.then(done.fail) .then(done.fail)
.catch(error => { .catch(error => {
expect(error).toBe(dummyError); expect(error).toBe(dummyError);
expect(dummyConfig.onLoadingFinished.calls.count()).toBe(0); expect(dummyConfig.onLoadingFinished.mock.calls.length).toBe(0);
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
......
...@@ -18,23 +18,23 @@ describe('Ajax', () => { ...@@ -18,23 +18,23 @@ describe('Ajax', () => {
beforeEach(() => { beforeEach(() => {
config.preprocessing = () => processedArray; config.preprocessing = () => processedArray;
spyOn(config, 'preprocessing').and.callFake(() => processedArray); jest.spyOn(config, 'preprocessing').mockImplementation(() => processedArray);
}); });
it('calls preprocessing', () => { it('calls preprocessing', () => {
Ajax.preprocessing(config, []); Ajax.preprocessing(config, []);
expect(config.preprocessing.calls.count()).toBe(1); expect(config.preprocessing.mock.calls.length).toBe(1);
}); });
it('overrides AjaxCache', () => { it('overrides AjaxCache', () => {
spyOn(AjaxCache, 'override').and.callFake((endpoint, results) => { jest.spyOn(AjaxCache, 'override').mockImplementation((endpoint, results) => {
expect(results).toEqual(processedArray); expect(results).toEqual(processedArray);
}); });
Ajax.preprocessing(config, []); Ajax.preprocessing(config, []);
expect(AjaxCache.override.calls.count()).toBe(1); expect(AjaxCache.override.mock.calls.length).toBe(1);
}); });
}); });
}); });
......
...@@ -4,25 +4,25 @@ import bp from '~/breakpoints'; ...@@ -4,25 +4,25 @@ import bp from '~/breakpoints';
describe('feature highlight options', () => { describe('feature highlight options', () => {
describe('domContentLoaded', () => { describe('domContentLoaded', () => {
it('should not call highlightFeatures when breakpoint is xs', () => { it('should not call highlightFeatures when breakpoint is xs', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('xs'); jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('xs');
expect(domContentLoaded()).toBe(false); expect(domContentLoaded()).toBe(false);
}); });
it('should not call highlightFeatures when breakpoint is sm', () => { it('should not call highlightFeatures when breakpoint is sm', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('sm'); jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('sm');
expect(domContentLoaded()).toBe(false); expect(domContentLoaded()).toBe(false);
}); });
it('should not call highlightFeatures when breakpoint is md', () => { it('should not call highlightFeatures when breakpoint is md', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('md'); jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('md');
expect(domContentLoaded()).toBe(false); expect(domContentLoaded()).toBe(false);
}); });
it('should call highlightFeatures when breakpoint is lg', () => { it('should call highlightFeatures when breakpoint is lg', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('lg'); jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('lg');
expect(domContentLoaded()).toBe(true); expect(domContentLoaded()).toBe(true);
}); });
......
...@@ -158,7 +158,7 @@ describe('RecentSearchesDropdownContent', () => { ...@@ -158,7 +158,7 @@ describe('RecentSearchesDropdownContent', () => {
let onRecentSearchesItemSelectedSpy; let onRecentSearchesItemSelectedSpy;
beforeEach(() => { beforeEach(() => {
onRecentSearchesItemSelectedSpy = jasmine.createSpy('spy'); onRecentSearchesItemSelectedSpy = jest.fn();
eventHub.$on('recentSearchesItemSelected', onRecentSearchesItemSelectedSpy); eventHub.$on('recentSearchesItemSelected', onRecentSearchesItemSelectedSpy);
vm = createComponent(propsDataWithItems); vm = createComponent(propsDataWithItems);
...@@ -180,7 +180,7 @@ describe('RecentSearchesDropdownContent', () => { ...@@ -180,7 +180,7 @@ describe('RecentSearchesDropdownContent', () => {
let onRequestClearRecentSearchesSpy; let onRequestClearRecentSearchesSpy;
beforeEach(() => { beforeEach(() => {
onRequestClearRecentSearchesSpy = jasmine.createSpy('spy'); onRequestClearRecentSearchesSpy = jest.fn();
eventHub.$on('requestClearRecentSearches', onRequestClearRecentSearchesSpy); eventHub.$on('requestClearRecentSearches', onRequestClearRecentSearchesSpy);
vm = createComponent(propsDataWithItems); vm = createComponent(propsDataWithItems);
......
...@@ -8,10 +8,10 @@ describe('Dropdown User', () => { ...@@ -8,10 +8,10 @@ describe('Dropdown User', () => {
let dropdownUser; let dropdownUser;
beforeEach(() => { beforeEach(() => {
spyOn(DropdownUser.prototype, 'bindEvents').and.callFake(() => {}); jest.spyOn(DropdownUser.prototype, 'bindEvents').mockImplementation(() => {});
spyOn(DropdownUser.prototype, 'getProjectId').and.callFake(() => {}); jest.spyOn(DropdownUser.prototype, 'getProjectId').mockImplementation(() => {});
spyOn(DropdownUser.prototype, 'getGroupId').and.callFake(() => {}); jest.spyOn(DropdownUser.prototype, 'getGroupId').mockImplementation(() => {});
spyOn(DropdownUtils, 'getSearchInput').and.callFake(() => {}); jest.spyOn(DropdownUtils, 'getSearchInput').mockImplementation(() => {});
dropdownUser = new DropdownUser({ dropdownUser = new DropdownUser({
tokenKeys: IssuableFilteredTokenKeys, tokenKeys: IssuableFilteredTokenKeys,
...@@ -19,7 +19,7 @@ describe('Dropdown User', () => { ...@@ -19,7 +19,7 @@ describe('Dropdown User', () => {
}); });
it('should not return the double quote found in value', () => { it('should not return the double quote found in value', () => {
spyOn(FilteredSearchTokenizer, 'processTokens').and.returnValue({ jest.spyOn(FilteredSearchTokenizer, 'processTokens').mockReturnValue({
lastToken: '"johnny appleseed', lastToken: '"johnny appleseed',
}); });
...@@ -27,7 +27,7 @@ describe('Dropdown User', () => { ...@@ -27,7 +27,7 @@ describe('Dropdown User', () => {
}); });
it('should not return the single quote found in value', () => { it('should not return the single quote found in value', () => {
spyOn(FilteredSearchTokenizer, 'processTokens').and.returnValue({ jest.spyOn(FilteredSearchTokenizer, 'processTokens').mockReturnValue({
lastToken: "'larry boy", lastToken: "'larry boy",
}); });
...@@ -37,9 +37,9 @@ describe('Dropdown User', () => { ...@@ -37,9 +37,9 @@ describe('Dropdown User', () => {
describe("config AjaxFilter's endpoint", () => { describe("config AjaxFilter's endpoint", () => {
beforeEach(() => { beforeEach(() => {
spyOn(DropdownUser.prototype, 'bindEvents').and.callFake(() => {}); jest.spyOn(DropdownUser.prototype, 'bindEvents').mockImplementation(() => {});
spyOn(DropdownUser.prototype, 'getProjectId').and.callFake(() => {}); jest.spyOn(DropdownUser.prototype, 'getProjectId').mockImplementation(() => {});
spyOn(DropdownUser.prototype, 'getGroupId').and.callFake(() => {}); jest.spyOn(DropdownUser.prototype, 'getGroupId').mockImplementation(() => {});
}); });
it('should return endpoint', () => { it('should return endpoint', () => {
......
...@@ -28,7 +28,7 @@ describe('FrequentItemsSearchInputComponent', () => { ...@@ -28,7 +28,7 @@ describe('FrequentItemsSearchInputComponent', () => {
describe('methods', () => { describe('methods', () => {
describe('setFocus', () => { describe('setFocus', () => {
it('should set focus to search input', () => { it('should set focus to search input', () => {
spyOn(vm.$refs.search, 'focus'); jest.spyOn(vm.$refs.search, 'focus').mockImplementation(() => {});
vm.setFocus(); vm.setFocus();
...@@ -39,13 +39,13 @@ describe('FrequentItemsSearchInputComponent', () => { ...@@ -39,13 +39,13 @@ describe('FrequentItemsSearchInputComponent', () => {
describe('mounted', () => { describe('mounted', () => {
it('should listen `dropdownOpen` event', done => { it('should listen `dropdownOpen` event', done => {
spyOn(eventHub, '$on'); jest.spyOn(eventHub, '$on').mockImplementation(() => {});
const vmX = createComponent().vm; const vmX = createComponent().vm;
localVue.nextTick(() => { localVue.nextTick(() => {
expect(eventHub.$on).toHaveBeenCalledWith( expect(eventHub.$on).toHaveBeenCalledWith(
`${vmX.namespace}-dropdownOpen`, `${vmX.namespace}-dropdownOpen`,
jasmine.any(Function), expect.any(Function),
); );
done(); done();
}); });
...@@ -55,7 +55,7 @@ describe('FrequentItemsSearchInputComponent', () => { ...@@ -55,7 +55,7 @@ describe('FrequentItemsSearchInputComponent', () => {
describe('beforeDestroy', () => { describe('beforeDestroy', () => {
it('should unbind event listeners on eventHub', done => { it('should unbind event listeners on eventHub', done => {
const vmX = createComponent().vm; const vmX = createComponent().vm;
spyOn(eventHub, '$off'); jest.spyOn(eventHub, '$off').mockImplementation(() => {});
vmX.$mount(); vmX.$mount();
vmX.$destroy(); vmX.$destroy();
...@@ -63,7 +63,7 @@ describe('FrequentItemsSearchInputComponent', () => { ...@@ -63,7 +63,7 @@ describe('FrequentItemsSearchInputComponent', () => {
localVue.nextTick(() => { localVue.nextTick(() => {
expect(eventHub.$off).toHaveBeenCalledWith( expect(eventHub.$off).toHaveBeenCalledWith(
`${vmX.namespace}-dropdownOpen`, `${vmX.namespace}-dropdownOpen`,
jasmine.any(Function), expect.any(Function),
); );
done(); done();
}); });
......
...@@ -3,83 +3,89 @@ ...@@ -3,83 +3,89 @@
import $ from 'jquery'; import $ from 'jquery';
import GlFieldErrors from '~/gl_field_errors'; import GlFieldErrors from '~/gl_field_errors';
describe('GL Style Field Errors', function() { describe('GL Style Field Errors', () => {
let testContext;
beforeEach(() => {
testContext = {};
});
preloadFixtures('static/gl_field_errors.html'); preloadFixtures('static/gl_field_errors.html');
beforeEach(function() { beforeEach(() => {
loadFixtures('static/gl_field_errors.html'); loadFixtures('static/gl_field_errors.html');
const $form = $('form.gl-show-field-errors'); const $form = $('form.gl-show-field-errors');
this.$form = $form; testContext.$form = $form;
this.fieldErrors = new GlFieldErrors($form); testContext.fieldErrors = new GlFieldErrors($form);
}); });
it('should select the correct input elements', function() { it('should select the correct input elements', () => {
expect(this.$form).toBeDefined(); expect(testContext.$form).toBeDefined();
expect(this.$form.length).toBe(1); expect(testContext.$form.length).toBe(1);
expect(this.fieldErrors).toBeDefined(); expect(testContext.fieldErrors).toBeDefined();
const { inputs } = this.fieldErrors.state; const { inputs } = testContext.fieldErrors.state;
expect(inputs.length).toBe(4); expect(inputs.length).toBe(4);
}); });
it('should ignore elements with custom error handling', function() { it('should ignore elements with custom error handling', () => {
const customErrorFlag = 'gl-field-error-ignore'; const customErrorFlag = 'gl-field-error-ignore';
const customErrorElem = $(`.${customErrorFlag}`); const customErrorElem = $(`.${customErrorFlag}`);
expect(customErrorElem.length).toBe(1); expect(customErrorElem.length).toBe(1);
const customErrors = this.fieldErrors.state.inputs.filter(input => { const customErrors = testContext.fieldErrors.state.inputs.filter(input => {
return input.inputElement.hasClass(customErrorFlag); return input.inputElement.hasClass(customErrorFlag);
}); });
expect(customErrors.length).toBe(0); expect(customErrors.length).toBe(0);
}); });
it('should not show any errors before submit attempt', function() { it('should not show any errors before submit attempt', () => {
this.$form testContext.$form
.find('.email') .find('.email')
.val('not-a-valid-email') .val('not-a-valid-email')
.keyup(); .keyup();
this.$form testContext.$form
.find('.text-required') .find('.text-required')
.val('') .val('')
.keyup(); .keyup();
this.$form testContext.$form
.find('.alphanumberic') .find('.alphanumberic')
.val('?---*') .val('?---*')
.keyup(); .keyup();
const errorsShown = this.$form.find('.gl-field-error-outline'); const errorsShown = testContext.$form.find('.gl-field-error-outline');
expect(errorsShown.length).toBe(0); expect(errorsShown.length).toBe(0);
}); });
it('should show errors when input valid is submitted', function() { it('should show errors when input valid is submitted', () => {
this.$form testContext.$form
.find('.email') .find('.email')
.val('not-a-valid-email') .val('not-a-valid-email')
.keyup(); .keyup();
this.$form testContext.$form
.find('.text-required') .find('.text-required')
.val('') .val('')
.keyup(); .keyup();
this.$form testContext.$form
.find('.alphanumberic') .find('.alphanumberic')
.val('?---*') .val('?---*')
.keyup(); .keyup();
this.$form.submit(); testContext.$form.submit();
const errorsShown = this.$form.find('.gl-field-error-outline'); const errorsShown = testContext.$form.find('.gl-field-error-outline');
expect(errorsShown.length).toBe(4); expect(errorsShown.length).toBe(4);
}); });
it('should properly track validity state on input after invalid submission attempt', function() { it('should properly track validity state on input after invalid submission attempt', () => {
this.$form.submit(); testContext.$form.submit();
const emailInputModel = this.fieldErrors.state.inputs[1]; const emailInputModel = testContext.fieldErrors.state.inputs[1];
const fieldState = emailInputModel.state; const fieldState = emailInputModel.state;
const emailInputElement = emailInputModel.inputElement; const emailInputElement = emailInputModel.inputElement;
...@@ -124,9 +130,9 @@ describe('GL Style Field Errors', function() { ...@@ -124,9 +130,9 @@ describe('GL Style Field Errors', function() {
expect(fieldState.valid).toBe(true); expect(fieldState.valid).toBe(true);
}); });
it('should properly infer error messages', function() { it('should properly infer error messages', () => {
this.$form.submit(); testContext.$form.submit();
const trackedInputs = this.fieldErrors.state.inputs; const trackedInputs = testContext.fieldErrors.state.inputs;
const inputHasTitle = trackedInputs[1]; const inputHasTitle = trackedInputs[1];
const hasTitleErrorElem = inputHasTitle.inputElement.siblings('.gl-field-error'); const hasTitleErrorElem = inputHasTitle.inputElement.siblings('.gl-field-error');
const inputNoTitle = trackedInputs[2]; const inputNoTitle = trackedInputs[2];
......
...@@ -38,7 +38,7 @@ describe('GpgBadges', () => { ...@@ -38,7 +38,7 @@ describe('GpgBadges', () => {
it('does not make a request if there is no container element', done => { it('does not make a request if there is no container element', done => {
setFixtures(''); setFixtures('');
spyOn(axios, 'get'); jest.spyOn(axios, 'get').mockImplementation(() => {});
GpgBadges.fetch() GpgBadges.fetch()
.then(() => { .then(() => {
...@@ -50,7 +50,7 @@ describe('GpgBadges', () => { ...@@ -50,7 +50,7 @@ describe('GpgBadges', () => {
it('throws an error if the endpoint is missing', done => { it('throws an error if the endpoint is missing', done => {
setFixtures('<div class="js-signature-container"></div>'); setFixtures('<div class="js-signature-container"></div>');
spyOn(axios, 'get'); jest.spyOn(axios, 'get').mockImplementation(() => {});
GpgBadges.fetch() GpgBadges.fetch()
.then(() => done.fail('Expected error to be thrown')) .then(() => done.fail('Expected error to be thrown'))
......
import $ from 'jquery'; import $ from 'jquery';
import initTodoToggle from '~/header'; import initTodoToggle from '~/header';
describe('Header', function() { describe('Header', () => {
const todosPendingCount = '.todos-count'; const todosPendingCount = '.todos-count';
const fixtureTemplate = 'issues/open-issue.html'; const fixtureTemplate = 'issues/open-issue.html';
......
...@@ -2,7 +2,13 @@ ...@@ -2,7 +2,13 @@
import './class_spec_helper'; import './class_spec_helper';
describe('ClassSpecHelper', function() { describe('ClassSpecHelper', () => {
let testContext;
beforeEach(() => {
testContext = {};
});
describe('itShouldBeAStaticMethod', () => { describe('itShouldBeAStaticMethod', () => {
beforeEach(() => { beforeEach(() => {
class TestClass { class TestClass {
...@@ -12,7 +18,7 @@ describe('ClassSpecHelper', function() { ...@@ -12,7 +18,7 @@ describe('ClassSpecHelper', function() {
static staticMethod() {} static staticMethod() {}
} }
this.TestClass = TestClass; testContext.TestClass = TestClass;
}); });
ClassSpecHelper.itShouldBeAStaticMethod(ClassSpecHelper, 'itShouldBeAStaticMethod'); ClassSpecHelper.itShouldBeAStaticMethod(ClassSpecHelper, 'itShouldBeAStaticMethod');
......
...@@ -16,8 +16,8 @@ describe('IDE stage file button', () => { ...@@ -16,8 +16,8 @@ describe('IDE stage file button', () => {
path: f.path, path: f.path,
}); });
spyOn(vm, 'stageChange'); jest.spyOn(vm, 'stageChange').mockImplementation(() => {});
spyOn(vm, 'discardFileChanges'); jest.spyOn(vm, 'discardFileChanges').mockImplementation(() => {});
vm.$mount(); vm.$mount();
}); });
......
...@@ -16,7 +16,7 @@ describe('IDE unstage file button', () => { ...@@ -16,7 +16,7 @@ describe('IDE unstage file button', () => {
path: f.path, path: f.path,
}); });
spyOn(vm, 'unstageChange'); jest.spyOn(vm, 'unstageChange').mockImplementation(() => {});
vm.$mount(); vm.$mount();
}); });
......
...@@ -40,7 +40,7 @@ describe('IDE job log scroll button', () => { ...@@ -40,7 +40,7 @@ describe('IDE job log scroll button', () => {
}); });
it('emits click event on click', () => { it('emits click event on click', () => {
spyOn(vm, '$emit'); jest.spyOn(vm, '$emit').mockImplementation(() => {});
vm.$el.querySelector('.btn-scroll').click(); vm.$el.querySelector('.btn-scroll').click();
......
...@@ -24,7 +24,7 @@ describe('IDE store file actions', () => { ...@@ -24,7 +24,7 @@ describe('IDE store file actions', () => {
relative_url_root: RELATIVE_URL_ROOT, relative_url_root: RELATIVE_URL_ROOT,
}; };
spyOn(router, 'push'); jest.spyOn(router, 'push').mockImplementation(() => {});
}); });
afterEach(() => { afterEach(() => {
...@@ -117,7 +117,7 @@ describe('IDE store file actions', () => { ...@@ -117,7 +117,7 @@ describe('IDE store file actions', () => {
let oldScrollToTab; let oldScrollToTab;
beforeEach(() => { beforeEach(() => {
scrollToTabSpy = jasmine.createSpy('scrollToTab'); scrollToTabSpy = jest.fn();
oldScrollToTab = store._actions.scrollToTab; // eslint-disable-line oldScrollToTab = store._actions.scrollToTab; // eslint-disable-line
store._actions.scrollToTab = [scrollToTabSpy]; // eslint-disable-line store._actions.scrollToTab = [scrollToTabSpy]; // eslint-disable-line
...@@ -131,7 +131,7 @@ describe('IDE store file actions', () => { ...@@ -131,7 +131,7 @@ describe('IDE store file actions', () => {
}); });
it('calls scrollToTab', () => { it('calls scrollToTab', () => {
const dispatch = jasmine.createSpy(); const dispatch = jest.fn();
actions.setFileActive( actions.setFileActive(
{ commit() {}, state: store.state, getters: store.getters, dispatch }, { commit() {}, state: store.state, getters: store.getters, dispatch },
...@@ -142,7 +142,7 @@ describe('IDE store file actions', () => { ...@@ -142,7 +142,7 @@ describe('IDE store file actions', () => {
}); });
it('commits SET_FILE_ACTIVE', () => { it('commits SET_FILE_ACTIVE', () => {
const commit = jasmine.createSpy(); const commit = jest.fn();
actions.setFileActive( actions.setFileActive(
{ commit, state: store.state, getters: store.getters, dispatch() {} }, { commit, state: store.state, getters: store.getters, dispatch() {} },
...@@ -161,7 +161,7 @@ describe('IDE store file actions', () => { ...@@ -161,7 +161,7 @@ describe('IDE store file actions', () => {
localFile.active = true; localFile.active = true;
store.state.openFiles.push(localFile); store.state.openFiles.push(localFile);
const commit = jasmine.createSpy(); const commit = jest.fn();
actions.setFileActive( actions.setFileActive(
{ commit, state: store.state, getters: store.getters, dispatch() {} }, { commit, state: store.state, getters: store.getters, dispatch() {} },
...@@ -179,7 +179,7 @@ describe('IDE store file actions', () => { ...@@ -179,7 +179,7 @@ describe('IDE store file actions', () => {
let localFile; let localFile;
beforeEach(() => { beforeEach(() => {
spyOn(service, 'getFileData').and.callThrough(); jest.spyOn(service, 'getFileData');
localFile = file(`newCreate-${Math.random()}`); localFile = file(`newCreate-${Math.random()}`);
store.state.entries[localFile.path] = localFile; store.state.entries[localFile.path] = localFile;
...@@ -329,7 +329,7 @@ describe('IDE store file actions', () => { ...@@ -329,7 +329,7 @@ describe('IDE store file actions', () => {
}); });
it('dispatches error action', done => { it('dispatches error action', done => {
const dispatch = jasmine.createSpy('dispatch'); const dispatch = jest.fn();
actions actions
.getFileData( .getFileData(
...@@ -339,7 +339,7 @@ describe('IDE store file actions', () => { ...@@ -339,7 +339,7 @@ describe('IDE store file actions', () => {
.then(() => { .then(() => {
expect(dispatch).toHaveBeenCalledWith('setErrorMessage', { expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
text: 'An error occurred whilst loading the file.', text: 'An error occurred whilst loading the file.',
action: jasmine.any(Function), action: expect.any(Function),
actionText: 'Please try again', actionText: 'Please try again',
actionPayload: { actionPayload: {
path: localFile.path, path: localFile.path,
...@@ -358,7 +358,7 @@ describe('IDE store file actions', () => { ...@@ -358,7 +358,7 @@ describe('IDE store file actions', () => {
let tmpFile; let tmpFile;
beforeEach(() => { beforeEach(() => {
spyOn(service, 'getRawFileData').and.callThrough(); jest.spyOn(service, 'getRawFileData');
tmpFile = file('tmpFile'); tmpFile = file('tmpFile');
store.state.entries[tmpFile.path] = tmpFile; store.state.entries[tmpFile.path] = tmpFile;
...@@ -392,7 +392,7 @@ describe('IDE store file actions', () => { ...@@ -392,7 +392,7 @@ describe('IDE store file actions', () => {
}); });
it('calls also getBaseRawFileData service method', done => { it('calls also getBaseRawFileData service method', done => {
spyOn(service, 'getBaseRawFileData').and.returnValue(Promise.resolve('baseraw')); jest.spyOn(service, 'getBaseRawFileData').mockReturnValue(Promise.resolve('baseraw'));
store.state.currentProjectId = 'gitlab-org/gitlab-ce'; store.state.currentProjectId = 'gitlab-org/gitlab-ce';
store.state.currentMergeRequestId = '1'; store.state.currentMergeRequestId = '1';
...@@ -443,7 +443,7 @@ describe('IDE store file actions', () => { ...@@ -443,7 +443,7 @@ describe('IDE store file actions', () => {
}); });
it('dispatches error action', done => { it('dispatches error action', done => {
const dispatch = jasmine.createSpy('dispatch'); const dispatch = jest.fn();
actions actions
.getRawFileData({ state: store.state, commit() {}, dispatch }, { path: tmpFile.path }) .getRawFileData({ state: store.state, commit() {}, dispatch }, { path: tmpFile.path })
...@@ -451,7 +451,7 @@ describe('IDE store file actions', () => { ...@@ -451,7 +451,7 @@ describe('IDE store file actions', () => {
.catch(() => { .catch(() => {
expect(dispatch).toHaveBeenCalledWith('setErrorMessage', { expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
text: 'An error occurred whilst loading the file content.', text: 'An error occurred whilst loading the file content.',
action: jasmine.any(Function), action: expect.any(Function),
actionText: 'Please try again', actionText: 'Please try again',
actionPayload: { actionPayload: {
path: tmpFile.path, path: tmpFile.path,
...@@ -575,8 +575,8 @@ describe('IDE store file actions', () => { ...@@ -575,8 +575,8 @@ describe('IDE store file actions', () => {
let tmpFile; let tmpFile;
beforeEach(() => { beforeEach(() => {
spyOn(eventHub, '$on'); jest.spyOn(eventHub, '$on').mockImplementation(() => {});
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
tmpFile = file(); tmpFile = file();
tmpFile.content = 'testing'; tmpFile.content = 'testing';
...@@ -756,7 +756,7 @@ describe('IDE store file actions', () => { ...@@ -756,7 +756,7 @@ describe('IDE store file actions', () => {
let f; let f;
beforeEach(() => { beforeEach(() => {
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
f = { f = {
...file('pendingFile'), ...file('pendingFile'),
...@@ -789,7 +789,7 @@ describe('IDE store file actions', () => { ...@@ -789,7 +789,7 @@ describe('IDE store file actions', () => {
describe('triggerFilesChange', () => { describe('triggerFilesChange', () => {
beforeEach(() => { beforeEach(() => {
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
}); });
it('emits event that files have changed', done => { it('emits event that files have changed', done => {
......
...@@ -14,8 +14,8 @@ describe('initImageDiff', () => { ...@@ -14,8 +14,8 @@ describe('initImageDiff', () => {
<div class="diff-file"></div> <div class="diff-file"></div>
`; `;
spyOn(ReplacedImageDiff.prototype, 'init').and.callFake(() => {}); jest.spyOn(ReplacedImageDiff.prototype, 'init').mockImplementation(() => {});
spyOn(ImageDiff.prototype, 'init').and.callFake(() => {}); jest.spyOn(ImageDiff.prototype, 'init').mockImplementation(() => {});
}); });
afterEach(() => { afterEach(() => {
......
...@@ -12,29 +12,31 @@ describe('initDiscussionTab', () => { ...@@ -12,29 +12,31 @@ describe('initDiscussionTab', () => {
}); });
it('should pass canCreateNote as false to initImageDiff', done => { it('should pass canCreateNote as false to initImageDiff', done => {
spyOn(initImageDiffHelper, 'initImageDiff').and.callFake((diffFileEl, canCreateNote) => { jest
expect(canCreateNote).toEqual(false); .spyOn(initImageDiffHelper, 'initImageDiff')
done(); .mockImplementation((diffFileEl, canCreateNote) => {
}); expect(canCreateNote).toEqual(false);
done();
});
initDiscussionTab(); initDiscussionTab();
}); });
it('should pass renderCommentBadge as true to initImageDiff', done => { it('should pass renderCommentBadge as true to initImageDiff', done => {
spyOn(initImageDiffHelper, 'initImageDiff').and.callFake( jest
(diffFileEl, canCreateNote, renderCommentBadge) => { .spyOn(initImageDiffHelper, 'initImageDiff')
.mockImplementation((diffFileEl, canCreateNote, renderCommentBadge) => {
expect(renderCommentBadge).toEqual(true); expect(renderCommentBadge).toEqual(true);
done(); done();
}, });
);
initDiscussionTab(); initDiscussionTab();
}); });
it('should call initImageDiff for each diffFileEls', () => { it('should call initImageDiff for each diffFileEls', () => {
spyOn(initImageDiffHelper, 'initImageDiff').and.callFake(() => {}); jest.spyOn(initImageDiffHelper, 'initImageDiff').mockImplementation(() => {});
initDiscussionTab(); initDiscussionTab();
expect(initImageDiffHelper.initImageDiff.calls.count()).toEqual(2); expect(initImageDiffHelper.initImageDiff.mock.calls.length).toEqual(2);
}); });
}); });
...@@ -15,7 +15,7 @@ describe('Edit Actions components', () => { ...@@ -15,7 +15,7 @@ describe('Edit Actions components', () => {
}); });
store.formState.title = 'test'; store.formState.title = 'test';
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
vm = new Component({ vm = new Component({
propsData: { propsData: {
...@@ -101,14 +101,14 @@ describe('Edit Actions components', () => { ...@@ -101,14 +101,14 @@ describe('Edit Actions components', () => {
describe('deleteIssuable', () => { describe('deleteIssuable', () => {
it('sends delete.issuable event when clicking save button', () => { it('sends delete.issuable event when clicking save button', () => {
spyOn(window, 'confirm').and.returnValue(true); jest.spyOn(window, 'confirm').mockReturnValue(true);
vm.$el.querySelector('.btn-danger').click(); vm.$el.querySelector('.btn-danger').click();
expect(eventHub.$emit).toHaveBeenCalledWith('delete.issuable', { destroy_confirm: true }); expect(eventHub.$emit).toHaveBeenCalledWith('delete.issuable', { destroy_confirm: true });
}); });
it('shows loading icon after clicking delete button', done => { it('shows loading icon after clicking delete button', done => {
spyOn(window, 'confirm').and.returnValue(true); jest.spyOn(window, 'confirm').mockReturnValue(true);
vm.$el.querySelector('.btn-danger').click(); vm.$el.querySelector('.btn-danger').click();
Vue.nextTick(() => { Vue.nextTick(() => {
...@@ -119,7 +119,7 @@ describe('Edit Actions components', () => { ...@@ -119,7 +119,7 @@ describe('Edit Actions components', () => {
}); });
it('does no actions when confirm is false', done => { it('does no actions when confirm is false', done => {
spyOn(window, 'confirm').and.returnValue(false); jest.spyOn(window, 'confirm').mockReturnValue(false);
vm.$el.querySelector('.btn-danger').click(); vm.$el.querySelector('.btn-danger').click();
Vue.nextTick(() => { Vue.nextTick(() => {
......
...@@ -20,7 +20,7 @@ describe('Description field component', () => { ...@@ -20,7 +20,7 @@ describe('Description field component', () => {
document.body.appendChild(el); document.body.appendChild(el);
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
vm = new Component({ vm = new Component({
el, el,
......
...@@ -17,7 +17,7 @@ describe('Title field component', () => { ...@@ -17,7 +17,7 @@ describe('Title field component', () => {
}); });
store.formState.title = 'test'; store.formState.title = 'test';
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
vm = new Component({ vm = new Component({
propsData: { propsData: {
......
...@@ -10,7 +10,7 @@ describe('Issue show index', () => { ...@@ -10,7 +10,7 @@ describe('Issue show index', () => {
}); });
document.body.appendChild(d); document.body.appendChild(d);
const alertSpy = spyOn(window, 'alert'); const alertSpy = jest.spyOn(window, 'alert');
initIssueableApp(); initIssueableApp();
expect(alertSpy).not.toHaveBeenCalled(); expect(alertSpy).not.toHaveBeenCalled();
......
...@@ -100,7 +100,7 @@ describe('Job log controllers', () => { ...@@ -100,7 +100,7 @@ describe('Job log controllers', () => {
}); });
it('emits scrollJobLogTop event on click', () => { it('emits scrollJobLogTop event on click', () => {
spyOn(vm, '$emit'); jest.spyOn(vm, '$emit').mockImplementation(() => {});
vm.$el.querySelector('.js-scroll-top').click(); vm.$el.querySelector('.js-scroll-top').click();
expect(vm.$emit).toHaveBeenCalledWith('scrollJobLogTop'); expect(vm.$emit).toHaveBeenCalledWith('scrollJobLogTop');
...@@ -127,7 +127,7 @@ describe('Job log controllers', () => { ...@@ -127,7 +127,7 @@ describe('Job log controllers', () => {
}); });
it('does not emit scrollJobLogTop event on click', () => { it('does not emit scrollJobLogTop event on click', () => {
spyOn(vm, '$emit'); jest.spyOn(vm, '$emit').mockImplementation(() => {});
vm.$el.querySelector('.js-scroll-top').click(); vm.$el.querySelector('.js-scroll-top').click();
expect(vm.$emit).not.toHaveBeenCalledWith('scrollJobLogTop'); expect(vm.$emit).not.toHaveBeenCalledWith('scrollJobLogTop');
...@@ -146,7 +146,7 @@ describe('Job log controllers', () => { ...@@ -146,7 +146,7 @@ describe('Job log controllers', () => {
}); });
it('emits scrollJobLogBottom event on click', () => { it('emits scrollJobLogBottom event on click', () => {
spyOn(vm, '$emit'); jest.spyOn(vm, '$emit').mockImplementation(() => {});
vm.$el.querySelector('.js-scroll-bottom').click(); vm.$el.querySelector('.js-scroll-bottom').click();
expect(vm.$emit).toHaveBeenCalledWith('scrollJobLogBottom'); expect(vm.$emit).toHaveBeenCalledWith('scrollJobLogBottom');
...@@ -173,7 +173,7 @@ describe('Job log controllers', () => { ...@@ -173,7 +173,7 @@ describe('Job log controllers', () => {
}); });
it('does not emit scrollJobLogBottom event on click', () => { it('does not emit scrollJobLogBottom event on click', () => {
spyOn(vm, '$emit'); jest.spyOn(vm, '$emit').mockImplementation(() => {});
vm.$el.querySelector('.js-scroll-bottom').click(); vm.$el.querySelector('.js-scroll-bottom').click();
expect(vm.$emit).not.toHaveBeenCalledWith('scrollJobLogBottom'); expect(vm.$emit).not.toHaveBeenCalledWith('scrollJobLogBottom');
......
...@@ -3,7 +3,7 @@ import NamespaceSelect from '~/namespace_select'; ...@@ -3,7 +3,7 @@ import NamespaceSelect from '~/namespace_select';
describe('NamespaceSelect', () => { describe('NamespaceSelect', () => {
beforeEach(() => { beforeEach(() => {
spyOn($.fn, 'glDropdown'); jest.spyOn($.fn, 'glDropdown').mockImplementation(() => {});
}); });
it('initializes glDropdown', () => { it('initializes glDropdown', () => {
...@@ -22,12 +22,12 @@ describe('NamespaceSelect', () => { ...@@ -22,12 +22,12 @@ describe('NamespaceSelect', () => {
const dropdown = document.createElement('div'); const dropdown = document.createElement('div');
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new NamespaceSelect({ dropdown }); new NamespaceSelect({ dropdown });
[glDropdownOptions] = $.fn.glDropdown.calls.argsFor(0); [[glDropdownOptions]] = $.fn.glDropdown.mock.calls;
}); });
it('prevents click events', () => { it('prevents click events', () => {
const dummyEvent = new Event('dummy'); const dummyEvent = new Event('dummy');
spyOn(dummyEvent, 'preventDefault'); jest.spyOn(dummyEvent, 'preventDefault').mockImplementation(() => {});
glDropdownOptions.clicked({ e: dummyEvent }); glDropdownOptions.clicked({ e: dummyEvent });
...@@ -43,12 +43,12 @@ describe('NamespaceSelect', () => { ...@@ -43,12 +43,12 @@ describe('NamespaceSelect', () => {
dropdown.dataset.isFilter = 'true'; dropdown.dataset.isFilter = 'true';
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new NamespaceSelect({ dropdown }); new NamespaceSelect({ dropdown });
[glDropdownOptions] = $.fn.glDropdown.calls.argsFor(0); [[glDropdownOptions]] = $.fn.glDropdown.mock.calls;
}); });
it('does not prevent click events', () => { it('does not prevent click events', () => {
const dummyEvent = new Event('dummy'); const dummyEvent = new Event('dummy');
spyOn(dummyEvent, 'preventDefault'); jest.spyOn(dummyEvent, 'preventDefault').mockImplementation(() => {});
glDropdownOptions.clicked({ e: dummyEvent }); glDropdownOptions.clicked({ e: dummyEvent });
......
import $ from 'jquery'; import $ from 'jquery';
import NewBranchForm from '~/new_branch_form'; import NewBranchForm from '~/new_branch_form';
describe('Branch', function() { describe('Branch', () => {
describe('create a new branch', function() { let testContext;
beforeEach(() => {
testContext = {};
});
describe('create a new branch', () => {
preloadFixtures('branches/new_branch.html'); preloadFixtures('branches/new_branch.html');
function fillNameWith(value) { function fillNameWith(value) {
...@@ -15,30 +21,28 @@ describe('Branch', function() { ...@@ -15,30 +21,28 @@ describe('Branch', function() {
expect($('.js-branch-name-error span').text()).toEqual(error); expect($('.js-branch-name-error span').text()).toEqual(error);
} }
beforeEach(function() { beforeEach(() => {
loadFixtures('branches/new_branch.html'); loadFixtures('branches/new_branch.html');
$('form').on('submit', function(e) { $('form').on('submit', e => e.preventDefault());
return e.preventDefault(); testContext.form = new NewBranchForm($('.js-create-branch-form'), []);
});
this.form = new NewBranchForm($('.js-create-branch-form'), []);
}); });
it("can't start with a dot", function() { it("can't start with a dot", () => {
fillNameWith('.foo'); fillNameWith('.foo');
expectToHaveError("can't start with '.'"); expectToHaveError("can't start with '.'");
}); });
it("can't start with a slash", function() { it("can't start with a slash", () => {
fillNameWith('/foo'); fillNameWith('/foo');
expectToHaveError("can't start with '/'"); expectToHaveError("can't start with '/'");
}); });
it("can't have two consecutive dots", function() { it("can't have two consecutive dots", () => {
fillNameWith('foo..bar'); fillNameWith('foo..bar');
expectToHaveError("can't contain '..'"); expectToHaveError("can't contain '..'");
}); });
it("can't have spaces anywhere", function() { it("can't have spaces anywhere", () => {
fillNameWith(' foo'); fillNameWith(' foo');
expectToHaveError("can't contain spaces"); expectToHaveError("can't contain spaces");
fillNameWith('foo bar'); fillNameWith('foo bar');
...@@ -47,7 +51,7 @@ describe('Branch', function() { ...@@ -47,7 +51,7 @@ describe('Branch', function() {
expectToHaveError("can't contain spaces"); expectToHaveError("can't contain spaces");
}); });
it("can't have ~ anywhere", function() { it("can't have ~ anywhere", () => {
fillNameWith('~foo'); fillNameWith('~foo');
expectToHaveError("can't contain '~'"); expectToHaveError("can't contain '~'");
fillNameWith('foo~bar'); fillNameWith('foo~bar');
...@@ -56,7 +60,7 @@ describe('Branch', function() { ...@@ -56,7 +60,7 @@ describe('Branch', function() {
expectToHaveError("can't contain '~'"); expectToHaveError("can't contain '~'");
}); });
it("can't have tilde anwhere", function() { it("can't have tilde anwhere", () => {
fillNameWith('~foo'); fillNameWith('~foo');
expectToHaveError("can't contain '~'"); expectToHaveError("can't contain '~'");
fillNameWith('foo~bar'); fillNameWith('foo~bar');
...@@ -65,7 +69,7 @@ describe('Branch', function() { ...@@ -65,7 +69,7 @@ describe('Branch', function() {
expectToHaveError("can't contain '~'"); expectToHaveError("can't contain '~'");
}); });
it("can't have caret anywhere", function() { it("can't have caret anywhere", () => {
fillNameWith('^foo'); fillNameWith('^foo');
expectToHaveError("can't contain '^'"); expectToHaveError("can't contain '^'");
fillNameWith('foo^bar'); fillNameWith('foo^bar');
...@@ -74,7 +78,7 @@ describe('Branch', function() { ...@@ -74,7 +78,7 @@ describe('Branch', function() {
expectToHaveError("can't contain '^'"); expectToHaveError("can't contain '^'");
}); });
it("can't have : anywhere", function() { it("can't have : anywhere", () => {
fillNameWith(':foo'); fillNameWith(':foo');
expectToHaveError("can't contain ':'"); expectToHaveError("can't contain ':'");
fillNameWith('foo:bar'); fillNameWith('foo:bar');
...@@ -83,7 +87,7 @@ describe('Branch', function() { ...@@ -83,7 +87,7 @@ describe('Branch', function() {
expectToHaveError("can't contain ':'"); expectToHaveError("can't contain ':'");
}); });
it("can't have question mark anywhere", function() { it("can't have question mark anywhere", () => {
fillNameWith('?foo'); fillNameWith('?foo');
expectToHaveError("can't contain '?'"); expectToHaveError("can't contain '?'");
fillNameWith('foo?bar'); fillNameWith('foo?bar');
...@@ -92,7 +96,7 @@ describe('Branch', function() { ...@@ -92,7 +96,7 @@ describe('Branch', function() {
expectToHaveError("can't contain '?'"); expectToHaveError("can't contain '?'");
}); });
it("can't have asterisk anywhere", function() { it("can't have asterisk anywhere", () => {
fillNameWith('*foo'); fillNameWith('*foo');
expectToHaveError("can't contain '*'"); expectToHaveError("can't contain '*'");
fillNameWith('foo*bar'); fillNameWith('foo*bar');
...@@ -101,7 +105,7 @@ describe('Branch', function() { ...@@ -101,7 +105,7 @@ describe('Branch', function() {
expectToHaveError("can't contain '*'"); expectToHaveError("can't contain '*'");
}); });
it("can't have open bracket anywhere", function() { it("can't have open bracket anywhere", () => {
fillNameWith('[foo'); fillNameWith('[foo');
expectToHaveError("can't contain '['"); expectToHaveError("can't contain '['");
fillNameWith('foo[bar'); fillNameWith('foo[bar');
...@@ -110,7 +114,7 @@ describe('Branch', function() { ...@@ -110,7 +114,7 @@ describe('Branch', function() {
expectToHaveError("can't contain '['"); expectToHaveError("can't contain '['");
}); });
it("can't have a backslash anywhere", function() { it("can't have a backslash anywhere", () => {
fillNameWith('\\foo'); fillNameWith('\\foo');
expectToHaveError("can't contain '\\'"); expectToHaveError("can't contain '\\'");
fillNameWith('foo\\bar'); fillNameWith('foo\\bar');
...@@ -119,7 +123,7 @@ describe('Branch', function() { ...@@ -119,7 +123,7 @@ describe('Branch', function() {
expectToHaveError("can't contain '\\'"); expectToHaveError("can't contain '\\'");
}); });
it("can't contain a sequence @{ anywhere", function() { it("can't contain a sequence @{ anywhere", () => {
fillNameWith('@{foo'); fillNameWith('@{foo');
expectToHaveError("can't contain '@{'"); expectToHaveError("can't contain '@{'");
fillNameWith('foo@{bar'); fillNameWith('foo@{bar');
...@@ -128,42 +132,42 @@ describe('Branch', function() { ...@@ -128,42 +132,42 @@ describe('Branch', function() {
expectToHaveError("can't contain '@{'"); expectToHaveError("can't contain '@{'");
}); });
it("can't have consecutive slashes", function() { it("can't have consecutive slashes", () => {
fillNameWith('foo//bar'); fillNameWith('foo//bar');
expectToHaveError("can't contain consecutive slashes"); expectToHaveError("can't contain consecutive slashes");
}); });
it("can't end with a slash", function() { it("can't end with a slash", () => {
fillNameWith('foo/'); fillNameWith('foo/');
expectToHaveError("can't end in '/'"); expectToHaveError("can't end in '/'");
}); });
it("can't end with a dot", function() { it("can't end with a dot", () => {
fillNameWith('foo.'); fillNameWith('foo.');
expectToHaveError("can't end in '.'"); expectToHaveError("can't end in '.'");
}); });
it("can't end with .lock", function() { it("can't end with .lock", () => {
fillNameWith('foo.lock'); fillNameWith('foo.lock');
expectToHaveError("can't end in '.lock'"); expectToHaveError("can't end in '.lock'");
}); });
it("can't be the single character @", function() { it("can't be the single character @", () => {
fillNameWith('@'); fillNameWith('@');
expectToHaveError("can't be '@'"); expectToHaveError("can't be '@'");
}); });
it('concatenates all error messages', function() { it('concatenates all error messages', () => {
fillNameWith('/foo bar?~.'); fillNameWith('/foo bar?~.');
expectToHaveError("can't start with '/', can't contain spaces, '?', '~', can't end in '.'"); expectToHaveError("can't start with '/', can't contain spaces, '?', '~', can't end in '.'");
}); });
it("doesn't duplicate error messages", function() { it("doesn't duplicate error messages", () => {
fillNameWith('?foo?bar?zoo?'); fillNameWith('?foo?bar?zoo?');
expectToHaveError("can't contain '?'"); expectToHaveError("can't contain '?'");
}); });
it('removes the error message when is a valid name', function() { it('removes the error message when is a valid name', () => {
fillNameWith('foo?bar'); fillNameWith('foo?bar');
expect($('.js-branch-name-error span').length).toEqual(1); expect($('.js-branch-name-error span').length).toEqual(1);
...@@ -172,25 +176,25 @@ describe('Branch', function() { ...@@ -172,25 +176,25 @@ describe('Branch', function() {
expect($('.js-branch-name-error span').length).toEqual(0); expect($('.js-branch-name-error span').length).toEqual(0);
}); });
it('can have dashes anywhere', function() { it('can have dashes anywhere', () => {
fillNameWith('-foo-bar-zoo-'); fillNameWith('-foo-bar-zoo-');
expect($('.js-branch-name-error span').length).toEqual(0); expect($('.js-branch-name-error span').length).toEqual(0);
}); });
it('can have underscores anywhere', function() { it('can have underscores anywhere', () => {
fillNameWith('_foo_bar_zoo_'); fillNameWith('_foo_bar_zoo_');
expect($('.js-branch-name-error span').length).toEqual(0); expect($('.js-branch-name-error span').length).toEqual(0);
}); });
it('can have numbers anywhere', function() { it('can have numbers anywhere', () => {
fillNameWith('1foo2bar3zoo4'); fillNameWith('1foo2bar3zoo4');
expect($('.js-branch-name-error span').length).toEqual(0); expect($('.js-branch-name-error span').length).toEqual(0);
}); });
it('can be only letters', function() { it('can be only letters', () => {
fillNameWith('foo'); fillNameWith('foo');
expect($('.js-branch-name-error span').length).toEqual(0); expect($('.js-branch-name-error span').length).toEqual(0);
......
...@@ -34,7 +34,7 @@ describe('DiscussionFilterNote component', () => { ...@@ -34,7 +34,7 @@ describe('DiscussionFilterNote component', () => {
describe('methods', () => { describe('methods', () => {
describe('selectFilter', () => { describe('selectFilter', () => {
it('emits `dropdownSelect` event on `eventHub` with provided param', () => { it('emits `dropdownSelect` event on `eventHub` with provided param', () => {
spyOn(eventHub, '$emit'); jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
vm.selectFilter(1); vm.selectFilter(1);
...@@ -74,7 +74,7 @@ describe('DiscussionFilterNote component', () => { ...@@ -74,7 +74,7 @@ describe('DiscussionFilterNote component', () => {
it('clicking `Show all activity` button calls `selectFilter("all")` method', () => { it('clicking `Show all activity` button calls `selectFilter("all")` method', () => {
const showAllBtn = vm.$el.querySelector('.discussion-filter-actions button:first-child'); const showAllBtn = vm.$el.querySelector('.discussion-filter-actions button:first-child');
spyOn(vm, 'selectFilter'); jest.spyOn(vm, 'selectFilter').mockImplementation(() => {});
showAllBtn.dispatchEvent(new Event('click')); showAllBtn.dispatchEvent(new Event('click'));
...@@ -83,7 +83,7 @@ describe('DiscussionFilterNote component', () => { ...@@ -83,7 +83,7 @@ describe('DiscussionFilterNote component', () => {
it('clicking `Show comments only` button calls `selectFilter("comments")` method', () => { it('clicking `Show comments only` button calls `selectFilter("comments")` method', () => {
const showAllBtn = vm.$el.querySelector('.discussion-filter-actions button:last-child'); const showAllBtn = vm.$el.querySelector('.discussion-filter-actions button:last-child');
spyOn(vm, 'selectFilter'); jest.spyOn(vm, 'selectFilter').mockImplementation(() => {});
showAllBtn.dispatchEvent(new Event('click')); showAllBtn.dispatchEvent(new Event('click'));
......
...@@ -90,7 +90,7 @@ describe('note_header component', () => { ...@@ -90,7 +90,7 @@ describe('note_header component', () => {
}); });
it('emits toggle event on click', done => { it('emits toggle event on click', done => {
spyOn(vm, '$emit'); jest.spyOn(vm, '$emit').mockImplementation(() => {});
vm.$el.querySelector('.js-vue-toggle-button').click(); vm.$el.querySelector('.js-vue-toggle-button').click();
......
...@@ -327,7 +327,7 @@ describe('Getters Notes Store', () => { ...@@ -327,7 +327,7 @@ describe('Getters Notes Store', () => {
beforeEach(() => { beforeEach(() => {
neighbor = {}; neighbor = {};
findUnresolvedDiscussionIdNeighbor = jasmine.createSpy().and.returnValue(neighbor); findUnresolvedDiscussionIdNeighbor = jest.fn(() => neighbor);
localGetters = { findUnresolvedDiscussionIdNeighbor }; localGetters = { findUnresolvedDiscussionIdNeighbor };
}); });
......
...@@ -498,7 +498,7 @@ describe('Notes Store mutations', () => { ...@@ -498,7 +498,7 @@ describe('Notes Store mutations', () => {
mutations.UPDATE_RESOLVABLE_DISCUSSIONS_COUNTS(state); mutations.UPDATE_RESOLVABLE_DISCUSSIONS_COUNTS(state);
expect(state).toEqual( expect(state).toEqual(
jasmine.objectContaining({ expect.objectContaining({
resolvableDiscussionsCount: 1, resolvableDiscussionsCount: 1,
unresolvedDiscussionsCount: 1, unresolvedDiscussionsCount: 1,
hasUnresolvedDiscussions: false, hasUnresolvedDiscussions: false,
...@@ -535,7 +535,7 @@ describe('Notes Store mutations', () => { ...@@ -535,7 +535,7 @@ describe('Notes Store mutations', () => {
mutations.UPDATE_RESOLVABLE_DISCUSSIONS_COUNTS(state); mutations.UPDATE_RESOLVABLE_DISCUSSIONS_COUNTS(state);
expect(state).toEqual( expect(state).toEqual(
jasmine.objectContaining({ expect.objectContaining({
resolvableDiscussionsCount: 4, resolvableDiscussionsCount: 4,
unresolvedDiscussionsCount: 2, unresolvedDiscussionsCount: 2,
hasUnresolvedDiscussions: true, hasUnresolvedDiscussions: true,
......
...@@ -6,7 +6,7 @@ import TimezoneDropdown, { ...@@ -6,7 +6,7 @@ import TimezoneDropdown, {
findTimezoneByIdentifier, findTimezoneByIdentifier,
} from '~/pages/projects/pipeline_schedules/shared/components/timezone_dropdown'; } from '~/pages/projects/pipeline_schedules/shared/components/timezone_dropdown';
describe('Timezone Dropdown', function() { describe('Timezone Dropdown', () => {
preloadFixtures('pipeline_schedules/edit.html'); preloadFixtures('pipeline_schedules/edit.html');
let $inputEl = null; let $inputEl = null;
...@@ -81,7 +81,7 @@ describe('Timezone Dropdown', function() { ...@@ -81,7 +81,7 @@ describe('Timezone Dropdown', function() {
}); });
it('will call a provided handler when a new timezone is selected', () => { it('will call a provided handler when a new timezone is selected', () => {
const onSelectTimezone = jasmine.createSpy('onSelectTimezoneMock'); const onSelectTimezone = jest.fn();
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new TimezoneDropdown({ new TimezoneDropdown({
$inputEl, $inputEl,
...@@ -111,7 +111,7 @@ describe('Timezone Dropdown', function() { ...@@ -111,7 +111,7 @@ describe('Timezone Dropdown', function() {
}); });
it('will call a provided `displayFormat` handler to format the dropdown value', () => { it('will call a provided `displayFormat` handler to format the dropdown value', () => {
const displayFormat = jasmine.createSpy('displayFormat'); const displayFormat = jest.fn();
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new TimezoneDropdown({ new TimezoneDropdown({
$inputEl, $inputEl,
......
...@@ -75,7 +75,7 @@ describe('Pipelines Nav Controls', () => { ...@@ -75,7 +75,7 @@ describe('Pipelines Nav Controls', () => {
}); });
it('should emit postAction event when reset runner cache button is clicked', () => { it('should emit postAction event when reset runner cache button is clicked', () => {
spyOn(component, '$emit'); jest.spyOn(component, '$emit').mockImplementation(() => {});
component.$el.querySelector('.js-clear-cache').click(); component.$el.querySelector('.js-clear-cache').click();
......
import '~/commons/polyfills/element'; import '~/commons/polyfills/element';
describe('Element polyfills', function() { describe('Element polyfills', () => {
let testContext;
beforeEach(() => {
testContext = {};
});
beforeEach(() => { beforeEach(() => {
this.element = document.createElement('ul'); testContext.element = document.createElement('ul');
}); });
describe('matches', () => { describe('matches', () => {
it('returns true if element matches the selector', () => { it('returns true if element matches the selector', () => {
expect(this.element.matches('ul')).toBeTruthy(); expect(testContext.element.matches('ul')).toBeTruthy();
}); });
it("returns false if element doesn't match the selector", () => { it("returns false if element doesn't match the selector", () => {
expect(this.element.matches('.not-an-element')).toBeFalsy(); expect(testContext.element.matches('.not-an-element')).toBeFalsy();
}); });
}); });
describe('closest', () => { describe('closest', () => {
beforeEach(() => { beforeEach(() => {
this.childElement = document.createElement('li'); testContext.childElement = document.createElement('li');
this.element.appendChild(this.childElement); testContext.element.appendChild(testContext.childElement);
}); });
it('returns the closest parent that matches the selector', () => { it('returns the closest parent that matches the selector', () => {
expect(this.childElement.closest('ul').toString()).toBe(this.element.toString()); expect(testContext.childElement.closest('ul').toString()).toBe(
testContext.element.toString(),
);
}); });
it('returns itself if it matches the selector', () => { it('returns itself if it matches the selector', () => {
expect(this.childElement.closest('li').toString()).toBe(this.childElement.toString()); expect(testContext.childElement.closest('li').toString()).toBe(
testContext.childElement.toString(),
);
}); });
it('returns undefined if nothing matches the selector', () => { it('returns undefined if nothing matches the selector', () => {
expect(this.childElement.closest('.no-an-element')).toBeFalsy(); expect(testContext.childElement.closest('.no-an-element')).toBeFalsy();
}); });
}); });
}); });
...@@ -4,16 +4,18 @@ describe('AddSshKeyValidation', () => { ...@@ -4,16 +4,18 @@ describe('AddSshKeyValidation', () => {
describe('submit', () => { describe('submit', () => {
it('returns true if isValid is true', () => { it('returns true if isValid is true', () => {
const addSshKeyValidation = new AddSshKeyValidation({}); const addSshKeyValidation = new AddSshKeyValidation({});
spyOn(AddSshKeyValidation, 'isPublicKey').and.returnValue(true); jest.spyOn(AddSshKeyValidation, 'isPublicKey').mockReturnValue(true);
expect(addSshKeyValidation.submit()).toBeTruthy(); expect(addSshKeyValidation.submit()).toBeTruthy();
}); });
it('calls preventDefault and toggleWarning if isValid is false', () => { it('calls preventDefault and toggleWarning if isValid is false', () => {
const addSshKeyValidation = new AddSshKeyValidation({}); const addSshKeyValidation = new AddSshKeyValidation({});
const event = jasmine.createSpyObj('event', ['preventDefault']); const event = {
spyOn(AddSshKeyValidation, 'isPublicKey').and.returnValue(false); preventDefault: jest.fn(),
spyOn(addSshKeyValidation, 'toggleWarning'); };
jest.spyOn(AddSshKeyValidation, 'isPublicKey').mockReturnValue(false);
jest.spyOn(addSshKeyValidation, 'toggleWarning').mockImplementation(() => {});
addSshKeyValidation.submit(event); addSshKeyValidation.submit(event);
......
...@@ -3,11 +3,17 @@ import ProjectSelectComboButton from '~/project_select_combo_button'; ...@@ -3,11 +3,17 @@ import ProjectSelectComboButton from '~/project_select_combo_button';
const fixturePath = 'static/project_select_combo_button.html'; const fixturePath = 'static/project_select_combo_button.html';
describe('Project Select Combo Button', function() { describe('Project Select Combo Button', () => {
let testContext;
beforeEach(() => {
testContext = {};
});
preloadFixtures(fixturePath); preloadFixtures(fixturePath);
beforeEach(function() { beforeEach(() => {
this.defaults = { testContext.defaults = {
label: 'Select project to create issue', label: 'Select project to create issue',
groupId: 12345, groupId: 12345,
projectMeta: { projectMeta: {
...@@ -24,97 +30,107 @@ describe('Project Select Combo Button', function() { ...@@ -24,97 +30,107 @@ describe('Project Select Combo Button', function() {
loadFixtures(fixturePath); loadFixtures(fixturePath);
this.newItemBtn = document.querySelector('.new-project-item-link'); testContext.newItemBtn = document.querySelector('.new-project-item-link');
this.projectSelectInput = document.querySelector('.project-item-select'); testContext.projectSelectInput = document.querySelector('.project-item-select');
}); });
describe('on page load when localStorage is empty', function() { describe('on page load when localStorage is empty', () => {
beforeEach(function() { beforeEach(() => {
this.comboButton = new ProjectSelectComboButton(this.projectSelectInput); testContext.comboButton = new ProjectSelectComboButton(testContext.projectSelectInput);
}); });
it('newItemBtn href is null', function() { it('newItemBtn href is null', () => {
expect(this.newItemBtn.getAttribute('href')).toBe(''); expect(testContext.newItemBtn.getAttribute('href')).toBe('');
}); });
it('newItemBtn text is the plain default label', function() { it('newItemBtn text is the plain default label', () => {
expect(this.newItemBtn.textContent).toBe(this.defaults.label); expect(testContext.newItemBtn.textContent).toBe(testContext.defaults.label);
}); });
}); });
describe('on page load when localStorage is filled', function() { describe('on page load when localStorage is filled', () => {
beforeEach(function() { beforeEach(() => {
window.localStorage.setItem( window.localStorage.setItem(
this.defaults.localStorageKey, testContext.defaults.localStorageKey,
JSON.stringify(this.defaults.projectMeta), JSON.stringify(testContext.defaults.projectMeta),
); );
this.comboButton = new ProjectSelectComboButton(this.projectSelectInput); testContext.comboButton = new ProjectSelectComboButton(testContext.projectSelectInput);
}); });
it('newItemBtn href is correctly set', function() { it('newItemBtn href is correctly set', () => {
expect(this.newItemBtn.getAttribute('href')).toBe(this.defaults.projectMeta.url); expect(testContext.newItemBtn.getAttribute('href')).toBe(
testContext.defaults.projectMeta.url,
);
}); });
it('newItemBtn text is the cached label', function() { it('newItemBtn text is the cached label', () => {
expect(this.newItemBtn.textContent).toBe(`New issue in ${this.defaults.projectMeta.name}`); expect(testContext.newItemBtn.textContent).toBe(
`New issue in ${testContext.defaults.projectMeta.name}`,
);
}); });
afterEach(function() { afterEach(() => {
window.localStorage.clear(); window.localStorage.clear();
}); });
}); });
describe('after selecting a new project', function() { describe('after selecting a new project', () => {
beforeEach(function() { beforeEach(() => {
this.comboButton = new ProjectSelectComboButton(this.projectSelectInput); testContext.comboButton = new ProjectSelectComboButton(testContext.projectSelectInput);
// mock the effect of selecting an item from the projects dropdown (select2) // mock the effect of selecting an item from the projects dropdown (select2)
$('.project-item-select') $('.project-item-select')
.val(JSON.stringify(this.defaults.newProjectMeta)) .val(JSON.stringify(testContext.defaults.newProjectMeta))
.trigger('change'); .trigger('change');
}); });
it('newItemBtn href is correctly set', function() { it('newItemBtn href is correctly set', () => {
expect(this.newItemBtn.getAttribute('href')).toBe('http://myothercoolproject.com/issues/new'); expect(testContext.newItemBtn.getAttribute('href')).toBe(
'http://myothercoolproject.com/issues/new',
);
}); });
it('newItemBtn text is the selected project label', function() { it('newItemBtn text is the selected project label', () => {
expect(this.newItemBtn.textContent).toBe(`New issue in ${this.defaults.newProjectMeta.name}`); expect(testContext.newItemBtn.textContent).toBe(
`New issue in ${testContext.defaults.newProjectMeta.name}`,
);
}); });
afterEach(function() { afterEach(() => {
window.localStorage.clear(); window.localStorage.clear();
}); });
}); });
describe('deriveTextVariants', function() { describe('deriveTextVariants', () => {
beforeEach(function() { beforeEach(() => {
this.mockExecutionContext = { testContext.mockExecutionContext = {
resourceType: '', resourceType: '',
resourceLabel: '', resourceLabel: '',
}; };
this.comboButton = new ProjectSelectComboButton(this.projectSelectInput); testContext.comboButton = new ProjectSelectComboButton(testContext.projectSelectInput);
this.method = this.comboButton.deriveTextVariants.bind(this.mockExecutionContext); testContext.method = testContext.comboButton.deriveTextVariants.bind(
testContext.mockExecutionContext,
);
}); });
it('correctly derives test variants for merge requests', function() { it('correctly derives test variants for merge requests', () => {
this.mockExecutionContext.resourceType = 'merge_requests'; testContext.mockExecutionContext.resourceType = 'merge_requests';
this.mockExecutionContext.resourceLabel = 'New merge request'; testContext.mockExecutionContext.resourceLabel = 'New merge request';
const returnedVariants = this.method(); const returnedVariants = testContext.method();
expect(returnedVariants.localStorageItemType).toBe('new-merge-request'); expect(returnedVariants.localStorageItemType).toBe('new-merge-request');
expect(returnedVariants.defaultTextPrefix).toBe('New merge request'); expect(returnedVariants.defaultTextPrefix).toBe('New merge request');
expect(returnedVariants.presetTextSuffix).toBe('merge request'); expect(returnedVariants.presetTextSuffix).toBe('merge request');
}); });
it('correctly derives text variants for issues', function() { it('correctly derives text variants for issues', () => {
this.mockExecutionContext.resourceType = 'issues'; testContext.mockExecutionContext.resourceType = 'issues';
this.mockExecutionContext.resourceLabel = 'New issue'; testContext.mockExecutionContext.resourceLabel = 'New issue';
const returnedVariants = this.method(); const returnedVariants = testContext.method();
expect(returnedVariants.localStorageItemType).toBe('new-issue'); expect(returnedVariants.localStorageItemType).toBe('new-issue');
expect(returnedVariants.defaultTextPrefix).toBe('New issue'); expect(returnedVariants.defaultTextPrefix).toBe('New issue');
......
...@@ -29,7 +29,7 @@ describe('popover', () => { ...@@ -29,7 +29,7 @@ describe('popover', () => {
toggleClass: () => {}, toggleClass: () => {},
}; };
spyOn(context, 'popover').and.callFake(method => { jest.spyOn(context, 'popover').mockImplementation(method => {
expect(method).toEqual('show'); expect(method).toEqual('show');
done(); done();
}); });
...@@ -44,7 +44,7 @@ describe('popover', () => { ...@@ -44,7 +44,7 @@ describe('popover', () => {
toggleClass: () => {}, toggleClass: () => {},
}; };
spyOn(context, 'toggleClass').and.callFake((classNames, show) => { jest.spyOn(context, 'toggleClass').mockImplementation((classNames, show) => {
expect(classNames).toEqual('disable-animation js-popover-show'); expect(classNames).toEqual('disable-animation js-popover-show');
expect(show).toEqual(true); expect(show).toEqual(true);
done(); done();
...@@ -80,7 +80,7 @@ describe('popover', () => { ...@@ -80,7 +80,7 @@ describe('popover', () => {
toggleClass: () => {}, toggleClass: () => {},
}; };
spyOn(context, 'popover').and.callFake(method => { jest.spyOn(context, 'popover').mockImplementation(method => {
expect(method).toEqual('hide'); expect(method).toEqual('hide');
done(); done();
}); });
...@@ -95,7 +95,7 @@ describe('popover', () => { ...@@ -95,7 +95,7 @@ describe('popover', () => {
toggleClass: () => {}, toggleClass: () => {},
}; };
spyOn(context, 'toggleClass').and.callFake((classNames, show) => { jest.spyOn(context, 'toggleClass').mockImplementation((classNames, show) => {
expect(classNames).toEqual('disable-animation js-popover-show'); expect(classNames).toEqual('disable-animation js-popover-show');
expect(show).toEqual(false); expect(show).toEqual(false);
done(); done();
...@@ -112,13 +112,13 @@ describe('popover', () => { ...@@ -112,13 +112,13 @@ describe('popover', () => {
length: 0, length: 0,
}; };
spyOn($.fn, 'init').and.callFake(selector => jest
selector === '.popover:hover' ? fakeJquery : $.fn, .spyOn($.fn, 'init')
); .mockImplementation(selector => (selector === '.popover:hover' ? fakeJquery : $.fn));
spyOn(togglePopover, 'call'); jest.spyOn(togglePopover, 'call').mockImplementation(() => {});
mouseleave(); mouseleave();
expect(togglePopover.call).toHaveBeenCalledWith(jasmine.any(Object), false); expect(togglePopover.call).toHaveBeenCalledWith(expect.any(Object), false);
}); });
it('does not call hide popover if .popover:hover is true', () => { it('does not call hide popover if .popover:hover is true', () => {
...@@ -126,10 +126,10 @@ describe('popover', () => { ...@@ -126,10 +126,10 @@ describe('popover', () => {
length: 1, length: 1,
}; };
spyOn($.fn, 'init').and.callFake(selector => jest
selector === '.popover:hover' ? fakeJquery : $.fn, .spyOn($.fn, 'init')
); .mockImplementation(selector => (selector === '.popover:hover' ? fakeJquery : $.fn));
spyOn(togglePopover, 'call'); jest.spyOn(togglePopover, 'call').mockImplementation(() => {});
mouseleave(); mouseleave();
expect(togglePopover.call).not.toHaveBeenCalledWith(false); expect(togglePopover.call).not.toHaveBeenCalledWith(false);
...@@ -140,15 +140,15 @@ describe('popover', () => { ...@@ -140,15 +140,15 @@ describe('popover', () => {
const context = {}; const context = {};
it('shows popover', () => { it('shows popover', () => {
spyOn(togglePopover, 'call').and.returnValue(false); jest.spyOn(togglePopover, 'call').mockReturnValue(false);
mouseenter.call(context); mouseenter.call(context);
expect(togglePopover.call).toHaveBeenCalledWith(jasmine.any(Object), true); expect(togglePopover.call).toHaveBeenCalledWith(expect.any(Object), true);
}); });
it('registers mouseleave event if popover is showed', done => { it('registers mouseleave event if popover is showed', done => {
spyOn(togglePopover, 'call').and.returnValue(true); jest.spyOn(togglePopover, 'call').mockReturnValue(true);
spyOn($.fn, 'on').and.callFake(eventName => { jest.spyOn($.fn, 'on').mockImplementation(eventName => {
expect(eventName).toEqual('mouseleave'); expect(eventName).toEqual('mouseleave');
done(); done();
}); });
...@@ -156,8 +156,8 @@ describe('popover', () => { ...@@ -156,8 +156,8 @@ describe('popover', () => {
}); });
it('does not register mouseleave event if popover is not showed', () => { it('does not register mouseleave event if popover is not showed', () => {
spyOn(togglePopover, 'call').and.returnValue(false); jest.spyOn(togglePopover, 'call').mockReturnValue(false);
const spy = spyOn($.fn, 'on').and.callFake(() => {}); const spy = jest.spyOn($.fn, 'on').mockImplementation(() => {});
mouseenter.call(context); mouseenter.call(context);
expect(spy).not.toHaveBeenCalled(); expect(spy).not.toHaveBeenCalled();
......
...@@ -27,9 +27,15 @@ const PARTICIPANT = { ...@@ -27,9 +27,15 @@ const PARTICIPANT = {
const PARTICIPANT_LIST = [PARTICIPANT, { ...PARTICIPANT, id: 2 }, { ...PARTICIPANT, id: 3 }]; const PARTICIPANT_LIST = [PARTICIPANT, { ...PARTICIPANT, id: 2 }, { ...PARTICIPANT, id: 3 }];
describe('Sidebar store', function() { describe('Sidebar store', () => {
let testContext;
beforeEach(() => {
testContext = {};
});
beforeEach(() => { beforeEach(() => {
this.store = new SidebarStore({ testContext.store = new SidebarStore({
currentUser: { currentUser: {
id: 1, id: 1,
name: 'Administrator', name: 'Administrator',
...@@ -48,60 +54,60 @@ describe('Sidebar store', function() { ...@@ -48,60 +54,60 @@ describe('Sidebar store', function() {
}); });
it('has default isFetching values', () => { it('has default isFetching values', () => {
expect(this.store.isFetching.assignees).toBe(true); expect(testContext.store.isFetching.assignees).toBe(true);
}); });
it('adds a new assignee', () => { it('adds a new assignee', () => {
this.store.addAssignee(ASSIGNEE); testContext.store.addAssignee(ASSIGNEE);
expect(this.store.assignees.length).toEqual(1); expect(testContext.store.assignees.length).toEqual(1);
}); });
it('removes an assignee', () => { it('removes an assignee', () => {
this.store.removeAssignee(ASSIGNEE); testContext.store.removeAssignee(ASSIGNEE);
expect(this.store.assignees.length).toEqual(0); expect(testContext.store.assignees.length).toEqual(0);
}); });
it('finds an existent assignee', () => { it('finds an existent assignee', () => {
let foundAssignee; let foundAssignee;
this.store.addAssignee(ASSIGNEE); testContext.store.addAssignee(ASSIGNEE);
foundAssignee = this.store.findAssignee(ASSIGNEE); foundAssignee = testContext.store.findAssignee(ASSIGNEE);
expect(foundAssignee).toBeDefined(); expect(foundAssignee).toBeDefined();
expect(foundAssignee).toEqual(ASSIGNEE); expect(foundAssignee).toEqual(ASSIGNEE);
foundAssignee = this.store.findAssignee(ANOTHER_ASSINEE); foundAssignee = testContext.store.findAssignee(ANOTHER_ASSINEE);
expect(foundAssignee).toBeUndefined(); expect(foundAssignee).toBeUndefined();
}); });
it('removes all assignees', () => { it('removes all assignees', () => {
this.store.removeAllAssignees(); testContext.store.removeAllAssignees();
expect(this.store.assignees.length).toEqual(0); expect(testContext.store.assignees.length).toEqual(0);
}); });
it('sets participants data', () => { it('sets participants data', () => {
expect(this.store.participants.length).toEqual(0); expect(testContext.store.participants.length).toEqual(0);
this.store.setParticipantsData({ testContext.store.setParticipantsData({
participants: PARTICIPANT_LIST, participants: PARTICIPANT_LIST,
}); });
expect(this.store.isFetching.participants).toEqual(false); expect(testContext.store.isFetching.participants).toEqual(false);
expect(this.store.participants.length).toEqual(PARTICIPANT_LIST.length); expect(testContext.store.participants.length).toEqual(PARTICIPANT_LIST.length);
}); });
it('sets subcriptions data', () => { it('sets subcriptions data', () => {
expect(this.store.subscribed).toEqual(null); expect(testContext.store.subscribed).toEqual(null);
this.store.setSubscriptionsData({ testContext.store.setSubscriptionsData({
subscribed: true, subscribed: true,
}); });
expect(this.store.isFetching.subscriptions).toEqual(false); expect(testContext.store.isFetching.subscriptions).toEqual(false);
expect(this.store.subscribed).toEqual(true); expect(testContext.store.subscribed).toEqual(true);
}); });
it('set assigned data', () => { it('set assigned data', () => {
...@@ -109,54 +115,54 @@ describe('Sidebar store', function() { ...@@ -109,54 +115,54 @@ describe('Sidebar store', function() {
assignees: UsersMockHelper.createNumberRandomUsers(3), assignees: UsersMockHelper.createNumberRandomUsers(3),
}; };
this.store.setAssigneeData(users); testContext.store.setAssigneeData(users);
expect(this.store.isFetching.assignees).toBe(false); expect(testContext.store.isFetching.assignees).toBe(false);
expect(this.store.assignees.length).toEqual(3); expect(testContext.store.assignees.length).toEqual(3);
}); });
it('sets fetching state', () => { it('sets fetching state', () => {
expect(this.store.isFetching.participants).toEqual(true); expect(testContext.store.isFetching.participants).toEqual(true);
this.store.setFetchingState('participants', false); testContext.store.setFetchingState('participants', false);
expect(this.store.isFetching.participants).toEqual(false); expect(testContext.store.isFetching.participants).toEqual(false);
}); });
it('sets loading state', () => { it('sets loading state', () => {
this.store.setLoadingState('assignees', true); testContext.store.setLoadingState('assignees', true);
expect(this.store.isLoading.assignees).toEqual(true); expect(testContext.store.isLoading.assignees).toEqual(true);
}); });
it('set time tracking data', () => { it('set time tracking data', () => {
this.store.setTimeTrackingData(Mock.time); testContext.store.setTimeTrackingData(Mock.time);
expect(this.store.timeEstimate).toEqual(Mock.time.time_estimate); expect(testContext.store.timeEstimate).toEqual(Mock.time.time_estimate);
expect(this.store.totalTimeSpent).toEqual(Mock.time.total_time_spent); expect(testContext.store.totalTimeSpent).toEqual(Mock.time.total_time_spent);
expect(this.store.humanTimeEstimate).toEqual(Mock.time.human_time_estimate); expect(testContext.store.humanTimeEstimate).toEqual(Mock.time.human_time_estimate);
expect(this.store.humanTotalTimeSpent).toEqual(Mock.time.human_total_time_spent); expect(testContext.store.humanTotalTimeSpent).toEqual(Mock.time.human_total_time_spent);
}); });
it('set autocomplete projects', () => { it('set autocomplete projects', () => {
const projects = [{ id: 0 }]; const projects = [{ id: 0 }];
this.store.setAutocompleteProjects(projects); testContext.store.setAutocompleteProjects(projects);
expect(this.store.autocompleteProjects).toEqual(projects); expect(testContext.store.autocompleteProjects).toEqual(projects);
}); });
it('sets subscribed state', () => { it('sets subscribed state', () => {
expect(this.store.subscribed).toEqual(null); expect(testContext.store.subscribed).toEqual(null);
this.store.setSubscribedState(true); testContext.store.setSubscribedState(true);
expect(this.store.subscribed).toEqual(true); expect(testContext.store.subscribed).toEqual(true);
}); });
it('set move to project ID', () => { it('set move to project ID', () => {
const projectId = 7; const projectId = 7;
this.store.setMoveToProjectId(projectId); testContext.store.setMoveToProjectId(projectId);
expect(this.store.moveToProjectId).toEqual(projectId); expect(testContext.store.moveToProjectId).toEqual(projectId);
}); });
}); });
...@@ -3,19 +3,19 @@ ...@@ -3,19 +3,19 @@
import $ from 'jquery'; import $ from 'jquery';
import syntaxHighlight from '~/syntax_highlight'; import syntaxHighlight from '~/syntax_highlight';
describe('Syntax Highlighter', function() { describe('Syntax Highlighter', () => {
const stubUserColorScheme = function(value) { const stubUserColorScheme = value => {
if (window.gon == null) { if (window.gon == null) {
window.gon = {}; window.gon = {};
} }
return (window.gon.user_color_scheme = value); return (window.gon.user_color_scheme = value);
}; };
describe('on a js-syntax-highlight element', function() { describe('on a js-syntax-highlight element', () => {
beforeEach(function() { beforeEach(() => {
return setFixtures('<div class="js-syntax-highlight"></div>'); setFixtures('<div class="js-syntax-highlight"></div>');
}); });
it('applies syntax highlighting', function() { it('applies syntax highlighting', () => {
stubUserColorScheme('monokai'); stubUserColorScheme('monokai');
syntaxHighlight($('.js-syntax-highlight')); syntaxHighlight($('.js-syntax-highlight'));
...@@ -23,14 +23,14 @@ describe('Syntax Highlighter', function() { ...@@ -23,14 +23,14 @@ describe('Syntax Highlighter', function() {
}); });
}); });
describe('on a parent element', function() { describe('on a parent element', () => {
beforeEach(function() { beforeEach(() => {
return setFixtures( setFixtures(
'<div class="parent">\n <div class="js-syntax-highlight"></div>\n <div class="foo"></div>\n <div class="js-syntax-highlight"></div>\n</div>', '<div class="parent">\n <div class="js-syntax-highlight"></div>\n <div class="foo"></div>\n <div class="js-syntax-highlight"></div>\n</div>',
); );
}); });
it('applies highlighting to all applicable children', function() { it('applies highlighting to all applicable children', () => {
stubUserColorScheme('monokai'); stubUserColorScheme('monokai');
syntaxHighlight($('.parent')); syntaxHighlight($('.parent'));
...@@ -38,11 +38,9 @@ describe('Syntax Highlighter', function() { ...@@ -38,11 +38,9 @@ describe('Syntax Highlighter', function() {
expect($('.monokai').length).toBe(2); expect($('.monokai').length).toBe(2);
}); });
it('prevents an infinite loop when no matches exist', function() { it('prevents an infinite loop when no matches exist', () => {
setFixtures('<div></div>'); setFixtures('<div></div>');
const highlight = function() { const highlight = () => syntaxHighlight($('div'));
return syntaxHighlight($('div'));
};
expect(highlight).not.toThrow(); expect(highlight).not.toThrow();
}); });
......
...@@ -25,10 +25,10 @@ describe('TaskList', () => { ...@@ -25,10 +25,10 @@ describe('TaskList', () => {
}); });
it('should call init when the class constructed', () => { it('should call init when the class constructed', () => {
spyOn(TaskList.prototype, 'init').and.callThrough(); jest.spyOn(TaskList.prototype, 'init');
spyOn(TaskList.prototype, 'disable'); jest.spyOn(TaskList.prototype, 'disable').mockImplementation(() => {});
spyOn($.prototype, 'taskList'); jest.spyOn($.prototype, 'taskList').mockImplementation(() => {});
spyOn($.prototype, 'on'); jest.spyOn($.prototype, 'on').mockImplementation(() => {});
taskList = createTaskList(); taskList = createTaskList();
const $taskListEl = $(taskList.taskListContainerSelector); const $taskListEl = $(taskList.taskListContainerSelector);
...@@ -59,7 +59,7 @@ describe('TaskList', () => { ...@@ -59,7 +59,7 @@ describe('TaskList', () => {
describe('disableTaskListItems', () => { describe('disableTaskListItems', () => {
it('should call taskList method with disable param', () => { it('should call taskList method with disable param', () => {
spyOn($.prototype, 'taskList'); jest.spyOn($.prototype, 'taskList').mockImplementation(() => {});
taskList.disableTaskListItems({ currentTarget }); taskList.disableTaskListItems({ currentTarget });
...@@ -69,7 +69,7 @@ describe('TaskList', () => { ...@@ -69,7 +69,7 @@ describe('TaskList', () => {
describe('enableTaskListItems', () => { describe('enableTaskListItems', () => {
it('should call taskList method with enable param', () => { it('should call taskList method with enable param', () => {
spyOn($.prototype, 'taskList'); jest.spyOn($.prototype, 'taskList').mockImplementation(() => {});
taskList.enableTaskListItems({ currentTarget }); taskList.enableTaskListItems({ currentTarget });
...@@ -79,8 +79,8 @@ describe('TaskList', () => { ...@@ -79,8 +79,8 @@ describe('TaskList', () => {
describe('disable', () => { describe('disable', () => {
it('should disable task list items and off document event', () => { it('should disable task list items and off document event', () => {
spyOn(taskList, 'disableTaskListItems'); jest.spyOn(taskList, 'disableTaskListItems').mockImplementation(() => {});
spyOn($.prototype, 'off'); jest.spyOn($.prototype, 'off').mockImplementation(() => {});
taskList.disable(); taskList.disable();
...@@ -95,10 +95,10 @@ describe('TaskList', () => { ...@@ -95,10 +95,10 @@ describe('TaskList', () => {
describe('update', () => { describe('update', () => {
it('should disable task list items and make a patch request then enable them again', done => { it('should disable task list items and make a patch request then enable them again', done => {
const response = { data: { lock_version: 3 } }; const response = { data: { lock_version: 3 } };
spyOn(taskList, 'enableTaskListItems'); jest.spyOn(taskList, 'enableTaskListItems').mockImplementation(() => {});
spyOn(taskList, 'disableTaskListItems'); jest.spyOn(taskList, 'disableTaskListItems').mockImplementation(() => {});
spyOn(taskList, 'onSuccess'); jest.spyOn(taskList, 'onSuccess').mockImplementation(() => {});
spyOn(axios, 'patch').and.returnValue(Promise.resolve(response)); jest.spyOn(axios, 'patch').mockReturnValue(Promise.resolve(response));
const value = 'hello world'; const value = 'hello world';
const endpoint = '/foo'; const endpoint = '/foo';
...@@ -139,9 +139,9 @@ describe('TaskList', () => { ...@@ -139,9 +139,9 @@ describe('TaskList', () => {
it('should handle request error and enable task list items', done => { it('should handle request error and enable task list items', done => {
const response = { data: { error: 1 } }; const response = { data: { error: 1 } };
spyOn(taskList, 'enableTaskListItems'); jest.spyOn(taskList, 'enableTaskListItems').mockImplementation(() => {});
spyOn(taskList, 'onError'); jest.spyOn(taskList, 'onError').mockImplementation(() => {});
spyOn(axios, 'patch').and.returnValue(Promise.reject({ response })); // eslint-disable-line prefer-promise-reject-errors jest.spyOn(axios, 'patch').mockReturnValue(Promise.reject({ response })); // eslint-disable-line prefer-promise-reject-errors
const event = { detail: {} }; const event = { detail: {} };
taskList taskList
......
...@@ -2,32 +2,39 @@ import $ from 'jquery'; ...@@ -2,32 +2,39 @@ import $ from 'jquery';
import VersionCheckImage from '~/version_check_image'; import VersionCheckImage from '~/version_check_image';
import ClassSpecHelper from './helpers/class_spec_helper'; import ClassSpecHelper from './helpers/class_spec_helper';
describe('VersionCheckImage', function() { describe('VersionCheckImage', () => {
describe('bindErrorEvent', function() { let testContext;
beforeEach(() => {
testContext = {};
});
describe('bindErrorEvent', () => {
ClassSpecHelper.itShouldBeAStaticMethod(VersionCheckImage, 'bindErrorEvent'); ClassSpecHelper.itShouldBeAStaticMethod(VersionCheckImage, 'bindErrorEvent');
beforeEach(function() { beforeEach(() => {
this.imageElement = $('<div></div>'); testContext.imageElement = $('<div></div>');
}); });
it('registers an error event', function() { it('registers an error event', () => {
spyOn($.prototype, 'on'); jest.spyOn($.prototype, 'on').mockImplementation(() => {});
spyOn($.prototype, 'off').and.callFake(function() { // eslint-disable-next-line func-names
jest.spyOn($.prototype, 'off').mockImplementation(function() {
return this; return this;
}); });
VersionCheckImage.bindErrorEvent(this.imageElement); VersionCheckImage.bindErrorEvent(testContext.imageElement);
expect($.prototype.off).toHaveBeenCalledWith('error'); expect($.prototype.off).toHaveBeenCalledWith('error');
expect($.prototype.on).toHaveBeenCalledWith('error', jasmine.any(Function)); expect($.prototype.on).toHaveBeenCalledWith('error', expect.any(Function));
}); });
it('hides the imageElement on error', function() { it('hides the imageElement on error', () => {
spyOn($.prototype, 'hide'); jest.spyOn($.prototype, 'hide').mockImplementation(() => {});
VersionCheckImage.bindErrorEvent(this.imageElement); VersionCheckImage.bindErrorEvent(testContext.imageElement);
this.imageElement.trigger('error'); testContext.imageElement.trigger('error');
expect($.prototype.hide).toHaveBeenCalled(); expect($.prototype.hide).toHaveBeenCalled();
}); });
......
...@@ -45,8 +45,8 @@ describe('GlModalVuex', () => { ...@@ -45,8 +45,8 @@ describe('GlModalVuex', () => {
state = createState(); state = createState();
actions = { actions = {
show: jasmine.createSpy('show'), show: jest.fn(),
hide: jasmine.createSpy('hide'), hide: jest.fn(),
}; };
}); });
...@@ -81,7 +81,7 @@ describe('GlModalVuex', () => { ...@@ -81,7 +81,7 @@ describe('GlModalVuex', () => {
}); });
it('passes listeners through to gl-modal', () => { it('passes listeners through to gl-modal', () => {
const ok = jasmine.createSpy('ok'); const ok = jest.fn();
factory({ factory({
listeners: { ok }, listeners: { ok },
...@@ -119,7 +119,7 @@ describe('GlModalVuex', () => { ...@@ -119,7 +119,7 @@ describe('GlModalVuex', () => {
state.isVisible = false; state.isVisible = false;
factory(); factory();
const rootEmit = spyOn(wrapper.vm.$root, '$emit'); const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit');
state.isVisible = true; state.isVisible = true;
...@@ -136,7 +136,7 @@ describe('GlModalVuex', () => { ...@@ -136,7 +136,7 @@ describe('GlModalVuex', () => {
state.isVisible = true; state.isVisible = true;
factory(); factory();
const rootEmit = spyOn(wrapper.vm.$root, '$emit'); const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit');
state.isVisible = false; state.isVisible = false;
......
...@@ -92,7 +92,7 @@ describe('Suggestion Diff component', () => { ...@@ -92,7 +92,7 @@ describe('Suggestion Diff component', () => {
describe('applySuggestion', () => { describe('applySuggestion', () => {
it('emits apply event when applySuggestion is called', () => { it('emits apply event when applySuggestion is called', () => {
const callback = () => {}; const callback = () => {};
spyOn(vm, '$emit'); jest.spyOn(vm, '$emit').mockImplementation(() => {});
vm.applySuggestion(callback); vm.applySuggestion(callback);
expect(vm.$emit).toHaveBeenCalledWith('apply', { suggestionId: vm.suggestion.id, callback }); expect(vm.$emit).toHaveBeenCalledWith('apply', { suggestionId: vm.suggestion.id, callback });
......
...@@ -86,7 +86,7 @@ describe('UserAvatarList', () => { ...@@ -86,7 +86,7 @@ describe('UserAvatarList', () => {
expect(linkProps).toEqual( expect(linkProps).toEqual(
items.map(x => items.map(x =>
jasmine.objectContaining({ expect.objectContaining({
linkHref: x.web_url, linkHref: x.web_url,
imgSrc: x.avatar_url, imgSrc: x.avatar_url,
imgAlt: x.name, imgAlt: x.name,
......
import BindInOut from '~/behaviors/bind_in_out';
import ClassSpecHelper from '../helpers/class_spec_helper';
describe('BindInOut', function() {
describe('constructor', function() {
beforeEach(function() {
this.in = {};
this.out = {};
this.bindInOut = new BindInOut(this.in, this.out);
});
it('should set .in', function() {
expect(this.bindInOut.in).toBe(this.in);
});
it('should set .out', function() {
expect(this.bindInOut.out).toBe(this.out);
});
it('should set .eventWrapper', function() {
expect(this.bindInOut.eventWrapper).toEqual({});
});
describe('if .in is an input', function() {
beforeEach(function() {
this.bindInOut = new BindInOut({ tagName: 'INPUT' });
});
it('should set .eventType to keyup ', function() {
expect(this.bindInOut.eventType).toEqual('keyup');
});
});
describe('if .in is a textarea', function() {
beforeEach(function() {
this.bindInOut = new BindInOut({ tagName: 'TEXTAREA' });
});
it('should set .eventType to keyup ', function() {
expect(this.bindInOut.eventType).toEqual('keyup');
});
});
describe('if .in is not an input or textarea', function() {
beforeEach(function() {
this.bindInOut = new BindInOut({ tagName: 'SELECT' });
});
it('should set .eventType to change ', function() {
expect(this.bindInOut.eventType).toEqual('change');
});
});
});
describe('addEvents', function() {
beforeEach(function() {
this.in = jasmine.createSpyObj('in', ['addEventListener']);
this.bindInOut = new BindInOut(this.in);
this.addEvents = this.bindInOut.addEvents();
});
it('should set .eventWrapper.updateOut', function() {
expect(this.bindInOut.eventWrapper.updateOut).toEqual(jasmine.any(Function));
});
it('should call .addEventListener', function() {
expect(this.in.addEventListener).toHaveBeenCalledWith(
this.bindInOut.eventType,
this.bindInOut.eventWrapper.updateOut,
);
});
it('should return the instance', function() {
expect(this.addEvents).toBe(this.bindInOut);
});
});
describe('updateOut', function() {
beforeEach(function() {
this.in = { value: 'the-value' };
this.out = { textContent: 'not-the-value' };
this.bindInOut = new BindInOut(this.in, this.out);
this.updateOut = this.bindInOut.updateOut();
});
it('should set .out.textContent to .in.value', function() {
expect(this.out.textContent).toBe(this.in.value);
});
it('should return the instance', function() {
expect(this.updateOut).toBe(this.bindInOut);
});
});
describe('removeEvents', function() {
beforeEach(function() {
this.in = jasmine.createSpyObj('in', ['removeEventListener']);
this.updateOut = () => {};
this.bindInOut = new BindInOut(this.in);
this.bindInOut.eventWrapper.updateOut = this.updateOut;
this.removeEvents = this.bindInOut.removeEvents();
});
it('should call .removeEventListener', function() {
expect(this.in.removeEventListener).toHaveBeenCalledWith(
this.bindInOut.eventType,
this.updateOut,
);
});
it('should return the instance', function() {
expect(this.removeEvents).toBe(this.bindInOut);
});
});
describe('initAll', function() {
beforeEach(function() {
this.ins = [0, 1, 2];
this.instances = [];
spyOn(document, 'querySelectorAll').and.returnValue(this.ins);
spyOn(Array.prototype, 'map').and.callThrough();
spyOn(BindInOut, 'init');
this.initAll = BindInOut.initAll();
});
ClassSpecHelper.itShouldBeAStaticMethod(BindInOut, 'initAll');
it('should call .querySelectorAll', function() {
expect(document.querySelectorAll).toHaveBeenCalledWith('*[data-bind-in]');
});
it('should call .map', function() {
expect(Array.prototype.map).toHaveBeenCalledWith(jasmine.any(Function));
});
it('should call .init for each element', function() {
expect(BindInOut.init.calls.count()).toEqual(3);
});
it('should return an array of instances', function() {
expect(this.initAll).toEqual(jasmine.any(Array));
});
});
describe('init', function() {
beforeEach(function() {
spyOn(BindInOut.prototype, 'addEvents').and.callFake(function() {
return this;
});
spyOn(BindInOut.prototype, 'updateOut').and.callFake(function() {
return this;
});
this.init = BindInOut.init({}, {});
});
ClassSpecHelper.itShouldBeAStaticMethod(BindInOut, 'init');
it('should call .addEvents', function() {
expect(BindInOut.prototype.addEvents).toHaveBeenCalled();
});
it('should call .updateOut', function() {
expect(BindInOut.prototype.updateOut).toHaveBeenCalled();
});
describe('if no anOut is provided', function() {
beforeEach(function() {
this.anIn = { dataset: { bindIn: 'the-data-bind-in' } };
spyOn(document, 'querySelector');
BindInOut.init(this.anIn);
});
it('should call .querySelector', function() {
expect(document.querySelector).toHaveBeenCalledWith(
`*[data-bind-out="${this.anIn.dataset.bindIn}"]`,
);
});
});
});
});
...@@ -74,6 +74,10 @@ describe Sentry::Client::Issue do ...@@ -74,6 +74,10 @@ describe Sentry::Client::Issue do
it 'has a correct GitLab issue url' do it 'has a correct GitLab issue url' do
expect(subject.gitlab_issue).to eq('https://gitlab.com/gitlab-org/gitlab/issues/1') expect(subject.gitlab_issue).to eq('https://gitlab.com/gitlab-org/gitlab/issues/1')
end end
it 'has the correct tags' do
expect(subject.tags).to eq({ level: issue_sample_response['level'], logger: issue_sample_response['logger'] })
end
end end
end end
end end
...@@ -17,7 +17,8 @@ describe ChatMessage::WikiPageMessage do ...@@ -17,7 +17,8 @@ describe ChatMessage::WikiPageMessage do
object_attributes: { object_attributes: {
title: 'Wiki page title', title: 'Wiki page title',
url: 'http://url.com', url: 'http://url.com',
content: 'Wiki page description' content: 'Wiki page content',
message: 'Wiki page commit message'
} }
} }
end end
...@@ -57,10 +58,10 @@ describe ChatMessage::WikiPageMessage do ...@@ -57,10 +58,10 @@ describe ChatMessage::WikiPageMessage do
args[:object_attributes][:action] = 'create' args[:object_attributes][:action] = 'create'
end end
it 'returns the attachment for a new wiki page' do it 'returns the commit message for a new wiki page' do
expect(subject.attachments).to eq([ expect(subject.attachments).to eq([
{ {
text: "Wiki page description", text: "Wiki page commit message",
color: color color: color
} }
]) ])
...@@ -72,10 +73,10 @@ describe ChatMessage::WikiPageMessage do ...@@ -72,10 +73,10 @@ describe ChatMessage::WikiPageMessage do
args[:object_attributes][:action] = 'update' args[:object_attributes][:action] = 'update'
end end
it 'returns the attachment for an updated wiki page' do it 'returns the commit message for an updated wiki page' do
expect(subject.attachments).to eq([ expect(subject.attachments).to eq([
{ {
text: "Wiki page description", text: "Wiki page commit message",
color: color color: color
} }
]) ])
...@@ -119,8 +120,8 @@ describe ChatMessage::WikiPageMessage do ...@@ -119,8 +120,8 @@ describe ChatMessage::WikiPageMessage do
args[:object_attributes][:action] = 'create' args[:object_attributes][:action] = 'create'
end end
it 'returns the attachment for a new wiki page' do it 'returns the commit message for a new wiki page' do
expect(subject.attachments).to eq('Wiki page description') expect(subject.attachments).to eq('Wiki page commit message')
end end
end end
...@@ -129,8 +130,8 @@ describe ChatMessage::WikiPageMessage do ...@@ -129,8 +130,8 @@ describe ChatMessage::WikiPageMessage do
args[:object_attributes][:action] = 'update' args[:object_attributes][:action] = 'update'
end end
it 'returns the attachment for an updated wiki page' do it 'returns the commit message for an updated wiki page' do
expect(subject.attachments).to eq('Wiki page description') expect(subject.attachments).to eq('Wiki page commit message')
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment