Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-01 15:08:57 +00:00
parent 875662ef7b
commit dd5d37c7f6
18 changed files with 236 additions and 135 deletions

View file

@ -121,7 +121,7 @@ gem 'carrierwave', '~> 1.3'
gem 'mini_magick', '~> 4.10.1'
# for backups
gem 'fog-aws', '~> 3.12'
gem 'fog-aws', '~> 3.14'
# Locked until fog-google resolves https://github.com/fog/fog-google/issues/421.
# Also see config/initializers/fog_core_patch.rb.
gem 'fog-core', '= 2.1.0'

View file

@ -409,7 +409,7 @@ GEM
fog-json
ipaddress (~> 0.8)
xml-simple (~> 1.1)
fog-aws (3.12.0)
fog-aws (3.14.0)
fog-core (~> 2.1)
fog-json (~> 1.1)
fog-xml (~> 0.1)
@ -1488,7 +1488,7 @@ DEPENDENCIES
flipper-active_support_cache_store (~> 0.21.0)
flowdock (~> 0.7)
fog-aliyun (~> 0.3)
fog-aws (~> 3.12)
fog-aws (~> 3.14)
fog-core (= 2.1.0)
fog-google (~> 1.15)
fog-local (~> 0.6)

View file

@ -97,14 +97,17 @@ export default {
</script>
<template>
<div class="discussion-header note-wrapper">
<div v-once class="timeline-icon gl-align-self-start gl-flex-shrink-0 gl-flex-shrink gl-mr-4">
<div class="discussion-header gl-display-flex gl-align-items-center gl-p-5">
<div
v-once
class="timeline-icon gl-align-self-start gl-flex-shrink-0 gl-flex-shrink gl-ml-3 gl-mr-4"
>
<user-avatar-link
v-if="author"
:link-href="author.path"
:img-src="author.avatar_url"
:img-alt="author.name"
:img-size="32"
:img-size="24"
:img-css-classes="'gl-mr-0!' /* NOTE: this is needed only while we migrate user-avatar-image to GlAvatar (https://gitlab.com/groups/gitlab-org/-/epics/7731) */"
/>
</div>

View file

@ -565,7 +565,6 @@ $system-note-svg-size: 16px;
}
.discussion-header {
min-height: $line-height-base * 2em;
box-sizing: content-box;
.note-header-info {
@ -580,6 +579,7 @@ $system-note-svg-size: 16px;
&.note-wrapper {
display: flex;
align-items: center;
padding-right: $gl-padding;
}
}

View file

@ -42,8 +42,6 @@ module Resolvers
def cutoff(id, sha)
if sha.present? || id.present?
specific_version(id, sha)
elsif at_version = context[:at_version_argument]
by_id(at_version) # See: DesignsResolver
else
:unconstrained
end

View file

@ -249,7 +249,7 @@ module Integrations
ref = data[:ref] || data.dig(:object_attributes, :ref)
return true if ref.blank? # No need to check protected branches when there is no ref
return true if Gitlab::Git.tag_ref?(ref) # Skip protected branch check because it doesn't support tags
return true if Gitlab::Git.tag_ref?(project.repository.expand_ref(ref) || ref) # Skip protected branch check because it doesn't support tags
notify_for_branch?(data)
end

View file

@ -117,6 +117,8 @@ module MergeRequests
if delete_source_branch?
MergeRequests::DeleteSourceBranchWorker.perform_async(@merge_request.id, @merge_request.source_branch_sha, branch_deletion_user.id)
end
merge_request_merge_param
end
def clean_merge_jid
@ -135,6 +137,12 @@ module MergeRequests
@merge_request.can_remove_source_branch?(branch_deletion_user)
end
def merge_request_merge_param
if @merge_request.can_remove_source_branch?(branch_deletion_user) && !params.fetch('should_remove_source_branch', nil).nil?
@merge_request.update(merge_params: @merge_request.merge_params.merge('should_remove_source_branch' => params['should_remove_source_branch']))
end
end
def handle_merge_error(log_message:, save_message_on_model: false)
Gitlab::AppLogger.error("MergeService ERROR: #{merge_request_info} - #{log_message}")
@merge_request.update(merge_error: log_message) if save_message_on_model

View file

@ -34,6 +34,6 @@
.gl-new-dropdown-item-text-wrapper
= _('Email patches')
%li.gl-new-dropdown-item
= link_to merge_request_path(@merge_request, format: :diff), class: 'dropdown-item', data: { qa_selector: 'download_plain_diff_menu_item' } do
= link_to merge_request_path(@merge_request, format: :diff), class: 'dropdown-item', download: '', data: { qa_selector: 'download_plain_diff_menu_item' } do
.gl-new-dropdown-item-text-wrapper
= _('Plain diff')

View file

@ -239,18 +239,19 @@ in the `connection` setting.
The connection settings match those provided by [fog-aws](https://github.com/fog/fog-aws):
| Setting | Description | Default |
|---------------------------------|------------------------------------|---------|
| `provider` | Always `AWS` for compatible hosts. | `AWS` |
| `aws_access_key_id` | AWS credentials, or compatible. | |
| `aws_secret_access_key` | AWS credentials, or compatible. | |
| `aws_signature_version` | AWS signature version to use. `2` or `4` are valid options. Digital Ocean Spaces and other providers may need `2`. | `4` |
| `enable_signature_v4_streaming` | Set to `true` to enable HTTP chunked transfers with [AWS v4 signatures](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html). Oracle Cloud S3 needs this to be `false`. | `true` |
| `region` | AWS region. | |
| `host` | S3 compatible host for when not using AWS. For example, `localhost` or `storage.example.com`. HTTPS and port 443 is assumed. | `s3.amazonaws.com` |
| `endpoint` | Can be used when configuring an S3 compatible service such as [MinIO](https://min.io), by entering a URL such as `http://127.0.0.1:9000`. This takes precedence over `host`. | (optional) |
| `path_style` | Set to `true` to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as `false` for AWS S3. | `false`. |
| `use_iam_profile` | Set to `true` to use IAM profile instead of access keys. | `false` |
| Setting | Description | Default |
|---------------------------------------------|------------------------------------|---------|
| `provider` | Always `AWS` for compatible hosts. | `AWS` |
| `aws_access_key_id` | AWS credentials, or compatible. | |
| `aws_secret_access_key` | AWS credentials, or compatible. | |
| `aws_signature_version` | AWS signature version to use. `2` or `4` are valid options. Digital Ocean Spaces and other providers may need `2`. | `4` |
| `enable_signature_v4_streaming` | Set to `true` to enable HTTP chunked transfers with [AWS v4 signatures](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html). Oracle Cloud S3 needs this to be `false`. | `true` |
| `region` | AWS region. | |
| `host` | S3 compatible host for when not using AWS. For example, `localhost` or `storage.example.com`. HTTPS and port 443 is assumed. | `s3.amazonaws.com` |
| `endpoint` | Can be used when configuring an S3 compatible service such as [MinIO](https://min.io), by entering a URL such as `http://127.0.0.1:9000`. This takes precedence over `host`. | (optional) |
| `path_style` | Set to `true` to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as `false` for AWS S3. | `false`. |
| `use_iam_profile` | Set to `true` to use IAM profile instead of access keys. | `false` |
| `aws_credentials_refresh_threshold_seconds` | Sets the [automatic refresh threshold](https://github.com/fog/fog-aws#controlling-credential-refresh-time-with-iam-authentication) when using temporary credentials in IAM. | `15` |
#### Oracle Cloud S3 connection settings

View file

@ -152,16 +152,14 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form "path=a
--form "file=@/path/to/file" "https://gitlab.example.com/api/v4/projects/import"
```
cURL doesn't support posting a file from a remote server. Importing a project from a remote server can be accomplished through something like the following:
cURL doesn't support posting a file from a remote server. This example imports a project
using Python's `open` method:
```python
import requests
from io import BytesIO
s3_file = requests.get(presigned_url)
url = 'https://gitlab.example.com/api/v4/projects/import'
files = {'file': ('file.tar.gz', BytesIO(s3_file.content))}
files = { "file": open("project_export.tar.gz", "rb") }
data = {
"path": "example-project",
"namespace": "example-group"
@ -293,6 +291,27 @@ curl --request POST \
}'
```
This example imports from an Amazon S3 bucket, using a module that connects to Amazon S3:
```python
import requests
from io import BytesIO
s3_file = requests.get(presigned_url)
url = 'https://gitlab.example.com/api/v4/projects/import'
files = {'file': ('file.tar.gz', BytesIO(s3_file.content))}
data = {
"path": "example-project",
"namespace": "example-group"
}
headers = {
'Private-Token': "<your_access_token>"
}
requests.post(url, headers=headers, data=data, files=files)
```
```json
{
"id": 1,

View file

@ -508,3 +508,13 @@ the `webservice` container has the following tags:
- `master`
- `master-ubi8`
- `master-fips`
### Testing merge requests with a FIPS pipeline
Merge requests that can trigger Package and QA, can trigger a FIPS package and a
Reference Architecture test pipeline. The base image used for the trigger is
Ubuntu 20.04 FIPS:
1. Trigger `package-and-qa`, if not already triggered.
1. On the `gitlab-omnibus-mirror` child pipeline, manually trigger `Trigger:package:fips`.
1. When the package job is complete, manually trigger the `RAT:FIPS` job.

View file

@ -409,15 +409,11 @@ module API
# error helpers
def forbidden!(reason = nil)
message = ['403 Forbidden']
message << "- #{reason}" if reason
render_api_error!(message.join(' '), 403)
render_api_error_with_reason!(403, '403 Forbidden', reason)
end
def bad_request!(reason = nil)
message = ['400 Bad request']
message << "- #{reason}" if reason
render_api_error!(message.join(' '), 400)
render_api_error_with_reason!(400, '400 Bad request', reason)
end
def bad_request_missing_attribute!(attribute)
@ -437,8 +433,8 @@ module API
end
end
def unauthorized!
render_api_error!('401 Unauthorized', 401)
def unauthorized!(reason = nil)
render_api_error_with_reason!(401, '401 Unauthorized', reason)
end
def not_allowed!(message = nil)
@ -491,6 +487,12 @@ module API
model.errors.messages
end
def render_api_error_with_reason!(status, message, reason)
message = [message]
message << "- #{reason}" if reason
render_api_error!(message.join(' '), status)
end
def render_api_error!(message, status)
render_structured_api_error!({ 'message' => message }, status)
end

View file

@ -23,7 +23,7 @@ module API
installation = JiraConnectInstallation.find_by_client_key(jwt.iss_claim)
if !installation || !jwt.valid?(installation.shared_secret) || !jwt.verify_context_qsh_claim
unauthorized!
unauthorized!('JWT authentication failed')
end
jira_user = installation.client.user_info(jwt.sub_claim)

View file

@ -106,14 +106,6 @@ RSpec.describe Resolvers::DesignManagement::VersionsResolver do
end
end
end
context 'by at_version in parent' do
before do
query_context[:at_version_argument] = first_version.to_global_id
end
it_behaves_like 'a query for all_versions up to the first_version'
end
end
end

View file

@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe API::Helpers do
using RSpec::Parameterized::TableSyntax
subject { Class.new.include(described_class).new }
subject(:helper) { Class.new.include(described_class).new }
describe '#current_user' do
include Rack::Test::Methods
@ -69,17 +69,17 @@ RSpec.describe API::Helpers do
shared_examples 'project finder' do
context 'when project exists' do
it 'returns requested project' do
expect(subject.find_project(existing_id)).to eq(project)
expect(helper.find_project(existing_id)).to eq(project)
end
it 'returns nil' do
expect(subject.find_project(non_existing_id)).to be_nil
expect(helper.find_project(non_existing_id)).to be_nil
end
end
context 'when project id is not provided' do
it 'returns nil' do
expect(subject.find_project(nil)).to be_nil
expect(helper.find_project(nil)).to be_nil
end
end
end
@ -105,7 +105,7 @@ RSpec.describe API::Helpers do
it 'does not hit the database' do
expect(Project).not_to receive(:find_by_full_path)
subject.find_project(non_existing_id)
helper.find_project(non_existing_id)
end
end
end
@ -116,7 +116,7 @@ RSpec.describe API::Helpers do
it 'does not return the project pending delete' do
expect(Project).not_to receive(:find_by_full_path)
expect(subject.find_project(project_pending_delete.id)).to be_nil
expect(helper.find_project(project_pending_delete.id)).to be_nil
end
end
@ -126,7 +126,7 @@ RSpec.describe API::Helpers do
it 'does not return the hidden project' do
expect(Project).not_to receive(:find_by_full_path)
expect(subject.find_project(hidden_project.id)).to be_nil
expect(helper.find_project(hidden_project.id)).to be_nil
end
end
end
@ -138,25 +138,25 @@ RSpec.describe API::Helpers do
shared_examples 'private project without access' do
before do
project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
allow(subject).to receive(:authenticate_non_public?).and_return(false)
allow(helper).to receive(:authenticate_non_public?).and_return(false)
end
it 'returns not found' do
expect(subject).to receive(:not_found!)
expect(helper).to receive(:not_found!)
subject.find_project!(project.id)
helper.find_project!(project.id)
end
end
context 'when user is authenticated' do
before do
allow(subject).to receive(:current_user).and_return(user)
allow(subject).to receive(:initial_current_user).and_return(user)
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:initial_current_user).and_return(user)
end
context 'public project' do
it 'returns requested project' do
expect(subject.find_project!(project.id)).to eq(project)
expect(helper.find_project!(project.id)).to eq(project)
end
end
@ -167,13 +167,13 @@ RSpec.describe API::Helpers do
context 'when user is not authenticated' do
before do
allow(subject).to receive(:current_user).and_return(nil)
allow(subject).to receive(:initial_current_user).and_return(nil)
allow(helper).to receive(:current_user).and_return(nil)
allow(helper).to receive(:initial_current_user).and_return(nil)
end
context 'public project' do
it 'returns requested project' do
expect(subject.find_project!(project.id)).to eq(project)
expect(helper.find_project!(project.id)).to eq(project)
end
end
@ -188,21 +188,21 @@ RSpec.describe API::Helpers do
let(:user) { project.first_owner}
before do
allow(subject).to receive(:current_user).and_return(user)
allow(subject).to receive(:authorized_project_scope?).and_return(true)
allow(subject).to receive(:job_token_authentication?).and_return(false)
allow(subject).to receive(:authenticate_non_public?).and_return(false)
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:authorized_project_scope?).and_return(true)
allow(helper).to receive(:job_token_authentication?).and_return(false)
allow(helper).to receive(:authenticate_non_public?).and_return(false)
end
shared_examples 'project finder' do
context 'when project exists' do
it 'returns requested project' do
expect(subject.find_project!(existing_id)).to eq(project)
expect(helper.find_project!(existing_id)).to eq(project)
end
it 'returns nil' do
expect(subject).to receive(:render_api_error!).with('404 Project Not Found', 404)
expect(subject.find_project!(non_existing_id)).to be_nil
expect(helper).to receive(:render_api_error!).with('404 Project Not Found', 404)
expect(helper.find_project!(non_existing_id)).to be_nil
end
end
end
@ -227,9 +227,9 @@ RSpec.describe API::Helpers do
it 'does not hit the database' do
expect(Project).not_to receive(:find_by_full_path)
expect(subject).to receive(:render_api_error!).with('404 Project Not Found', 404)
expect(helper).to receive(:render_api_error!).with('404 Project Not Found', 404)
subject.find_project!(non_existing_id)
helper.find_project!(non_existing_id)
end
end
end
@ -243,25 +243,25 @@ RSpec.describe API::Helpers do
shared_examples 'private group without access' do
before do
group.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
allow(subject).to receive(:authenticate_non_public?).and_return(false)
allow(helper).to receive(:authenticate_non_public?).and_return(false)
end
it 'returns not found' do
expect(subject).to receive(:not_found!)
expect(helper).to receive(:not_found!)
subject.find_group!(group.id)
helper.find_group!(group.id)
end
end
context 'when user is authenticated' do
before do
allow(subject).to receive(:current_user).and_return(user)
allow(subject).to receive(:initial_current_user).and_return(user)
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:initial_current_user).and_return(user)
end
context 'public group' do
it 'returns requested group' do
expect(subject.find_group!(group.id)).to eq(group)
expect(helper.find_group!(group.id)).to eq(group)
end
end
@ -272,13 +272,13 @@ RSpec.describe API::Helpers do
context 'when user is not authenticated' do
before do
allow(subject).to receive(:current_user).and_return(nil)
allow(subject).to receive(:initial_current_user).and_return(nil)
allow(helper).to receive(:current_user).and_return(nil)
allow(helper).to receive(:initial_current_user).and_return(nil)
end
context 'public group' do
it 'returns requested group' do
expect(subject.find_group!(group.id)).to eq(group)
expect(helper.find_group!(group.id)).to eq(group)
end
end
@ -293,21 +293,21 @@ RSpec.describe API::Helpers do
let(:user) { group.first_owner }
before do
allow(subject).to receive(:current_user).and_return(user)
allow(subject).to receive(:authorized_project_scope?).and_return(true)
allow(subject).to receive(:job_token_authentication?).and_return(false)
allow(subject).to receive(:authenticate_non_public?).and_return(false)
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:authorized_project_scope?).and_return(true)
allow(helper).to receive(:job_token_authentication?).and_return(false)
allow(helper).to receive(:authenticate_non_public?).and_return(false)
end
shared_examples 'group finder' do
context 'when group exists' do
it 'returns requested group' do
expect(subject.find_group!(existing_id)).to eq(group)
expect(helper.find_group!(existing_id)).to eq(group)
end
it 'returns nil' do
expect(subject).to receive(:render_api_error!).with('404 Group Not Found', 404)
expect(subject.find_group!(non_existing_id)).to be_nil
expect(helper).to receive(:render_api_error!).with('404 Group Not Found', 404)
expect(helper.find_group!(non_existing_id)).to be_nil
end
end
end
@ -335,25 +335,25 @@ RSpec.describe API::Helpers do
shared_examples 'private group without access' do
before do
group.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private'))
allow(subject).to receive(:authenticate_non_public?).and_return(false)
allow(helper).to receive(:authenticate_non_public?).and_return(false)
end
it 'returns not found' do
expect(subject).to receive(:not_found!)
expect(helper).to receive(:not_found!)
subject.find_group_by_full_path!(group.full_path)
helper.find_group_by_full_path!(group.full_path)
end
end
context 'when user is authenticated' do
before do
allow(subject).to receive(:current_user).and_return(user)
allow(subject).to receive(:initial_current_user).and_return(user)
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:initial_current_user).and_return(user)
end
context 'public group' do
it 'returns requested group' do
expect(subject.find_group_by_full_path!(group.full_path)).to eq(group)
expect(helper.find_group_by_full_path!(group.full_path)).to eq(group)
end
end
@ -367,7 +367,7 @@ RSpec.describe API::Helpers do
end
it 'returns requested group with access' do
expect(subject.find_group_by_full_path!(group.full_path)).to eq(group)
expect(helper.find_group_by_full_path!(group.full_path)).to eq(group)
end
end
end
@ -375,13 +375,13 @@ RSpec.describe API::Helpers do
context 'when user is not authenticated' do
before do
allow(subject).to receive(:current_user).and_return(nil)
allow(subject).to receive(:initial_current_user).and_return(nil)
allow(helper).to receive(:current_user).and_return(nil)
allow(helper).to receive(:initial_current_user).and_return(nil)
end
context 'public group' do
it 'returns requested group' do
expect(subject.find_group_by_full_path!(group.full_path)).to eq(group)
expect(helper.find_group_by_full_path!(group.full_path)).to eq(group)
end
end
@ -397,13 +397,13 @@ RSpec.describe API::Helpers do
shared_examples 'namespace finder' do
context 'when namespace exists' do
it 'returns requested namespace' do
expect(subject.find_namespace(existing_id)).to eq(namespace)
expect(helper.find_namespace(existing_id)).to eq(namespace)
end
end
context "when namespace doesn't exists" do
it 'returns nil' do
expect(subject.find_namespace(non_existing_id)).to be_nil
expect(helper.find_namespace(non_existing_id)).to be_nil
end
end
end
@ -427,9 +427,9 @@ RSpec.describe API::Helpers do
let(:user1) { create(:user) }
before do
allow(subject).to receive(:current_user).and_return(user1)
allow(subject).to receive(:header).and_return(nil)
allow(subject).to receive(:not_found!).and_raise('404 Namespace not found')
allow(helper).to receive(:current_user).and_return(user1)
allow(helper).to receive(:header).and_return(nil)
allow(helper).to receive(:not_found!).and_raise('404 Namespace not found')
end
context 'when namespace is group' do
@ -477,7 +477,7 @@ RSpec.describe API::Helpers do
describe '#find_namespace!' do
let(:namespace_finder) do
subject.find_namespace!(namespace.id)
helper.find_namespace!(namespace.id)
end
it_behaves_like 'user namespace finder'
@ -488,7 +488,7 @@ RSpec.describe API::Helpers do
let_it_be(:other_project) { create(:project) }
let_it_be(:job) { create(:ci_build) }
let(:send_authorized_project_scope) { subject.authorized_project_scope?(project) }
let(:send_authorized_project_scope) { helper.authorized_project_scope?(project) }
where(:job_token_authentication, :route_setting, :feature_flag, :same_job_project, :expected_result) do
false | false | false | false | true
@ -511,9 +511,9 @@ RSpec.describe API::Helpers do
with_them do
before do
allow(subject).to receive(:job_token_authentication?).and_return(job_token_authentication)
allow(subject).to receive(:route_authentication_setting).and_return(job_token_scope: route_setting ? :project : nil)
allow(subject).to receive(:current_authenticated_job).and_return(job)
allow(helper).to receive(:job_token_authentication?).and_return(job_token_authentication)
allow(helper).to receive(:route_authentication_setting).and_return(job_token_scope: route_setting ? :project : nil)
allow(helper).to receive(:current_authenticated_job).and_return(job)
allow(job).to receive(:project).and_return(same_job_project ? project : other_project)
stub_feature_flags(ci_job_token_scope: false)
@ -531,15 +531,15 @@ RSpec.describe API::Helpers do
let(:blob) { double(name: 'foobar') }
let(:send_git_blob) do
subject.send(:send_git_blob, repository, blob)
subject.header
helper.send(:send_git_blob, repository, blob)
helper.header
end
before do
allow(subject).to receive(:env).and_return({})
allow(subject).to receive(:content_type)
allow(subject).to receive(:header).and_return({})
allow(subject).to receive(:body).and_return('')
allow(helper).to receive(:env).and_return({})
allow(helper).to receive(:content_type)
allow(helper).to receive(:header).and_return({})
allow(helper).to receive(:body).and_return('')
allow(Gitlab::Workhorse).to receive(:send_git_blob)
end
@ -572,19 +572,19 @@ RSpec.describe API::Helpers do
it 'tracks redis hll event' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with(event_name, values: value)
subject.increment_unique_values(event_name, value)
helper.increment_unique_values(event_name, value)
end
it 'logs an exception for unknown event' do
expect(Gitlab::AppLogger).to receive(:warn).with("Redis tracking event failed for event: #{unknown_event}, message: Unknown event #{unknown_event}")
subject.increment_unique_values(unknown_event, value)
helper.increment_unique_values(unknown_event, value)
end
it 'does not track event for nil values' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
subject.increment_unique_values(unknown_event, nil)
helper.increment_unique_values(unknown_event, nil)
end
end
@ -659,21 +659,21 @@ RSpec.describe API::Helpers do
context 'when unmodified check passes' do
before do
allow(subject).to receive(:check_unmodified_since!).with(project.updated_at).and_return(true)
allow(helper).to receive(:check_unmodified_since!).with(project.updated_at).and_return(true)
end
it 'destroys given project' do
allow(subject).to receive(:status).with(204)
allow(subject).to receive(:body).with(false)
allow(helper).to receive(:status).with(204)
allow(helper).to receive(:body).with(false)
expect(project).to receive(:destroy).and_call_original
expect { subject.destroy_conditionally!(project) }.to change(Project, :count).by(-1)
expect { helper.destroy_conditionally!(project) }.to change(Project, :count).by(-1)
end
end
context 'when unmodified check fails' do
before do
allow(subject).to receive(:check_unmodified_since!).with(project.updated_at).and_throw(:error)
allow(helper).to receive(:check_unmodified_since!).with(project.updated_at).and_throw(:error)
end
# #destroy_conditionally! uses Grape errors which Ruby-throws a symbol, shifting execution to somewhere else.
@ -683,7 +683,7 @@ RSpec.describe API::Helpers do
it 'does not destroy given project' do
expect(project).not_to receive(:destroy)
expect { subject.destroy_conditionally!(project) }.to throw_symbol(:error).and change { Project.count }.by(0)
expect { helper.destroy_conditionally!(project) }.to throw_symbol(:error).and change { Project.count }.by(0)
end
end
end
@ -692,30 +692,30 @@ RSpec.describe API::Helpers do
let(:unmodified_since_header) { Time.now.change(usec: 0) }
before do
allow(subject).to receive(:headers).and_return('If-Unmodified-Since' => unmodified_since_header.to_s)
allow(helper).to receive(:headers).and_return('If-Unmodified-Since' => unmodified_since_header.to_s)
end
context 'when last modified is later than header value' do
it 'renders error' do
expect(subject).to receive(:render_api_error!)
expect(helper).to receive(:render_api_error!)
subject.check_unmodified_since!(unmodified_since_header + 1.hour)
helper.check_unmodified_since!(unmodified_since_header + 1.hour)
end
end
context 'when last modified is earlier than header value' do
it 'does not render error' do
expect(subject).not_to receive(:render_api_error!)
expect(helper).not_to receive(:render_api_error!)
subject.check_unmodified_since!(unmodified_since_header - 1.hour)
helper.check_unmodified_since!(unmodified_since_header - 1.hour)
end
end
context 'when last modified is equal to header value' do
it 'does not render error' do
expect(subject).not_to receive(:render_api_error!)
expect(helper).not_to receive(:render_api_error!)
subject.check_unmodified_since!(unmodified_since_header)
helper.check_unmodified_since!(unmodified_since_header)
end
end
@ -723,9 +723,9 @@ RSpec.describe API::Helpers do
let(:unmodified_since_header) { nil }
it 'does not render error' do
expect(subject).not_to receive(:render_api_error!)
expect(helper).not_to receive(:render_api_error!)
subject.check_unmodified_since!(Time.now)
helper.check_unmodified_since!(Time.now)
end
end
@ -733,9 +733,9 @@ RSpec.describe API::Helpers do
let(:unmodified_since_header) { "abcd" }
it 'does not render error' do
expect(subject).not_to receive(:render_api_error!)
expect(helper).not_to receive(:render_api_error!)
subject.check_unmodified_since!(Time.now)
helper.check_unmodified_since!(Time.now)
end
end
end
@ -810,14 +810,71 @@ RSpec.describe API::Helpers do
before do
u = current_user_set ? user : nil
subject.instance_variable_set(:@current_user, u)
helper.instance_variable_set(:@current_user, u)
allow(subject).to receive(:params).and_return(params)
allow(helper).to receive(:params).and_return(params)
end
it 'returns the expected result' do
expect(subject.order_by_similarity?(allow_unauthorized: allow_unauthorized)).to eq(expected)
expect(helper.order_by_similarity?(allow_unauthorized: allow_unauthorized)).to eq(expected)
end
end
end
describe '#render_api_error_with_reason!' do
before do
allow(helper).to receive(:env).and_return({})
allow(helper).to receive(:header).and_return({})
allow(helper).to receive(:error!)
end
it 'renders error with code' do
expect(helper).to receive(:set_status_code_in_env).with(999)
expect(helper).to receive(:error!).with({ 'message' => 'a message - good reason' }, 999, {})
helper.render_api_error_with_reason!(999, 'a message', 'good reason')
end
end
describe '#unauthorized!' do
it 'renders 401' do
expect(helper).to receive(:render_api_error_with_reason!).with(401, '401 Unauthorized', nil)
helper.unauthorized!
end
it 'renders 401 with a reason' do
expect(helper).to receive(:render_api_error_with_reason!).with(401, '401 Unauthorized', 'custom reason')
helper.unauthorized!('custom reason')
end
end
describe '#forbidden!' do
it 'renders 401' do
expect(helper).to receive(:render_api_error_with_reason!).with(403, '403 Forbidden', nil)
helper.forbidden!
end
it 'renders 401 with a reason' do
expect(helper).to receive(:render_api_error_with_reason!).with(403, '403 Forbidden', 'custom reason')
helper.forbidden!('custom reason')
end
end
describe '#bad_request!' do
it 'renders 400' do
expect(helper).to receive(:render_api_error_with_reason!).with(400, '400 Bad request', nil)
helper.bad_request!
end
it 'renders 401 with a reason' do
expect(helper).to receive(:render_api_error_with_reason!).with(400, '400 Bad request', 'custom reason')
helper.bad_request!('custom reason')
end
end
end

View file

@ -41,6 +41,7 @@ RSpec.describe API::Integrations::JiraConnect::Subscriptions do
post_subscriptions
expect(response).to have_gitlab_http_status(:unauthorized)
expect(json_response).to eq('message' => '401 Unauthorized - JWT authentication failed')
end
end

View file

@ -2645,6 +2645,7 @@ RSpec.describe API::MergeRequests do
expect(response).to have_gitlab_http_status(:ok)
expect(source_repository.branch_exists?(source_branch)).to be false
expect(merge_request.reload.should_remove_source_branch?).to be true
end
end
@ -2663,6 +2664,7 @@ RSpec.describe API::MergeRequests do
expect(response).to have_gitlab_http_status(:ok)
expect(source_repository.branch_exists?(source_branch)).to be false
expect(merge_request.reload.should_remove_source_branch?).to be nil
end
it 'does not remove the source branch' do
@ -2673,6 +2675,7 @@ RSpec.describe API::MergeRequests do
expect(response).to have_gitlab_http_status(:ok)
expect(source_repository.branch_exists?(source_branch)).to be_truthy
expect(merge_request.reload.should_remove_source_branch?).to be false
end
end

View file

@ -263,10 +263,13 @@ RSpec.describe MergeRequests::MergeService do
merge_request.update_attribute(:merge_params, { 'force_remove_source_branch' => '1' })
end
# Not a real use case. When a merger merges a MR , merge param 'should_remove_source_branch' is defined
it 'removes the source branch using the author user' do
expect(::MergeRequests::DeleteSourceBranchWorker).to receive(:perform_async).with(merge_request.id, merge_request.source_branch_sha, merge_request.author.id)
service.execute(merge_request)
expect(merge_request.reload.should_remove_source_branch?).to be nil
end
context 'when the merger set the source branch not to be removed' do
@ -276,6 +279,8 @@ RSpec.describe MergeRequests::MergeService do
expect(::MergeRequests::DeleteSourceBranchWorker).not_to receive(:perform_async)
service.execute(merge_request)
expect(merge_request.reload.should_remove_source_branch?).to be false
end
end
end
@ -289,6 +294,8 @@ RSpec.describe MergeRequests::MergeService do
expect(::MergeRequests::DeleteSourceBranchWorker).to receive(:perform_async).with(merge_request.id, merge_request.source_branch_sha, user.id)
service.execute(merge_request)
expect(merge_request.reload.should_remove_source_branch?).to be true
end
end
end