diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-02 12:07:57 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-02 12:07:57 +0000 |
commit | 988b28ec1a379d38f6ac9ed04886ee564fd447fd (patch) | |
tree | 9d93267209387e62d23ea7abf81ef9c0d64f2f0b /spec | |
parent | a325f3a104748ecc68df7c3d793940aa709a111f (diff) | |
download | gitlab-ce-988b28ec1a379d38f6ac9ed04886ee564fd447fd.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
22 files changed, 512 insertions, 270 deletions
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb index 1c58c2b5c97..11c70d3aeca 100644 --- a/spec/controllers/groups_controller_spec.rb +++ b/spec/controllers/groups_controller_spec.rb @@ -411,6 +411,13 @@ describe GroupsController do expect(group.reload.project_creation_level).to eq(::Gitlab::Access::MAINTAINER_PROJECT_ACCESS) end + it 'updates the default_branch_protection successfully' do + post :update, params: { id: group.to_param, group: { default_branch_protection: ::Gitlab::Access::PROTECTION_DEV_CAN_MERGE } } + + expect(response).to have_gitlab_http_status(:found) + expect(group.reload.default_branch_protection).to eq(::Gitlab::Access::PROTECTION_DEV_CAN_MERGE) + end + context 'when a project inside the group has container repositories' do before do stub_container_registry_config(enabled: true) diff --git a/spec/fixtures/csv_gitlab_export.csv b/spec/fixtures/csv_gitlab_export.csv new file mode 100644 index 00000000000..65422509eef --- /dev/null +++ b/spec/fixtures/csv_gitlab_export.csv @@ -0,0 +1,5 @@ +Issue ID,URL,Title,State,Description,Author,Author Username,Assignee,Assignee Username,Confidential,Locked,Due Date,Created At (UTC),Updated At (UTC),Closed At (UTC),Milestone,Weight,Labels,Time Estimate,Time Spent,Epic ID,Epic Title +1,http://localhost:3000/jashkenas/underscore/issues/1,Title,Open,,Elva Jerde,jamel,Tierra Effertz,aurora_hahn,No,No,,2020-01-17 10:36:26,2020-02-19 10:36:26,,v1.0,,"Brene,Cutlass,Escort,GVM",0,0,, +3,http://localhost:3000/jashkenas/underscore/issues/3,Nihil impedit neque quos totam ut aut enim cupiditate doloribus molestiae.,Open,Omnis aliquid sint laudantium quam.,Marybeth Goodwin,rocio.blanda,Annemarie Von,reynalda_howe,No,No,,2020-01-23 10:36:26,2020-02-19 10:36:27,,v1.0,,"Brene,Cutlass,Escort,GVM",0,0,, +34,http://localhost:3000/jashkenas/underscore/issues/34,Dismiss Cipher with no integrity,Open,,Marybeth Goodwin,rocio.blanda,"","",No,No,,2020-02-19 10:38:49,2020-02-19 10:38:49,,,,,0,0,, +35,http://localhost:3000/jashkenas/underscore/issues/35,Test Title,Open,Test Description,Marybeth Goodwin,rocio.blanda,"","",No,No,,2020-02-19 10:38:49,2020-02-19 10:38:49,,,,,0,0,, diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb index 2ec477fc494..d0eb0475879 100644 --- a/spec/graphql/gitlab_schema_spec.rb +++ b/spec/graphql/gitlab_schema_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' describe GitlabSchema do + let_it_be(:implementations) { GraphQL::Relay::BaseConnection::CONNECTION_IMPLEMENTATIONS } let(:user) { build :user } it 'uses batch loading' do @@ -33,12 +34,30 @@ describe GitlabSchema do expect(described_class.query).to eq(::Types::QueryType.to_graphql) end - it 'paginates active record relations using `Gitlab::Graphql::Connections::KeysetConnection`' do - connection = GraphQL::Relay::BaseConnection::CONNECTION_IMPLEMENTATIONS[ActiveRecord::Relation.name] + it 'paginates active record relations using `Connections::Keyset::Connection`' do + connection = implementations[ActiveRecord::Relation.name] expect(connection).to eq(Gitlab::Graphql::Connections::Keyset::Connection) end + it 'paginates ExternallyPaginatedArray using `Connections::ExternallyPaginatedArrayConnection`' do + connection = implementations[Gitlab::Graphql::ExternallyPaginatedArray.name] + + expect(connection).to eq(Gitlab::Graphql::Connections::ExternallyPaginatedArrayConnection) + end + + it 'paginates FilterableArray using `Connections::FilterableArrayConnection`' do + connection = implementations[Gitlab::Graphql::FilterableArray.name] + + expect(connection).to eq(Gitlab::Graphql::Connections::FilterableArrayConnection) + end + + it 'paginates OffsetActiveRecordRelation using `Pagination::OffsetActiveRecordRelationConnection`' do + connection = implementations[Gitlab::Graphql::Pagination::Relations::OffsetActiveRecordRelation.name] + + expect(connection).to eq(Gitlab::Graphql::Pagination::OffsetActiveRecordRelationConnection) + end + describe '.execute' do context 'for different types of users' do context 'when no context' do diff --git a/spec/lib/gitlab/access/branch_protection_spec.rb b/spec/lib/gitlab/access/branch_protection_spec.rb index 7f2979e8e28..e4b763357c4 100644 --- a/spec/lib/gitlab/access/branch_protection_spec.rb +++ b/spec/lib/gitlab/access/branch_protection_spec.rb @@ -51,4 +51,21 @@ describe Gitlab::Access::BranchProtection do end end end + + describe '#fully_protected?' do + using RSpec::Parameterized::TableSyntax + + where(:level, :result) do + Gitlab::Access::PROTECTION_NONE | false + Gitlab::Access::PROTECTION_DEV_CAN_PUSH | false + Gitlab::Access::PROTECTION_DEV_CAN_MERGE | false + Gitlab::Access::PROTECTION_FULL | true + end + + with_them do + it do + expect(described_class.new(level).fully_protected?).to eq(result) + end + end + end end diff --git a/spec/lib/gitlab/auth/current_user_mode_spec.rb b/spec/lib/gitlab/auth/current_user_mode_spec.rb index 7c2fdac6c25..2b910fac155 100644 --- a/spec/lib/gitlab/auth/current_user_mode_spec.rb +++ b/spec/lib/gitlab/auth/current_user_mode_spec.rb @@ -3,294 +3,330 @@ require 'spec_helper' describe Gitlab::Auth::CurrentUserMode, :do_not_mock_admin_mode, :request_store do - include_context 'custom session' - let(:user) { build_stubbed(:user) } subject { described_class.new(user) } - before do - allow(ActiveSession).to receive(:list_sessions).with(user).and_return([session]) - end - - shared_examples 'admin mode cannot be enabled' do - it 'is false by default' do - expect(subject.admin_mode?).to be(false) - end - - it 'cannot be enabled with a valid password' do - subject.enable_admin_mode!(password: user.password) - - expect(subject.admin_mode?).to be(false) - end - - it 'cannot be enabled with an invalid password' do - subject.enable_admin_mode!(password: nil) - - expect(subject.admin_mode?).to be(false) - end - - it 'cannot be enabled with empty params' do - subject.enable_admin_mode! + context 'when session is available' do + include_context 'custom session' - expect(subject.admin_mode?).to be(false) + before do + allow(ActiveSession).to receive(:list_sessions).with(user).and_return([session]) end - it 'disable has no effect' do - subject.enable_admin_mode! - subject.disable_admin_mode! - - expect(subject.admin_mode?).to be(false) - end + shared_examples 'admin mode cannot be enabled' do + it 'is false by default' do + expect(subject.admin_mode?).to be(false) + end - context 'skipping password validation' do it 'cannot be enabled with a valid password' do - subject.enable_admin_mode!(password: user.password, skip_password_validation: true) + subject.enable_admin_mode!(password: user.password) expect(subject.admin_mode?).to be(false) end it 'cannot be enabled with an invalid password' do - subject.enable_admin_mode!(skip_password_validation: true) + subject.enable_admin_mode!(password: nil) expect(subject.admin_mode?).to be(false) end - end - end - describe '#admin_mode?' do - context 'when the user is a regular user' do - it_behaves_like 'admin mode cannot be enabled' + it 'cannot be enabled with empty params' do + subject.enable_admin_mode! - context 'bypassing session' do - it_behaves_like 'admin mode cannot be enabled' do - around do |example| - described_class.bypass_session!(user.id) { example.run } - end - end + expect(subject.admin_mode?).to be(false) end - end - - context 'when the user is an admin' do - let(:user) { build_stubbed(:user, :admin) } - context 'when admin mode not requested' do - it 'is false by default' do - expect(subject.admin_mode?).to be(false) - end - - it 'raises exception if we try to enable it' do - expect do - subject.enable_admin_mode!(password: user.password) - end.to raise_error(::Gitlab::Auth::CurrentUserMode::NotRequestedError) + it 'disable has no effect' do + subject.enable_admin_mode! + subject.disable_admin_mode! - expect(subject.admin_mode?).to be(false) - end + expect(subject.admin_mode?).to be(false) end - context 'when admin mode requested first' do - before do - subject.request_admin_mode! - end + context 'skipping password validation' do + it 'cannot be enabled with a valid password' do + subject.enable_admin_mode!(password: user.password, skip_password_validation: true) - it 'is false by default' do expect(subject.admin_mode?).to be(false) end it 'cannot be enabled with an invalid password' do - subject.enable_admin_mode!(password: nil) + subject.enable_admin_mode!(skip_password_validation: true) expect(subject.admin_mode?).to be(false) end + end + end - it 'can be enabled with a valid password' do - subject.enable_admin_mode!(password: user.password) + describe '#admin_mode?' do + context 'when the user is a regular user' do + it_behaves_like 'admin mode cannot be enabled' - expect(subject.admin_mode?).to be(true) + context 'bypassing session' do + it_behaves_like 'admin mode cannot be enabled' do + around do |example| + described_class.bypass_session!(user.id) { example.run } + end + end end + end - it 'can be disabled' do - subject.enable_admin_mode!(password: user.password) - subject.disable_admin_mode! + context 'when the user is an admin' do + let(:user) { build_stubbed(:user, :admin) } - expect(subject.admin_mode?).to be(false) + context 'when admin mode not requested' do + it 'is false by default' do + expect(subject.admin_mode?).to be(false) + end + + it 'raises exception if we try to enable it' do + expect do + subject.enable_admin_mode!(password: user.password) + end.to raise_error(::Gitlab::Auth::CurrentUserMode::NotRequestedError) + + expect(subject.admin_mode?).to be(false) + end end - it 'will expire in the future' do - subject.enable_admin_mode!(password: user.password) - expect(subject.admin_mode?).to be(true), 'admin mode is not active in the present' + context 'when admin mode requested first' do + before do + subject.request_admin_mode! + end - Timecop.freeze(Gitlab::Auth::CurrentUserMode::MAX_ADMIN_MODE_TIME.from_now) do - # in the future this will be a new request, simulate by clearing the RequestStore - Gitlab::SafeRequestStore.clear! + it 'is false by default' do + expect(subject.admin_mode?).to be(false) + end + + it 'cannot be enabled with an invalid password' do + subject.enable_admin_mode!(password: nil) - expect(subject.admin_mode?).to be(false), 'admin mode did not expire in the future' + expect(subject.admin_mode?).to be(false) end - end - context 'skipping password validation' do it 'can be enabled with a valid password' do - subject.enable_admin_mode!(password: user.password, skip_password_validation: true) + subject.enable_admin_mode!(password: user.password) expect(subject.admin_mode?).to be(true) end - it 'can be enabled with an invalid password' do - subject.enable_admin_mode!(skip_password_validation: true) + it 'can be disabled' do + subject.enable_admin_mode!(password: user.password) + subject.disable_admin_mode! - expect(subject.admin_mode?).to be(true) + expect(subject.admin_mode?).to be(false) end - end - context 'with two independent sessions' do - let(:another_session) { {} } - let(:another_subject) { described_class.new(user) } + it 'will expire in the future' do + subject.enable_admin_mode!(password: user.password) + expect(subject.admin_mode?).to be(true), 'admin mode is not active in the present' - before do - allow(ActiveSession).to receive(:list_sessions).with(user).and_return([session, another_session]) + Timecop.freeze(Gitlab::Auth::CurrentUserMode::MAX_ADMIN_MODE_TIME.from_now) do + # in the future this will be a new request, simulate by clearing the RequestStore + Gitlab::SafeRequestStore.clear! + + expect(subject.admin_mode?).to be(false), 'admin mode did not expire in the future' + end end - it 'can be enabled in one and seen in the other' do - Gitlab::Session.with_session(another_session) do - another_subject.request_admin_mode! - another_subject.enable_admin_mode!(password: user.password) + context 'skipping password validation' do + it 'can be enabled with a valid password' do + subject.enable_admin_mode!(password: user.password, skip_password_validation: true) + + expect(subject.admin_mode?).to be(true) end - expect(subject.admin_mode?).to be(true) + it 'can be enabled with an invalid password' do + subject.enable_admin_mode!(skip_password_validation: true) + + expect(subject.admin_mode?).to be(true) + end end - end - end - context 'bypassing session' do - it 'is active by default' do - described_class.bypass_session!(user.id) do - expect(subject.admin_mode?).to be(true) + context 'with two independent sessions' do + let(:another_session) { {} } + let(:another_subject) { described_class.new(user) } + + before do + allow(ActiveSession).to receive(:list_sessions).with(user).and_return([session, another_session]) + end + + it 'can be enabled in one and seen in the other' do + Gitlab::Session.with_session(another_session) do + another_subject.request_admin_mode! + another_subject.enable_admin_mode!(password: user.password) + end + + expect(subject.admin_mode?).to be(true) + end end end - it 'enable has no effect' do - described_class.bypass_session!(user.id) do - subject.request_admin_mode! - subject.enable_admin_mode!(password: user.password) + context 'bypassing session' do + it 'is active by default' do + described_class.bypass_session!(user.id) do + expect(subject.admin_mode?).to be(true) + end + end - expect(subject.admin_mode?).to be(true) + it 'enable has no effect' do + described_class.bypass_session!(user.id) do + subject.request_admin_mode! + subject.enable_admin_mode!(password: user.password) + + expect(subject.admin_mode?).to be(true) + end end - end - it 'disable has no effect' do - described_class.bypass_session!(user.id) do - subject.disable_admin_mode! + it 'disable has no effect' do + described_class.bypass_session!(user.id) do + subject.disable_admin_mode! - expect(subject.admin_mode?).to be(true) + expect(subject.admin_mode?).to be(true) + end end end end end - end - describe '#enable_admin_mode!' do - let(:user) { build_stubbed(:user, :admin) } + describe '#enable_admin_mode!' do + let(:user) { build_stubbed(:user, :admin) } - it 'creates a timestamp in the session' do - subject.request_admin_mode! - subject.enable_admin_mode!(password: user.password) + it 'creates a timestamp in the session' do + subject.request_admin_mode! + subject.enable_admin_mode!(password: user.password) - expect(session).to include(expected_session_entry(be_within(1.second).of Time.now)) + expect(session).to include(expected_session_entry(be_within(1.second).of Time.now)) + end end - end - describe '#enable_sessionless_admin_mode!' do - let(:user) { build_stubbed(:user, :admin) } + describe '#disable_admin_mode!' do + let(:user) { build_stubbed(:user, :admin) } - it 'enabled admin mode without password' do - subject.enable_sessionless_admin_mode! + it 'sets the session timestamp to nil' do + subject.request_admin_mode! + subject.disable_admin_mode! - expect(subject.admin_mode?).to be(true) + expect(session).to include(expected_session_entry(be_nil)) + end end - end - describe '#disable_admin_mode!' do - let(:user) { build_stubbed(:user, :admin) } + describe '.with_current_request_admin_mode' do + context 'with a regular user' do + it 'user is not available inside nor outside the yielded block' do + described_class.with_current_admin(user) do + expect(described_class.current_admin).to be_nil + end - it 'sets the session timestamp to nil' do - subject.request_admin_mode! - subject.disable_admin_mode! + expect(described_class.bypass_session_admin_id).to be_nil + end + end - expect(session).to include(expected_session_entry(be_nil)) - end - end + context 'with an admin user' do + let(:user) { build_stubbed(:user, :admin) } - describe '.bypass_session!' do - context 'with a regular user' do - it 'admin mode is false' do - described_class.bypass_session!(user.id) do - expect(subject.admin_mode?).to be(false) - expect(described_class.bypass_session_admin_id).to be(user.id) + context 'admin mode is disabled' do + it 'user is not available inside nor outside the yielded block' do + described_class.with_current_admin(user) do + expect(described_class.current_admin).to be_nil + end + + expect(described_class.bypass_session_admin_id).to be_nil + end end - expect(described_class.bypass_session_admin_id).to be_nil - end - end + context 'admin mode is enabled' do + before do + subject.request_admin_mode! + subject.enable_admin_mode!(password: user.password) + end - context 'with an admin user' do - let(:user) { build_stubbed(:user, :admin) } + it 'user is available only inside the yielded block' do + described_class.with_current_admin(user) do + expect(described_class.current_admin).to be(user) + end - it 'admin mode is true' do - described_class.bypass_session!(user.id) do - expect(subject.admin_mode?).to be(true) - expect(described_class.bypass_session_admin_id).to be(user.id) + expect(described_class.current_admin).to be_nil + end end - - expect(described_class.bypass_session_admin_id).to be_nil end end - end - describe '.with_current_request_admin_mode' do - context 'with a regular user' do - it 'user is not available inside nor outside the yielded block' do - described_class.with_current_admin(user) do - expect(described_class.current_admin).to be_nil - end + def expected_session_entry(value_matcher) + { + Gitlab::Auth::CurrentUserMode::SESSION_STORE_KEY => a_hash_including( + Gitlab::Auth::CurrentUserMode::ADMIN_MODE_START_TIME_KEY => value_matcher) + } + end + end - expect(described_class.bypass_session_admin_id).to be_nil + context 'when no session available' do + around do |example| + Gitlab::Session.with_session(nil) do + example.run end end - context 'with an admin user' do - let(:user) { build_stubbed(:user, :admin) } + describe '.bypass_session!' do + context 'when providing a block' do + context 'with a regular user' do + it 'admin mode is false' do + described_class.bypass_session!(user.id) do + expect(Gitlab::Session.current).to be_nil + expect(subject.admin_mode?).to be(false) + expect(described_class.bypass_session_admin_id).to be(user.id) + end - context 'admin mode is disabled' do - it 'user is not available inside nor outside the yielded block' do - described_class.with_current_admin(user) do - expect(described_class.current_admin).to be_nil + expect(described_class.bypass_session_admin_id).to be_nil end + end - expect(described_class.bypass_session_admin_id).to be_nil + context 'with an admin user' do + let(:user) { build_stubbed(:user, :admin) } + + it 'admin mode is true' do + described_class.bypass_session!(user.id) do + expect(Gitlab::Session.current).to be_nil + expect(subject.admin_mode?).to be(true) + expect(described_class.bypass_session_admin_id).to be(user.id) + end + + expect(described_class.bypass_session_admin_id).to be_nil + end end end - context 'admin mode is enabled' do - before do - subject.request_admin_mode! - subject.enable_admin_mode!(password: user.password) - end + context 'when not providing a block' do + context 'with a regular user' do + it 'admin mode is false' do + described_class.bypass_session!(user.id) - it 'user is available only inside the yielded block' do - described_class.with_current_admin(user) do - expect(described_class.current_admin).to be(user) + expect(Gitlab::Session.current).to be_nil + expect(subject.admin_mode?).to be(false) + expect(described_class.bypass_session_admin_id).to be(user.id) + + described_class.reset_bypass_session! + + expect(described_class.bypass_session_admin_id).to be_nil end + end - expect(described_class.current_admin).to be_nil + context 'with an admin user' do + let(:user) { build_stubbed(:user, :admin) } + + it 'admin mode is true' do + described_class.bypass_session!(user.id) + + expect(Gitlab::Session.current).to be_nil + expect(subject.admin_mode?).to be(true) + expect(described_class.bypass_session_admin_id).to be(user.id) + + described_class.reset_bypass_session! + + expect(described_class.bypass_session_admin_id).to be_nil + end end end end end - - def expected_session_entry(value_matcher) - { - Gitlab::Auth::CurrentUserMode::SESSION_STORE_KEY => a_hash_including( - Gitlab::Auth::CurrentUserMode::ADMIN_MODE_START_TIME_KEY => value_matcher) - } - end end diff --git a/spec/lib/gitlab/graphql/pagination/offset_active_record_relation_connection_spec.rb b/spec/lib/gitlab/graphql/pagination/offset_active_record_relation_connection_spec.rb new file mode 100644 index 00000000000..2269b4def82 --- /dev/null +++ b/spec/lib/gitlab/graphql/pagination/offset_active_record_relation_connection_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Graphql::Pagination::OffsetActiveRecordRelationConnection do + it 'subclasses from GraphQL::Relay::RelationConnection' do + expect(described_class.superclass).to eq GraphQL::Relay::RelationConnection + end +end diff --git a/spec/lib/gitlab/user_access_spec.rb b/spec/lib/gitlab/user_access_spec.rb index 2f4ab2e71db..8d13f377677 100644 --- a/spec/lib/gitlab/user_access_spec.rb +++ b/spec/lib/gitlab/user_access_spec.rb @@ -46,32 +46,27 @@ describe Gitlab::UserAccess do expect(project_access.can_push_to_branch?('master')).to be_truthy end - it 'returns false if user is developer and project is fully protected' do - empty_project.add_developer(user) - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_FULL) - - expect(project_access.can_push_to_branch?('master')).to be_falsey - end - - it 'returns false if user is developer and it is not allowed to push new commits but can merge into branch' do - empty_project.add_developer(user) - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_MERGE) - - expect(project_access.can_push_to_branch?('master')).to be_falsey - end - - it 'returns true if user is developer and project is unprotected' do - empty_project.add_developer(user) - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_NONE) - - expect(project_access.can_push_to_branch?('master')).to be_truthy - end - - it 'returns true if user is developer and project grants developers permission' do - empty_project.add_developer(user) - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_PUSH) - - expect(project_access.can_push_to_branch?('master')).to be_truthy + context 'when the user is a developer' do + using RSpec::Parameterized::TableSyntax + + before do + empty_project.add_developer(user) + end + + where(:default_branch_protection_level, :result) do + Gitlab::Access::PROTECTION_NONE | true + Gitlab::Access::PROTECTION_DEV_CAN_PUSH | true + Gitlab::Access::PROTECTION_DEV_CAN_MERGE | false + Gitlab::Access::PROTECTION_FULL | false + end + + with_them do + it do + expect(empty_project.namespace).to receive(:default_branch_protection).and_return(default_branch_protection_level).at_least(:once) + + expect(project_access.can_push_to_branch?('master')).to eq(result) + end + end end end diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb index ab7e12cd43c..86dfa586862 100644 --- a/spec/models/deployment_spec.rb +++ b/spec/models/deployment_spec.rb @@ -520,6 +520,21 @@ describe Deployment do end end + describe '#create_ref' do + let(:deployment) { build(:deployment) } + + subject { deployment.create_ref } + + it 'creates a ref using the sha' do + expect(deployment.project.repository).to receive(:create_ref).with( + deployment.sha, + "refs/environments/#{deployment.environment.name}/deployments/#{deployment.iid}" + ) + + subject + end + end + describe '#playable_build' do subject { deployment.playable_build } diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index 48cabd4301c..03aef7aea5c 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -325,26 +325,6 @@ describe Environment, :use_clean_rails_memory_store_caching do end end - describe '#first_deployment_for' do - let(:project) { create(:project, :repository) } - let!(:deployment) { create(:deployment, :succeed, environment: environment, ref: commit.parent.id) } - let!(:deployment1) { create(:deployment, :succeed, environment: environment, ref: commit.id) } - let(:head_commit) { project.commit } - let(:commit) { project.commit.parent } - - it 'returns deployment id for the environment', :sidekiq_might_not_need_inline do - expect(environment.first_deployment_for(commit.id)).to eq deployment1 - end - - it 'return nil when no deployment is found' do - expect(environment.first_deployment_for(head_commit.id)).to eq nil - end - - it 'returns a UTF-8 ref', :sidekiq_might_not_need_inline do - expect(environment.first_deployment_for(commit.id).ref).to be_utf8 - end - end - describe '#environment_type' do subject { environment.environment_type } diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 54e54366c5a..276fbc2cb54 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -531,6 +531,41 @@ describe Namespace do end end + describe "#default_branch_protection" do + let(:namespace) { create(:namespace) } + let(:default_branch_protection) { nil } + let(:group) { create(:group, default_branch_protection: default_branch_protection) } + + before do + stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_MERGE) + end + + context 'for a namespace' do + # Unlike a group, the settings of a namespace cannot be altered + # via the UI or the API. + + it 'returns the instance level setting' do + expect(namespace.default_branch_protection).to eq(Gitlab::Access::PROTECTION_DEV_CAN_MERGE) + end + end + + context 'for a group' do + context 'that has not altered the default value' do + it 'returns the instance level setting' do + expect(group.default_branch_protection).to eq(Gitlab::Access::PROTECTION_DEV_CAN_MERGE) + end + end + + context 'that has altered the default value' do + let(:default_branch_protection) { Gitlab::Access::PROTECTION_FULL } + + it 'returns the group level setting' do + expect(group.default_branch_protection).to eq(default_branch_protection) + end + end + end + end + describe '#self_and_hierarchy' do let!(:group) { create(:group, path: 'git_lab') } let!(:nested_group) { create(:group, parent: group) } diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 2b4a832634f..4885d4b63ff 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1623,6 +1623,29 @@ describe Project do end end + describe '#default_branch_protected?' do + using RSpec::Parameterized::TableSyntax + + let_it_be(:project) { create(:project) } + + subject { project.default_branch_protected? } + + where(:default_branch_protection_level, :result) do + Gitlab::Access::PROTECTION_NONE | false + Gitlab::Access::PROTECTION_DEV_CAN_PUSH | false + Gitlab::Access::PROTECTION_DEV_CAN_MERGE | true + Gitlab::Access::PROTECTION_FULL | true + end + + with_them do + before do + expect(project.namespace).to receive(:default_branch_protection).and_return(default_branch_protection_level) + end + + it { is_expected.to eq(result) } + end + end + describe '#pages_url' do let(:group) { create(:group, name: group_name) } let(:project) { create(:project, namespace: group, name: project_name) } @@ -4576,7 +4599,7 @@ describe Project do end it 'does not protect when branch protection is disabled' do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_NONE) + expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_NONE) project.after_import @@ -4584,7 +4607,7 @@ describe Project do end it "gives developer access to push when branch protection is set to 'developers can push'" do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_PUSH) + expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_DEV_CAN_PUSH) project.after_import @@ -4594,7 +4617,7 @@ describe Project do end it "gives developer access to merge when branch protection is set to 'developers can merge'" do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_MERGE) + expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_DEV_CAN_MERGE) project.after_import diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb index 7f8a60dafa8..30fce1cd5c4 100644 --- a/spec/models/protected_branch_spec.rb +++ b/spec/models/protected_branch_spec.rb @@ -164,31 +164,45 @@ describe ProtectedBranch do end end - context "new project" do - let(:project) { create(:project) } + context 'new project' do + using RSpec::Parameterized::TableSyntax - it 'returns false when default_protected_branch is unprotected' do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_NONE) + let(:project) { create(:project) } - expect(described_class.protected?(project, 'master')).to be false - end + context 'when the group has set their own default_branch_protection level' do + where(:default_branch_protection_level, :result) do + Gitlab::Access::PROTECTION_NONE | false + Gitlab::Access::PROTECTION_DEV_CAN_PUSH | false + Gitlab::Access::PROTECTION_DEV_CAN_MERGE | true + Gitlab::Access::PROTECTION_FULL | true + end - it 'returns false when default_protected_branch lets developers push' do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_PUSH) + with_them do + it 'protects the default branch based on the default branch protection setting of the group' do + expect(project.namespace).to receive(:default_branch_protection).and_return(default_branch_protection_level) - expect(described_class.protected?(project, 'master')).to be false + expect(described_class.protected?(project, 'master')).to eq(result) + end + end end - it 'returns true when default_branch_protection does not let developers push but let developer merge branches' do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_MERGE) - - expect(described_class.protected?(project, 'master')).to be true - end + context 'when the group has not set their own default_branch_protection level' do + where(:default_branch_protection_level, :result) do + Gitlab::Access::PROTECTION_NONE | false + Gitlab::Access::PROTECTION_DEV_CAN_PUSH | false + Gitlab::Access::PROTECTION_DEV_CAN_MERGE | true + Gitlab::Access::PROTECTION_FULL | true + end - it 'returns true when default_branch_protection is in full protection' do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_FULL) + with_them do + before do + stub_application_setting(default_branch_protection: default_branch_protection_level) + end - expect(described_class.protected?(project, 'master')).to be true + it 'protects the default branch based on the instance level default branch protection setting' do + expect(described_class.protected?(project, 'master')).to eq(result) + end + end end end end diff --git a/spec/requests/api/api_guard/admin_mode_middleware_spec.rb b/spec/requests/api/api_guard/admin_mode_middleware_spec.rb new file mode 100644 index 00000000000..8973afe6570 --- /dev/null +++ b/spec/requests/api/api_guard/admin_mode_middleware_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe API::APIGuard::AdminModeMiddleware, :do_not_mock_admin_mode, :request_store do + let(:user) { create(:admin) } + + it 'is loaded' do + expect(API::API.middleware).to include([:use, described_class]) + end + + context 'when there is an exception in the api call' do + let(:app) do + Class.new(API::API) do + get 'willfail' do + raise StandardError.new('oh noes!') + end + end + end + + it 'resets admin mode' do + Gitlab::Auth::CurrentUserMode.bypass_session!(user.id) + + expect(Gitlab::Auth::CurrentUserMode.bypass_session_admin_id).to be(user.id) + expect(Gitlab::Auth::CurrentUserMode).to receive(:reset_bypass_session!).and_call_original + + get api('/willfail') + + expect(response.status).to eq(500) + expect(response.body).to include('oh noes!') + + expect(Gitlab::Auth::CurrentUserMode.bypass_session_admin_id).to be_nil + end + end +end diff --git a/spec/requests/api/graphql/group_query_spec.rb b/spec/requests/api/graphql/group_query_spec.rb index 6e2663fb090..a38d1857076 100644 --- a/spec/requests/api/graphql/group_query_spec.rb +++ b/spec/requests/api/graphql/group_query_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' # Based on spec/requests/api/groups_spec.rb # Should follow closely in order to ensure all situations are covered -describe 'getting group information' do +describe 'getting group information', :do_not_mock_admin_mode do include GraphqlHelpers include UploadHelpers diff --git a/spec/requests/api/graphql/mutations/snippets/mark_as_spam_spec.rb b/spec/requests/api/graphql/mutations/snippets/mark_as_spam_spec.rb index f80a3401134..05e3f7e6806 100644 --- a/spec/requests/api/graphql/mutations/snippets/mark_as_spam_spec.rb +++ b/spec/requests/api/graphql/mutations/snippets/mark_as_spam_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe 'Mark snippet as spam' do +describe 'Mark snippet as spam', :do_not_mock_admin_mode do include GraphqlHelpers let_it_be(:admin) { create(:admin) } diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index e8499246840..fb564bb398b 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -545,7 +545,8 @@ describe API::Groups do name: new_group_name, request_access_enabled: true, project_creation_level: "noone", - subgroup_creation_level: "maintainer" + subgroup_creation_level: "maintainer", + default_branch_protection: ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS } expect(response).to have_gitlab_http_status(:ok) @@ -566,6 +567,7 @@ describe API::Groups do expect(json_response['projects'].length).to eq(2) expect(json_response['shared_projects']).to be_an Array expect(json_response['shared_projects'].length).to eq(0) + expect(json_response['default_branch_protection']).to eq(::Gitlab::Access::MAINTAINER_PROJECT_ACCESS) end it 'returns 404 for a non existing group' do diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 12ac601c013..5a302f0528e 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe API::Users do +describe API::Users, :do_not_mock_admin_mode do let(:user) { create(:user, username: 'user.with.dot') } let(:admin) { create(:admin) } let(:key) { create(:key, user: user) } diff --git a/spec/services/deployments/after_create_service_spec.rb b/spec/services/deployments/after_create_service_spec.rb index 51c6de2c0b9..605700c73b2 100644 --- a/spec/services/deployments/after_create_service_spec.rb +++ b/spec/services/deployments/after_create_service_spec.rb @@ -49,7 +49,7 @@ describe Deployments::AfterCreateService do it 'creates ref' do expect_any_instance_of(Repository) .to receive(:create_ref) - .with(deployment.ref, deployment.send(:ref_path)) + .with(deployment.sha, deployment.send(:ref_path)) service.execute end diff --git a/spec/services/git/branch_push_service_spec.rb b/spec/services/git/branch_push_service_spec.rb index 8b4f45010ed..d7357cf4d0b 100644 --- a/spec/services/git/branch_push_service_spec.rb +++ b/spec/services/git/branch_push_service_spec.rb @@ -186,7 +186,7 @@ describe Git::BranchPushService, services: true do end it "when pushing a branch for the first time with default branch protection disabled" do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_NONE) + expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_NONE) expect(project).to receive(:execute_hooks) expect(project.default_branch).to eq("master") @@ -195,7 +195,7 @@ describe Git::BranchPushService, services: true do end it "when pushing a branch for the first time with default branch protection set to 'developers can push'" do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_PUSH) + expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_DEV_CAN_PUSH) expect(project).to receive(:execute_hooks) expect(project.default_branch).to eq("master") @@ -208,7 +208,7 @@ describe Git::BranchPushService, services: true do end it "when pushing a branch for the first time with an existing branch permission configured" do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_PUSH) + expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_DEV_CAN_PUSH) create(:protected_branch, :no_one_can_push, :developers_can_merge, project: project, name: 'master') expect(project).to receive(:execute_hooks) @@ -223,7 +223,7 @@ describe Git::BranchPushService, services: true do end it "when pushing a branch for the first time with default branch protection set to 'developers can merge'" do - stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_MERGE) + expect(project.namespace).to receive(:default_branch_protection).and_return(Gitlab::Access::PROTECTION_DEV_CAN_MERGE) expect(project).to receive(:execute_hooks) expect(project.default_branch).to eq("master") diff --git a/spec/services/issues/import_csv_service_spec.rb b/spec/services/issues/import_csv_service_spec.rb index e7370407d4c..aa43892a36d 100644 --- a/spec/services/issues/import_csv_service_spec.rb +++ b/spec/services/issues/import_csv_service_spec.rb @@ -27,6 +27,29 @@ describe Issues::ImportCsvService do end end + context 'with a file generated by Gitlab CSV export' do + let(:file) { fixture_file_upload('spec/fixtures/csv_gitlab_export.csv') } + + it 'imports the CSV without errors' do + expect_next_instance_of(Notify) do |instance| + expect(instance).to receive(:import_issues_csv_email) + end + + expect(subject[:success]).to eq(4) + expect(subject[:error_lines]).to eq([]) + expect(subject[:parse_error]).to eq(false) + end + + it 'correctly sets the issue attributes' do + expect { subject }.to change { project.issues.count }.by 4 + + expect(project.issues.reload.last).to have_attributes( + title: 'Test Title', + description: 'Test Description' + ) + end + end + context 'comma delimited file' do let(:file) { fixture_file_upload('spec/fixtures/csv_comma.csv') } @@ -39,6 +62,15 @@ describe Issues::ImportCsvService do expect(subject[:error_lines]).to eq([]) expect(subject[:parse_error]).to eq(false) end + + it 'correctly sets the issue attributes' do + expect { subject }.to change { project.issues.count }.by 3 + + expect(project.issues.reload.last).to have_attributes( + title: 'Title with quote"', + description: 'Description' + ) + end end context 'tab delimited file with error row' do @@ -53,6 +85,15 @@ describe Issues::ImportCsvService do expect(subject[:error_lines]).to eq([3]) expect(subject[:parse_error]).to eq(false) end + + it 'correctly sets the issue attributes' do + expect { subject }.to change { project.issues.count }.by 2 + + expect(project.issues.reload.last).to have_attributes( + title: 'Hello', + description: 'World' + ) + end end context 'semicolon delimited file with CRLF' do @@ -67,6 +108,15 @@ describe Issues::ImportCsvService do expect(subject[:error_lines]).to eq([4]) expect(subject[:parse_error]).to eq(false) end + + it 'correctly sets the issue attributes' do + expect { subject }.to change { project.issues.count }.by 3 + + expect(project.issues.reload.last).to have_attributes( + title: 'Hello', + description: 'World' + ) + end end end end diff --git a/spec/services/projects/protect_default_branch_service_spec.rb b/spec/services/projects/protect_default_branch_service_spec.rb index c145b2c06c6..c0b819ab17b 100644 --- a/spec/services/projects/protect_default_branch_service_spec.rb +++ b/spec/services/projects/protect_default_branch_service_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' describe Projects::ProtectDefaultBranchService do let(:service) { described_class.new(project) } - let(:project) { instance_spy(Project) } + let(:project) { create(:project) } describe '#execute' do before do @@ -147,7 +147,7 @@ describe Projects::ProtectDefaultBranchService do describe '#protect_branch?' do context 'when default branch protection is disabled' do it 'returns false' do - allow(Gitlab::CurrentSettings) + allow(project.namespace) .to receive(:default_branch_protection) .and_return(Gitlab::Access::PROTECTION_NONE) @@ -157,7 +157,7 @@ describe Projects::ProtectDefaultBranchService do context 'when default branch protection is enabled' do before do - allow(Gitlab::CurrentSettings) + allow(project.namespace) .to receive(:default_branch_protection) .and_return(Gitlab::Access::PROTECTION_DEV_CAN_MERGE) @@ -199,7 +199,7 @@ describe Projects::ProtectDefaultBranchService do describe '#push_access_level' do context 'when developers can push' do it 'returns the DEVELOPER access level' do - allow(Gitlab::CurrentSettings) + allow(project.namespace) .to receive(:default_branch_protection) .and_return(Gitlab::Access::PROTECTION_DEV_CAN_PUSH) @@ -209,7 +209,7 @@ describe Projects::ProtectDefaultBranchService do context 'when developers can not push' do it 'returns the MAINTAINER access level' do - allow(Gitlab::CurrentSettings) + allow(project.namespace) .to receive(:default_branch_protection) .and_return(Gitlab::Access::PROTECTION_DEV_CAN_MERGE) @@ -221,7 +221,7 @@ describe Projects::ProtectDefaultBranchService do describe '#merge_access_level' do context 'when developers can merge' do it 'returns the DEVELOPER access level' do - allow(Gitlab::CurrentSettings) + allow(project.namespace) .to receive(:default_branch_protection) .and_return(Gitlab::Access::PROTECTION_DEV_CAN_MERGE) @@ -231,7 +231,7 @@ describe Projects::ProtectDefaultBranchService do context 'when developers can not merge' do it 'returns the MAINTAINER access level' do - allow(Gitlab::CurrentSettings) + allow(project.namespace) .to receive(:default_branch_protection) .and_return(Gitlab::Access::PROTECTION_DEV_CAN_PUSH) diff --git a/spec/support/helpers/wait_for_requests.rb b/spec/support/helpers/wait_for_requests.rb index d5483d0b0a7..52d1c59ab03 100644 --- a/spec/support/helpers/wait_for_requests.rb +++ b/spec/support/helpers/wait_for_requests.rb @@ -34,14 +34,14 @@ module WaitForRequests # Wait for active Rack requests and client-side AJAX requests def wait_for_all_requests wait_for('pending requests complete') do - finished_all_rack_reqiests? && + finished_all_rack_requests? && finished_all_js_requests? end end private - def finished_all_rack_reqiests? + def finished_all_rack_requests? Gitlab::Testing::RequestBlockerMiddleware.num_active_requests.zero? end |