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>2021-06-15 00:10:22 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-15 00:10:22 +0300
commit5b829393a732143e31e2f9a62b6ca2cfb7ebb147 (patch)
tree85260ce9fd49ea62df0cea5b750f8c0db1b5a082
parentf69bc1dab50e86440bb4ffdc507ca5efd94bf459 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/keybindings.js7
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts.js14
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue8
-rw-r--r--app/finders/pending_todos_finder.rb9
-rw-r--r--app/graphql/types/ci/runner_type.rb2
-rw-r--r--app/models/todo.rb1
-rw-r--r--app/services/discussions/resolve_service.rb7
-rw-r--r--app/services/todo_service.rb2
-rw-r--r--app/views/admin/application_settings/appearances/preview_sign_in.html.haml2
-rw-r--r--doc/administration/consul.md12
-rw-r--r--doc/api/graphql/reference/index.md2
-rw-r--r--doc/topics/autodevops/index.md4
-rw-r--r--doc/topics/autodevops/quick_start_guide.md22
-rw-r--r--doc/topics/autodevops/requirements.md4
-rw-r--r--doc/user/clusters/applications.md8
-rw-r--r--doc/user/project/issues/design_management.md3
-rw-r--r--doc/user/todos.md1
-rw-r--r--lib/gitlab/highlight.rb15
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/finders/pending_todos_finder_spec.rb28
-rw-r--r--spec/frontend/behaviors/shortcuts/keybindings_spec.js11
-rw-r--r--spec/graphql/types/ci/runner_type_spec.rb6
-rw-r--r--spec/lib/gitlab/highlight_spec.rb22
-rw-r--r--spec/models/todo_spec.rb12
-rw-r--r--spec/services/discussions/resolve_service_spec.rb45
25 files changed, 219 insertions, 31 deletions
diff --git a/app/assets/javascripts/behaviors/shortcuts/keybindings.js b/app/assets/javascripts/behaviors/shortcuts/keybindings.js
index c63dba05f10..005ef103ded 100644
--- a/app/assets/javascripts/behaviors/shortcuts/keybindings.js
+++ b/app/assets/javascripts/behaviors/shortcuts/keybindings.js
@@ -105,6 +105,12 @@ export const TOGGLE_PERFORMANCE_BAR = {
defaultKeys: ['p b'], // eslint-disable-line @gitlab/require-i18n-strings
};
+export const HIDE_APPEARING_CONTENT = {
+ id: 'globalShortcuts.hideAppearingContent',
+ description: __('Hide tooltips or popovers'),
+ defaultKeys: ['esc'],
+};
+
export const TOGGLE_CANARY = {
id: 'globalShortcuts.toggleCanary',
description: __('Toggle GitLab Next'),
@@ -492,6 +498,7 @@ export const GLOBAL_SHORTCUTS_GROUP = {
GO_TO_YOUR_MERGE_REQUESTS,
GO_TO_YOUR_TODO_LIST,
TOGGLE_PERFORMANCE_BAR,
+ HIDE_APPEARING_CONTENT,
],
};
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
index 03cba78cf31..ac2a4184176 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
@@ -12,6 +12,7 @@ import {
START_SEARCH,
FOCUS_FILTER_BAR,
TOGGLE_PERFORMANCE_BAR,
+ HIDE_APPEARING_CONTENT,
TOGGLE_CANARY,
TOGGLE_MARKDOWN_PREVIEW,
GO_TO_YOUR_TODO_LIST,
@@ -78,6 +79,7 @@ export default class Shortcuts {
Mousetrap.bind(keysFor(START_SEARCH), Shortcuts.focusSearch);
Mousetrap.bind(keysFor(FOCUS_FILTER_BAR), this.focusFilter.bind(this));
Mousetrap.bind(keysFor(TOGGLE_PERFORMANCE_BAR), Shortcuts.onTogglePerfBar);
+ Mousetrap.bind(keysFor(HIDE_APPEARING_CONTENT), Shortcuts.hideAppearingContent);
Mousetrap.bind(keysFor(TOGGLE_CANARY), Shortcuts.onToggleCanary);
const findFileURL = document.body.dataset.findFile;
@@ -202,6 +204,18 @@ export default class Shortcuts {
}
}
+ static hideAppearingContent(e) {
+ const elements = document.querySelectorAll('.tooltip, .popover');
+
+ elements.forEach((element) => {
+ element.style.display = 'none';
+ });
+
+ if (e.preventDefault) {
+ e.preventDefault();
+ }
+ }
+
/**
* Initializes markdown editor shortcuts on the provided `<textarea>` element
*
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
index d900cfcdf2b..c16c29f3222 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
@@ -152,6 +152,9 @@ export default {
update(data) {
return data.project?.ciTemplate?.content || '';
},
+ result({ data }) {
+ this.updateCiConfig(data.project?.ciTemplate?.content || '');
+ },
error() {
this.reportFailure(LOAD_FAILURE_UNKNOWN);
},
@@ -170,9 +173,6 @@ export default {
isEmpty() {
return this.currentCiFileContent === '';
},
- templateOrCurrentContent() {
- return this.isNewCiConfigFile ? this.starterTemplate : this.currentCiFileContent;
- },
},
i18n: {
tabEdit: s__('Pipelines|Edit'),
@@ -280,7 +280,7 @@ export default {
/>
<pipeline-editor-home
:ci-config-data="ciConfigData"
- :ci-file-content="templateOrCurrentContent"
+ :ci-file-content="currentCiFileContent"
:is-new-ci-config-file="isNewCiConfigFile"
@commit="updateOnCommit"
@resetContent="resetContent"
diff --git a/app/finders/pending_todos_finder.rb b/app/finders/pending_todos_finder.rb
index d79a2340379..509370b49a8 100644
--- a/app/finders/pending_todos_finder.rb
+++ b/app/finders/pending_todos_finder.rb
@@ -26,6 +26,7 @@ class PendingTodosFinder
todos = by_project(todos)
todos = by_target_id(todos)
todos = by_target_type(todos)
+ todos = by_discussion(todos)
by_commit_id(todos)
end
@@ -60,4 +61,12 @@ class PendingTodosFinder
todos
end
end
+
+ def by_discussion(todos)
+ if (discussion = params[:discussion])
+ todos.for_note(discussion.notes)
+ else
+ todos
+ end
+ end
end
diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb
index 3abed7289d5..837d91ef765 100644
--- a/app/graphql/types/ci/runner_type.rb
+++ b/app/graphql/types/ci/runner_type.rb
@@ -40,3 +40,5 @@ module Types
end
end
end
+
+Types::Ci::RunnerType.prepend_mod_with('Types::Ci::RunnerType')
diff --git a/app/models/todo.rb b/app/models/todo.rb
index 23685fb68e0..94a99603848 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -61,6 +61,7 @@ class Todo < ApplicationRecord
scope :for_author, -> (author) { where(author: author) }
scope :for_user, -> (user) { where(user: user) }
scope :for_project, -> (projects) { where(project: projects) }
+ scope :for_note, -> (notes) { where(note: notes) }
scope :for_undeleted_projects, -> { joins(:project).merge(Project.without_deleted) }
scope :for_group, -> (group) { where(group: group) }
scope :for_type, -> (type) { where(target_type: type) }
diff --git a/app/services/discussions/resolve_service.rb b/app/services/discussions/resolve_service.rb
index 3b733023eae..baf14aa8a03 100644
--- a/app/services/discussions/resolve_service.rb
+++ b/app/services/discussions/resolve_service.rb
@@ -47,9 +47,16 @@ module Discussions
MergeRequests::ResolvedDiscussionNotificationService.new(project: project, current_user: current_user).execute(merge_request)
end
+ resolve_user_todos_for(discussion)
SystemNoteService.discussion_continued_in_issue(discussion, project, current_user, follow_up_issue) if follow_up_issue
end
+ def resolve_user_todos_for(discussion)
+ return unless discussion.for_design?
+
+ TodoService.new.resolve_todos_for_target(discussion, current_user)
+ end
+
def first_discussion
@first_discussion ||= discussions.first
end
diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb
index fc6543a8efc..71bb813f384 100644
--- a/app/services/todo_service.rb
+++ b/app/services/todo_service.rb
@@ -316,6 +316,8 @@ class TodoService
attributes.merge!(target_id: nil, commit_id: target.id)
elsif target.is_a?(Issue)
attributes[:issue_type] = target.issue_type
+ elsif target.is_a?(Discussion)
+ attributes.merge!(target_type: nil, target_id: nil, discussion: target)
end
attributes
diff --git a/app/views/admin/application_settings/appearances/preview_sign_in.html.haml b/app/views/admin/application_settings/appearances/preview_sign_in.html.haml
index a317611862c..77c37abbeef 100644
--- a/app/views/admin/application_settings/appearances/preview_sign_in.html.haml
+++ b/app/views/admin/application_settings/appearances/preview_sign_in.html.haml
@@ -8,5 +8,5 @@
= label_tag :password
= password_field_tag :password, nil, class: "form-control gl-form-input bottom", title: _('This field is required.')
.form-group
- = button_tag _("Sign in"), class: "btn gl-button btn-confirm"
+ = button_tag _("Sign in"), class: "btn gl-button btn-confirm", type: "button"
diff --git a/doc/administration/consul.md b/doc/administration/consul.md
index c7fe076dcce..c88047c4c61 100644
--- a/doc/administration/consul.md
+++ b/doc/administration/consul.md
@@ -15,11 +15,17 @@ turn communicate with the servers.
GitLab Premium includes a bundled version of [Consul](https://www.consul.io/)
a service networking solution that you can manage by using `/etc/gitlab/gitlab.rb`.
+## Prerequisites
+
+Before configuring Consul:
+
+1. Review the [reference architecture](reference_architectures/index.md#available-reference-architectures)
+ documentation to determine the number of Consul server nodes you should have.
+1. If necessary, ensure the [appropriate ports are open](https://docs.gitlab.com/omnibus/package-information/defaults.html#ports) in your firewall.
+
## Configure the Consul nodes
-After you review the [reference architecture](reference_architectures/index.md#available-reference-architectures)
-documentation to determine the number of Consul server nodes you should have,
-on _each_ Consul server node:
+On _each_ Consul server node:
1. Follow the instructions to [install](https://about.gitlab.com/install/)
GitLab by choosing your preferred platform, but do not supply the
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index f47b060e73b..5420dfb0b7b 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -7544,6 +7544,8 @@ Represents the total number of issues and their weights for a particular day.
| <a id="cirunneripaddress"></a>`ipAddress` | [`String!`](#string) | IP address of the runner. |
| <a id="cirunnerlocked"></a>`locked` | [`Boolean`](#boolean) | Indicates the runner is locked. |
| <a id="cirunnermaximumtimeout"></a>`maximumTimeout` | [`Int`](#int) | Maximum timeout (in seconds) for jobs processed by the runner. |
+| <a id="cirunnerprivateprojectsminutescostfactor"></a>`privateProjectsMinutesCostFactor` | [`Float`](#float) | Private projects' "minutes cost factor" associated with the runner (GitLab.com only). |
+| <a id="cirunnerpublicprojectsminutescostfactor"></a>`publicProjectsMinutesCostFactor` | [`Float`](#float) | Public projects' "minutes cost factor" associated with the runner (GitLab.com only). |
| <a id="cirunnerrevision"></a>`revision` | [`String!`](#string) | Revision of the runner. |
| <a id="cirunnerrununtagged"></a>`runUntagged` | [`Boolean!`](#boolean) | Indicates the runner is able to run untagged jobs. |
| <a id="cirunnerrunnertype"></a>`runnerType` | [`CiRunnerType!`](#cirunnertype) | Type of the runner. |
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index 8d3b01f3b79..949b7ff4e9d 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -289,8 +289,8 @@ To add a different cluster for each environment:
1. Navigate to your project's **Operations > Kubernetes**.
1. Create the Kubernetes clusters with their respective environment scope, as
described from the table above.
-1. After creating the clusters, navigate to each cluster and install
- Ingress. Wait for the Ingress IP address to be assigned.
+1. After creating the clusters, navigate to each cluster and [install
+ Ingress](quick_start_guide.md#install-ingress). Wait for the Ingress IP address to be assigned.
1. Make sure you've [configured your DNS](#auto-devops-base-domain) with the
specified Auto DevOps domains.
1. Navigate to each cluster's page, through **Operations > Kubernetes**,
diff --git a/doc/topics/autodevops/quick_start_guide.md b/doc/topics/autodevops/quick_start_guide.md
index 7d5ee10f604..6d42a9a4274 100644
--- a/doc/topics/autodevops/quick_start_guide.md
+++ b/doc/topics/autodevops/quick_start_guide.md
@@ -106,7 +106,8 @@ status on your [GCP dashboard](https://console.cloud.google.com/kubernetes).
After your cluster is running, you must install NGINX Ingress Controller as a
load balancer, to route traffic from the internet to your application. Because
you've created a Google GKE cluster in this guide, you can install NGINX Ingress Controller
-with Google Cloud Shell:
+through the GitLab [Cluster management project template](../../user/clusters/management_project_template.md),
+or manually with Google Cloud Shell:
1. Go to your cluster's details page, and click the **Advanced Settings** tab.
1. Click the link to Google Kubernetes Engine to visit the cluster on Google Cloud Console.
@@ -114,21 +115,28 @@ with Google Cloud Shell:
1. After the Cloud Shell starts, run these commands to install NGINX Ingress Controller:
```shell
- helm repo add nginx-stable https://helm.nginx.com/stable
+ kubectl create ns gitlab-managed-apps
+ helm repo add stable https://charts.helm.sh/stable
helm repo update
- helm install nginx-ingress nginx-stable/nginx-ingress
+ helm install ingress stable/nginx-ingress -n gitlab-managed-apps
# Check that the ingress controller is installed successfully
- kubectl get service nginx-ingress-nginx-ingress
+ kubectl get service ingress-nginx-ingress-controller -n gitlab-managed-apps
```
-1. A few minutes after you install NGINX, the load balancer obtains an IP address, and you can
- get the external IP address with this command:
+## Configure your base domain
+
+Follow these steps to configure the Base Domain where your apps will be accessible.
+1. A few minutes after you install NGINX, the load balancer obtains an IP address, and you can
+ get the external IP address with the following command:
+
```shell
- kubectl get service nginx-ingress-nginx-ingress -ojson | jq -r '.status.loadBalancer.ingress[].ip'
+ kubectl get service ingress-nginx-ingress-controller -n gitlab-managed-apps -ojson | jq -r '.status.loadBalancer.ingress[].ip'
```
+ Replace `gitlab-managed-apps` if you have overwritten your namespace.
+
Copy this IP address, as you need it in the next step.
1. Go back to the cluster page on GitLab, and go to the **Details** tab.
diff --git a/doc/topics/autodevops/requirements.md b/doc/topics/autodevops/requirements.md
index ccffb5913f5..7e59ecb4916 100644
--- a/doc/topics/autodevops/requirements.md
+++ b/doc/topics/autodevops/requirements.md
@@ -30,8 +30,8 @@ To make full use of Auto DevOps with Kubernetes, you need:
deployments, any Ingress controller should work, but as of GitLab 14.0,
[canary deployments](../../user/project/canary_deployments.md) require
NGINX Ingress. You can deploy the NGINX Ingress controller to your
- Kubernetes cluster by installing the
- [`ingress-nginx`](https://github.com/kubernetes/ingress-nginx/tree/master/charts/ingress-nginx)
+ Kubernetes cluster either through the GitLab [Cluster management project template](../../user/clusters/management_project_template.md)
+ or manually by using the [`ingress-nginx`](https://github.com/kubernetes/ingress-nginx/tree/master/charts/ingress-nginx)
Helm chart.
NOTE:
diff --git a/doc/user/clusters/applications.md b/doc/user/clusters/applications.md
index f712dcace73..5f047de5938 100644
--- a/doc/user/clusters/applications.md
+++ b/doc/user/clusters/applications.md
@@ -1029,7 +1029,13 @@ at least 2 people from the
The one-click installation method was deprecated in GitLab 13.9 and removed in [GitLab 14.0](https://gitlab.com/groups/gitlab-org/-/epics/4280).
The removal does not break nor uninstall any apps you have installed, it only
removes the "Applications" tab from the cluster page.
-Follow the process to [take ownership of your GitLab Managed Apps](#take-ownership-of-your-gitlab-managed-apps).
+The new recommended way to manage cluster applications is to use the [cluster management project template](management_project_template.md).
+
+- If you want to migrate your GitLab managed apps management to this template, read
+ [migrating from GitLab managed apps to project template](migrating_from_gma_to_project_template.md).
+- If you don't want to use the template, you can also manually manage your applications.
+ For that, follow the process to
+ [take ownership of your GitLab Managed Apps](#take-ownership-of-your-gitlab-managed-apps).
If you are not yet on GitLab 14.0 or later, you can refer to [an older version of this document](https://docs.gitlab.com/13.12/ee/user/clusters/applications.html#install-with-one-click-deprecated).
diff --git a/doc/user/project/issues/design_management.md b/doc/user/project/issues/design_management.md
index 8b67c7e03ce..8c42a27b471 100644
--- a/doc/user/project/issues/design_management.md
+++ b/doc/user/project/issues/design_management.md
@@ -219,6 +219,9 @@ There are two ways to resolve/unresolve a Design thread:
![Resolve checkbox](img/resolve_design-discussion_checkbox_v13_1.png)
+Resolving a discussion thread will also mark any pending to-do related to notes
+inside the thread as done. This is applicable only for to-dos owned by the user triggering the action.
+
Note that your resolved comment pins disappear from the Design to free up space for new discussions.
However, if you need to revisit or find a resolved discussion, all of your resolved threads are
available in the **Resolved Comment** area at the bottom of the right sidebar.
diff --git a/doc/user/todos.md b/doc/user/todos.md
index 695532abf9f..4227f46dfa8 100644
--- a/doc/user/todos.md
+++ b/doc/user/todos.md
@@ -112,6 +112,7 @@ Actions that dismiss to-do items include:
- Changing the milestone
- Adding/removing a label
- Commenting on the issue
+- Resolving a [design discussion thread](project/issues/design_management.md#resolve-design-threads)
Your To-Do List is personal, and items are only marked as done if you take
action. If you close the issue or merge request, your to-do item is marked as
diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb
index 2d58bb88816..d05ced00a6b 100644
--- a/lib/gitlab/highlight.rb
+++ b/lib/gitlab/highlight.rb
@@ -70,6 +70,8 @@ module Gitlab
end
def highlight_rich(text, continue: true)
+ add_highlight_attempt_metric
+
tag = lexer.tag
tokens = lexer.lex(text, continue: continue)
Timeout.timeout(timeout_time) { @formatter.format(tokens, context.merge(tag: tag)).html_safe }
@@ -90,12 +92,25 @@ module Gitlab
Gitlab::DependencyLinker.link(blob_name, text, highlighted_text)
end
+ def add_highlight_attempt_metric
+ return unless Feature.enabled?(:track_highlight_timeouts)
+
+ highlighting_attempt.increment(source: (@language || "undefined"))
+ end
+
def add_highlight_timeout_metric
return unless Feature.enabled?(:track_highlight_timeouts)
highlight_timeout.increment(source: Gitlab::Runtime.sidekiq? ? "background" : "foreground")
end
+ def highlighting_attempt
+ @highlight_attempt ||= Gitlab::Metrics.counter(
+ :file_highlighting_attempt,
+ 'Counts the times highlighting has been attempted on a file'
+ )
+ end
+
def highlight_timeout
@highlight_timeout ||= Gitlab::Metrics.counter(
:highlight_timeout,
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 63be6e28249..b4c82b69b43 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -16281,6 +16281,9 @@ msgstr ""
msgid "Hide shared projects"
msgstr ""
+msgid "Hide tooltips or popovers"
+msgstr ""
+
msgid "Hide value"
msgid_plural "Hide values"
msgstr[0] ""
diff --git a/spec/finders/pending_todos_finder_spec.rb b/spec/finders/pending_todos_finder_spec.rb
index b17915f0d59..f317d8b1633 100644
--- a/spec/finders/pending_todos_finder_spec.rb
+++ b/spec/finders/pending_todos_finder_spec.rb
@@ -3,8 +3,11 @@
require 'spec_helper'
RSpec.describe PendingTodosFinder do
- let(:user) { create(:user) }
- let(:user2) { create(:user) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+ let_it_be(:issue) { create(:issue) }
+ let_it_be(:note) { create(:note) }
+
let(:users) { [user, user2] }
describe '#execute' do
@@ -30,20 +33,16 @@ RSpec.describe PendingTodosFinder do
end
it 'supports retrieving of todos for a specific todo target' do
- issue = create(:issue)
- note = create(:note)
todo = create(:todo, :pending, user: user, target: issue)
create(:todo, :pending, user: user, target: note)
- todos = described_class.new(users, target_id: issue.id).execute
+ todos = described_class.new(users, target_id: issue.id, target_type: 'Issue').execute
expect(todos).to eq([todo])
end
it 'supports retrieving of todos for a specific target type' do
- issue = create(:issue)
- note = create(:note)
todo = create(:todo, :pending, user: user, target: issue)
create(:todo, :pending, user: user, target: note)
@@ -61,5 +60,20 @@ RSpec.describe PendingTodosFinder do
expect(todos).to eq([todo])
end
+
+ it 'supports retrieving of todos for specific discussion' do
+ first_discussion_note = create(:discussion_note_on_issue, noteable: issue, project: issue.project)
+ note_2 = create(:note, discussion_id: first_discussion_note.discussion_id)
+ note_3 = create(:note, discussion_id: first_discussion_note.discussion_id)
+ todo1 = create(:todo, :pending, target: issue, note: note_2, user: note_2.author)
+ todo2 = create(:todo, :pending, target: issue, note: note_3, user: note_3.author)
+ create(:todo, :pending, note: note, user: user)
+ discussion = Discussion.lazy_find(first_discussion_note.discussion_id)
+ users = [note_2.author, note_3.author, user]
+
+ todos = described_class.new(users, discussion: discussion).execute
+
+ expect(todos).to contain_exactly(todo1, todo2)
+ end
end
end
diff --git a/spec/frontend/behaviors/shortcuts/keybindings_spec.js b/spec/frontend/behaviors/shortcuts/keybindings_spec.js
index 53ce06e78c6..3ad44a16ae1 100644
--- a/spec/frontend/behaviors/shortcuts/keybindings_spec.js
+++ b/spec/frontend/behaviors/shortcuts/keybindings_spec.js
@@ -5,6 +5,7 @@ import {
getCustomizations,
keybindingGroups,
TOGGLE_PERFORMANCE_BAR,
+ HIDE_APPEARING_CONTENT,
LOCAL_STORAGE_KEY,
WEB_IDE_COMMIT,
} from '~/behaviors/shortcuts/keybindings';
@@ -95,4 +96,14 @@ describe('~/behaviors/shortcuts/keybindings', () => {
expect(keysFor(TOGGLE_PERFORMANCE_BAR)).toEqual(['p b']);
});
});
+
+ describe('when tooltips or popovers are visible', () => {
+ beforeEach(() => {
+ setupCustomizations();
+ });
+
+ it('returns the default keybinding for the command', () => {
+ expect(keysFor(HIDE_APPEARING_CONTENT)).toEqual(['esc']);
+ });
+ });
});
diff --git a/spec/graphql/types/ci/runner_type_spec.rb b/spec/graphql/types/ci/runner_type_spec.rb
index dfe4a30c5b7..f27216f4d39 100644
--- a/spec/graphql/types/ci/runner_type_spec.rb
+++ b/spec/graphql/types/ci/runner_type_spec.rb
@@ -2,15 +2,17 @@
require 'spec_helper'
-RSpec.describe Types::Ci::RunnerType do
+RSpec.describe GitlabSchema.types['CiRunner'] do
specify { expect(described_class.graphql_name).to eq('CiRunner') }
+ specify { expect(described_class).to require_graphql_authorizations(:read_runner) }
+
it 'contains attributes related to a runner' do
expected_fields = %w[
id description contacted_at maximum_timeout access_level active status
version short_sha revision locked run_untagged ip_address runner_type tag_list
]
- expect(described_class).to have_graphql_fields(*expected_fields)
+ expect(described_class).to include_graphql_fields(*expected_fields)
end
end
diff --git a/spec/lib/gitlab/highlight_spec.rb b/spec/lib/gitlab/highlight_spec.rb
index 74388273c8d..1f06019c929 100644
--- a/spec/lib/gitlab/highlight_spec.rb
+++ b/spec/lib/gitlab/highlight_spec.rb
@@ -143,9 +143,21 @@ RSpec.describe Gitlab::Highlight do
end
describe 'highlight timeouts' do
- context 'when there is a timeout error while highlighting' do
- let(:result) { described_class.highlight(file_name, content) }
+ let(:result) { described_class.highlight(file_name, content, language: "ruby") }
+
+ context 'when there is an attempt' do
+ it "increments the attempt counter with a defined language" do
+ expect { result }.to change { highlight_attempt_total("ruby") }
+ end
+
+ it "increments the attempt counter with an undefined language" do
+ expect do
+ described_class.highlight(file_name, content)
+ end.to change { highlight_attempt_total("undefined") }
+ end
+ end
+ context 'when there is a timeout error while highlighting' do
before do
allow(Timeout).to receive(:timeout).twice.and_raise(Timeout::Error)
# This is done twice because it's rescued first and then
@@ -177,6 +189,12 @@ RSpec.describe Gitlab::Highlight do
.get(source: source)
end
+ def highlight_attempt_total(source)
+ Gitlab::Metrics
+ .counter(:file_highlighting_attempt, 'Counts the times highlighting has been attempted on a file')
+ .get(source: source)
+ end
+
def over_highlight_size_limit(source)
Gitlab::Metrics
.counter(:over_highlight_size_limit,
diff --git a/spec/models/todo_spec.rb b/spec/models/todo_spec.rb
index caa0a886abf..651e2cf273f 100644
--- a/spec/models/todo_spec.rb
+++ b/spec/models/todo_spec.rb
@@ -376,6 +376,18 @@ RSpec.describe Todo do
end
end
+ describe '.for_note' do
+ it 'returns todos that belongs to notes' do
+ note_1 = create(:note, noteable: issue, project: issue.project)
+ note_2 = create(:note, noteable: issue, project: issue.project)
+ todo_1 = create(:todo, note: note_1)
+ todo_2 = create(:todo, note: note_2)
+ create(:todo, note: create(:note))
+
+ expect(described_class.for_note([note_1, note_2])).to contain_exactly(todo_1, todo_2)
+ end
+ end
+
describe '.group_by_user_id_and_state' do
let_it_be(:user1) { create(:user) }
let_it_be(:user2) { create(:user) }
diff --git a/spec/services/discussions/resolve_service_spec.rb b/spec/services/discussions/resolve_service_spec.rb
index 2e30455eb0a..24de1d90526 100644
--- a/spec/services/discussions/resolve_service_spec.rb
+++ b/spec/services/discussions/resolve_service_spec.rb
@@ -121,5 +121,50 @@ RSpec.describe Discussions::ResolveService do
service.execute
end
end
+
+ context 'when resolving a discussion' do
+ def resolve_discussion(discussion, user)
+ described_class.new(project, user, one_or_more_discussions: discussion).execute
+ end
+
+ context 'in a design' do
+ let_it_be(:design) { create(:design, :with_file, issue: create(:issue, project: project)) }
+ let_it_be(:user_1) { create(:user) }
+ let_it_be(:user_2) { create(:user) }
+ let_it_be(:discussion_1) { create(:diff_note_on_design, noteable: design, project: project, author: user_1).to_discussion }
+ let_it_be(:discussion_2) { create(:diff_note_on_design, noteable: design, project: project, author: user_2).to_discussion }
+
+ before do
+ project.add_developer(user_1)
+ project.add_developer(user_2)
+ end
+
+ context 'when user resolving discussion has open todos' do
+ let!(:user_1_todo_for_discussion_1) { create(:todo, :pending, user: user_1, target: design, note: discussion_1.notes.first, project: project) }
+ let!(:user_1_todo_2_for_discussion_1) { create(:todo, :pending, user: user_1, target: design, note: discussion_1.notes.first, project: project) }
+ let!(:user_1_todo_for_discussion_2) { create(:todo, :pending, user: user_1, target: design, note: discussion_2.notes.first, project: project) }
+ let!(:user_2_todo_for_discussion_1) { create(:todo, :pending, user: user_2, target: design, note: discussion_1.notes.first, project: project) }
+
+ it 'marks user todos for given discussion as done' do
+ resolve_discussion(discussion_1, user_1)
+
+ expect(user_1_todo_for_discussion_1.reload).to be_done
+ expect(user_1_todo_2_for_discussion_1.reload).to be_done
+ expect(user_1_todo_for_discussion_2.reload).to be_pending
+ expect(user_2_todo_for_discussion_1.reload).to be_pending
+ end
+ end
+ end
+
+ context 'in a merge request' do
+ let!(:user_todo_for_discussion) { create(:todo, :pending, user: user, target: merge_request, note: discussion.notes.first, project: project) }
+
+ it 'does not mark user todo as done' do
+ resolve_discussion(discussion, user)
+
+ expect(user_todo_for_discussion).to be_pending
+ end
+ end
+ end
end
end