summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-12-20 15:07:34 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-20 15:07:34 +0000
commit8b61452138ecc511b52cd49be4ee6b8a80390c50 (patch)
tree122b817432c2a0f0e23767bd95791a89b20540c0
parentf864f8a7aafa45b0e4c04e4312f89da4b1227c0f (diff)
downloadgitlab-ce-8b61452138ecc511b52cd49be4ee6b8a80390c50.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--VERSION2
-rw-r--r--app/models/project_services/chat_message/wiki_page_message.rb2
-rw-r--r--app/serializers/error_tracking/detailed_error_entity.rb1
-rw-r--r--changelogs/unreleased/119031-add-tags-to-sentry-error-api-rest.yml5
-rw-r--r--changelogs/unreleased/39140-scope-modsec-feature-flag-to-groups.yml5
-rw-r--r--changelogs/unreleased/wiki-page-message.yml5
-rw-r--r--danger/commit_messages/Dangerfile14
-rw-r--r--db/migrate/20191217212348_add_modsecurity_enabled_to_ingress_application.rb16
-rw-r--r--db/schema.rb1
-rw-r--r--doc/development/fe_guide/design_patterns.md6
-rw-r--r--lib/gitlab/error_tracking/detailed_error.rb1
-rw-r--r--lib/sentry/client/issue.rb8
-rw-r--r--spec/factories/error_tracking/detailed_error.rb6
-rw-r--r--spec/fixtures/api/schemas/error_tracking/error_detailed.json34
-rw-r--r--spec/frontend/behaviors/bind_in_out_spec.js204
-rw-r--r--spec/frontend/bootstrap_jquery_spec.js (renamed from spec/javascripts/bootstrap_jquery_spec.js)25
-rw-r--r--spec/frontend/branches/branches_delete_modal_spec.js (renamed from spec/javascripts/branches/branches_delete_modal_spec.js)2
-rw-r--r--spec/frontend/breakpoints_spec.js (renamed from spec/javascripts/breakpoints_spec.js)6
-rw-r--r--spec/frontend/diffs/components/settings_dropdown_spec.js (renamed from spec/javascripts/diffs/components/settings_dropdown_spec.js)14
-rw-r--r--spec/frontend/droplab/constants_spec.js39
-rw-r--r--spec/frontend/droplab/plugins/ajax_filter_spec.js (renamed from spec/javascripts/droplab/plugins/ajax_filter_spec.js)10
-rw-r--r--spec/frontend/droplab/plugins/ajax_spec.js (renamed from spec/javascripts/droplab/plugins/ajax_spec.js)8
-rw-r--r--spec/frontend/feature_highlight/feature_highlight_options_spec.js (renamed from spec/javascripts/feature_highlight/feature_highlight_options_spec.js)8
-rw-r--r--spec/frontend/filtered_search/components/recent_searches_dropdown_content_spec.js (renamed from spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js)4
-rw-r--r--spec/frontend/filtered_search/dropdown_user_spec.js (renamed from spec/javascripts/filtered_search/dropdown_user_spec.js)18
-rw-r--r--spec/frontend/frequent_items/components/frequent_items_search_input_spec.js (renamed from spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js)10
-rw-r--r--spec/frontend/gl_field_errors_spec.js (renamed from spec/javascripts/gl_field_errors_spec.js)62
-rw-r--r--spec/frontend/gpg_badges_spec.js (renamed from spec/javascripts/gpg_badges_spec.js)4
-rw-r--r--spec/frontend/header_spec.js (renamed from spec/javascripts/header_spec.js)2
-rw-r--r--spec/frontend/helpers/class_spec_helper_spec.js (renamed from spec/javascripts/helpers/class_spec_helper_spec.js)10
-rw-r--r--spec/frontend/ide/components/commit_sidebar/stage_button_spec.js (renamed from spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js)4
-rw-r--r--spec/frontend/ide/components/commit_sidebar/unstage_button_spec.js (renamed from spec/javascripts/ide/components/commit_sidebar/unstage_button_spec.js)2
-rw-r--r--spec/frontend/ide/components/jobs/detail/scroll_button_spec.js (renamed from spec/javascripts/ide/components/jobs/detail/scroll_button_spec.js)2
-rw-r--r--spec/frontend/ide/stores/actions/file_spec.js (renamed from spec/javascripts/ide/stores/actions/file_spec.js)32
-rw-r--r--spec/frontend/image_diff/helpers/init_image_diff_spec.js (renamed from spec/javascripts/image_diff/helpers/init_image_diff_spec.js)4
-rw-r--r--spec/frontend/image_diff/init_discussion_tab_spec.js (renamed from spec/javascripts/image_diff/init_discussion_tab_spec.js)22
-rw-r--r--spec/frontend/issue_show/components/edit_actions_spec.js (renamed from spec/javascripts/issue_show/components/edit_actions_spec.js)8
-rw-r--r--spec/frontend/issue_show/components/fields/description_spec.js (renamed from spec/javascripts/issue_show/components/fields/description_spec.js)2
-rw-r--r--spec/frontend/issue_show/components/fields/title_spec.js (renamed from spec/javascripts/issue_show/components/fields/title_spec.js)2
-rw-r--r--spec/frontend/issue_show/index_spec.js (renamed from spec/javascripts/issue_show/index_spec.js)2
-rw-r--r--spec/frontend/jobs/components/job_log_controllers_spec.js (renamed from spec/javascripts/jobs/components/job_log_controllers_spec.js)8
-rw-r--r--spec/frontend/namespace_select_spec.js (renamed from spec/javascripts/namespace_select_spec.js)10
-rw-r--r--spec/frontend/new_branch_spec.js (renamed from spec/javascripts/new_branch_spec.js)68
-rw-r--r--spec/frontend/notes/components/discussion_filter_note_spec.js (renamed from spec/javascripts/notes/components/discussion_filter_note_spec.js)6
-rw-r--r--spec/frontend/notes/components/note_header_spec.js (renamed from spec/javascripts/notes/components/note_header_spec.js)2
-rw-r--r--spec/frontend/notes/stores/getters_spec.js (renamed from spec/javascripts/notes/stores/getters_spec.js)2
-rw-r--r--spec/frontend/notes/stores/mutation_spec.js (renamed from spec/javascripts/notes/stores/mutation_spec.js)4
-rw-r--r--spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js (renamed from spec/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js)6
-rw-r--r--spec/frontend/pipelines/nav_controls_spec.js (renamed from spec/javascripts/pipelines/nav_controls_spec.js)2
-rw-r--r--spec/frontend/polyfills/element_spec.js46
-rw-r--r--spec/frontend/profile/add_ssh_key_validation_spec.js (renamed from spec/javascripts/profile/add_ssh_key_validation_spec.js)10
-rw-r--r--spec/frontend/project_select_combo_button_spec.js140
-rw-r--r--spec/frontend/shared/popover_spec.js (renamed from spec/javascripts/shared/popover_spec.js)38
-rw-r--r--spec/frontend/sidebar/sidebar_store_spec.js168
-rw-r--r--spec/frontend/syntax_highlight_spec.js (renamed from spec/javascripts/syntax_highlight_spec.js)26
-rw-r--r--spec/frontend/task_list_spec.js (renamed from spec/javascripts/task_list_spec.js)30
-rw-r--r--spec/frontend/version_check_image_spec.js42
-rw-r--r--spec/frontend/vue_shared/components/gl_modal_vuex_spec.js (renamed from spec/javascripts/vue_shared/components/gl_modal_vuex_spec.js)10
-rw-r--r--spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js (renamed from spec/javascripts/vue_shared/components/markdown/suggestion_diff_spec.js)2
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js (renamed from spec/javascripts/vue_shared/components/user_avatar/user_avatar_list_spec.js)2
-rw-r--r--spec/javascripts/behaviors/bind_in_out_spec.js192
-rw-r--r--spec/javascripts/droplab/constants_spec.js39
-rw-r--r--spec/javascripts/polyfills/element_spec.js36
-rw-r--r--spec/javascripts/project_select_combo_button_spec.js124
-rw-r--r--spec/javascripts/sidebar/sidebar_store_spec.js162
-rw-r--r--spec/javascripts/version_check_image_spec.js35
-rw-r--r--spec/lib/sentry/client/issue_spec.rb4
-rw-r--r--spec/models/project_services/chat_message/wiki_page_message_spec.rb19
68 files changed, 990 insertions, 855 deletions
diff --git a/VERSION b/VERSION
index 56219811eaa..158cd7e61ba 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-12.6.0-pre
+12.7.0-pre
diff --git a/app/models/project_services/chat_message/wiki_page_message.rb b/app/models/project_services/chat_message/wiki_page_message.rb
index b605d289278..ebe7abb379f 100644
--- a/app/models/project_services/chat_message/wiki_page_message.rb
+++ b/app/models/project_services/chat_message/wiki_page_message.rb
@@ -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]
diff --git a/app/serializers/error_tracking/detailed_error_entity.rb b/app/serializers/error_tracking/detailed_error_entity.rb
index dd0cac8e4cd..fdafa2cf203 100644
--- a/app/serializers/error_tracking/detailed_error_entity.rb
+++ b/app/serializers/error_tracking/detailed_error_entity.rb
@@ -21,6 +21,7 @@ module ErrorTracking
:project_slug,
:short_id,
:status,
+ :tags,
:title,
:type,
:user_count
diff --git a/changelogs/unreleased/119031-add-tags-to-sentry-error-api-rest.yml b/changelogs/unreleased/119031-add-tags-to-sentry-error-api-rest.yml
new file mode 100644
index 00000000000..19713a6fea2
--- /dev/null
+++ b/changelogs/unreleased/119031-add-tags-to-sentry-error-api-rest.yml
@@ -0,0 +1,5 @@
+---
+title: Add tags to sentry detailed error response
+merge_request: 22068
+author:
+type: added
diff --git a/changelogs/unreleased/39140-scope-modsec-feature-flag-to-groups.yml b/changelogs/unreleased/39140-scope-modsec-feature-flag-to-groups.yml
new file mode 100644
index 00000000000..54b0a8ac6db
--- /dev/null
+++ b/changelogs/unreleased/39140-scope-modsec-feature-flag-to-groups.yml
@@ -0,0 +1,5 @@
+---
+title: Add modsecurity_enabled setting to managed ingress
+merge_request: 21968
+author:
+type: added
diff --git a/changelogs/unreleased/wiki-page-message.yml b/changelogs/unreleased/wiki-page-message.yml
new file mode 100644
index 00000000000..028c3cfd1e0
--- /dev/null
+++ b/changelogs/unreleased/wiki-page-message.yml
@@ -0,0 +1,5 @@
+---
+title: Include commit message instead of entire page content in Wiki chat notifications
+merge_request: 21722
+author: Ville Skyttä
+type: changed
diff --git a/danger/commit_messages/Dangerfile b/danger/commit_messages/Dangerfile
index 60bc90139ab..a7466aa6ffb 100644
--- a/danger/commit_messages/Dangerfile
+++ b/danger/commit_messages/Dangerfile
@@ -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
diff --git a/db/migrate/20191217212348_add_modsecurity_enabled_to_ingress_application.rb b/db/migrate/20191217212348_add_modsecurity_enabled_to_ingress_application.rb
new file mode 100644
index 00000000000..2690a5762dd
--- /dev/null
+++ b/db/migrate/20191217212348_add_modsecurity_enabled_to_ingress_application.rb
@@ -0,0 +1,16 @@
+# 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
diff --git a/db/schema.rb b/db/schema.rb
index dee28ea4287..0f709482884 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -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
diff --git a/doc/development/fe_guide/design_patterns.md b/doc/development/fe_guide/design_patterns.md
index a7a0f39e2f3..72a7861ffcb 100644
--- a/doc/development/fe_guide/design_patterns.md
+++ b/doc/development/fe_guide/design_patterns.md
@@ -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() {
diff --git a/lib/gitlab/error_tracking/detailed_error.rb b/lib/gitlab/error_tracking/detailed_error.rb
index 169d6c03f12..a95e367c8b8 100644
--- a/lib/gitlab/error_tracking/detailed_error.rb
+++ b/lib/gitlab/error_tracking/detailed_error.rb
@@ -26,6 +26,7 @@ module Gitlab
:project_slug,
:short_id,
:status,
+ :tags,
:title,
:type,
:user_count
diff --git a/lib/sentry/client/issue.rb b/lib/sentry/client/issue.rb
index 08ed5392a11..28e87ab18a1 100644
--- a/lib/sentry/client/issue.rb
+++ b/lib/sentry/client/issue.rb
@@ -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
diff --git a/spec/factories/error_tracking/detailed_error.rb b/spec/factories/error_tracking/detailed_error.rb
index f12c327d403..b0114558bd4 100644
--- a/spec/factories/error_tracking/detailed_error.rb
+++ b/spec/factories/error_tracking/detailed_error.rb
@@ -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]
diff --git a/spec/fixtures/api/schemas/error_tracking/error_detailed.json b/spec/fixtures/api/schemas/error_tracking/error_detailed.json
index 2a1cd2c03e0..9a6797bf3c7 100644
--- a/spec/fixtures/api/schemas/error_tracking/error_detailed.json
+++ b/spec/fixtures/api/schemas/error_tracking/error_detailed.json
@@ -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"] },
diff --git a/spec/frontend/behaviors/bind_in_out_spec.js b/spec/frontend/behaviors/bind_in_out_spec.js
new file mode 100644
index 00000000000..923b6d372dd
--- /dev/null
+++ b/spec/frontend/behaviors/bind_in_out_spec.js
@@ -0,0 +1,204 @@
+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}"]`,
+ );
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/bootstrap_jquery_spec.js b/spec/frontend/bootstrap_jquery_spec.js
index 6957cf40301..d5d592e3839 100644
--- a/spec/javascripts/bootstrap_jquery_spec.js
+++ b/spec/frontend/bootstrap_jquery_spec.js
@@ -1,37 +1,40 @@
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();
diff --git a/spec/javascripts/branches/branches_delete_modal_spec.js b/spec/frontend/branches/branches_delete_modal_spec.js
index b223b8e2c0a..21608feafc8 100644
--- a/spec/javascripts/branches/branches_delete_modal_spec.js
+++ b/spec/frontend/branches/branches_delete_modal_spec.js
@@ -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();
diff --git a/spec/javascripts/breakpoints_spec.js b/spec/frontend/breakpoints_spec.js
index fc0d9eb907a..c9014ddd3e2 100644
--- a/spec/javascripts/breakpoints_spec.js
+++ b/spec/frontend/breakpoints_spec.js
@@ -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);
});
diff --git a/spec/javascripts/diffs/components/settings_dropdown_spec.js b/spec/frontend/diffs/components/settings_dropdown_spec.js
index 6c08474ffd2..c360f5584ca 100644
--- a/spec/javascripts/diffs/components/settings_dropdown_spec.js
+++ b/spec/frontend/diffs/components/settings_dropdown_spec.js
@@ -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,
diff --git a/spec/frontend/droplab/constants_spec.js b/spec/frontend/droplab/constants_spec.js
new file mode 100644
index 00000000000..fd48228d6a2
--- /dev/null
+++ b/spec/frontend/droplab/constants_spec.js
@@ -0,0 +1,39 @@
+import * as constants from '~/droplab/constants';
+
+describe('constants', () => {
+ describe('DATA_TRIGGER', () => {
+ it('should be `data-dropdown-trigger`', () => {
+ expect(constants.DATA_TRIGGER).toBe('data-dropdown-trigger');
+ });
+ });
+
+ describe('DATA_DROPDOWN', () => {
+ it('should be `data-dropdown`', () => {
+ expect(constants.DATA_DROPDOWN).toBe('data-dropdown');
+ });
+ });
+
+ describe('SELECTED_CLASS', () => {
+ it('should be `droplab-item-selected`', () => {
+ expect(constants.SELECTED_CLASS).toBe('droplab-item-selected');
+ });
+ });
+
+ describe('ACTIVE_CLASS', () => {
+ it('should be `droplab-item-active`', () => {
+ expect(constants.ACTIVE_CLASS).toBe('droplab-item-active');
+ });
+ });
+
+ describe('TEMPLATE_REGEX', () => {
+ it('should be a handlebars templating syntax regex', () => {
+ expect(constants.TEMPLATE_REGEX).toEqual(/\{\{(.+?)\}\}/g);
+ });
+ });
+
+ describe('IGNORE_CLASS', () => {
+ it('should be `droplab-item-ignore`', () => {
+ expect(constants.IGNORE_CLASS).toBe('droplab-item-ignore');
+ });
+ });
+});
diff --git a/spec/javascripts/droplab/plugins/ajax_filter_spec.js b/spec/frontend/droplab/plugins/ajax_filter_spec.js
index 5dbe50af07f..5ec0400cbc5 100644
--- a/spec/javascripts/droplab/plugins/ajax_filter_spec.js
+++ b/spec/frontend/droplab/plugins/ajax_filter_spec.js
@@ -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);
diff --git a/spec/javascripts/droplab/plugins/ajax_spec.js b/spec/frontend/droplab/plugins/ajax_spec.js
index 2f492d00c0a..1d7576ce420 100644
--- a/spec/javascripts/droplab/plugins/ajax_spec.js
+++ b/spec/frontend/droplab/plugins/ajax_spec.js
@@ -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);
});
});
});
diff --git a/spec/javascripts/feature_highlight/feature_highlight_options_spec.js b/spec/frontend/feature_highlight/feature_highlight_options_spec.js
index 7f9425d8abe..cd41d1ed091 100644
--- a/spec/javascripts/feature_highlight/feature_highlight_options_spec.js
+++ b/spec/frontend/feature_highlight/feature_highlight_options_spec.js
@@ -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);
});
diff --git a/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js b/spec/frontend/filtered_search/components/recent_searches_dropdown_content_spec.js
index d1742dcedfa..2543fb8768b 100644
--- a/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js
+++ b/spec/frontend/filtered_search/components/recent_searches_dropdown_content_spec.js
@@ -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);
diff --git a/spec/javascripts/filtered_search/dropdown_user_spec.js b/spec/frontend/filtered_search/dropdown_user_spec.js
index f764800fff0..8eef10290bf 100644
--- a/spec/javascripts/filtered_search/dropdown_user_spec.js
+++ b/spec/frontend/filtered_search/dropdown_user_spec.js
@@ -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', () => {
diff --git a/spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js b/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js
index be11af8428f..e5f1ab21c7f 100644
--- a/spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js
+++ b/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js
@@ -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();
});
diff --git a/spec/javascripts/gl_field_errors_spec.js b/spec/frontend/gl_field_errors_spec.js
index 294f219d6fe..4653f519f65 100644
--- a/spec/javascripts/gl_field_errors_spec.js
+++ b/spec/frontend/gl_field_errors_spec.js
@@ -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];
diff --git a/spec/javascripts/gpg_badges_spec.js b/spec/frontend/gpg_badges_spec.js
index 4731484e02d..809cc5c88e2 100644
--- a/spec/javascripts/gpg_badges_spec.js
+++ b/spec/frontend/gpg_badges_spec.js
@@ -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'))
diff --git a/spec/javascripts/header_spec.js b/spec/frontend/header_spec.js
index c36d3be1b22..00b5b306d66 100644
--- a/spec/javascripts/header_spec.js
+++ b/spec/frontend/header_spec.js
@@ -1,7 +1,7 @@
import $ from 'jquery';
import initTodoToggle from '~/header';
-describe('Header', function() {
+describe('Header', () => {
const todosPendingCount = '.todos-count';
const fixtureTemplate = 'issues/open-issue.html';
diff --git a/spec/javascripts/helpers/class_spec_helper_spec.js b/spec/frontend/helpers/class_spec_helper_spec.js
index f6268b0fb6d..533d5687bde 100644
--- a/spec/javascripts/helpers/class_spec_helper_spec.js
+++ b/spec/frontend/helpers/class_spec_helper_spec.js
@@ -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');
diff --git a/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js b/spec/frontend/ide/components/commit_sidebar/stage_button_spec.js
index e09ccbe2a63..b59de4dac0e 100644
--- a/spec/javascripts/ide/components/commit_sidebar/stage_button_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/stage_button_spec.js
@@ -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();
});
diff --git a/spec/javascripts/ide/components/commit_sidebar/unstage_button_spec.js b/spec/frontend/ide/components/commit_sidebar/unstage_button_spec.js
index 917bbb9fb46..53b53c8c815 100644
--- a/spec/javascripts/ide/components/commit_sidebar/unstage_button_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/unstage_button_spec.js
@@ -16,7 +16,7 @@ describe('IDE unstage file button', () => {
path: f.path,
});
- spyOn(vm, 'unstageChange');
+ jest.spyOn(vm, 'unstageChange').mockImplementation(() => {});
vm.$mount();
});
diff --git a/spec/javascripts/ide/components/jobs/detail/scroll_button_spec.js b/spec/frontend/ide/components/jobs/detail/scroll_button_spec.js
index fff382a107f..096851a5401 100644
--- a/spec/javascripts/ide/components/jobs/detail/scroll_button_spec.js
+++ b/spec/frontend/ide/components/jobs/detail/scroll_button_spec.js
@@ -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();
diff --git a/spec/javascripts/ide/stores/actions/file_spec.js b/spec/frontend/ide/stores/actions/file_spec.js
index 03d1125c23a..283ea266821 100644
--- a/spec/javascripts/ide/stores/actions/file_spec.js
+++ b/spec/frontend/ide/stores/actions/file_spec.js
@@ -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 => {
diff --git a/spec/javascripts/image_diff/helpers/init_image_diff_spec.js b/spec/frontend/image_diff/helpers/init_image_diff_spec.js
index ba501d58965..dc872ace265 100644
--- a/spec/javascripts/image_diff/helpers/init_image_diff_spec.js
+++ b/spec/frontend/image_diff/helpers/init_image_diff_spec.js
@@ -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(() => {
diff --git a/spec/javascripts/image_diff/init_discussion_tab_spec.js b/spec/frontend/image_diff/init_discussion_tab_spec.js
index 5eb87e1df25..f459fdf5a08 100644
--- a/spec/javascripts/image_diff/init_discussion_tab_spec.js
+++ b/spec/frontend/image_diff/init_discussion_tab_spec.js
@@ -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);
});
});
diff --git a/spec/javascripts/issue_show/components/edit_actions_spec.js b/spec/frontend/issue_show/components/edit_actions_spec.js
index 2ab74ae4e10..b0c1894058e 100644
--- a/spec/javascripts/issue_show/components/edit_actions_spec.js
+++ b/spec/frontend/issue_show/components/edit_actions_spec.js
@@ -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(() => {
diff --git a/spec/javascripts/issue_show/components/fields/description_spec.js b/spec/frontend/issue_show/components/fields/description_spec.js
index f5f87a6bfbf..8ea326ad1ee 100644
--- a/spec/javascripts/issue_show/components/fields/description_spec.js
+++ b/spec/frontend/issue_show/components/fields/description_spec.js
@@ -20,7 +20,7 @@ describe('Description field component', () => {
document.body.appendChild(el);
- spyOn(eventHub, '$emit');
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
vm = new Component({
el,
diff --git a/spec/javascripts/issue_show/components/fields/title_spec.js b/spec/frontend/issue_show/components/fields/title_spec.js
index 62dff983250..99e8658b89f 100644
--- a/spec/javascripts/issue_show/components/fields/title_spec.js
+++ b/spec/frontend/issue_show/components/fields/title_spec.js
@@ -17,7 +17,7 @@ describe('Title field component', () => {
});
store.formState.title = 'test';
- spyOn(eventHub, '$emit');
+ jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
vm = new Component({
propsData: {
diff --git a/spec/javascripts/issue_show/index_spec.js b/spec/frontend/issue_show/index_spec.js
index fa0b426c06c..e80d1b83c11 100644
--- a/spec/javascripts/issue_show/index_spec.js
+++ b/spec/frontend/issue_show/index_spec.js
@@ -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();
diff --git a/spec/javascripts/jobs/components/job_log_controllers_spec.js b/spec/frontend/jobs/components/job_log_controllers_spec.js
index d527c6708fc..04f20811601 100644
--- a/spec/javascripts/jobs/components/job_log_controllers_spec.js
+++ b/spec/frontend/jobs/components/job_log_controllers_spec.js
@@ -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');
diff --git a/spec/javascripts/namespace_select_spec.js b/spec/frontend/namespace_select_spec.js
index 07b82ce721e..399fa950769 100644
--- a/spec/javascripts/namespace_select_spec.js
+++ b/spec/frontend/namespace_select_spec.js
@@ -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 });
diff --git a/spec/javascripts/new_branch_spec.js b/spec/frontend/new_branch_spec.js
index 4e3140ce4f1..cff7ec1a9ee 100644
--- a/spec/javascripts/new_branch_spec.js
+++ b/spec/frontend/new_branch_spec.js
@@ -1,8 +1,14 @@
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);
diff --git a/spec/javascripts/notes/components/discussion_filter_note_spec.js b/spec/frontend/notes/components/discussion_filter_note_spec.js
index 52d2e7ce947..6b5f42a84e8 100644
--- a/spec/javascripts/notes/components/discussion_filter_note_spec.js
+++ b/spec/frontend/notes/components/discussion_filter_note_spec.js
@@ -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'));
diff --git a/spec/javascripts/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js
index 6d1a7ef370f..9b432387654 100644
--- a/spec/javascripts/notes/components/note_header_spec.js
+++ b/spec/frontend/notes/components/note_header_spec.js
@@ -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();
diff --git a/spec/javascripts/notes/stores/getters_spec.js b/spec/frontend/notes/stores/getters_spec.js
index d69f469c7c7..83417bd70ef 100644
--- a/spec/javascripts/notes/stores/getters_spec.js
+++ b/spec/frontend/notes/stores/getters_spec.js
@@ -327,7 +327,7 @@ describe('Getters Notes Store', () => {
beforeEach(() => {
neighbor = {};
- findUnresolvedDiscussionIdNeighbor = jasmine.createSpy().and.returnValue(neighbor);
+ findUnresolvedDiscussionIdNeighbor = jest.fn(() => neighbor);
localGetters = { findUnresolvedDiscussionIdNeighbor };
});
diff --git a/spec/javascripts/notes/stores/mutation_spec.js b/spec/frontend/notes/stores/mutation_spec.js
index ade4725dd68..49debe348e2 100644
--- a/spec/javascripts/notes/stores/mutation_spec.js
+++ b/spec/frontend/notes/stores/mutation_spec.js
@@ -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,
diff --git a/spec/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js b/spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js
index 5f4dba5ecb9..8917251d285 100644
--- a/spec/javascripts/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js
+++ b/spec/frontend/pages/projects/pipeline_schedules/shared/components/timezone_dropdown_spec.js
@@ -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,
diff --git a/spec/javascripts/pipelines/nav_controls_spec.js b/spec/frontend/pipelines/nav_controls_spec.js
index 7806cdf1477..6d28da0ea2a 100644
--- a/spec/javascripts/pipelines/nav_controls_spec.js
+++ b/spec/frontend/pipelines/nav_controls_spec.js
@@ -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();
diff --git a/spec/frontend/polyfills/element_spec.js b/spec/frontend/polyfills/element_spec.js
new file mode 100644
index 00000000000..64ce248ca44
--- /dev/null
+++ b/spec/frontend/polyfills/element_spec.js
@@ -0,0 +1,46 @@
+import '~/commons/polyfills/element';
+
+describe('Element polyfills', () => {
+ let testContext;
+
+ beforeEach(() => {
+ testContext = {};
+ });
+
+ beforeEach(() => {
+ testContext.element = document.createElement('ul');
+ });
+
+ describe('matches', () => {
+ it('returns true if element matches the selector', () => {
+ expect(testContext.element.matches('ul')).toBeTruthy();
+ });
+
+ it("returns false if element doesn't match the selector", () => {
+ expect(testContext.element.matches('.not-an-element')).toBeFalsy();
+ });
+ });
+
+ describe('closest', () => {
+ beforeEach(() => {
+ testContext.childElement = document.createElement('li');
+ testContext.element.appendChild(testContext.childElement);
+ });
+
+ it('returns the closest parent that matches the selector', () => {
+ expect(testContext.childElement.closest('ul').toString()).toBe(
+ testContext.element.toString(),
+ );
+ });
+
+ it('returns itself if it matches the selector', () => {
+ expect(testContext.childElement.closest('li').toString()).toBe(
+ testContext.childElement.toString(),
+ );
+ });
+
+ it('returns undefined if nothing matches the selector', () => {
+ expect(testContext.childElement.closest('.no-an-element')).toBeFalsy();
+ });
+ });
+});
diff --git a/spec/javascripts/profile/add_ssh_key_validation_spec.js b/spec/frontend/profile/add_ssh_key_validation_spec.js
index c71a2885acc..1fec864599c 100644
--- a/spec/javascripts/profile/add_ssh_key_validation_spec.js
+++ b/spec/frontend/profile/add_ssh_key_validation_spec.js
@@ -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);
diff --git a/spec/frontend/project_select_combo_button_spec.js b/spec/frontend/project_select_combo_button_spec.js
new file mode 100644
index 00000000000..c47db71b4ac
--- /dev/null
+++ b/spec/frontend/project_select_combo_button_spec.js
@@ -0,0 +1,140 @@
+import $ from 'jquery';
+import ProjectSelectComboButton from '~/project_select_combo_button';
+
+const fixturePath = 'static/project_select_combo_button.html';
+
+describe('Project Select Combo Button', () => {
+ let testContext;
+
+ beforeEach(() => {
+ testContext = {};
+ });
+
+ preloadFixtures(fixturePath);
+
+ beforeEach(() => {
+ testContext.defaults = {
+ label: 'Select project to create issue',
+ groupId: 12345,
+ projectMeta: {
+ name: 'My Cool Project',
+ url: 'http://mycoolproject.com',
+ },
+ newProjectMeta: {
+ name: 'My Other Cool Project',
+ url: 'http://myothercoolproject.com',
+ },
+ localStorageKey: 'group-12345-new-issue-recent-project',
+ relativePath: 'issues/new',
+ };
+
+ loadFixtures(fixturePath);
+
+ testContext.newItemBtn = document.querySelector('.new-project-item-link');
+ testContext.projectSelectInput = document.querySelector('.project-item-select');
+ });
+
+ describe('on page load when localStorage is empty', () => {
+ beforeEach(() => {
+ testContext.comboButton = new ProjectSelectComboButton(testContext.projectSelectInput);
+ });
+
+ it('newItemBtn href is null', () => {
+ expect(testContext.newItemBtn.getAttribute('href')).toBe('');
+ });
+
+ it('newItemBtn text is the plain default label', () => {
+ expect(testContext.newItemBtn.textContent).toBe(testContext.defaults.label);
+ });
+ });
+
+ describe('on page load when localStorage is filled', () => {
+ beforeEach(() => {
+ window.localStorage.setItem(
+ testContext.defaults.localStorageKey,
+ JSON.stringify(testContext.defaults.projectMeta),
+ );
+ testContext.comboButton = new ProjectSelectComboButton(testContext.projectSelectInput);
+ });
+
+ it('newItemBtn href is correctly set', () => {
+ expect(testContext.newItemBtn.getAttribute('href')).toBe(
+ testContext.defaults.projectMeta.url,
+ );
+ });
+
+ it('newItemBtn text is the cached label', () => {
+ expect(testContext.newItemBtn.textContent).toBe(
+ `New issue in ${testContext.defaults.projectMeta.name}`,
+ );
+ });
+
+ afterEach(() => {
+ window.localStorage.clear();
+ });
+ });
+
+ 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(testContext.defaults.newProjectMeta))
+ .trigger('change');
+ });
+
+ 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', () => {
+ expect(testContext.newItemBtn.textContent).toBe(
+ `New issue in ${testContext.defaults.newProjectMeta.name}`,
+ );
+ });
+
+ afterEach(() => {
+ window.localStorage.clear();
+ });
+ });
+
+ describe('deriveTextVariants', () => {
+ beforeEach(() => {
+ testContext.mockExecutionContext = {
+ resourceType: '',
+ resourceLabel: '',
+ };
+
+ testContext.comboButton = new ProjectSelectComboButton(testContext.projectSelectInput);
+
+ testContext.method = testContext.comboButton.deriveTextVariants.bind(
+ testContext.mockExecutionContext,
+ );
+ });
+
+ it('correctly derives test variants for merge requests', () => {
+ testContext.mockExecutionContext.resourceType = 'merge_requests';
+ testContext.mockExecutionContext.resourceLabel = 'New merge request';
+
+ 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', () => {
+ testContext.mockExecutionContext.resourceType = 'issues';
+ testContext.mockExecutionContext.resourceLabel = 'New issue';
+
+ const returnedVariants = testContext.method();
+
+ expect(returnedVariants.localStorageItemType).toBe('new-issue');
+ expect(returnedVariants.defaultTextPrefix).toBe('New issue');
+ expect(returnedVariants.presetTextSuffix).toBe('issue');
+ });
+ });
+});
diff --git a/spec/javascripts/shared/popover_spec.js b/spec/frontend/shared/popover_spec.js
index cc2b2014d38..bbde936185e 100644
--- a/spec/javascripts/shared/popover_spec.js
+++ b/spec/frontend/shared/popover_spec.js
@@ -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();
diff --git a/spec/frontend/sidebar/sidebar_store_spec.js b/spec/frontend/sidebar/sidebar_store_spec.js
new file mode 100644
index 00000000000..6d063a7cfcf
--- /dev/null
+++ b/spec/frontend/sidebar/sidebar_store_spec.js
@@ -0,0 +1,168 @@
+import SidebarStore from '~/sidebar/stores/sidebar_store';
+import Mock from './mock_data';
+import UsersMockHelper from '../helpers/user_mock_data_helper';
+
+const ASSIGNEE = {
+ id: 2,
+ name: 'gitlab user 2',
+ username: 'gitlab2',
+ avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+};
+
+const ANOTHER_ASSINEE = {
+ id: 3,
+ name: 'gitlab user 3',
+ username: 'gitlab3',
+ avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+};
+
+const PARTICIPANT = {
+ id: 1,
+ state: 'active',
+ username: 'marcene',
+ name: 'Allie Will',
+ web_url: 'foo.com',
+ avatar_url: 'gravatar.com/avatar/xxx',
+};
+
+const PARTICIPANT_LIST = [PARTICIPANT, { ...PARTICIPANT, id: 2 }, { ...PARTICIPANT, id: 3 }];
+
+describe('Sidebar store', () => {
+ let testContext;
+
+ beforeEach(() => {
+ testContext = {};
+ });
+
+ beforeEach(() => {
+ testContext.store = new SidebarStore({
+ currentUser: {
+ id: 1,
+ name: 'Administrator',
+ username: 'root',
+ avatar_url:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ },
+ editable: true,
+ rootPath: '/',
+ endpoint: '/gitlab-org/gitlab-shell/issues/5.json',
+ });
+ });
+
+ afterEach(() => {
+ SidebarStore.singleton = null;
+ });
+
+ it('has default isFetching values', () => {
+ expect(testContext.store.isFetching.assignees).toBe(true);
+ });
+
+ it('adds a new assignee', () => {
+ testContext.store.addAssignee(ASSIGNEE);
+
+ expect(testContext.store.assignees.length).toEqual(1);
+ });
+
+ it('removes an assignee', () => {
+ testContext.store.removeAssignee(ASSIGNEE);
+
+ expect(testContext.store.assignees.length).toEqual(0);
+ });
+
+ it('finds an existent assignee', () => {
+ let foundAssignee;
+
+ testContext.store.addAssignee(ASSIGNEE);
+ foundAssignee = testContext.store.findAssignee(ASSIGNEE);
+
+ expect(foundAssignee).toBeDefined();
+ expect(foundAssignee).toEqual(ASSIGNEE);
+ foundAssignee = testContext.store.findAssignee(ANOTHER_ASSINEE);
+
+ expect(foundAssignee).toBeUndefined();
+ });
+
+ it('removes all assignees', () => {
+ testContext.store.removeAllAssignees();
+
+ expect(testContext.store.assignees.length).toEqual(0);
+ });
+
+ it('sets participants data', () => {
+ expect(testContext.store.participants.length).toEqual(0);
+
+ testContext.store.setParticipantsData({
+ participants: PARTICIPANT_LIST,
+ });
+
+ expect(testContext.store.isFetching.participants).toEqual(false);
+ expect(testContext.store.participants.length).toEqual(PARTICIPANT_LIST.length);
+ });
+
+ it('sets subcriptions data', () => {
+ expect(testContext.store.subscribed).toEqual(null);
+
+ testContext.store.setSubscriptionsData({
+ subscribed: true,
+ });
+
+ expect(testContext.store.isFetching.subscriptions).toEqual(false);
+ expect(testContext.store.subscribed).toEqual(true);
+ });
+
+ it('set assigned data', () => {
+ const users = {
+ assignees: UsersMockHelper.createNumberRandomUsers(3),
+ };
+
+ testContext.store.setAssigneeData(users);
+
+ expect(testContext.store.isFetching.assignees).toBe(false);
+ expect(testContext.store.assignees.length).toEqual(3);
+ });
+
+ it('sets fetching state', () => {
+ expect(testContext.store.isFetching.participants).toEqual(true);
+
+ testContext.store.setFetchingState('participants', false);
+
+ expect(testContext.store.isFetching.participants).toEqual(false);
+ });
+
+ it('sets loading state', () => {
+ testContext.store.setLoadingState('assignees', true);
+
+ expect(testContext.store.isLoading.assignees).toEqual(true);
+ });
+
+ it('set time tracking data', () => {
+ testContext.store.setTimeTrackingData(Mock.time);
+
+ 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 }];
+ testContext.store.setAutocompleteProjects(projects);
+
+ expect(testContext.store.autocompleteProjects).toEqual(projects);
+ });
+
+ it('sets subscribed state', () => {
+ expect(testContext.store.subscribed).toEqual(null);
+
+ testContext.store.setSubscribedState(true);
+
+ expect(testContext.store.subscribed).toEqual(true);
+ });
+
+ it('set move to project ID', () => {
+ const projectId = 7;
+ testContext.store.setMoveToProjectId(projectId);
+
+ expect(testContext.store.moveToProjectId).toEqual(projectId);
+ });
+});
diff --git a/spec/javascripts/syntax_highlight_spec.js b/spec/frontend/syntax_highlight_spec.js
index 99c47fa31d4..d2fb5983f7b 100644
--- a/spec/javascripts/syntax_highlight_spec.js
+++ b/spec/frontend/syntax_highlight_spec.js
@@ -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();
});
diff --git a/spec/javascripts/task_list_spec.js b/spec/frontend/task_list_spec.js
index 563f402de58..1261833e3ec 100644
--- a/spec/javascripts/task_list_spec.js
+++ b/spec/frontend/task_list_spec.js
@@ -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
diff --git a/spec/frontend/version_check_image_spec.js b/spec/frontend/version_check_image_spec.js
new file mode 100644
index 00000000000..2ab157105a1
--- /dev/null
+++ b/spec/frontend/version_check_image_spec.js
@@ -0,0 +1,42 @@
+import $ from 'jquery';
+import VersionCheckImage from '~/version_check_image';
+import ClassSpecHelper from './helpers/class_spec_helper';
+
+describe('VersionCheckImage', () => {
+ let testContext;
+
+ beforeEach(() => {
+ testContext = {};
+ });
+
+ describe('bindErrorEvent', () => {
+ ClassSpecHelper.itShouldBeAStaticMethod(VersionCheckImage, 'bindErrorEvent');
+
+ beforeEach(() => {
+ testContext.imageElement = $('<div></div>');
+ });
+
+ 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(testContext.imageElement);
+
+ expect($.prototype.off).toHaveBeenCalledWith('error');
+ expect($.prototype.on).toHaveBeenCalledWith('error', expect.any(Function));
+ });
+
+ it('hides the imageElement on error', () => {
+ jest.spyOn($.prototype, 'hide').mockImplementation(() => {});
+
+ VersionCheckImage.bindErrorEvent(testContext.imageElement);
+
+ testContext.imageElement.trigger('error');
+
+ expect($.prototype.hide).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/javascripts/vue_shared/components/gl_modal_vuex_spec.js b/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
index eb78d37db3e..4b7636041b6 100644
--- a/spec/javascripts/vue_shared/components/gl_modal_vuex_spec.js
+++ b/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
@@ -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;
diff --git a/spec/javascripts/vue_shared/components/markdown/suggestion_diff_spec.js b/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
index dc929e83eb7..3c5e7500ba7 100644
--- a/spec/javascripts/vue_shared/components/markdown/suggestion_diff_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
@@ -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 });
diff --git a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_list_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
index 96bc3b0cc17..9f0cdc651b6 100644
--- a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_list_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_list_spec.js
@@ -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,
diff --git a/spec/javascripts/behaviors/bind_in_out_spec.js b/spec/javascripts/behaviors/bind_in_out_spec.js
deleted file mode 100644
index 0c214f5886a..00000000000
--- a/spec/javascripts/behaviors/bind_in_out_spec.js
+++ /dev/null
@@ -1,192 +0,0 @@
-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}"]`,
- );
- });
- });
- });
-});
diff --git a/spec/javascripts/droplab/constants_spec.js b/spec/javascripts/droplab/constants_spec.js
deleted file mode 100644
index 23b69defec6..00000000000
--- a/spec/javascripts/droplab/constants_spec.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import * as constants from '~/droplab/constants';
-
-describe('constants', function() {
- describe('DATA_TRIGGER', function() {
- it('should be `data-dropdown-trigger`', function() {
- expect(constants.DATA_TRIGGER).toBe('data-dropdown-trigger');
- });
- });
-
- describe('DATA_DROPDOWN', function() {
- it('should be `data-dropdown`', function() {
- expect(constants.DATA_DROPDOWN).toBe('data-dropdown');
- });
- });
-
- describe('SELECTED_CLASS', function() {
- it('should be `droplab-item-selected`', function() {
- expect(constants.SELECTED_CLASS).toBe('droplab-item-selected');
- });
- });
-
- describe('ACTIVE_CLASS', function() {
- it('should be `droplab-item-active`', function() {
- expect(constants.ACTIVE_CLASS).toBe('droplab-item-active');
- });
- });
-
- describe('TEMPLATE_REGEX', function() {
- it('should be a handlebars templating syntax regex', function() {
- expect(constants.TEMPLATE_REGEX).toEqual(/\{\{(.+?)\}\}/g);
- });
- });
-
- describe('IGNORE_CLASS', function() {
- it('should be `droplab-item-ignore`', function() {
- expect(constants.IGNORE_CLASS).toBe('droplab-item-ignore');
- });
- });
-});
diff --git a/spec/javascripts/polyfills/element_spec.js b/spec/javascripts/polyfills/element_spec.js
deleted file mode 100644
index d35df595c72..00000000000
--- a/spec/javascripts/polyfills/element_spec.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import '~/commons/polyfills/element';
-
-describe('Element polyfills', function() {
- beforeEach(() => {
- this.element = document.createElement('ul');
- });
-
- describe('matches', () => {
- it('returns true if element matches the selector', () => {
- expect(this.element.matches('ul')).toBeTruthy();
- });
-
- it("returns false if element doesn't match the selector", () => {
- expect(this.element.matches('.not-an-element')).toBeFalsy();
- });
- });
-
- describe('closest', () => {
- beforeEach(() => {
- this.childElement = document.createElement('li');
- this.element.appendChild(this.childElement);
- });
-
- it('returns the closest parent that matches the selector', () => {
- expect(this.childElement.closest('ul').toString()).toBe(this.element.toString());
- });
-
- it('returns itself if it matches the selector', () => {
- expect(this.childElement.closest('li').toString()).toBe(this.childElement.toString());
- });
-
- it('returns undefined if nothing matches the selector', () => {
- expect(this.childElement.closest('.no-an-element')).toBeFalsy();
- });
- });
-});
diff --git a/spec/javascripts/project_select_combo_button_spec.js b/spec/javascripts/project_select_combo_button_spec.js
deleted file mode 100644
index dc85292c23e..00000000000
--- a/spec/javascripts/project_select_combo_button_spec.js
+++ /dev/null
@@ -1,124 +0,0 @@
-import $ from 'jquery';
-import ProjectSelectComboButton from '~/project_select_combo_button';
-
-const fixturePath = 'static/project_select_combo_button.html';
-
-describe('Project Select Combo Button', function() {
- preloadFixtures(fixturePath);
-
- beforeEach(function() {
- this.defaults = {
- label: 'Select project to create issue',
- groupId: 12345,
- projectMeta: {
- name: 'My Cool Project',
- url: 'http://mycoolproject.com',
- },
- newProjectMeta: {
- name: 'My Other Cool Project',
- url: 'http://myothercoolproject.com',
- },
- localStorageKey: 'group-12345-new-issue-recent-project',
- relativePath: 'issues/new',
- };
-
- loadFixtures(fixturePath);
-
- this.newItemBtn = document.querySelector('.new-project-item-link');
- this.projectSelectInput = document.querySelector('.project-item-select');
- });
-
- describe('on page load when localStorage is empty', function() {
- beforeEach(function() {
- this.comboButton = new ProjectSelectComboButton(this.projectSelectInput);
- });
-
- it('newItemBtn href is null', function() {
- expect(this.newItemBtn.getAttribute('href')).toBe('');
- });
-
- it('newItemBtn text is the plain default label', function() {
- expect(this.newItemBtn.textContent).toBe(this.defaults.label);
- });
- });
-
- describe('on page load when localStorage is filled', function() {
- beforeEach(function() {
- window.localStorage.setItem(
- this.defaults.localStorageKey,
- JSON.stringify(this.defaults.projectMeta),
- );
- this.comboButton = new ProjectSelectComboButton(this.projectSelectInput);
- });
-
- it('newItemBtn href is correctly set', function() {
- expect(this.newItemBtn.getAttribute('href')).toBe(this.defaults.projectMeta.url);
- });
-
- it('newItemBtn text is the cached label', function() {
- expect(this.newItemBtn.textContent).toBe(`New issue in ${this.defaults.projectMeta.name}`);
- });
-
- afterEach(function() {
- window.localStorage.clear();
- });
- });
-
- describe('after selecting a new project', function() {
- beforeEach(function() {
- this.comboButton = new ProjectSelectComboButton(this.projectSelectInput);
-
- // mock the effect of selecting an item from the projects dropdown (select2)
- $('.project-item-select')
- .val(JSON.stringify(this.defaults.newProjectMeta))
- .trigger('change');
- });
-
- it('newItemBtn href is correctly set', function() {
- expect(this.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}`);
- });
-
- afterEach(function() {
- window.localStorage.clear();
- });
- });
-
- describe('deriveTextVariants', function() {
- beforeEach(function() {
- this.mockExecutionContext = {
- resourceType: '',
- resourceLabel: '',
- };
-
- this.comboButton = new ProjectSelectComboButton(this.projectSelectInput);
-
- this.method = this.comboButton.deriveTextVariants.bind(this.mockExecutionContext);
- });
-
- it('correctly derives test variants for merge requests', function() {
- this.mockExecutionContext.resourceType = 'merge_requests';
- this.mockExecutionContext.resourceLabel = 'New merge request';
-
- const returnedVariants = this.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';
-
- const returnedVariants = this.method();
-
- expect(returnedVariants.localStorageItemType).toBe('new-issue');
- expect(returnedVariants.defaultTextPrefix).toBe('New issue');
- expect(returnedVariants.presetTextSuffix).toBe('issue');
- });
- });
-});
diff --git a/spec/javascripts/sidebar/sidebar_store_spec.js b/spec/javascripts/sidebar/sidebar_store_spec.js
deleted file mode 100644
index 85ff70fffbd..00000000000
--- a/spec/javascripts/sidebar/sidebar_store_spec.js
+++ /dev/null
@@ -1,162 +0,0 @@
-import SidebarStore from '~/sidebar/stores/sidebar_store';
-import Mock from './mock_data';
-import UsersMockHelper from '../helpers/user_mock_data_helper';
-
-const ASSIGNEE = {
- id: 2,
- name: 'gitlab user 2',
- username: 'gitlab2',
- avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
-};
-
-const ANOTHER_ASSINEE = {
- id: 3,
- name: 'gitlab user 3',
- username: 'gitlab3',
- avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
-};
-
-const PARTICIPANT = {
- id: 1,
- state: 'active',
- username: 'marcene',
- name: 'Allie Will',
- web_url: 'foo.com',
- avatar_url: 'gravatar.com/avatar/xxx',
-};
-
-const PARTICIPANT_LIST = [PARTICIPANT, { ...PARTICIPANT, id: 2 }, { ...PARTICIPANT, id: 3 }];
-
-describe('Sidebar store', function() {
- beforeEach(() => {
- this.store = new SidebarStore({
- currentUser: {
- id: 1,
- name: 'Administrator',
- username: 'root',
- avatar_url:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- },
- editable: true,
- rootPath: '/',
- endpoint: '/gitlab-org/gitlab-shell/issues/5.json',
- });
- });
-
- afterEach(() => {
- SidebarStore.singleton = null;
- });
-
- it('has default isFetching values', () => {
- expect(this.store.isFetching.assignees).toBe(true);
- });
-
- it('adds a new assignee', () => {
- this.store.addAssignee(ASSIGNEE);
-
- expect(this.store.assignees.length).toEqual(1);
- });
-
- it('removes an assignee', () => {
- this.store.removeAssignee(ASSIGNEE);
-
- expect(this.store.assignees.length).toEqual(0);
- });
-
- it('finds an existent assignee', () => {
- let foundAssignee;
-
- this.store.addAssignee(ASSIGNEE);
- foundAssignee = this.store.findAssignee(ASSIGNEE);
-
- expect(foundAssignee).toBeDefined();
- expect(foundAssignee).toEqual(ASSIGNEE);
- foundAssignee = this.store.findAssignee(ANOTHER_ASSINEE);
-
- expect(foundAssignee).toBeUndefined();
- });
-
- it('removes all assignees', () => {
- this.store.removeAllAssignees();
-
- expect(this.store.assignees.length).toEqual(0);
- });
-
- it('sets participants data', () => {
- expect(this.store.participants.length).toEqual(0);
-
- this.store.setParticipantsData({
- participants: PARTICIPANT_LIST,
- });
-
- expect(this.store.isFetching.participants).toEqual(false);
- expect(this.store.participants.length).toEqual(PARTICIPANT_LIST.length);
- });
-
- it('sets subcriptions data', () => {
- expect(this.store.subscribed).toEqual(null);
-
- this.store.setSubscriptionsData({
- subscribed: true,
- });
-
- expect(this.store.isFetching.subscriptions).toEqual(false);
- expect(this.store.subscribed).toEqual(true);
- });
-
- it('set assigned data', () => {
- const users = {
- assignees: UsersMockHelper.createNumberRandomUsers(3),
- };
-
- this.store.setAssigneeData(users);
-
- expect(this.store.isFetching.assignees).toBe(false);
- expect(this.store.assignees.length).toEqual(3);
- });
-
- it('sets fetching state', () => {
- expect(this.store.isFetching.participants).toEqual(true);
-
- this.store.setFetchingState('participants', false);
-
- expect(this.store.isFetching.participants).toEqual(false);
- });
-
- it('sets loading state', () => {
- this.store.setLoadingState('assignees', true);
-
- expect(this.store.isLoading.assignees).toEqual(true);
- });
-
- it('set time tracking data', () => {
- this.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);
- });
-
- it('set autocomplete projects', () => {
- const projects = [{ id: 0 }];
- this.store.setAutocompleteProjects(projects);
-
- expect(this.store.autocompleteProjects).toEqual(projects);
- });
-
- it('sets subscribed state', () => {
- expect(this.store.subscribed).toEqual(null);
-
- this.store.setSubscribedState(true);
-
- expect(this.store.subscribed).toEqual(true);
- });
-
- it('set move to project ID', () => {
- const projectId = 7;
- this.store.setMoveToProjectId(projectId);
-
- expect(this.store.moveToProjectId).toEqual(projectId);
- });
-});
diff --git a/spec/javascripts/version_check_image_spec.js b/spec/javascripts/version_check_image_spec.js
deleted file mode 100644
index 0e69fcc4c5f..00000000000
--- a/spec/javascripts/version_check_image_spec.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import $ from 'jquery';
-import VersionCheckImage from '~/version_check_image';
-import ClassSpecHelper from './helpers/class_spec_helper';
-
-describe('VersionCheckImage', function() {
- describe('bindErrorEvent', function() {
- ClassSpecHelper.itShouldBeAStaticMethod(VersionCheckImage, 'bindErrorEvent');
-
- beforeEach(function() {
- this.imageElement = $('<div></div>');
- });
-
- it('registers an error event', function() {
- spyOn($.prototype, 'on');
- spyOn($.prototype, 'off').and.callFake(function() {
- return this;
- });
-
- VersionCheckImage.bindErrorEvent(this.imageElement);
-
- expect($.prototype.off).toHaveBeenCalledWith('error');
- expect($.prototype.on).toHaveBeenCalledWith('error', jasmine.any(Function));
- });
-
- it('hides the imageElement on error', function() {
- spyOn($.prototype, 'hide');
-
- VersionCheckImage.bindErrorEvent(this.imageElement);
-
- this.imageElement.trigger('error');
-
- expect($.prototype.hide).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/lib/sentry/client/issue_spec.rb b/spec/lib/sentry/client/issue_spec.rb
index 17548e2081d..20665c59a8d 100644
--- a/spec/lib/sentry/client/issue_spec.rb
+++ b/spec/lib/sentry/client/issue_spec.rb
@@ -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
diff --git a/spec/models/project_services/chat_message/wiki_page_message_spec.rb b/spec/models/project_services/chat_message/wiki_page_message_spec.rb
index c3db516f253..1346a43335e 100644
--- a/spec/models/project_services/chat_message/wiki_page_message_spec.rb
+++ b/spec/models/project_services/chat_message/wiki_page_message_spec.rb
@@ -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