Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-06-23 03:08:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-23 03:08:58 +0300
commit94221585cabf666f38ac989978838393fc3bf56e (patch)
tree54cae93eba04c045b3b2037bbcdbaf913320c9c6
parent2319d04d069d5e066e35cc44035239b21d3fae32 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/boards/components/board_card.vue4
-rw-r--r--app/assets/javascripts/boards/index.js2
-rw-r--r--app/assets/javascripts/deploy_keys/components/action_btn.vue9
-rw-r--r--app/assets/javascripts/deploy_keys/components/app.vue4
-rw-r--r--app/assets/javascripts/groups/components/app.vue4
-rw-r--r--app/assets/javascripts/groups/components/groups.vue7
-rw-r--r--app/assets/javascripts/groups/components/item_actions.vue2
-rw-r--r--app/assets/javascripts/helpers/event_hub_factory.js38
-rw-r--r--app/assets/javascripts/sidebar/event_hub.js4
-rw-r--r--app/models/merge_request.rb3
-rw-r--r--doc/.vale/gitlab/CurrentStatus.yml12
-rw-r--r--doc/.vale/gitlab/spelling-exceptions.txt2
-rw-r--r--doc/administration/gitaly/index.md11
-rw-r--r--doc/user/application_security/sast/index.md2
-rw-r--r--doc/user/application_security/secret_detection/index.md2
-rw-r--r--doc/user/project/index.md72
-rw-r--r--locale/gitlab.pot15
-rw-r--r--package.json1
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb2
-rw-r--r--spec/frontend/boards/board_card_spec.js2
-rw-r--r--spec/frontend/deploy_keys/components/action_btn_spec.js2
-rw-r--r--spec/frontend/deploy_keys/components/app_spec.js6
-rw-r--r--spec/frontend/groups/components/app_spec.js8
-rw-r--r--spec/frontend/groups/components/groups_spec.js5
-rw-r--r--spec/frontend/groups/components/item_actions_spec.js5
-rw-r--r--spec/frontend/helpers/event_hub_factory_spec.js99
-rw-r--r--spec/migrations/20200526231421_update_index_approval_rule_name_for_code_owners_rule_type_spec.rb21
-rw-r--r--spec/models/merge_request_spec.rb6
-rw-r--r--yarn.lock12
30 files changed, 220 insertions, 144 deletions
diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue
index e120e058ede..246d3b9dcd1 100644
--- a/app/assets/javascripts/boards/components/board_card.vue
+++ b/app/assets/javascripts/boards/components/board_card.vue
@@ -89,10 +89,10 @@ export default {
eventHub.$emit('clearDetailIssue', isMultiSelect);
if (isMultiSelect) {
- eventHub.$emit('newDetailIssue', [this.issue, isMultiSelect]);
+ eventHub.$emit('newDetailIssue', this.issue, isMultiSelect);
}
} else {
- eventHub.$emit('newDetailIssue', [this.issue, isMultiSelect]);
+ eventHub.$emit('newDetailIssue', this.issue, isMultiSelect);
boardsStore.setListDetail(this.list);
}
}
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index 01e01ad6b8e..a882cd1cdfa 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -202,7 +202,7 @@ export default () => {
updateTokens() {
this.filterManager.updateTokens();
},
- updateDetailIssue([newIssue, multiSelect = false]) {
+ updateDetailIssue(newIssue, multiSelect = false) {
const { sidebarInfoEndpoint } = newIssue;
if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
newIssue.setFetchingState('subscriptions', true);
diff --git a/app/assets/javascripts/deploy_keys/components/action_btn.vue b/app/assets/javascripts/deploy_keys/components/action_btn.vue
index c2c90bd472b..af7c391ab70 100644
--- a/app/assets/javascripts/deploy_keys/components/action_btn.vue
+++ b/app/assets/javascripts/deploy_keys/components/action_btn.vue
@@ -30,12 +30,9 @@ export default {
doAction() {
this.isLoading = true;
- eventHub.$emit(`${this.type}.key`, [
- this.deployKey,
- () => {
- this.isLoading = false;
- },
- ]);
+ eventHub.$emit(`${this.type}.key`, this.deployKey, () => {
+ this.isLoading = false;
+ });
},
},
};
diff --git a/app/assets/javascripts/deploy_keys/components/app.vue b/app/assets/javascripts/deploy_keys/components/app.vue
index c747b63473a..83d2ffe2b3e 100644
--- a/app/assets/javascripts/deploy_keys/components/app.vue
+++ b/app/assets/javascripts/deploy_keys/components/app.vue
@@ -90,13 +90,13 @@ export default {
return new Flash(s__('DeployKeys|Error getting deploy keys'));
});
},
- enableKey([deployKey]) {
+ enableKey(deployKey) {
this.service
.enableKey(deployKey.id)
.then(this.fetchKeys)
.catch(() => new Flash(s__('DeployKeys|Error enabling deploy key')));
},
- disableKey([deployKey, callback]) {
+ disableKey(deployKey, callback) {
if (
// eslint-disable-next-line no-alert
window.confirm(s__('DeployKeys|You are going to remove this deploy key. Are you sure?'))
diff --git a/app/assets/javascripts/groups/components/app.vue b/app/assets/javascripts/groups/components/app.vue
index 0f2ee4a5224..0b401f4d732 100644
--- a/app/assets/javascripts/groups/components/app.vue
+++ b/app/assets/javascripts/groups/components/app.vue
@@ -123,7 +123,7 @@ export default {
this.updateGroups(res, Boolean(filterGroupsBy));
});
},
- fetchPage([page, filterGroupsBy, sortBy, archived]) {
+ fetchPage(page, filterGroupsBy, sortBy, archived) {
this.isLoading = true;
return this.fetchGroups({
@@ -169,7 +169,7 @@ export default {
parentGroup.isOpen = false;
}
},
- showLeaveGroupModal([group, parentGroup]) {
+ showLeaveGroupModal(group, parentGroup) {
const { fullName } = group;
this.targetGroup = group;
this.targetParentGroup = parentGroup;
diff --git a/app/assets/javascripts/groups/components/groups.vue b/app/assets/javascripts/groups/components/groups.vue
index daf145d4eca..c7acc21378b 100644
--- a/app/assets/javascripts/groups/components/groups.vue
+++ b/app/assets/javascripts/groups/components/groups.vue
@@ -35,12 +35,7 @@ export default {
const filterGroupsParam = getParameterByName('filter');
const sortParam = getParameterByName('sort');
const archivedParam = getParameterByName('archived');
- eventHub.$emit(`${this.action}fetchPage`, [
- page,
- filterGroupsParam,
- sortParam,
- archivedParam,
- ]);
+ eventHub.$emit(`${this.action}fetchPage`, page, filterGroupsParam, sortParam, archivedParam);
},
},
};
diff --git a/app/assets/javascripts/groups/components/item_actions.vue b/app/assets/javascripts/groups/components/item_actions.vue
index c91551da475..985ea5a9019 100644
--- a/app/assets/javascripts/groups/components/item_actions.vue
+++ b/app/assets/javascripts/groups/components/item_actions.vue
@@ -37,7 +37,7 @@ export default {
},
methods: {
onLeaveGroup() {
- eventHub.$emit(`${this.action}showLeaveGroupModal`, [this.group, this.parentGroup]);
+ eventHub.$emit(`${this.action}showLeaveGroupModal`, this.group, this.parentGroup);
},
},
};
diff --git a/app/assets/javascripts/helpers/event_hub_factory.js b/app/assets/javascripts/helpers/event_hub_factory.js
index 08cfe40b52d..863f490a63e 100644
--- a/app/assets/javascripts/helpers/event_hub_factory.js
+++ b/app/assets/javascripts/helpers/event_hub_factory.js
@@ -1,26 +1,18 @@
-import mitt from 'mitt';
+import Vue from 'vue';
+/**
+ * Return a Vue like event hub
+ *
+ * - $on
+ * - $off
+ * - $once
+ * - $emit
+ *
+ * Please note, this was once implemented with `mitt`, but since then has been reverted
+ * because of some API issues. https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35074
+ *
+ * We'd like to shy away from using a full fledged Vue instance from this in the future.
+ */
export default () => {
- const emitter = mitt();
-
- const originalEmit = emitter.emit;
-
- emitter.once = (event, handler) => {
- const wrappedHandler = evt => {
- handler(evt);
- emitter.off(event, wrappedHandler);
- };
- emitter.on(event, wrappedHandler);
- };
-
- emitter.emit = (event, args = []) => {
- originalEmit(event, args);
- };
-
- emitter.$on = emitter.on;
- emitter.$once = emitter.once;
- emitter.$off = emitter.off;
- emitter.$emit = emitter.emit;
-
- return emitter;
+ return new Vue();
};
diff --git a/app/assets/javascripts/sidebar/event_hub.js b/app/assets/javascripts/sidebar/event_hub.js
index dd4bd9a5ab7..f35506fd5de 100644
--- a/app/assets/javascripts/sidebar/event_hub.js
+++ b/app/assets/javascripts/sidebar/event_hub.js
@@ -1,6 +1,6 @@
-import createEventHub from '~/helpers/event_hub_factory';
+import Vue from 'vue';
-const eventHub = createEventHub();
+const eventHub = new Vue();
// TODO: remove eventHub hack after code splitting refactor
window.emitSidebarEvent = (...args) => eventHub.$emit(...args);
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index adf4c0ffa15..68ff336a1bb 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -946,7 +946,8 @@ class MergeRequest < ApplicationRecord
end
def can_remove_source_branch?(current_user)
- !ProtectedBranch.protected?(source_project, source_branch) &&
+ source_project &&
+ !ProtectedBranch.protected?(source_project, source_branch) &&
!source_project.root_ref?(source_branch) &&
Ability.allowed?(current_user, :push_code, source_project) &&
diff_head_sha == source_branch_head.try(:sha)
diff --git a/doc/.vale/gitlab/CurrentStatus.yml b/doc/.vale/gitlab/CurrentStatus.yml
new file mode 100644
index 00000000000..52bcea23d5b
--- /dev/null
+++ b/doc/.vale/gitlab/CurrentStatus.yml
@@ -0,0 +1,12 @@
+---
+# Suggestion: gitlab.CurrentStatus
+# Checks for words that indicate a product or feature may change in the future.
+#
+# For a list of all options, see https://errata-ai.github.io/vale/styles/
+extends: existence
+message: 'Avoid words like "%s" that promise future changes.'
+level: suggestion
+ignorecase: true
+link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#language-to-avoid
+tokens:
+ - currently
diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt
index edc9059d1ac..7fe7fb2d6da 100644
--- a/doc/.vale/gitlab/spelling-exceptions.txt
+++ b/doc/.vale/gitlab/spelling-exceptions.txt
@@ -335,8 +335,6 @@ Puma
Python
Qualys
Rackspace
-Raketask
-Raketasks
reachability
rebase
rebased
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index 9522eaea88c..0439adccfe4 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -402,6 +402,17 @@ git_data_dirs({
})
```
+You should use configuration similar to the following:
+
+```ruby
+git_data_dirs({
+ 'default' => { 'gitaly_address' => 'tcp://gitaly1.internal:8075' },
+ # this should be the IP address of the GitLab server that has Gitaly running on it
+ 'storage1' => { 'gitaly_address' => 'tcp://gitlab.internal:8075' },
+ 'storage2' => { 'gitaly_address' => 'tcp://gitaly2.internal:8075' },
+})
+```
+
**For Omnibus GitLab**
1. Edit `/etc/gitlab/gitlab.rb`:
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index 90cb3594d23..b70272515a7 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -287,7 +287,7 @@ SAST can be [configured](#customizing-the-sast-settings) using environment varia
#### Logging Level
-You can control the verbosity of logs by setting the `SECURE_LOG_LEVEL` env var. It's default is set to `info`, you can set it to any of the following levels:
+You can control the verbosity of logs by setting the `SECURE_LOG_LEVEL` env var. The default is set to `info`, you can set it to any of the following levels:
- `panic`
- `fatal`
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index e0cbaeda24c..c47d4ae9996 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -148,7 +148,7 @@ Secret Detection can be customized by defining available variables:
### Logging Level
-You can control the verbosity of logs by setting the `SECURE_LOG_LEVEL` env var. It's default is set to `info`, you can set it to any of the following levels:
+You can control the verbosity of logs by setting the `SECURE_LOG_LEVEL` env var. The default is set to `info`, you can set it to any of the following levels:
- `panic`
- `fatal`
diff --git a/doc/user/project/index.md b/doc/user/project/index.md
index 9f7fde4cf5d..a3d63c0e77d 100644
--- a/doc/user/project/index.md
+++ b/doc/user/project/index.md
@@ -261,14 +261,52 @@ When [renaming a user](../profile/index.md#changing-your-username),
## Use your project as a Go package
-Any project can be used as a Go package including private projects in subgroups.
-GitLab responds correctly to `go get` and `godoc.org` discovery requests,
-including the [`go-import`](https://golang.org/cmd/go/#hdr-Remote_import_paths)
-and [`go-source`](https://github.com/golang/gddo/wiki/Source-Code-Links) meta
-tags, respectively. To use packages hosted in private projects with the `go get`
-command, use a [`.netrc` file](https://ec.haxx.se/usingcurl-netrc.html) and a
-[personal access token](../profile/personal_access_tokens.md) in the password
-field.
+Any project can be used as a Go package. GitLab responds correctly to `go get`
+and `godoc.org` discovery requests, including the
+[`go-import`](https://golang.org/cmd/go/#hdr-Remote_import_paths) and
+[`go-source`](https://github.com/golang/gddo/wiki/Source-Code-Links) meta tags.
+
+Private projects, including projects in subgroups, can be used as a Go package,
+but may require configuration to work correctly. GitLab will respond correctly
+to `go get` discovery requests for projects that *are not* in subgroups,
+regardless of authentication or authorization.
+[Authentication](#authenticate-go-requests) is required to use a private project
+in a subgroup as a Go package. Otherwise, GitLab will truncate the path for
+private projects in subgroups to the first two segments, causing `go get` to
+fail.
+
+GitLab implements its own Go proxy. This feature must be enabled by an
+administrator and requires additional configuration. See [GitLab Go
+Proxy](../packages/go_proxy/index.md).
+
+### Disable Go module features for private projects
+
+In Go 1.12 and later, Go queries module proxies and checksum databases in the
+process of [fetching a
+module](../../development/go_guide/dependencies.md#fetching). This can be
+selectively disabled with `GOPRIVATE` (disable both),
+[`GONOPROXY`](../../development/go_guide/dependencies.md#proxies) (disable proxy
+queries), and [`GONOSUMDB`](../../development/go_guide/dependencies.md#fetching)
+(disable checksum queries).
+
+`GOPRIVATE`, `GONOPROXY`, and `GONOSUMDB` are comma-separated lists of Go
+modules and Go module prefixes. For example,
+`GOPRIVATE=gitlab.example.com/my/private/project` will disable queries for that
+one project, but `GOPRIVATE=gitlab.example.com` will disable queries for *all*
+projects on GitLab.com. Go will not query module proxies if the module name or a
+prefix of it appears in `GOPRIVATE` or `GONOPROXY`. Go will not query checksum
+databases if the module name or a prefix of it appears in `GONOPRIVATE` or
+`GONOSUMDB`.
+
+### Authenticate Go requests
+
+To authenticate requests to private projects made by Go, use a [`.netrc`
+file](https://ec.haxx.se/usingcurl-netrc.html) and a [personal access
+token](../profile/personal_access_tokens.md) in the password field. **This only
+works if your GitLab instance can be accessed with HTTPS.** The `go` command
+will not transmit credentials over insecure connections. This will authenticate
+all HTTPS requests made directly by Go but will not authenticate requests made
+through Git.
For example:
@@ -278,6 +316,24 @@ login <gitlab_user_name>
password <personal_access_token>
```
+NOTE: **Note:**
+On Windows, Go reads `~/_netrc` instead of `~/.netrc`.
+
+### Authenticate Git fetches
+
+If a module cannot be fetched from a proxy, Go will fall back to using Git (for
+GitLab projects). Git will use `.netrc` to authenticate requests. Alternatively,
+Git can be configured to embed specific credentials in the request URL, or to
+use SSH instead of HTTPS (as Go always uses HTTPS to fetch Git repositories):
+
+```shell
+# embed credentials in any request to GitLab.com:
+git config --global url."https://${user}:${personal_access_token}@gitlab.example.com".insteadOf "https://gitlab.example.com"
+
+# use SSH instead of HTTPS:
+git config --global url."git@gitlab.example.com".insteadOf "https://gitlab.example.com"
+```
+
## Access project page with project ID
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53671) in GitLab 11.8.
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ea1a38bb4e8..5d001f3c0e4 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -7310,6 +7310,9 @@ msgstr ""
msgid "Delete this attachment"
msgstr ""
+msgid "Delete user list"
+msgstr ""
+
msgid "Delete variable"
msgstr ""
@@ -24761,6 +24764,9 @@ msgstr ""
msgid "User key was successfully removed."
msgstr ""
+msgid "User list %{name} will be removed. Are you sure?"
+msgstr ""
+
msgid "User map"
msgstr ""
@@ -24782,6 +24788,12 @@ msgstr ""
msgid "User was successfully updated."
msgstr ""
+msgid "UserList|Delete %{name}?"
+msgstr ""
+
+msgid "UserList|created %{timeago}"
+msgstr ""
+
msgid "UserOnboardingTour|%{activeTour}/%{totalTours}"
msgstr ""
@@ -26944,9 +26956,6 @@ msgstr ""
msgid "created %{timeAgo}"
msgstr ""
-msgid "created %{timeago}"
-msgstr ""
-
msgid "customize"
msgstr ""
diff --git a/package.json b/package.json
index aff2d285fb3..2abe1e69f84 100644
--- a/package.json
+++ b/package.json
@@ -105,7 +105,6 @@
"mermaid": "^8.5.2",
"mersenne-twister": "1.1.0",
"minimatch": "^3.0.4",
- "mitt": "^1.2.0",
"monaco-editor": "^0.18.1",
"monaco-editor-webpack-plugin": "^1.7.0",
"mousetrap": "^1.4.6",
diff --git a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
index 30163aacfaa..d2020ff6ec7 100644
--- a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_dependent_relationship_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- context 'Release', :docker, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/217250', type: :investigating } do
+ context 'Release', :docker do
describe 'Parent-child pipelines dependent relationship' do
let!(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
index 16272767f9f..9d9b187e77a 100644
--- a/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/pipeline/parent_child_pipelines_independent_relationship_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- context 'Release', :docker, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/217250', type: :investigating } do
+ context 'Release', :docker do
describe 'Parent-child pipelines independent relationship' do
let!(:project) do
Resource::Project.fabricate_via_api! do |project|
diff --git a/spec/frontend/boards/board_card_spec.js b/spec/frontend/boards/board_card_spec.js
index 6bfbc7cb12f..959c71d05ca 100644
--- a/spec/frontend/boards/board_card_spec.js
+++ b/spec/frontend/boards/board_card_spec.js
@@ -196,7 +196,7 @@ describe('Board card', () => {
wrapper.trigger('mousedown');
wrapper.trigger('mouseup');
- expect(eventHub.$emit).toHaveBeenCalledWith('newDetailIssue', [wrapper.vm.issue, undefined]);
+ expect(eventHub.$emit).toHaveBeenCalledWith('newDetailIssue', wrapper.vm.issue, undefined);
expect(boardsStore.detail.list).toEqual(wrapper.vm.list);
});
diff --git a/spec/frontend/deploy_keys/components/action_btn_spec.js b/spec/frontend/deploy_keys/components/action_btn_spec.js
index 78312751429..b8211b02464 100644
--- a/spec/frontend/deploy_keys/components/action_btn_spec.js
+++ b/spec/frontend/deploy_keys/components/action_btn_spec.js
@@ -32,7 +32,7 @@ describe('Deploy keys action btn', () => {
wrapper.trigger('click');
return wrapper.vm.$nextTick().then(() => {
- expect(eventHub.$emit).toHaveBeenCalledWith('enable.key', [deployKey, expect.any(Function)]);
+ expect(eventHub.$emit).toHaveBeenCalledWith('enable.key', deployKey, expect.anything());
});
});
diff --git a/spec/frontend/deploy_keys/components/app_spec.js b/spec/frontend/deploy_keys/components/app_spec.js
index cf54b7e60aa..291502c9ed7 100644
--- a/spec/frontend/deploy_keys/components/app_spec.js
+++ b/spec/frontend/deploy_keys/components/app_spec.js
@@ -88,7 +88,7 @@ describe('Deploy keys app component', () => {
jest.spyOn(wrapper.vm.service, 'getKeys').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'enableKey').mockImplementation(() => Promise.resolve());
- eventHub.$emit('enable.key', [key]);
+ eventHub.$emit('enable.key', key);
return wrapper.vm.$nextTick();
})
@@ -106,7 +106,7 @@ describe('Deploy keys app component', () => {
jest.spyOn(wrapper.vm.service, 'getKeys').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'disableKey').mockImplementation(() => Promise.resolve());
- eventHub.$emit('disable.key', [key]);
+ eventHub.$emit('disable.key', key);
return wrapper.vm.$nextTick();
})
@@ -124,7 +124,7 @@ describe('Deploy keys app component', () => {
jest.spyOn(wrapper.vm.service, 'getKeys').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'disableKey').mockImplementation(() => Promise.resolve());
- eventHub.$emit('remove.key', [key]);
+ eventHub.$emit('remove.key', key);
return wrapper.vm.$nextTick();
})
diff --git a/spec/frontend/groups/components/app_spec.js b/spec/frontend/groups/components/app_spec.js
index 3c04cac7402..35eda21e047 100644
--- a/spec/frontend/groups/components/app_spec.js
+++ b/spec/frontend/groups/components/app_spec.js
@@ -184,7 +184,7 @@ describe('AppComponent', () => {
jest.spyOn(window.history, 'replaceState').mockImplementation(() => {});
jest.spyOn($, 'scrollTo').mockImplementation(() => {});
- const fetchPagePromise = vm.fetchPage([2, null, null, true]);
+ const fetchPagePromise = vm.fetchPage(2, null, null, true);
expect(vm.isLoading).toBe(true);
expect(vm.fetchGroups).toHaveBeenCalledWith({
@@ -275,7 +275,7 @@ describe('AppComponent', () => {
expect(vm.targetGroup).toBe(null);
expect(vm.targetParentGroup).toBe(null);
- vm.showLeaveGroupModal([group, mockParentGroupItem]);
+ vm.showLeaveGroupModal(group, mockParentGroupItem);
expect(vm.targetGroup).not.toBe(null);
expect(vm.targetParentGroup).not.toBe(null);
@@ -286,7 +286,7 @@ describe('AppComponent', () => {
expect(vm.showModal).toBe(false);
expect(vm.groupLeaveConfirmationMessage).toBe('');
- vm.showLeaveGroupModal([group, mockParentGroupItem]);
+ vm.showLeaveGroupModal(group, mockParentGroupItem);
expect(vm.showModal).toBe(true);
expect(vm.groupLeaveConfirmationMessage).toBe(
@@ -298,7 +298,7 @@ describe('AppComponent', () => {
describe('hideLeaveGroupModal', () => {
it('hides modal confirmation which is shown before leaving the group', () => {
const group = { ...mockParentGroupItem };
- vm.showLeaveGroupModal([group, mockParentGroupItem]);
+ vm.showLeaveGroupModal(group, mockParentGroupItem);
expect(vm.showModal).toBe(true);
vm.hideLeaveGroupModal();
diff --git a/spec/frontend/groups/components/groups_spec.js b/spec/frontend/groups/components/groups_spec.js
index 42c3c813941..6205400eb03 100644
--- a/spec/frontend/groups/components/groups_spec.js
+++ b/spec/frontend/groups/components/groups_spec.js
@@ -41,12 +41,13 @@ describe('GroupsComponent', () => {
vm.change(2);
- expect(eventHub.$emit).toHaveBeenCalledWith('fetchPage', [
+ expect(eventHub.$emit).toHaveBeenCalledWith(
+ 'fetchPage',
2,
expect.any(Object),
expect.any(Object),
expect.any(Object),
- ]);
+ );
});
});
});
diff --git a/spec/frontend/groups/components/item_actions_spec.js b/spec/frontend/groups/components/item_actions_spec.js
index 1ca42f28c7f..c0dc1a816e6 100644
--- a/spec/frontend/groups/components/item_actions_spec.js
+++ b/spec/frontend/groups/components/item_actions_spec.js
@@ -31,10 +31,11 @@ describe('ItemActionsComponent', () => {
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
vm.onLeaveGroup();
- expect(eventHub.$emit).toHaveBeenCalledWith('showLeaveGroupModal', [
+ expect(eventHub.$emit).toHaveBeenCalledWith(
+ 'showLeaveGroupModal',
vm.group,
vm.parentGroup,
- ]);
+ );
});
});
});
diff --git a/spec/frontend/helpers/event_hub_factory_spec.js b/spec/frontend/helpers/event_hub_factory_spec.js
index dcfec6b836a..d29b9ddba34 100644
--- a/spec/frontend/helpers/event_hub_factory_spec.js
+++ b/spec/frontend/helpers/event_hub_factory_spec.js
@@ -1,77 +1,84 @@
import createEventHub from '~/helpers/event_hub_factory';
+const TEST_EVENT = 'foobar';
+
describe('event bus factory', () => {
let eventBus;
+ let handler;
beforeEach(() => {
eventBus = createEventHub();
+ handler = jest.fn();
});
afterEach(() => {
eventBus = null;
});
- describe('underlying module', () => {
- let mitt;
+ describe('instance', () => {
+ it.each`
+ method
+ ${'$on'}
+ ${'$once'}
+ ${'$off'}
+ ${'$emit'}
+ `('has $method method', ({ method }) => {
+ expect(eventBus[method]).toEqual(expect.any(Function));
+ });
+ });
+ describe('$on', () => {
beforeEach(() => {
- jest.resetModules();
- jest.mock('mitt');
+ eventBus.$on(TEST_EVENT, handler);
+ });
- // eslint-disable-next-line global-require
- mitt = require('mitt');
- mitt.mockReturnValue(() => ({}));
+ it('calls handler when event is emitted', () => {
+ eventBus.$emit(TEST_EVENT);
+ expect(handler).toHaveBeenCalledWith();
+ });
- const createEventHubActual = jest.requireActual('~/helpers/event_hub_factory').default;
- eventBus = createEventHubActual();
+ it('calls handler with multiple args', () => {
+ eventBus.$emit(TEST_EVENT, 'arg1', 'arg2', 'arg3');
+ expect(handler).toHaveBeenCalledWith('arg1', 'arg2', 'arg3');
});
- it('creates an emitter', () => {
- expect(mitt).toHaveBeenCalled();
+ it('calls handler multiple times', () => {
+ eventBus.$emit(TEST_EVENT, 'arg1', 'arg2', 'arg3');
+ eventBus.$emit(TEST_EVENT, 'arg1', 'arg2', 'arg3');
+
+ expect(handler).toHaveBeenCalledTimes(2);
});
- });
- describe('instance', () => {
- it.each`
- method
- ${'on'}
- ${'once'}
- ${'off'}
- ${'emit'}
- `('binds $$method to $method ', ({ method }) => {
- expect(typeof eventBus[method]).toBe('function');
- expect(eventBus[method]).toBe(eventBus[`$${method}`]);
+ it('does not call handler after $off with handler', () => {
+ eventBus.$off(TEST_EVENT, handler);
+
+ eventBus.$emit(TEST_EVENT);
+
+ expect(handler).not.toHaveBeenCalled();
});
- });
- describe('once', () => {
- const event = 'foobar';
- let handler;
+ it('does not call handler after $off', () => {
+ eventBus.$off(TEST_EVENT);
- beforeEach(() => {
- jest.spyOn(eventBus, 'on');
- jest.spyOn(eventBus, 'off');
- handler = jest.fn();
- eventBus.once(event, handler);
+ eventBus.$emit(TEST_EVENT);
+
+ expect(handler).not.toHaveBeenCalled();
});
+ });
- it('calls on internally', () => {
- expect(eventBus.on).toHaveBeenCalled();
+ describe('$once', () => {
+ beforeEach(() => {
+ eventBus.$once(TEST_EVENT, handler);
});
it('calls handler when event is emitted', () => {
- eventBus.emit(event);
+ eventBus.$emit(TEST_EVENT);
expect(handler).toHaveBeenCalled();
});
- it('calls off when event is emitted', () => {
- eventBus.emit(event);
- expect(eventBus.off).toHaveBeenCalled();
- });
-
it('calls the handler only once when event is emitted multiple times', () => {
- eventBus.emit(event);
- eventBus.emit(event);
+ eventBus.$emit(TEST_EVENT);
+ eventBus.$emit(TEST_EVENT);
expect(handler).toHaveBeenCalledTimes(1);
});
@@ -80,14 +87,18 @@ describe('event bus factory', () => {
handler = jest.fn().mockImplementation(() => {
throw new Error();
});
- eventBus.once(event, handler);
+ eventBus.$once(TEST_EVENT, handler);
});
it('calls off when event is emitted', () => {
expect(() => {
- eventBus.emit(event);
+ eventBus.$emit(TEST_EVENT);
}).toThrow();
- expect(eventBus.off).toHaveBeenCalled();
+ expect(() => {
+ eventBus.$emit(TEST_EVENT);
+ }).not.toThrow();
+
+ expect(handler).toHaveBeenCalledTimes(1);
});
});
});
diff --git a/spec/migrations/20200526231421_update_index_approval_rule_name_for_code_owners_rule_type_spec.rb b/spec/migrations/20200526231421_update_index_approval_rule_name_for_code_owners_rule_type_spec.rb
index 9842cfbc28d..387c477a58e 100644
--- a/spec/migrations/20200526231421_update_index_approval_rule_name_for_code_owners_rule_type_spec.rb
+++ b/spec/migrations/20200526231421_update_index_approval_rule_name_for_code_owners_rule_type_spec.rb
@@ -78,8 +78,8 @@ describe UpdateIndexApprovalRuleNameForCodeOwnersRuleType do
disable_migrations_output { migrate! }
- # After running the migration, expect `section == nil` rules to still
- # be blocked by the legacy indices, but sectional rules are allowed.
+ # After running the migration, expect `section == nil` rules to still be
+ # blocked by the legacy indices, but sectional rules are allowed.
#
expect { create_sectional_approval_rules }
.to change { approval_rules.count }.by(2)
@@ -115,8 +115,8 @@ describe UpdateIndexApprovalRuleNameForCodeOwnersRuleType do
described_class::LEGACY_INDEX_NAME_CODE_OWNERS
)
- # Since ApprovalMergeRequestRules are EE-specific, we expect none to
- # be deleted during the migration.
+ # Since ApprovalMergeRequestRules are EE-specific, we expect none to be
+ # deleted during the migration.
#
expect { disable_migrations_output { migration.down } }
.not_to change { approval_rules.count }
@@ -144,17 +144,14 @@ describe UpdateIndexApprovalRuleNameForCodeOwnersRuleType do
expect { create_two_matching_nil_section_approval_rules }
.to raise_exception(ActiveRecord::RecordNotUnique)
- # Run the down migration. This will remove the 2 approval rules we create
- # above, and call MergeRequests::SyncCodeOwnerApprovalRules to recreate
- # new ones.
- #
expect(MergeRequests::SyncCodeOwnerApprovalRules)
.to receive(:new).with(MergeRequest.find(merge_request.id)).once.and_call_original
- # We expect approval_rules.count to be changed by -3 as we're deleting the
- # 3 rules created above, and MergeRequests::SyncCodeOwnerApprovalRules
- # will not be able to create new one with an empty (or missing)
- # CODEOWNERS file.
+ # Run the down migration. This will remove the 3 approval rules we create
+ # above, and call MergeRequests::SyncCodeOwnerApprovalRules to recreate
+ # new ones. However, as there is no CODEOWNERS file in this test
+ # context, no approval rules will be created, so we can expect
+ # approval_rules.count to be changed by -3.
#
expect { disable_migrations_output { migration.down } }
.to change { approval_rules.count }.by(-3)
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index c70ddac5da6..031b0688c7b 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -1170,6 +1170,12 @@ describe MergeRequest do
expect(subject.can_remove_source_branch?(user)).to be_falsey
end
+ it "can't be removed because source project has been deleted" do
+ subject.source_project = nil
+
+ expect(subject.can_remove_source_branch?(user)).to be_falsey
+ end
+
it "can't remove a root ref" do
subject.update(source_branch: 'master', target_branch: 'feature')
diff --git a/yarn.lock b/yarn.lock
index a2d0656233f..6dc60a5a81f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8232,11 +8232,6 @@ mississippi@^3.0.0:
stream-each "^1.1.0"
through2 "^2.0.0"
-mitt@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.2.0.tgz#cb24e6569c806e31bd4e3995787fe38a04fdf90d"
- integrity sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==
-
mixin-deep@^1.2.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566"
@@ -9763,16 +9758,11 @@ rc@^1.2.8, rc@~1.2.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
-react-is@^16.12.0:
+react-is@^16.12.0, react-is@^16.8.4:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-react-is@^16.8.4:
- version "16.8.6"
- resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
- integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
-
read-pkg-up@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"