提交 3aaaf9cd 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 a0b26c6d
......@@ -188,7 +188,7 @@ export default {
<template v-if="shouldRenderFolderContent(model)">
<div v-if="model.isLoadingFolderContent" :key="`loading-item-${i}`">
<gl-loading-icon size="md" class="prepend-top-16" />
<gl-loading-icon size="md" class="gl-mt-5" />
</div>
<template v-else>
......
......@@ -88,7 +88,6 @@ class GfmAutoComplete {
if (this.enableMap.labels) this.setupLabels($input);
if (this.enableMap.snippets) this.setupSnippets($input);
// We don't instantiate the quick actions autocomplete for note and issue/MR edit forms
$input.filter('[data-supports-quick-actions="true"]').atwho({
at: '/',
alias: 'commands',
......
......@@ -55,7 +55,7 @@ export default {
class="note-textarea js-gfm-input js-autosize markdown-area
qa-description-textarea"
dir="auto"
data-supports-quick-actions="false"
data-supports-quick-actions="true"
:aria-label="__('Description')"
:placeholder="__('Write a comment or drag your files here…')"
@keydown.meta.enter="updateIssuable"
......
......@@ -389,7 +389,7 @@ export default {
</markdown-field>
<gl-alert
v-if="isToggleBlockedIssueWarning"
class="prepend-top-16"
class="gl-mt-5"
:title="__('Are you sure you want to close this blocked issue?')"
:primary-button-text="__('Yes, close issue')"
:secondary-button-text="__('Cancel')"
......
......@@ -399,7 +399,6 @@ img.emoji {
.prepend-top-5 { margin-top: 5px; }
.prepend-top-10 { margin-top: 10px; }
.prepend-top-15 { margin-top: 15px; }
.prepend-top-16 { margin-top: 16px; }
.prepend-top-20 { margin-top: 20px; }
.prepend-left-5 { margin-left: 5px; }
.prepend-left-10 { margin-left: 10px; }
......@@ -407,7 +406,6 @@ img.emoji {
.prepend-left-default { margin-left: $gl-padding; }
.prepend-left-20 { margin-left: 20px; }
.prepend-left-64 { margin-left: 64px; }
.append-right-2 { margin-right: 2px; }
.append-right-5 { margin-right: 5px; }
.append-right-10 { margin-right: 10px; }
.append-right-15 { margin-right: 15px; }
......
......@@ -179,7 +179,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def update
@merge_request = ::MergeRequests::UpdateService.new(project, current_user, merge_request_params).execute(@merge_request)
@merge_request = ::MergeRequests::UpdateService.new(project, current_user, merge_request_update_params).execute(@merge_request)
respond_to do |format|
format.html do
......@@ -313,6 +313,10 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
private
def merge_request_update_params
merge_request_params.merge!(params.permit(:merge_request_diff_head_sha))
end
def head_pipeline
strong_memoize(:head_pipeline) do
pipeline = @merge_request.head_pipeline
......
......@@ -66,7 +66,11 @@ module AlertManagement
def process_resolved_alert_management_alert
return if am_alert.blank?
return if am_alert.resolve(ends_at)
if am_alert.resolve(ends_at)
close_issue(am_alert.issue)
return
end
logger.warn(
message: 'Unable to update AlertManagement::Alert status to resolved',
......@@ -75,6 +79,16 @@ module AlertManagement
)
end
def close_issue(issue)
return if issue.blank? || issue.closed?
Issues::CloseService
.new(project, User.alert_bot)
.execute(issue, system_note: false)
SystemNoteService.auto_resolve_prometheus_alert(issue, project, User.alert_bot) if issue.reset.closed?
end
def logger
@logger ||= Gitlab::AppLogger
end
......
......@@ -21,7 +21,7 @@ module ExclusiveLeaseGuard
lease = exclusive_lease.try_obtain
unless lease
log_error('Cannot obtain an exclusive lease. There must be another instance already in execution.')
log_error("Cannot obtain an exclusive lease for #{self.class.name}. There must be another instance already in execution.")
return
end
......
......@@ -115,7 +115,7 @@ class IssuableBaseService < BaseService
new_label_ids.uniq
end
def handle_quick_actions_on_create(issuable)
def handle_quick_actions(issuable)
merge_quick_actions_into_params!(issuable)
end
......@@ -123,17 +123,21 @@ class IssuableBaseService < BaseService
original_description = params.fetch(:description, issuable.description)
description, command_params =
QuickActions::InterpretService.new(project, current_user)
QuickActions::InterpretService.new(project, current_user, quick_action_options)
.execute(original_description, issuable, only: only)
# Avoid a description already set on an issuable to be overwritten by a nil
params[:description] = description if description
params[:description] = description if description && description != original_description
params.merge!(command_params)
end
def quick_action_options
{}
end
def create(issuable)
handle_quick_actions_on_create(issuable)
handle_quick_actions(issuable)
filter_params(issuable)
params.delete(:state_event)
......@@ -177,11 +181,13 @@ class IssuableBaseService < BaseService
end
def update(issuable)
handle_quick_actions(issuable)
filter_params(issuable)
change_state(issuable)
change_subscription(issuable)
change_todo(issuable)
toggle_award(issuable)
filter_params(issuable)
old_associations = associations_before_update(issuable)
label_ids = process_label_ids(params, existing_label_ids: issuable.label_ids)
......
......@@ -2,6 +2,7 @@
module MergeRequests
class BaseService < ::IssuableBaseService
extend ::Gitlab::Utils::Override
include MergeRequests::AssignsMergeParams
def create_note(merge_request, state = merge_request.state)
......@@ -63,6 +64,12 @@ module MergeRequests
super
end
override :handle_quick_actions
def handle_quick_actions(merge_request)
super
handle_wip_event(merge_request)
end
def handle_wip_event(merge_request)
if wip_event = params.delete(:wip_event)
# We update the title that is provided in the params or we use the mr title
......
......@@ -33,12 +33,6 @@ module MergeRequests
super
end
# Override from IssuableBaseService
def handle_quick_actions_on_create(merge_request)
super
handle_wip_event(merge_request)
end
private
def set_projects!
......
......@@ -2,6 +2,8 @@
module MergeRequests
class UpdateService < MergeRequests::BaseService
extend ::Gitlab::Utils::Override
def execute(merge_request)
# We don't allow change of source/target projects and source branch
# after merge request was created
......@@ -9,14 +11,11 @@ module MergeRequests
params.delete(:target_project_id)
params.delete(:source_branch)
merge_from_quick_action(merge_request) if params[:merge]
if merge_request.closed_without_fork?
params.delete(:target_branch)
params.delete(:force_remove_source_branch)
end
handle_wip_event(merge_request)
update_task_event(merge_request) || update(merge_request)
end
......@@ -77,26 +76,6 @@ module MergeRequests
todo_service.update_merge_request(merge_request, current_user)
end
def merge_from_quick_action(merge_request)
last_diff_sha = params.delete(:merge)
if Feature.enabled?(:merge_orchestration_service, merge_request.project, default_enabled: true)
MergeRequests::MergeOrchestrationService
.new(project, current_user, { sha: last_diff_sha })
.execute(merge_request)
else
return unless merge_request.mergeable_with_quick_action?(current_user, last_diff_sha: last_diff_sha)
merge_request.update(merge_error: nil)
if merge_request.head_pipeline_active?
AutoMergeService.new(project, current_user, { sha: last_diff_sha }).execute(merge_request, AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS)
else
merge_request.merge_async(current_user.id, { sha: last_diff_sha })
end
end
end
def reopen_service
MergeRequests::ReopenService
end
......@@ -134,6 +113,37 @@ module MergeRequests
issuable, issuable.project, current_user, branch_type,
old_branch, new_branch)
end
override :handle_quick_actions
def handle_quick_actions(merge_request)
super
merge_from_quick_action(merge_request) if params[:merge]
end
def merge_from_quick_action(merge_request)
last_diff_sha = params.delete(:merge)
if Feature.enabled?(:merge_orchestration_service, merge_request.project, default_enabled: true)
MergeRequests::MergeOrchestrationService
.new(project, current_user, { sha: last_diff_sha })
.execute(merge_request)
else
return unless merge_request.mergeable_with_quick_action?(current_user, last_diff_sha: last_diff_sha)
merge_request.update(merge_error: nil)
if merge_request.head_pipeline_active?
AutoMergeService.new(project, current_user, { sha: last_diff_sha }).execute(merge_request, AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS)
else
merge_request.merge_async(current_user.id, { sha: last_diff_sha })
end
end
end
override :quick_action_options
def quick_action_options
{ merge_request_diff_head_sha: params.delete(:merge_request_diff_head_sha) }
end
end
end
......
......@@ -14,8 +14,17 @@ class Repositories::DestroyService < Repositories::BaseService
log_info(%Q{Repository "#{disk_path}" moved to "#{removal_path}" for repository "#{full_path}"})
current_repository = repository
container.run_after_commit do
# Because GitlabShellWorker is inside a run_after_commit callback it will
# never be triggered on a read-only instance.
#
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/223272
if Gitlab::Database.read_only?
Repositories::ShellDestroyService.new(current_repository).execute
else
container.run_after_commit do
Repositories::ShellDestroyService.new(current_repository).execute
end
end
log_info("Repository \"#{full_path}\" was removed")
......
......@@ -41,7 +41,7 @@
= _('Create branch')
%li.divider.droplab-item-ignore
%li.droplab-item-ignore.gl-ml-3.gl-mr-3.prepend-top-16
%li.droplab-item-ignore.gl-ml-3.gl-mr-3.gl-mt-5
- if can_create_confidential_merge_request?
#js-forked-project{ data: { namespace_path: @project.namespace.full_path, project_path: @project.full_path, new_fork_path: new_project_fork_path(@project), help_page_path: help_page_path('user/project/merge_requests') } }
.form-group
......
- project = local_assigns.fetch(:project)
- model = local_assigns.fetch(:model)
- form = local_assigns.fetch(:form)
- placeholder = model.is_a?(MergeRequest) ? _('Describe the goal of the changes and what reviewers should be aware of.') : _('Write a comment or drag your files here…')
- supports_quick_actions = model.new_record?
- if supports_quick_actions
- preview_url = preview_markdown_path(project, target_type: model.class.name)
- else
- preview_url = preview_markdown_path(project)
- supports_quick_actions = true
- preview_url = preview_markdown_path(project, target_type: model.class.name)
.form-group.row.detail-page-description
= form.label :description, 'Description', class: 'col-form-label col-sm-2'
.col-sm-10
- if model.is_a?(MergeRequest)
= hidden_field_tag :merge_request_diff_head_sha, model.diff_head_sha
- if model.is_a?(Issuable)
= render 'shared/issuable/form/template_selector', issuable: model
......
......@@ -9,7 +9,7 @@
.col-md-12.col-lg-6
- if can?(current_user, :read_cross_project)
.activities-block
.prepend-top-16
.gl-mt-5
.d-flex.align-items-center.border-bottom
%h4.flex-grow
= s_('UserProfile|Activity')
......@@ -20,7 +20,7 @@
.col-md-12.col-lg-6
.projects-block
.prepend-top-16
.gl-mt-5
.d-flex.align-items-center.border-bottom
%h4.flex-grow
= s_('UserProfile|Personal projects')
......
---
title: Support quick actions when editing issue, merge request, and epic descriptions
merge_request: 31186
author:
type: added
---
title: Automatically close related issue when resolving Alert Management Prometheus
Alert
merge_request: 35208
author:
type: added
---
title: Drop partitions_dynamic schema if it exists
merge_request: 35426
author:
type: other
---
title: Log name of class that failed to obtain exclusive lease
merge_request: 35228
author:
type: added
---
title: Upgrade Pages to 1.20.0
merge_request: 35177
author:
type: added
# frozen_string_literal: true
class DropPartitionsDynamicSchemaIfExists < ActiveRecord::Migration[6.0]
DOWNTIME = false
def up
# This targets GitLab.com only - we deployed a migration to create this schema, but reverted the change
execute 'DROP SCHEMA IF EXISTS partitions_dynamic'
end
def down
# no-op
end
end
......@@ -23453,5 +23453,6 @@ COPY "schema_migrations" (version) FROM STDIN;
20200623185440
20200624075411
20200625045442
20200626130220
\.
......@@ -896,7 +896,7 @@ if [[ -d "/builds/gitlab-examples/ci-debug-trace/.git" ]]; then
++ CI_SERVER_VERSION_PATCH=0
++ export CI_SERVER_REVISION=f4cc00ae823
++ CI_SERVER_REVISION=f4cc00ae823
++ export GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_project_service_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_clusters,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,cluster_health,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,pseudonymizer,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
++ export GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_project_service_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_clusters,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,pseudonymizer,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
++ GITLAB_FEATURES=audit_events,burndown_charts,code_owners,contribution_analytics,description_diffs,elastic_search,group_bulk_edit,group_burndown_charts,group_webhooks,issuable_default_templates,issue_weights,jenkins_integration,ldap_group_sync,member_lock,merge_request_approvers,multiple_issue_assignees,multiple_ldap_servers,multiple_merge_request_assignees,protected_refs_for_users,push_rules,related_issues,repository_mirrors,repository_size_limit,scoped_issue_board,usage_quotas,visual_review_app,wip_limits,adjourned_deletion_for_projects_and_groups,admin_audit_log,auditor_user,batch_comments,blocking_merge_requests,board_assignee_lists,board_milestone_lists,ci_cd_projects,cluster_deployments,code_analytics,code_owner_approval_required,commit_committer_check,cross_project_pipelines,custom_file_templates,custom_file_templates_for_namespace,custom_project_templates,custom_prometheus_metrics,cycle_analytics_for_groups,db_load_balancing,default_project_deletion_protection,dependency_proxy,deploy_board,design_management,email_additional_text,extended_audit_events,external_authorization_service_api_management,feature_flags,file_locks,geo,github_project_service_integration,group_allowed_email_domains,group_project_templates,group_saml,issues_analytics,jira_dev_panel_integration,ldap_group_sync_filter,merge_pipelines,merge_request_performance_metrics,merge_trains,metrics_reports,multiple_approval_rules,multiple_clusters,multiple_group_issue_boards,object_storage,operations_dashboard,packages,productivity_analytics,project_aliases,protected_environments,reject_unsigned_commits,required_ci_templates,scoped_labels,service_desk,smartcard_auth,group_timelogs,type_of_work_analytics,unprotection_restrictions,ci_project_subscriptions,cluster_health,container_scanning,dast,dependency_scanning,epics,group_ip_restriction,incident_management,insights,license_management,personal_access_token_expiration_policy,pod_logs,prometheus_alerts,pseudonymizer,report_approver_rules,sast,security_dashboard,tracing,web_ide_terminal
++ export CI_PROJECT_ID=17893
++ CI_PROJECT_ID=17893
......
......@@ -26,7 +26,7 @@ The source of the documentation exists within the codebase of each GitLab applic
| --- | --- |
| [GitLab](https://gitlab.com/gitlab-org/gitlab/) | [`/doc`](https://gitlab.com/gitlab-org/gitlab/tree/master/doc) |
| [GitLab Runner](https://gitlab.com/gitlab-org/gitlab-runner/) | [`/docs`](https://gitlab.com/gitlab-org/gitlab-runner/tree/master/docs) |
| [Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/) | [`/doc`](https://gitlab.com/gitlab-org/gitlab/tree/master/doc) |
| [Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/) | [`/doc`](https://gitlab.com/gitlab-org/omnibus-gitlab/tree/master/doc) |
| [Charts](https://gitlab.com/gitlab-org/charts/gitlab) | [`/doc`](https://gitlab.com/gitlab-org/charts/gitlab/tree/master/doc) |
Documentation issues and merge requests are part of their respective repositories and all have the label `Documentation`.
......
......@@ -259,7 +259,7 @@ For example, to add support for files referenced by a `Widget` model with a
# frozen_string_literal: true
class Geo::WidgetRegistry < Geo::BaseRegistry
include Geo::StateMachineRegistry
include Geo::ReplicableRegistry
MODEL_CLASS = ::Widget
MODEL_FOREIGN_KEY = :widget_id
......
......@@ -7,14 +7,15 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Quick Actions
> - Introduced in [GitLab 12.1](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/26672):
> once an action is executed, an alert appears when a quick action is successfully applied.
> - In [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/16877) and later, you can use
> quick actions when updating the description of issues, epics, and merge requests.
Quick actions are textual shortcuts for common actions on issues, epics, merge requests,
and commits that are usually done by clicking buttons or dropdowns in GitLab's UI.
You can enter these commands while creating a new issue or merge request, or
in comments of issues, epics, merge requests, and commits. Each command should be
on a separate line in order to be properly detected and executed.
> From [GitLab 12.1](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/26672), once an
> action is executed, an alert appears when a quick action is successfully applied.
You can enter these commands in the description or in comments of issues, epics, merge requests, and commits.
Each command should be on a separate line in order to be properly detected and executed.
## Quick Actions for issues, merge requests and epics
......
......@@ -16,7 +16,9 @@ FactoryBot.define do
end
trait :with_issue do
issue
after(:create) do |alert|
create(:issue, alert_management_alert: alert, project: alert.project)
end
end
trait :with_assignee do |alert|
......
......@@ -3,24 +3,23 @@
require 'spec_helper'
RSpec.describe 'GFM autocomplete', :js do
let(:issue_xss_title) { 'This will execute alert<img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;' }
let(:user_xss_title) { 'eve <img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;' }
let(:label_xss_title) { 'alert label &lt;img src=x onerror="alert(\'Hello xss\');" a' }
let(:milestone_xss_title) { 'alert milestone &lt;img src=x onerror="alert(\'Hello xss\');" a' }
let(:user_xss) { create(:user, name: user_xss_title, username: 'xss.user') }
let(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') }
let(:project) { create(:project) }
let(:label) { create(:label, project: project, title: 'special+') }
let_it_be(:user_xss_title) { 'eve <img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;' }
let_it_be(:user_xss) { create(:user, name: user_xss_title, username: 'xss.user') }
let_it_be(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') }
let_it_be(:project) { create(:project) }
let_it_be(:label) { create(:label, project: project, title: 'special+') }
let(:issue) { create(:issue, project: project) }
before_all do
project.add_maintainer(user)
project.add_maintainer(user_xss)
end
describe 'when tribute_autocomplete feature flag is off' do
before do
stub_feature_flags(tribute_autocomplete: false)
project.add_maintainer(user)
project.add_maintainer(user_xss)
sign_in(user)
visit project_issue_path(project, issue)
......@@ -45,6 +44,14 @@ RSpec.describe 'GFM autocomplete', :js do
expect(find('.description')).to have_content(user.to_reference)
end
it 'opens quick action autocomplete when updating description' do
find('.js-issuable-edit').click
find('#issue-description').native.send_keys('/')
expect(page).to have_selector('.atwho-container')
end
it 'opens autocomplete menu when field starts with text' do
page.within '.timeline-content-form' do
find('#note-body').native.send_keys('@')
......@@ -54,6 +61,7 @@ RSpec.describe 'GFM autocomplete', :js do
end
it 'opens autocomplete menu for Issues when field starts with text with item escaping HTML characters' do
issue_xss_title = 'This will execute alert<img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;'
create(:issue, project: project, title: issue_xss_title)
page.within '.timeline-content-form' do
......@@ -84,6 +92,7 @@ RSpec.describe 'GFM autocomplete', :js do
end
it 'opens autocomplete menu for Milestone when field starts with text with item escaping HTML characters' do
milestone_xss_title = 'alert milestone &lt;img src=x onerror="alert(\'Hello xss\');" a'
create(:milestone, project: project, title: milestone_xss_title)
page.within '.timeline-content-form' do
......@@ -327,6 +336,7 @@ RSpec.describe 'GFM autocomplete', :js do
context 'labels' do
it 'opens autocomplete menu for Labels when field starts with text with item escaping HTML characters' do
label_xss_title = 'alert label &lt;img src=x onerror="alert(\'Hello xss\');" a'
create(:label, project: project, title: label_xss_title)
note = find('#note-body')
......@@ -462,9 +472,6 @@ RSpec.describe 'GFM autocomplete', :js do
before do
stub_feature_flags(tribute_autocomplete: true)
project.add_maintainer(user)
project.add_maintainer(user_xss)
sign_in(user)
visit project_issue_path(project, issue)
......
......@@ -78,7 +78,7 @@ RSpec.describe 'getting Alert Management Alerts' do
expect(second_alert).to include(
'iid' => resolved_alert.iid.to_s,
'issueIid' => nil,
'issueIid' => resolved_alert.issue_iid.to_s,
'status' => 'RESOLVED',
'endedAt' => resolved_alert.ended_at.strftime('%Y-%m-%dT%H:%M:%SZ')
)
......
......@@ -123,6 +123,21 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
it 'resolves an existing alert' do
expect { execute }.to change { alert.reload.resolved? }.to(true)
end
context 'existing issue' do
let!(:alert) { create(:alert_management_alert, :with_issue, project: project, fingerprint: parsed_alert.gitlab_fingerprint) }
it 'closes the issue' do
issue = alert.issue
expect { execute }
.to change { issue.reload.state }
.from('opened')
.to('closed')
end
specify { expect { execute }.to change(Note, :count).by(1) }
end
end
context 'when status change did not succeed' do
......
......@@ -51,7 +51,7 @@ RSpec.describe ExclusiveLeaseGuard, :clean_gitlab_redis_shared_state do
it 'does not call internal_method but logs error', :aggregate_failures do
expect(subject).not_to receive(:internal_method)
expect(Gitlab::AppLogger).to receive(:error).with('Cannot obtain an exclusive lease. There must be another instance already in execution.')
expect(Gitlab::AppLogger).to receive(:error).with("Cannot obtain an exclusive lease for #{subject.class.name}. There must be another instance already in execution.")
subject.call
end
......
......@@ -284,7 +284,9 @@ RSpec.describe Issues::CreateService do
end
end
it_behaves_like 'new issuable record that supports quick actions'
it_behaves_like 'issuable record that supports quick actions' do
let(:issuable) { described_class.new(project, user, params).execute }
end
context 'Quick actions' do
context 'with assignee and milestone in params and command' do
......
......@@ -866,5 +866,10 @@ RSpec.describe Issues::UpdateService, :mailer do
end
end
end
it_behaves_like 'issuable record that supports quick actions' do
let(:existing_issue) { create(:issue, project: project) }
let(:issuable) { described_class.new(project, user, params).execute(existing_issue) }
end
end
end
......@@ -339,13 +339,14 @@ RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
end
end
it_behaves_like 'new issuable record that supports quick actions' do
it_behaves_like 'issuable record that supports quick actions' do
let(:default_params) do
{
source_branch: 'feature',
target_branch: 'master'
}
end
let(:issuable) { described_class.new(project, user, params).execute }
end
context 'Quick actions' do
......
......@@ -737,5 +737,10 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
.to change { merge_request.reload.force_remove_source_branch? }.from(nil).to(true)
end
end
it_behaves_like 'issuable record that supports quick actions' do
let(:existing_merge_request) { create(:merge_request, source_project: project) }
let(:issuable) { described_class.new(project, user, params).execute(existing_merge_request) }
end
end
end
......@@ -139,7 +139,7 @@ RSpec.describe Projects::GitDeduplicationService do
end
it 'fails when a lease is already out' do
expect(service).to receive(:log_error).with('Cannot obtain an exclusive lease. There must be another instance already in execution.')
expect(service).to receive(:log_error).with("Cannot obtain an exclusive lease for #{service.class.name}. There must be another instance already in execution.")
service.execute
end
......
......@@ -34,6 +34,21 @@ RSpec.describe Repositories::DestroyService do
project.touch
end
context 'on a read-only instance' do
before do
allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end
it 'schedules the repository deletion' do
expect(Repositories::ShellDestroyService).to receive(:new).with(repository).and_call_original
expect(GitlabShellWorker).to receive(:perform_in)
.with(Repositories::ShellDestroyService::REPO_REMOVAL_DELAY, :remove_repository, project.repository_storage, remove_path)
subject
end
end
it 'removes the repository', :sidekiq_inline do
subject
......
......@@ -3,20 +3,25 @@
# Specifications for behavior common to all objects with executable attributes.
# It can take a `default_params`.
RSpec.shared_examples 'new issuable record that supports quick actions' do
let!(:project) { create(:project, :repository) }
let(:user) { create(:user).tap { |u| project.add_maintainer(u) } }
let(:assignee) { create(:user) }
let!(:milestone) { create(:milestone, project: project) }
let!(:labels) { create_list(:label, 3, project: project) }
RSpec.shared_examples 'issuable record that supports quick actions' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let_it_be(:assignee) { create(:user) }
let_it_be(:milestone) { create(:milestone, project: project) }
let_it_be(:labels) { create_list(:label, 3, project: project) }
let(:base_params) { { title: 'My issuable title' } }
let(:params) { base_params.merge(defined?(default_params) ? default_params : {}).merge(example_params) }
let(:issuable) { described_class.new(project, user, params).execute }
before do
before_all do
project.add_maintainer(user)
project.add_maintainer(assignee)
end
before do
issuable.reload
end
context 'with labels in command only' do
let(:example_params) do
{
......@@ -25,7 +30,6 @@ RSpec.shared_examples 'new issuable record that supports quick actions' do
end
it 'attaches labels to issuable' do
expect(issuable).to be_persisted
expect(issuable.label_ids).to match_array([labels.first.id, labels.second.id])
end
end
......@@ -39,7 +43,6 @@ RSpec.shared_examples 'new issuable record that supports quick actions' do
end
it 'attaches all labels to issuable' do
expect(issuable).to be_persisted
expect(issuable.label_ids).to match_array([labels.first.id, labels.second.id])
end
end
......@@ -52,22 +55,8 @@ RSpec.shared_examples 'new issuable record that supports quick actions' do
end
it 'assigns and sets milestone to issuable' do
expect(issuable).to be_persisted
expect(issuable.assignees).to eq([assignee])
expect(issuable.milestone).to eq(milestone)
end
end
describe '/close' do
let(:example_params) do
{
description: '/close'
}
end
it 'returns an open issue' do
expect(issuable).to be_persisted
expect(issuable).to be_open
end
end
end
......@@ -53,13 +53,17 @@ RSpec.shared_examples 'an editable merge request' do
find('#merge_request_description').native.send_keys('')
fill_in 'merge_request_description', with: user.to_reference[0..4]
wait_for_requests
page.within('.atwho-view') do
expect(page).to have_content(user2.name)
end
end
it 'description has quick action autocomplete', :js do
find('#merge_request_description').native.send_keys('/')
expect(page).to have_selector('.atwho-container')
end
it 'has class js-quick-submit in form' do
expect(page).to have_selector('.js-quick-submit')
end
......
# frozen_string_literal: true
RSpec.shared_examples 'merge quick action' do
context 'when the current user can merge the MR' do
context 'when updating the description' do
before do
sign_in(user)
visit project_merge_request_path(project, merge_request)
visit edit_project_merge_request_path(project, merge_request)
end
it 'merges the MR', :sidekiq_might_not_need_inline do
add_note("/merge")
expect(page).to have_content 'Merged this merge request.'
it 'merges the MR', :sidekiq_inline do
fill_in('Description', with: '/merge')
click_button('Save changes')
expect(page).to have_content('Merged')
expect(merge_request.reload).to be_merged
end
end
context 'when auto merge is avialable' do
context 'when creating a new note' do
context 'when the current user can merge the MR' do
before do
create(:ci_pipeline, :detached_merge_request_pipeline,
project: project, merge_request: merge_request)
merge_request.update_head_pipeline
sign_in(user)
visit project_merge_request_path(project, merge_request)
end
it 'schedules to merge the MR' do
it 'merges the MR', :sidekiq_inline do
add_note("/merge")
expect(page).to have_content "Scheduled to merge this merge request (Merge when pipeline succeeds)."
expect(page).to have_content 'Merged this merge request.'
expect(merge_request.reload).to be_auto_merge_enabled
expect(merge_request.reload).not_to be_merged
expect(merge_request.reload).to be_merged
end
end
end
context 'when the head diff changes in the meanwhile' do
before do
merge_request.source_branch = 'another_branch'
merge_request.save
sign_in(user)
visit project_merge_request_path(project, merge_request)
end
context 'when auto merge is available' do
before do
create(:ci_pipeline, :detached_merge_request_pipeline,
project: project, merge_request: merge_request)
merge_request.update_head_pipeline
end
it 'does not merge the MR' do
add_note("/merge")
it 'schedules to merge the MR' do
add_note("/merge")
expect(page).not_to have_content 'Your commands have been executed!'
expect(page).to have_content "Scheduled to merge this merge request (Merge when pipeline succeeds)."
expect(merge_request.reload).not_to be_merged
expect(merge_request.reload).to be_auto_merge_enabled
expect(merge_request.reload).not_to be_merged
end
end
end
end
context 'when the current user cannot merge the MR' do
before do
project.add_guest(guest)
sign_in(guest)
visit project_merge_request_path(project, merge_request)
context 'when the head diff changes in the meanwhile' do
before do
merge_request.source_branch = 'another_branch'
merge_request.save
sign_in(user)
visit project_merge_request_path(project, merge_request)
end
it 'does not merge the MR' do
add_note("/merge")
expect(page).not_to have_content 'Your commands have been executed!'
expect(merge_request.reload).not_to be_merged
end
end
it 'does not merge the MR' do
add_note("/merge")
context 'when the current user cannot merge the MR' do
before do
project.add_guest(guest)
sign_in(guest)
visit project_merge_request_path(project, merge_request)
end
it 'does not merge the MR' do
add_note("/merge")
expect(page).not_to have_content 'Your commands have been executed!'
expect(page).not_to have_content 'Your commands have been executed!'
expect(merge_request.reload).not_to be_merged
expect(merge_request.reload).not_to be_merged
end
end
end
end
......@@ -32,7 +32,7 @@ RSpec.describe RepositoryRemoveRemoteWorker do
expect(subject)
.to receive(:log_error)
.with('Cannot obtain an exclusive lease. There must be another instance already in execution.')
.with("Cannot obtain an exclusive lease for #{subject.class.name}. There must be another instance already in execution.")
subject.perform(project.id, remote_name)
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册