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