Commit 69db8c79 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 4913f421 01cae961
32b44d3c44af62f55c1049743149c103dfd58fb7 d950585cb9763c6014ae2c9b7c4f4923d90c9f81
...@@ -4,8 +4,9 @@ ...@@ -4,8 +4,9 @@
%fieldset %fieldset
%h5= _('Permissions') %h5= _('Permissions')
.form-group - unless ::Feature.enabled?(:saas_user_caps)
= render 'shared/allow_request_access', form: f .form-group
= render 'shared/allow_request_access', form: f
- if @group.root? - if @group.root?
.form-group.gl-mb-3 .form-group.gl-mb-3
...@@ -43,5 +44,6 @@ ...@@ -43,5 +44,6 @@
= render_if_exists 'groups/settings/prevent_forking', f: f, group: @group = render_if_exists 'groups/settings/prevent_forking', f: f, group: @group
= render 'groups/settings/two_factor_auth', f: f, group: @group = render 'groups/settings/two_factor_auth', f: f, group: @group
= render_if_exists 'groups/personal_access_token_expiration_policy', f: f, group: @group = render_if_exists 'groups/personal_access_token_expiration_policy', f: f, group: @group
= render_if_exists 'groups/settings/membership', f: f
= render_if_exists 'groups/member_lock_setting', f: f, group: @group = render_if_exists 'groups/member_lock_setting', f: f, group: @group
= f.submit _('Save changes'), class: 'btn gl-button btn-confirm gl-mt-3 js-dirty-submit', data: { qa_selector: 'save_permissions_changes_button' } = f.submit _('Save changes'), class: 'btn gl-button btn-confirm gl-mt-3 js-dirty-submit', data: { qa_selector: 'save_permissions_changes_button' }
...@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332963 ...@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332963
milestone: '14.0' milestone: '14.0'
type: development type: development
group: group::pipeline authoring group: group::pipeline authoring
default_enabled: false default_enabled: true
...@@ -4472,7 +4472,6 @@ Input type: `VulnerabilityCreateInput` ...@@ -4472,7 +4472,6 @@ Input type: `VulnerabilityCreateInput`
| <a id="mutationvulnerabilitycreateproject"></a>`project` | [`ProjectID!`](#projectid) | ID of the project to attach the vulnerability to. | | <a id="mutationvulnerabilitycreateproject"></a>`project` | [`ProjectID!`](#projectid) | ID of the project to attach the vulnerability to. |
| <a id="mutationvulnerabilitycreateresolvedat"></a>`resolvedAt` | [`Time`](#time) | Timestamp of when the vulnerability state changed to resolved (defaults to creation time if status is `resolved`). | | <a id="mutationvulnerabilitycreateresolvedat"></a>`resolvedAt` | [`Time`](#time) | Timestamp of when the vulnerability state changed to resolved (defaults to creation time if status is `resolved`). |
| <a id="mutationvulnerabilitycreatescannername"></a>`scannerName` | [`String!`](#string) | Name of the security scanner used to discover the vulnerability. | | <a id="mutationvulnerabilitycreatescannername"></a>`scannerName` | [`String!`](#string) | Name of the security scanner used to discover the vulnerability. |
| <a id="mutationvulnerabilitycreatescannertype"></a>`scannerType` | [`SecurityScannerType!`](#securityscannertype) | Type of the security scanner used to discover the vulnerability. |
| <a id="mutationvulnerabilitycreateseverity"></a>`severity` | [`VulnerabilitySeverity`](#vulnerabilityseverity) | Severity of the vulnerability (defaults to `unknown`). | | <a id="mutationvulnerabilitycreateseverity"></a>`severity` | [`VulnerabilitySeverity`](#vulnerabilityseverity) | Severity of the vulnerability (defaults to `unknown`). |
| <a id="mutationvulnerabilitycreatesolution"></a>`solution` | [`String`](#string) | How to fix this vulnerability. | | <a id="mutationvulnerabilitycreatesolution"></a>`solution` | [`String`](#string) | How to fix this vulnerability. |
| <a id="mutationvulnerabilitycreatestate"></a>`state` | [`VulnerabilityState`](#vulnerabilitystate) | State of the vulnerability (defaults to `detected`). | | <a id="mutationvulnerabilitycreatestate"></a>`state` | [`VulnerabilityState`](#vulnerabilitystate) | State of the vulnerability (defaults to `detected`). |
......
...@@ -81,7 +81,9 @@ export default { ...@@ -81,7 +81,9 @@ export default {
}, },
error: createPolicyFetchError, error: createPolicyFetchError,
skip() { skip() {
return this.isLoadingEnvironments || !this.shouldShowNetworkPolicies; return (
!this.hasEnvironment || this.isLoadingEnvironments || !this.shouldShowNetworkPolicies
);
}, },
}, },
scanExecutionPolicies: { scanExecutionPolicies: {
......
...@@ -19,10 +19,6 @@ module Mutations ...@@ -19,10 +19,6 @@ module Mutations
required: true, required: true,
description: 'Description of the vulnerability.' description: 'Description of the vulnerability.'
argument :scanner_type, Types::SecurityScannerTypeEnum,
required: true,
description: 'Type of the security scanner used to discover the vulnerability.'
argument :scanner_name, GraphQL::Types::String, argument :scanner_name, GraphQL::Types::String,
required: true, required: true,
description: 'Name of the security scanner used to discover the vulnerability.' description: 'Name of the security scanner used to discover the vulnerability.'
...@@ -118,8 +114,7 @@ module Mutations ...@@ -118,8 +114,7 @@ module Mutations
]) ])
scanner_params = { scanner_params = {
name: params.fetch(:scanner_name), name: params.fetch(:scanner_name)
type: params.fetch(:scanner_type)
} }
{ {
......
- return unless ::Feature.enabled?(:saas_user_caps)
%h5= _('Membership')
.form-group{ data: { testid: 'membership-form-group' } }
= render 'shared/allow_request_access', form: f
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
module EE module EE
module Gitlab module Gitlab
module Checks module Checks
module BaseSingleChecker module BaseChecker
extend ActiveSupport::Concern extend ActiveSupport::Concern
include ::Gitlab::Utils::StrongMemoize include ::Gitlab::Utils::StrongMemoize
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
module EE module EE
module Gitlab module Gitlab
module Checks module Checks
module SingleChangeAccess module ChangesAccess
extend ActiveSupport::Concern extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
override :ref_level_checks override :bulk_access_checks!
def ref_level_checks def bulk_access_checks!
super super
PushRuleCheck.new(self).validate! PushRuleCheck.new(self).validate!
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
module EE module EE
module Gitlab module Gitlab
module Checks module Checks
class PushRuleCheck < ::Gitlab::Checks::BaseSingleChecker class PushRuleCheck < ::Gitlab::Checks::BaseBulkChecker
def validate! def validate!
return unless push_rule return unless push_rule
...@@ -19,17 +19,23 @@ module EE ...@@ -19,17 +19,23 @@ module EE
# @return [Nil] returns nil unless an error is raised # @return [Nil] returns nil unless an error is raised
# @raise [Gitlab::GitAccess::ForbiddenError] if check fails # @raise [Gitlab::GitAccess::ForbiddenError] if check fails
def check_tag_or_branch! def check_tag_or_branch!
if tag_name changes_access.single_change_accesses.each do |single_change_access|
PushRules::TagCheck.new(change_access).validate! if single_change_access.tag_name
else PushRules::TagCheck.new(single_change_access).validate!
PushRules::BranchCheck.new(change_access).validate! else
PushRules::BranchCheck.new(single_change_access).validate!
end
end end
nil
end end
# @return [Nil] returns nil unless an error is raised # @return [Nil] returns nil unless an error is raised
# @raise [Gitlab::GitAccess::ForbiddenError] if check fails # @raise [Gitlab::GitAccess::ForbiddenError] if check fails
def check_file_size! def check_file_size!
PushRules::FileSizeCheck.new(change_access).validate! PushRules::FileSizeCheck.new(changes_access).validate!
nil
end end
# Run the checks one after the other. # Run the checks one after the other.
......
...@@ -4,7 +4,7 @@ module EE ...@@ -4,7 +4,7 @@ module EE
module Gitlab module Gitlab
module Checks module Checks
module PushRules module PushRules
class FileSizeCheck < ::Gitlab::Checks::BaseSingleChecker class FileSizeCheck < ::Gitlab::Checks::BaseBulkChecker
LOG_MESSAGE = "Checking if any files are larger than the allowed size..." LOG_MESSAGE = "Checking if any files are larger than the allowed size..."
def validate! def validate!
...@@ -12,14 +12,21 @@ module EE ...@@ -12,14 +12,21 @@ module EE
logger.log_timed(LOG_MESSAGE) do logger.log_timed(LOG_MESSAGE) do
max_file_size = push_rule.max_file_size max_file_size = push_rule.max_file_size
blobs = project.repository.new_blobs(newrev, dynamic_timeout: logger.time_left)
large_blob = blobs.find do |blob| changes_access.changes.each do |change|
::Gitlab::Utils.bytes_to_megabytes(blob.size) > max_file_size newrev = change[:newrev]
end
next if newrev.blank? || ::Gitlab::Git.blank_ref?(newrev)
blobs = project.repository.new_blobs(newrev, dynamic_timeout: logger.time_left)
large_blob = blobs.find do |blob|
::Gitlab::Utils.bytes_to_megabytes(blob.size) > max_file_size
end
if large_blob if large_blob
raise ::Gitlab::GitAccess::ForbiddenError, %Q{File "#{large_blob.path}" is larger than the allowed size of #{max_file_size} MB} raise ::Gitlab::GitAccess::ForbiddenError, %Q{File "#{large_blob.path}" is larger than the allowed size of #{max_file_size} MB}
end
end end
end end
end end
......
...@@ -32,9 +32,10 @@ const environments = [ ...@@ -32,9 +32,10 @@ const environments = [
global_id: 'gid://gitlab/Environment/3', global_id: 'gid://gitlab/Environment/3',
}, },
]; ];
const networkPoliciesSpy = networkPolicies(mockNetworkPoliciesResponse);
const scanExecutionPoliciesSpy = scanExecutionPolicies(mockScanExecutionPoliciesResponse); const scanExecutionPoliciesSpy = scanExecutionPolicies(mockScanExecutionPoliciesResponse);
const defaultRequestHandlers = { const defaultRequestHandlers = {
networkPolicies: networkPolicies(mockNetworkPoliciesResponse), networkPolicies: networkPoliciesSpy,
scanExecutionPolicies: scanExecutionPoliciesSpy, scanExecutionPolicies: scanExecutionPoliciesSpy,
}; };
const pendingHandler = jest.fn(() => new Promise(() => {})); const pendingHandler = jest.fn(() => new Promise(() => {}));
...@@ -45,13 +46,19 @@ describe('PoliciesList component', () => { ...@@ -45,13 +46,19 @@ describe('PoliciesList component', () => {
let requestHandlers; let requestHandlers;
const factory = (mountFn = mountExtended) => (options = {}) => { const factory = (mountFn = mountExtended) => (options = {}) => {
const { state = {}, handlers, ...wrapperOptions } = options;
store = createStore(); store = createStore();
const { state, handlers, ...wrapperOptions } = options; store.replaceState({
Object.assign(store.state.networkPolicies, { ...store.state,
...state, threatMonitoring: {
...store.state.threatMonitoring,
environments,
currentEnvironmentId: environments[0].id,
...state.threatMonitoring,
},
}); });
store.state.threatMonitoring.environments = environments;
store.state.threatMonitoring.currentEnvironmentId = environments[0].id;
requestHandlers = { requestHandlers = {
...defaultRequestHandlers, ...defaultRequestHandlers,
...handlers, ...handlers,
...@@ -260,8 +267,7 @@ describe('PoliciesList component', () => { ...@@ -260,8 +267,7 @@ describe('PoliciesList component', () => {
describe('with allEnvironments enabled', () => { describe('with allEnvironments enabled', () => {
beforeEach(() => { beforeEach(() => {
mountWrapper(); mountWrapper({ state: { threatMonitoring: { allEnvironments: true } } });
wrapper.vm.$store.state.threatMonitoring.allEnvironments = true;
}); });
it('renders environments column', () => { it('renders environments column', () => {
...@@ -312,7 +318,26 @@ describe('PoliciesList component', () => { ...@@ -312,7 +318,26 @@ describe('PoliciesList component', () => {
}); });
}); });
describe('given no environement', () => { describe('given loading environment', () => {
beforeEach(() => {
mountWrapper({
propsData: {
hasEnvironment: true,
},
state: {
threatMonitoring: {
isLoadingEnvironments: true,
},
},
});
});
it('does not make a request for network policies', () => {
expect(networkPoliciesSpy).not.toHaveBeenCalled();
});
});
describe('given no environments', () => {
beforeEach(() => { beforeEach(() => {
mountWrapper({ mountWrapper({
propsData: { propsData: {
...@@ -321,8 +346,12 @@ describe('PoliciesList component', () => { ...@@ -321,8 +346,12 @@ describe('PoliciesList component', () => {
}); });
}); });
it('does not make a request for network policies', () => {
expect(networkPoliciesSpy).not.toHaveBeenCalled();
});
it('does not render default network policies', () => { it('does not render default network policies', () => {
expect(findPolicyStatusCells()).toHaveLength(3); expect(findPolicyStatusCells()).toHaveLength(1);
}); });
}); });
}); });
...@@ -32,7 +32,6 @@ RSpec.describe Mutations::Vulnerabilities::Create do ...@@ -32,7 +32,6 @@ RSpec.describe Mutations::Vulnerabilities::Create do
project: project_gid, project: project_gid,
title: "Test vulnerability", title: "Test vulnerability",
description: "Test vulnerability created via GraphQL", description: "Test vulnerability created via GraphQL",
scanner_type: "dast",
scanner_name: "My custom DAST scanner", scanner_name: "My custom DAST scanner",
identifiers: [identifier_attributes], identifiers: [identifier_attributes],
state: "detected", state: "detected",
...@@ -74,7 +73,6 @@ RSpec.describe Mutations::Vulnerabilities::Create do ...@@ -74,7 +73,6 @@ RSpec.describe Mutations::Vulnerabilities::Create do
project: project_gid, project: project_gid,
title: "Test vulnerability", title: "Test vulnerability",
description: "Test vulnerability created via GraphQL", description: "Test vulnerability created via GraphQL",
scanner_type: "dast",
scanner_name: "My custom DAST scanner", scanner_name: "My custom DAST scanner",
identifiers: [identifier_attributes], identifiers: [identifier_attributes],
state: "detected", state: "detected",
...@@ -122,7 +120,6 @@ RSpec.describe Mutations::Vulnerabilities::Create do ...@@ -122,7 +120,6 @@ RSpec.describe Mutations::Vulnerabilities::Create do
project: project_gid, project: project_gid,
title: "Test vulnerability", title: "Test vulnerability",
description: "Test vulnerability created via GraphQL", description: "Test vulnerability created via GraphQL",
scanner_type: "dast",
scanner_name: "My custom DAST scanner", scanner_name: "My custom DAST scanner",
identifiers: [identifier_attributes], identifiers: [identifier_attributes],
state: state, state: state,
......
...@@ -3,9 +3,16 @@ ...@@ -3,9 +3,16 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe EE::Gitlab::Checks::PushRuleCheck do RSpec.describe EE::Gitlab::Checks::PushRuleCheck do
include_context 'push rules checks context' include_context 'changes access checks context'
let(:push_rule) { create(:push_rule, :commit_message) } let(:push_rule) { create(:push_rule, :commit_message) }
let(:project) { create(:project, :public, :repository, push_rule: push_rule) }
before do
allow(project.repository).to receive(:new_commits).and_return(
project.repository.commits_between('be93687618e4b132087f430a4d8fc3a609c9b77c', '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51')
)
end
shared_examples "push checks" do shared_examples "push checks" do
before do before do
...@@ -28,8 +35,11 @@ RSpec.describe EE::Gitlab::Checks::PushRuleCheck do ...@@ -28,8 +35,11 @@ RSpec.describe EE::Gitlab::Checks::PushRuleCheck do
end end
context 'when tag name exists' do context 'when tag name exists' do
before do let(:changes) do
allow(change_access).to receive(:tag_name).and_return(true) [
# Update of a tag.
{ oldrev: oldrev, newrev: newrev, ref: 'refs/tags/name' }
]
end end
it 'validates tags push rules' do it 'validates tags push rules' do
...@@ -43,8 +53,11 @@ RSpec.describe EE::Gitlab::Checks::PushRuleCheck do ...@@ -43,8 +53,11 @@ RSpec.describe EE::Gitlab::Checks::PushRuleCheck do
end end
context 'when tag name does not exists' do context 'when tag name does not exists' do
before do let(:changes) do
allow(change_access).to receive(:tag_name).and_return(false) [
# Update of a branch.
{ oldrev: oldrev, newrev: newrev, ref: 'refs/heads/name' }
]
end end
it 'validates branches push rules' do it 'validates branches push rules' do
...@@ -56,6 +69,24 @@ RSpec.describe EE::Gitlab::Checks::PushRuleCheck do ...@@ -56,6 +69,24 @@ RSpec.describe EE::Gitlab::Checks::PushRuleCheck do
subject.validate! subject.validate!
end end
end end
context 'when tag and branch exist' do
let(:changes) do
[
{ oldrev: oldrev, newrev: newrev, ref: 'refs/heads/name' },
{ oldrev: oldrev, newrev: newrev, ref: 'refs/tags/name' }
]
end
it 'validates tag and branch push rules' do
expect_any_instance_of(EE::Gitlab::Checks::PushRules::TagCheck)
.to receive(:validate!)
expect_any_instance_of(EE::Gitlab::Checks::PushRules::BranchCheck)
.to receive(:validate!)
subject.validate!
end
end
end end
describe '#validate!' do describe '#validate!' do
......
...@@ -5,6 +5,29 @@ require 'spec_helper' ...@@ -5,6 +5,29 @@ require 'spec_helper'
RSpec.describe EE::Gitlab::Checks::PushRules::FileSizeCheck do RSpec.describe EE::Gitlab::Checks::PushRules::FileSizeCheck do
include_context 'push rules checks context' include_context 'push rules checks context'
let(:changes) do
[
# Update of existing branch
{ oldrev: oldrev, newrev: newrev, ref: ref },
# Creation of new branch
{ newrev: newrev, ref: 'refs/heads/something' },
# Deletion of branch
{ oldrev: oldrev, ref: 'refs/heads/deleteme' }
]
end
let(:changes_access) do
Gitlab::Checks::ChangesAccess.new(
changes,
project: project,
user_access: user_access,
protocol: protocol,
logger: logger
)
end
subject { described_class.new(changes_access) }
describe '#validate!' do describe '#validate!' do
let(:push_rule) { create(:push_rule, max_file_size: 1) } let(:push_rule) { create(:push_rule, max_file_size: 1) }
# SHA of the 2-mb-file branch # SHA of the 2-mb-file branch
......
...@@ -2,13 +2,28 @@ ...@@ -2,13 +2,28 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::Checks::SingleChangeAccess do RSpec.describe Gitlab::Checks::ChangesAccess do
describe '#validate!' do describe '#validate!' do
include_context 'push rules checks context' include_context 'push rules checks context'
let(:push_rule) { create(:push_rule, deny_delete_tag: true) } let(:push_rule) { create(:push_rule, deny_delete_tag: true) }
let(:changes) do
[
{ oldrev: oldrev, newrev: newrev, ref: ref }
]
end
let(:changes_access) do
Gitlab::Checks::ChangesAccess.new(
changes,
project: project,
user_access: user_access,
protocol: protocol,
logger: logger
)
end
subject { change_access } subject { changes_access }
it_behaves_like 'check ignored when push rule unlicensed' it_behaves_like 'check ignored when push rule unlicensed'
......
...@@ -13,18 +13,13 @@ module API ...@@ -13,18 +13,13 @@ module API
post '/lint' do post '/lint' do
unauthorized! if (Gitlab::CurrentSettings.signup_disabled? || Gitlab::CurrentSettings.signup_limited?) && current_user.nil? unauthorized! if (Gitlab::CurrentSettings.signup_disabled? || Gitlab::CurrentSettings.signup_limited?) && current_user.nil?
result = Gitlab::Ci::YamlProcessor.new(params[:content], user: current_user).execute result = Gitlab::Ci::Lint.new(project: nil, current_user: current_user)
.validate(params[:content], dry_run: false)
status 200 status 200
Entities::Ci::Lint::Result.represent(result, current_user: current_user).serializable_hash.tap do |presented_result|
response = if result.errors.empty? presented_result[:status] = presented_result[:valid] ? 'valid' : 'invalid'
{ status: 'valid', errors: [], warnings: result.warnings } presented_result.delete(:merged_yaml) unless params[:include_merged_yaml]
else
{ status: 'invalid', errors: result.errors, warnings: result.warnings }
end
response.tap do |response|
response[:merged_yaml] = result.merged_yaml if params[:include_merged_yaml]
end end
end end
end end
......
...@@ -30,5 +30,3 @@ module Gitlab ...@@ -30,5 +30,3 @@ module Gitlab
end end
end end
end end
Gitlab::Checks::BaseSingleChecker.prepend_mod_with('Gitlab::Checks::BaseSingleChecker')
...@@ -76,23 +76,33 @@ module Gitlab ...@@ -76,23 +76,33 @@ module Gitlab
result result
end end
def single_change_accesses
@single_changes_accesses ||=
changes.map do |change|
commits =
if change[:newrev].blank? || Gitlab::Git.blank_ref?(change[:newrev])
[]
else
Gitlab::Lazy.new { commits_for(change[:newrev]) }
end
Checks::SingleChangeAccess.new(
change,
user_access: user_access,
project: project,
protocol: protocol,
logger: logger,
commits: commits
)
end
end
protected protected
def single_access_checks! def single_access_checks!
# Iterate over all changes to find if user allowed all of them to be applied # Iterate over all changes to find if user allowed all of them to be applied
changes.each do |change| single_change_accesses.each do |single_change_access|
commits = Gitlab::Lazy.new { commits_for(change[:newrev]) } single_change_access.validate!
# If user does not have access to make at least one change, cancel all
# push by allowing the exception to bubble up
Checks::SingleChangeAccess.new(
change,
user_access: user_access,
project: project,
protocol: protocol,
logger: logger,
commits: commits
).validate!
end end
end end
...@@ -102,3 +112,5 @@ module Gitlab ...@@ -102,3 +112,5 @@ module Gitlab
end end
end end
end end
Gitlab::Checks::ChangesAccess.prepend_mod_with('Gitlab::Checks::ChangesAccess')
...@@ -21,7 +21,7 @@ module Gitlab ...@@ -21,7 +21,7 @@ module Gitlab
def initialize(project:, current_user:, sha: nil) def initialize(project:, current_user:, sha: nil)
@project = project @project = project
@current_user = current_user @current_user = current_user
@sha = sha || project.repository.commit&.sha @sha = sha || project&.repository&.commit&.sha
end end
def validate(content, dry_run: false) def validate(content, dry_run: false)
......
...@@ -20811,6 +20811,9 @@ msgstr "" ...@@ -20811,6 +20811,9 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access" msgid "Members of a group may only view projects they have permission to access"
msgstr "" msgstr ""
msgid "Membership"
msgstr ""
msgid "Members|%{time} by %{user}" msgid "Members|%{time} by %{user}"
msgstr "" msgstr ""
......
...@@ -174,6 +174,101 @@ RSpec.describe Gitlab::Checks::ChangesAccess do ...@@ -174,6 +174,101 @@ RSpec.describe Gitlab::Checks::ChangesAccess do
end end
end end
describe '#single_change_accesses' do
let(:commits_for) { {} }
let(:expected_accesses) { [] }
shared_examples '#single_change_access' do
before do
commits_for.each do |id, commits|
expect(subject)
.to receive(:commits_for)
.with(id)
.and_return(commits)
end
end
it 'returns an array of SingleChangeAccess' do
# Commits are wrapped in a Gitlab::Lazy and thus need to be resolved
# first such that we can directly compare types.
actual_accesses = subject.single_change_accesses
.each { |access| access.instance_variable_set(:@commits, access.commits.to_a) }
expect(actual_accesses).to match_array(expected_accesses)
end
end
context 'with no changes' do
let(:changes) { [] }
it_behaves_like '#single_change_access'
end
context 'with a single change and no new commits' do
let(:commits_for) { { 'new' => [] } }
let(:changes) do
[
{ oldrev: 'old', newrev: 'new', ref: 'refs/heads/branch' }
]
end
let(:expected_accesses) do
[
have_attributes(oldrev: 'old', newrev: 'new', ref: 'refs/heads/branch', commits: [])
]
end
it_behaves_like '#single_change_access'
end
context 'with a single change and new commits' do
let(:commits_for) { { 'new' => [create_commit('new', [])] } }
let(:changes) do
[
{ oldrev: 'old', newrev: 'new', ref: 'refs/heads/branch' }
]
end
let(:expected_accesses) do
[
have_attributes(oldrev: 'old', newrev: 'new', ref: 'refs/heads/branch', commits: [create_commit('new', [])])
]
end
it_behaves_like '#single_change_access'
end
context 'with multiple changes' do
let(:commits_for) do
{
'a' => [create_commit('a', [])],
'c' => [create_commit('c', [])],
'd' => []
}
end
let(:changes) do
[
{ newrev: 'a', ref: 'refs/heads/a' },
{ oldrev: 'b', ref: 'refs/heads/b' },
{ oldrev: 'a', newrev: 'c', ref: 'refs/heads/c' },
{ newrev: 'd', ref: 'refs/heads/d' }
]
end
let(:expected_accesses) do
[
have_attributes(newrev: 'a', ref: 'refs/heads/a', commits: [create_commit('a', [])]),
have_attributes(oldrev: 'b', ref: 'refs/heads/b', commits: []),
have_attributes(oldrev: 'a', newrev: 'c', ref: 'refs/heads/c', commits: [create_commit('c', [])]),
have_attributes(newrev: 'd', ref: 'refs/heads/d', commits: [])
]
end
it_behaves_like '#single_change_access'
end
end
def create_commit(id, parent_ids) def create_commit(id, parent_ids)
Gitlab::Git::Commit.new(project.repository, { Gitlab::Git::Commit.new(project.repository, {
id: id, id: id,
......
...@@ -113,7 +113,6 @@ RSpec.describe API::Lint do ...@@ -113,7 +113,6 @@ RSpec.describe API::Lint do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response['status']).to eq('valid') expect(json_response['status']).to eq('valid')
expect(json_response['warnings']).not_to be_empty expect(json_response['warnings']).not_to be_empty
expect(json_response['status']).to eq('valid')
expect(json_response['errors']).to eq([]) expect(json_response['errors']).to eq([])
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment