Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
b27cd9649f
commit
aeda2f64b4
|
@ -1 +1 @@
|
||||||
8b033b1763e80468b4f11a572e1425d1064692e2
|
40e19e808a320ce357c2ce5edfa3cf09def58477
|
||||||
|
|
|
@ -27,7 +27,8 @@ class PendingTodosFinder
|
||||||
todos = by_target_id(todos)
|
todos = by_target_id(todos)
|
||||||
todos = by_target_type(todos)
|
todos = by_target_type(todos)
|
||||||
todos = by_discussion(todos)
|
todos = by_discussion(todos)
|
||||||
by_commit_id(todos)
|
todos = by_commit_id(todos)
|
||||||
|
by_action(todos)
|
||||||
end
|
end
|
||||||
|
|
||||||
def by_project(todos)
|
def by_project(todos)
|
||||||
|
@ -69,4 +70,10 @@ class PendingTodosFinder
|
||||||
todos
|
todos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def by_action(todos)
|
||||||
|
return todos if params[:action].blank?
|
||||||
|
|
||||||
|
todos.for_action(params[:action])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1152,8 +1152,6 @@ class MergeRequest < ApplicationRecord
|
||||||
|
|
||||||
# rubocop: disable CodeReuse/ServiceClass
|
# rubocop: disable CodeReuse/ServiceClass
|
||||||
def mergeable_state?(skip_ci_check: false, skip_discussions_check: false)
|
def mergeable_state?(skip_ci_check: false, skip_discussions_check: false)
|
||||||
return false unless open?
|
|
||||||
|
|
||||||
if Feature.enabled?(:improved_mergeability_checks, self.project, default_enabled: :yaml)
|
if Feature.enabled?(:improved_mergeability_checks, self.project, default_enabled: :yaml)
|
||||||
additional_checks = MergeRequests::Mergeability::RunChecksService.new(
|
additional_checks = MergeRequests::Mergeability::RunChecksService.new(
|
||||||
merge_request: self,
|
merge_request: self,
|
||||||
|
@ -1164,6 +1162,7 @@ class MergeRequest < ApplicationRecord
|
||||||
)
|
)
|
||||||
additional_checks.execute.all?(&:success?)
|
additional_checks.execute.all?(&:success?)
|
||||||
else
|
else
|
||||||
|
return false unless open?
|
||||||
return false if draft?
|
return false if draft?
|
||||||
return false if broken?
|
return false if broken?
|
||||||
return false unless skip_discussions_check || mergeable_discussions_state?
|
return false unless skip_discussions_check || mergeable_discussions_state?
|
||||||
|
|
|
@ -34,6 +34,8 @@ class Todo < ApplicationRecord
|
||||||
ATTENTION_REQUESTED => :attention_requested
|
ATTENTION_REQUESTED => :attention_requested
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
|
ACTIONS_MULTIPLE_ALLOWED = [Todo::MENTIONED, Todo::DIRECTLY_ADDRESSED].freeze
|
||||||
|
|
||||||
belongs_to :author, class_name: "User"
|
belongs_to :author, class_name: "User"
|
||||||
belongs_to :note
|
belongs_to :note
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
|
|
|
@ -22,9 +22,7 @@ module AlertManagement
|
||||||
return result unless result.success?
|
return result unless result.success?
|
||||||
|
|
||||||
issue = result.payload[:issue]
|
issue = result.payload[:issue]
|
||||||
update_title_for(issue)
|
perform_after_create_tasks(issue)
|
||||||
|
|
||||||
SystemNoteService.new_alert_issue(alert, issue, user)
|
|
||||||
|
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
@ -56,6 +54,12 @@ module AlertManagement
|
||||||
issue.update!(title: "#{DEFAULT_INCIDENT_TITLE} #{issue.iid}")
|
issue.update!(title: "#{DEFAULT_INCIDENT_TITLE} #{issue.iid}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def perform_after_create_tasks(issue)
|
||||||
|
update_title_for(issue)
|
||||||
|
|
||||||
|
SystemNoteService.new_alert_issue(alert, issue, user)
|
||||||
|
end
|
||||||
|
|
||||||
def error(message, issue = nil)
|
def error(message, issue = nil)
|
||||||
ServiceResponse.error(payload: { issue: issue }, message: message)
|
ServiceResponse.error(payload: { issue: issue }, message: message)
|
||||||
end
|
end
|
||||||
|
@ -75,3 +79,5 @@ module AlertManagement
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
AlertManagement::CreateAlertIssueService.prepend_mod
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module MergeRequests
|
||||||
|
module Mergeability
|
||||||
|
class CheckOpenStatusService < CheckBaseService
|
||||||
|
def execute
|
||||||
|
if merge_request.open?
|
||||||
|
success
|
||||||
|
else
|
||||||
|
failure
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def skip?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def cacheable?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -7,6 +7,7 @@ module MergeRequests
|
||||||
# We want to have the cheapest checks first in the list,
|
# We want to have the cheapest checks first in the list,
|
||||||
# that way we can fail fast before running the more expensive ones
|
# that way we can fail fast before running the more expensive ones
|
||||||
CHECKS = [
|
CHECKS = [
|
||||||
|
CheckOpenStatusService,
|
||||||
CheckDraftStatusService,
|
CheckDraftStatusService,
|
||||||
CheckBrokenStatusService,
|
CheckBrokenStatusService,
|
||||||
CheckDiscussionsStatusService,
|
CheckDiscussionsStatusService,
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#
|
#
|
||||||
class TodoService
|
class TodoService
|
||||||
include Gitlab::Utils::UsageData
|
include Gitlab::Utils::UsageData
|
||||||
|
|
||||||
# When create an issue we should:
|
# When create an issue we should:
|
||||||
#
|
#
|
||||||
# * create a todo for assignee if issue is assigned
|
# * create a todo for assignee if issue is assigned
|
||||||
|
@ -229,8 +230,24 @@ class TodoService
|
||||||
|
|
||||||
return if users.empty?
|
return if users.empty?
|
||||||
|
|
||||||
users_with_pending_todos = pending_todos(users, attributes).distinct_user_ids
|
users_single_todos, users_multiple_todos = users.partition { |u| Feature.disabled?(:multiple_todos, u) }
|
||||||
users.reject! { |user| users_with_pending_todos.include?(user.id) && Feature.disabled?(:multiple_todos, user) }
|
excluded_user_ids = []
|
||||||
|
|
||||||
|
if users_single_todos.present?
|
||||||
|
excluded_user_ids += pending_todos(
|
||||||
|
users_single_todos,
|
||||||
|
attributes.slice(:project_id, :target_id, :target_type, :commit_id, :discussion)
|
||||||
|
).distinct_user_ids
|
||||||
|
end
|
||||||
|
|
||||||
|
if users_multiple_todos.present? && !Todo::ACTIONS_MULTIPLE_ALLOWED.include?(attributes.fetch(:action))
|
||||||
|
excluded_user_ids += pending_todos(
|
||||||
|
users_multiple_todos,
|
||||||
|
attributes.slice(:project_id, :target_id, :target_type, :commit_id, :discussion, :action)
|
||||||
|
).distinct_user_ids
|
||||||
|
end
|
||||||
|
|
||||||
|
users.reject! { |user| excluded_user_ids.include?(user.id) }
|
||||||
|
|
||||||
todos = users.map do |user|
|
todos = users.map do |user|
|
||||||
issue_type = attributes.delete(:issue_type)
|
issue_type = attributes.delete(:issue_type)
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Currently we register validator only for `dev` or `test` environment
|
# Currently we register validator only for `dev` or `test` environment
|
||||||
if Gitlab.dev_or_test_env? || Gitlab::Utils.to_boolean(ENV['GITLAB_ENABLE_QUERY_ANALYZERS'], default: false)
|
Gitlab::Database::QueryAnalyzer.instance.hook!
|
||||||
Gitlab::Database::QueryAnalyzer.instance.hook!
|
Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(::Gitlab::Database::QueryAnalyzers::GitlabSchemasMetrics)
|
||||||
Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(::Gitlab::Database::QueryAnalyzers::GitlabSchemasMetrics)
|
|
||||||
|
|
||||||
if Rails.env.test? || Gitlab::Utils.to_boolean(ENV['ENABLE_CROSS_DATABASE_MODIFICATION_DETECTION'], default: false)
|
if Rails.env.test? || Gitlab::Utils.to_boolean(ENV['ENABLE_CROSS_DATABASE_MODIFICATION_DETECTION'], default: false)
|
||||||
Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(::Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification)
|
Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(::Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification)
|
||||||
end
|
end
|
||||||
|
|
||||||
Gitlab::Application.configure do |config|
|
Gitlab::Application.configure do |config|
|
||||||
config.middleware.use(Gitlab::Middleware::QueryAnalyzer)
|
config.middleware.use(Gitlab::Middleware::QueryAnalyzer)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -101,11 +101,11 @@ understand the GitLab architecture.
|
||||||
A complete architecture diagram is available in our
|
A complete architecture diagram is available in our
|
||||||
[component diagram](#component-diagram) below.
|
[component diagram](#component-diagram) below.
|
||||||
|
|
||||||
![Simplified Component Overview](img/architecture_simplified.png)
|
![Simplified Component Overview](img/architecture_simplified_v14_9.png)
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
To update this diagram, GitLab team members can edit this source file:
|
To update this diagram, use and update this source file:
|
||||||
https://docs.google.com/drawings/d/1fBzAyklyveF-i-2q-OHUIqDkYfjjxC4mq5shwKSZHLs/edit.
|
https://miro.com/app/board/uXjVOH3lzXo=/
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Component diagram
|
### Component diagram
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
|
@ -81,10 +81,8 @@ If you use Gitpod and you get an error about Jira not being able to access the d
|
||||||
|
|
||||||
GitLab for Jira users can authenticate with GitLab using GitLab OAuth.
|
GitLab for Jira users can authenticate with GitLab using GitLab OAuth.
|
||||||
|
|
||||||
FLAG:
|
WARNING:
|
||||||
By default this feature is not available. To make it available,
|
This feature is not ready for production use. The feature flag should only be enabled in development.
|
||||||
ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `jira_connect_oauth`.
|
|
||||||
The feature is not ready for production use.
|
|
||||||
|
|
||||||
The following steps describe setting up an environment to test the GitLab OAuth flow:
|
The following steps describe setting up an environment to test the GitLab OAuth flow:
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
||||||
|
|
||||||
# Service Ping Guide **(FREE SELF)**
|
# Service Ping Guide **(FREE SELF)**
|
||||||
|
|
||||||
> Introduced in GitLab Ultimate 11.2, more statistics.
|
> - Introduced in GitLab Ultimate 11.2, more statistics.
|
||||||
|
> - In GitLab 14.1, [renamed from Usage Ping to Service Ping](https://gitlab.com/groups/gitlab-org/-/epics/5990). In 14.0 and earlier, use the Usage Ping documentation for the Rails commands appropriate to your version.
|
||||||
|
|
||||||
Service Ping is a GitLab process that collects and sends a weekly payload to GitLab.
|
Service Ping is a GitLab process that collects and sends a weekly payload to GitLab.
|
||||||
The payload provides important high-level data that helps our product, support,
|
The payload provides important high-level data that helps our product, support,
|
||||||
|
|
|
@ -54,7 +54,8 @@ To-do items aren't affected by [GitLab notification email settings](profile/noti
|
||||||
|
|
||||||
<!-- When the feature flag is removed, integrate this topic into the one above. -->
|
<!-- When the feature flag is removed, integrate this topic into the one above. -->
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28355) in GitLab 13.8 [with a flag](../administration/feature_flags.md) named `multiple_todos`. Disabled by default.
|
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28355) in GitLab 13.8 [with a flag](../administration/feature_flags.md) named `multiple_todos`. Disabled by default.
|
||||||
|
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82470) in GitLab 14.9: only mentions create multiple to-do items.
|
||||||
|
|
||||||
FLAG:
|
FLAG:
|
||||||
On self-managed GitLab, by default this feature is not available. To make it available per user,
|
On self-managed GitLab, by default this feature is not available. To make it available per user,
|
||||||
|
@ -62,8 +63,11 @@ ask an administrator to [enable the feature flag](../administration/feature_flag
|
||||||
On GitLab.com, this feature is not available.
|
On GitLab.com, this feature is not available.
|
||||||
The feature is not ready for production use.
|
The feature is not ready for production use.
|
||||||
|
|
||||||
When you enable this feature, new actions for the same user on the same object
|
When you enable this feature:
|
||||||
create new to-do items.
|
|
||||||
|
- Every time you're mentioned, GitLab creates a new to-do item for you.
|
||||||
|
- Other [actions that create to-do items](#actions-that-create-to-do-items)
|
||||||
|
create one to-do item per action type on the issue, MR, and so on.
|
||||||
|
|
||||||
## Create a to-do item
|
## Create a to-do item
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,35 @@ module Gitlab
|
||||||
{
|
{
|
||||||
image: 'illustrations/manual_action.svg',
|
image: 'illustrations/manual_action.svg',
|
||||||
size: 'svg-394',
|
size: 'svg-394',
|
||||||
title: 'Waiting for approval',
|
title: _('Waiting for approval'),
|
||||||
content: "This job deploys to the protected environment \"#{subject.deployment&.environment&.name}\" which requires approvals. Use the Deployments API to approve or reject the deployment."
|
content: _("This job deploys to the protected environment \"%{environment}\" which requires approvals.") % { environment: subject.deployment&.environment&.name }
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_action?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def action_icon
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def action_title
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def action_button_title
|
||||||
|
_('Go to environments page to approve or reject')
|
||||||
|
end
|
||||||
|
|
||||||
|
def action_path
|
||||||
|
project_environments_path(subject.project)
|
||||||
|
end
|
||||||
|
|
||||||
|
def action_method
|
||||||
|
:get
|
||||||
|
end
|
||||||
|
|
||||||
def self.matches?(build, user)
|
def self.matches?(build, user)
|
||||||
build.waiting_for_deployment_approval?
|
build.waiting_for_deployment_approval?
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,7 +33,7 @@ module Gitlab
|
||||||
chain.add ::Gitlab::SidekiqMiddleware::BatchLoader
|
chain.add ::Gitlab::SidekiqMiddleware::BatchLoader
|
||||||
chain.add ::Gitlab::SidekiqMiddleware::InstrumentationLogger
|
chain.add ::Gitlab::SidekiqMiddleware::InstrumentationLogger
|
||||||
chain.add ::Gitlab::SidekiqMiddleware::AdminMode::Server
|
chain.add ::Gitlab::SidekiqMiddleware::AdminMode::Server
|
||||||
chain.add ::Gitlab::SidekiqMiddleware::QueryAnalyzer if Gitlab.dev_or_test_env? || Gitlab::Utils.to_boolean(ENV['GITLAB_ENABLE_QUERY_ANALYZERS'], default: false)
|
chain.add ::Gitlab::SidekiqMiddleware::QueryAnalyzer
|
||||||
chain.add ::Gitlab::SidekiqVersioning::Middleware
|
chain.add ::Gitlab::SidekiqVersioning::Middleware
|
||||||
chain.add ::Gitlab::SidekiqStatus::ServerMiddleware
|
chain.add ::Gitlab::SidekiqStatus::ServerMiddleware
|
||||||
chain.add ::Gitlab::SidekiqMiddleware::WorkerContext::Server
|
chain.add ::Gitlab::SidekiqMiddleware::WorkerContext::Server
|
||||||
|
|
|
@ -16955,6 +16955,9 @@ msgstr ""
|
||||||
msgid "Go to environments"
|
msgid "Go to environments"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Go to environments page to approve or reject"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Go to epic"
|
msgid "Go to epic"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -37837,6 +37840,9 @@ msgstr ""
|
||||||
msgid "This job depends on upstream jobs that need to succeed in order for this job to be triggered"
|
msgid "This job depends on upstream jobs that need to succeed in order for this job to be triggered"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "This job deploys to the protected environment \"%{environment}\" which requires approvals."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "This job does not have a trace."
|
msgid "This job does not have a trace."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -41246,6 +41252,9 @@ msgstr ""
|
||||||
msgid "Wait for the file to load to copy its contents"
|
msgid "Wait for the file to load to copy its contents"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Waiting for approval"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Waiting for merge (open and assigned)"
|
msgid "Waiting for merge (open and assigned)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -75,5 +75,15 @@ RSpec.describe PendingTodosFinder do
|
||||||
|
|
||||||
expect(todos).to contain_exactly(todo1, todo2)
|
expect(todos).to contain_exactly(todo1, todo2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'supports retrieving of todos for a specific action' do
|
||||||
|
todo = create(:todo, :pending, user: user, target: issue, action: Todo::MENTIONED)
|
||||||
|
|
||||||
|
create(:todo, :pending, user: user, target: issue, action: Todo::ASSIGNED)
|
||||||
|
|
||||||
|
todos = described_class.new(users, action: Todo::MENTIONED).execute
|
||||||
|
|
||||||
|
expect(todos).to contain_exactly(todo)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,22 +5,10 @@ require 'spec_helper'
|
||||||
RSpec.describe Gitlab::Ci::Status::Build::WaitingForApproval do
|
RSpec.describe Gitlab::Ci::Status::Build::WaitingForApproval do
|
||||||
let_it_be(:project) { create(:project, :repository) }
|
let_it_be(:project) { create(:project, :repository) }
|
||||||
let_it_be(:user) { create(:user) }
|
let_it_be(:user) { create(:user) }
|
||||||
|
let_it_be(:build) { create(:ci_build, :manual, environment: 'production', project: project) }
|
||||||
|
|
||||||
subject { described_class.new(Gitlab::Ci::Status::Core.new(build, user)) }
|
subject { described_class.new(Gitlab::Ci::Status::Core.new(build, user)) }
|
||||||
|
|
||||||
describe '#illustration' do
|
|
||||||
let(:build) { create(:ci_build, :manual, environment: 'production', project: project) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
environment = create(:environment, name: 'production', project: project)
|
|
||||||
create(:deployment, :blocked, project: project, environment: environment, deployable: build)
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(subject.illustration).to include(:image, :size) }
|
|
||||||
it { expect(subject.illustration[:title]).to eq('Waiting for approval') }
|
|
||||||
it { expect(subject.illustration[:content]).to include('This job deploys to the protected environment "production"') }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.matches?' do
|
describe '.matches?' do
|
||||||
subject { described_class.matches?(build, user) }
|
subject { described_class.matches?(build, user) }
|
||||||
|
|
||||||
|
@ -46,4 +34,39 @@ RSpec.describe Gitlab::Ci::Status::Build::WaitingForApproval do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#illustration' do
|
||||||
|
before do
|
||||||
|
environment = create(:environment, name: 'production', project: project)
|
||||||
|
create(:deployment, :blocked, project: project, environment: environment, deployable: build)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject.illustration).to include(:image, :size) }
|
||||||
|
it { expect(subject.illustration[:title]).to eq('Waiting for approval') }
|
||||||
|
it { expect(subject.illustration[:content]).to include('This job deploys to the protected environment "production"') }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#has_action?' do
|
||||||
|
it { expect(subject.has_action?).to be_truthy }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#action_icon' do
|
||||||
|
it { expect(subject.action_icon).to be_nil }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#action_title' do
|
||||||
|
it { expect(subject.action_title).to be_nil }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#action_button_title' do
|
||||||
|
it { expect(subject.action_button_title).to eq('Go to environments page to approve or reject') }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#action_path' do
|
||||||
|
it { expect(subject.action_path).to include('environments') }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#action_method' do
|
||||||
|
it { expect(subject.action_method).to eq(:get) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
RSpec.describe MergeRequests::Mergeability::CheckOpenStatusService do
|
||||||
|
subject(:check_open_status) { described_class.new(merge_request: merge_request, params: {}) }
|
||||||
|
|
||||||
|
let(:merge_request) { build(:merge_request) }
|
||||||
|
|
||||||
|
describe '#execute' do
|
||||||
|
before do
|
||||||
|
expect(merge_request).to receive(:open?).and_return(open)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the merge request is open' do
|
||||||
|
let(:open) { true }
|
||||||
|
|
||||||
|
it 'returns a check result with status success' do
|
||||||
|
expect(check_open_status.execute.status).to eq Gitlab::MergeRequests::Mergeability::CheckResult::SUCCESS_STATUS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the merge request is not open' do
|
||||||
|
let(:open) { false }
|
||||||
|
|
||||||
|
it 'returns a check result with status failed' do
|
||||||
|
expect(check_open_status.execute.status).to eq Gitlab::MergeRequests::Mergeability::CheckResult::FAILED_STATUS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#skip?' do
|
||||||
|
it 'returns false' do
|
||||||
|
expect(check_open_status.skip?).to eq false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#cacheable?' do
|
||||||
|
it 'returns false' do
|
||||||
|
expect(check_open_status.cacheable?).to eq false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -47,7 +47,7 @@ RSpec.describe MergeRequests::Mergeability::RunChecksService do
|
||||||
expect(service).not_to receive(:execute)
|
expect(service).not_to receive(:execute)
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(execute).to match_array([success_result, success_result, success_result])
|
expect(execute).to match_array([success_result, success_result, success_result, success_result])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -628,12 +628,32 @@ RSpec.describe TodoService do
|
||||||
stub_feature_flags(multiple_todos: true)
|
stub_feature_flags(multiple_todos: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a todo even if user already has a pending todo' do
|
it 'creates a MENTIONED todo even if user already has a pending MENTIONED todo' do
|
||||||
create(:todo, :mentioned, user: member, project: project, target: issue, author: author)
|
create(:todo, :mentioned, user: member, project: project, target: issue, author: author)
|
||||||
|
|
||||||
expect { service.update_issue(issue, author) }.to change(member.todos, :count)
|
expect { service.update_issue(issue, author) }.to change(member.todos, :count)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'creates a DIRECTLY_ADDRESSED todo even if user already has a pending DIRECTLY_ADDRESSED todo' do
|
||||||
|
create(:todo, :directly_addressed, user: member, project: project, target: issue, author: author)
|
||||||
|
|
||||||
|
issue.update!(description: "#{member.to_reference}, what do you think?")
|
||||||
|
|
||||||
|
expect { service.update_issue(issue, author) }.to change(member.todos, :count)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates an ASSIGNED todo even if user already has a pending MARKED todo' do
|
||||||
|
create(:todo, :marked, user: john_doe, project: project, target: assigned_issue, author: author)
|
||||||
|
|
||||||
|
expect { service.reassigned_assignable(assigned_issue, author) }.to change(john_doe.todos, :count)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not create an ASSIGNED todo if user already has an ASSIGNED todo' do
|
||||||
|
create(:todo, :assigned, user: john_doe, project: project, target: assigned_issue, author: author)
|
||||||
|
|
||||||
|
expect { service.reassigned_assignable(assigned_issue, author) }.not_to change(john_doe.todos, :count)
|
||||||
|
end
|
||||||
|
|
||||||
it 'creates multiple todos if a user is assigned and mentioned in a new issue' do
|
it 'creates multiple todos if a user is assigned and mentioned in a new issue' do
|
||||||
assigned_issue.description = mentions
|
assigned_issue.description = mentions
|
||||||
service.new_issue(assigned_issue, author)
|
service.new_issue(assigned_issue, author)
|
||||||
|
|
Loading…
Reference in New Issue