diff options
author | Pawel Chojnacki <pawel@chojnacki.ws> | 2017-06-16 18:19:41 +0200 |
---|---|---|
committer | Pawel Chojnacki <pawel@chojnacki.ws> | 2017-06-16 18:19:41 +0200 |
commit | 9f2c992ff1520e35d9b7bc26d603d597bc189618 (patch) | |
tree | 17af71363c63d99a15c76b1edcbceddc87bfc12d /spec/lib/gitlab | |
parent | 64bb0d37d4ef1f8574355019f198e40bc9b70224 (diff) | |
parent | 5f42009f8dcc29d559ee415e92c88858e361f063 (diff) | |
download | gitlab-ce-9f2c992ff1520e35d9b7bc26d603d597bc189618.tar.gz |
Merge remote-tracking branch 'upstream/master' into 28717-additional-metrics-review-branch
Diffstat (limited to 'spec/lib/gitlab')
60 files changed, 1697 insertions, 352 deletions
diff --git a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb index 94dcddcc30c..fc72df575be 100644 --- a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb +++ b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb @@ -40,7 +40,9 @@ describe Gitlab::Auth::UniqueIpsLimiter, :redis, lib: true do end context 'allow 2 unique ips' do - before { current_application_settings.update!(unique_ips_limit_per_user: 2) } + before do + current_application_settings.update!(unique_ips_limit_per_user: 2) + end it 'blocks user trying to login from third ip' do change_ip('ip1') diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index 50bc3ef1b7c..d09da951869 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -17,7 +17,11 @@ describe Gitlab::Auth, lib: true do end it 'OPTIONAL_SCOPES contains all non-default scopes' do - expect(subject::OPTIONAL_SCOPES).to eq [:read_user, :openid] + expect(subject::OPTIONAL_SCOPES).to eq %i[read_user read_registry openid] + end + + it 'REGISTRY_SCOPES contains all registry related scopes' do + expect(subject::REGISTRY_SCOPES).to eq %i[read_registry] end end @@ -143,6 +147,13 @@ describe Gitlab::Auth, lib: true do expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_token, full_authentication_abilities)) end + it 'succeeds for personal access tokens with the `read_registry` scope' do + personal_access_token = create(:personal_access_token, scopes: ['read_registry']) + + expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: '') + expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_token, [:read_container_image])) + end + it 'succeeds if it is an impersonation token' do impersonation_token = create(:personal_access_token, :impersonation, scopes: ['api']) @@ -150,18 +161,11 @@ describe Gitlab::Auth, lib: true do expect(gl_auth.find_for_git_client('', impersonation_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(impersonation_token.user, nil, :personal_token, full_authentication_abilities)) end - it 'fails for personal access tokens with other scopes' do + it 'limits abilities based on scope' do personal_access_token = create(:personal_access_token, scopes: ['read_user']) - expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: '') - expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(nil, nil)) - end - - it 'fails for impersonation token with other scopes' do - impersonation_token = create(:personal_access_token, scopes: ['read_user']) - - expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: '') - expect(gl_auth.find_for_git_client('', impersonation_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(nil, nil)) + expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: '') + expect(gl_auth.find_for_git_client('', personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(personal_access_token.user, nil, :personal_token, [])) end it 'fails if password is nil' do @@ -200,6 +204,12 @@ describe Gitlab::Auth, lib: true do expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: login) expect(gl_auth.find_for_git_client(login, 'bar', project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new) end + + it 'throws an error suggesting user create a PAT when internal auth is disabled' do + allow_any_instance_of(ApplicationSetting).to receive(:signin_enabled?) { false } + + expect { gl_auth.find_for_git_client('foo', 'bar', project: nil, ip: 'ip') }.to raise_error(Gitlab::Auth::MissingPersonalTokenError) + end end describe 'find_with_user_password' do diff --git a/spec/lib/gitlab/background_migration_spec.rb b/spec/lib/gitlab/background_migration_spec.rb new file mode 100644 index 00000000000..f2073b9bcb3 --- /dev/null +++ b/spec/lib/gitlab/background_migration_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' + +describe Gitlab::BackgroundMigration do + describe '.steal' do + it 'steals jobs from a queue' do + queue = [double(:job, args: ['Foo', [10, 20]])] + + allow(Sidekiq::Queue).to receive(:new). + with(BackgroundMigrationWorker.sidekiq_options['queue']). + and_return(queue) + + expect(queue[0]).to receive(:delete) + + expect(described_class).to receive(:perform).with('Foo', [10, 20]) + + described_class.steal('Foo') + end + + it 'does not steal jobs for a different migration' do + queue = [double(:job, args: ['Foo', [10, 20]])] + + allow(Sidekiq::Queue).to receive(:new). + with(BackgroundMigrationWorker.sidekiq_options['queue']). + and_return(queue) + + expect(described_class).not_to receive(:perform) + + expect(queue[0]).not_to receive(:delete) + + described_class.steal('Bar') + end + end + + describe '.perform' do + it 'performs a background migration' do + instance = double(:instance) + klass = double(:klass, new: instance) + + expect(described_class).to receive(:const_get). + with('Foo'). + and_return(klass) + + expect(instance).to receive(:perform).with(10, 20) + + described_class.perform('Foo', [10, 20]) + end + end +end diff --git a/spec/lib/gitlab/backup/repository_spec.rb b/spec/lib/gitlab/backup/repository_spec.rb new file mode 100644 index 00000000000..51c1e9d657b --- /dev/null +++ b/spec/lib/gitlab/backup/repository_spec.rb @@ -0,0 +1,63 @@ +require 'spec_helper' + +describe Backup::Repository, lib: true do + let(:progress) { StringIO.new } + let!(:project) { create(:empty_project) } + + before do + allow(progress).to receive(:puts) + allow(progress).to receive(:print) + + allow_any_instance_of(String).to receive(:color) do |string, _color| + string + end + + allow_any_instance_of(described_class).to receive(:progress).and_return(progress) + end + + describe '#dump' do + describe 'repo failure' do + before do + allow_any_instance_of(Repository).to receive(:empty_repo?).and_raise(Rugged::OdbError) + allow(Gitlab::Popen).to receive(:popen).and_return(['normal output', 0]) + end + + it 'does not raise error' do + expect { described_class.new.dump }.not_to raise_error + end + + it 'shows the appropriate error' do + described_class.new.dump + + expect(progress).to have_received(:puts).with("Ignoring repository error and continuing backing up project: #{project.full_path} - Rugged::OdbError") + end + end + + describe 'command failure' do + before do + allow_any_instance_of(Repository).to receive(:empty_repo?).and_return(false) + allow(Gitlab::Popen).to receive(:popen).and_return(['error', 1]) + end + + it 'shows the appropriate error' do + described_class.new.dump + + expect(progress).to have_received(:puts).with("Ignoring error on #{project.full_path} - error") + end + end + end + + describe '#restore' do + describe 'command failure' do + before do + allow(Gitlab::Popen).to receive(:popen).and_return(['error', 1]) + end + + it 'shows the appropriate error' do + described_class.new.restore + + expect(progress).to have_received(:puts).with("Ignoring error on #{project.full_path} - error") + end + end + end +end diff --git a/spec/lib/gitlab/badge/build/status_spec.rb b/spec/lib/gitlab/badge/build/status_spec.rb index 3c5414701a7..6abf4ca46a9 100644 --- a/spec/lib/gitlab/badge/build/status_spec.rb +++ b/spec/lib/gitlab/badge/build/status_spec.rb @@ -29,7 +29,9 @@ describe Gitlab::Badge::Build::Status do let!(:build) { create_build(project, sha, branch) } context 'build success' do - before { build.success! } + before do + build.success! + end describe '#status' do it 'is successful' do @@ -39,7 +41,9 @@ describe Gitlab::Badge::Build::Status do end context 'build failed' do - before { build.drop! } + before do + build.drop! + end describe '#status' do it 'failed' do diff --git a/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb b/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb index ec6d3e34a96..3799a324db4 100644 --- a/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb +++ b/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb @@ -4,7 +4,9 @@ describe Gitlab::ChatCommands::Presenters::IssueSearch do let(:project) { create(:empty_project) } let(:message) { subject[:text] } - before { create_list(:issue, 2, project: project) } + before do + create_list(:issue, 2, project: project) + end subject { described_class.new(project.issues).present } diff --git a/spec/lib/gitlab/checks/change_access_spec.rb b/spec/lib/gitlab/checks/change_access_spec.rb index c0c309d8179..643e590438a 100644 --- a/spec/lib/gitlab/checks/change_access_spec.rb +++ b/spec/lib/gitlab/checks/change_access_spec.rb @@ -20,7 +20,9 @@ describe Gitlab::Checks::ChangeAccess, lib: true do ).exec end - before { project.add_developer(user) } + before do + project.add_developer(user) + end context 'without failed checks' do it "doesn't raise an error" do @@ -50,7 +52,9 @@ describe Gitlab::Checks::ChangeAccess, lib: true do let!(:protected_tag) { create(:protected_tag, project: project, name: 'v*') } context 'as master' do - before { project.add_master(user) } + before do + project.add_master(user) + end context 'deletion' do let(:oldrev) { 'be93687618e4b132087f430a4d8fc3a609c9b77c' } diff --git a/spec/lib/gitlab/ci/build/image_spec.rb b/spec/lib/gitlab/ci/build/image_spec.rb index 382385dfd6b..773a52cdfbc 100644 --- a/spec/lib/gitlab/ci/build/image_spec.rb +++ b/spec/lib/gitlab/ci/build/image_spec.rb @@ -10,12 +10,28 @@ describe Gitlab::Ci::Build::Image do let(:image_name) { 'ruby:2.1' } let(:job) { create(:ci_build, options: { image: image_name } ) } - it 'fabricates an object of the proper class' do - is_expected.to be_kind_of(described_class) + context 'when image is defined as string' do + it 'fabricates an object of the proper class' do + is_expected.to be_kind_of(described_class) + end + + it 'populates fabricated object with the proper name attribute' do + expect(subject.name).to eq(image_name) + end end - it 'populates fabricated object with the proper name attribute' do - expect(subject.name).to eq(image_name) + context 'when image is defined as hash' do + let(:entrypoint) { '/bin/sh' } + let(:job) { create(:ci_build, options: { image: { name: image_name, entrypoint: entrypoint } } ) } + + it 'fabricates an object of the proper class' do + is_expected.to be_kind_of(described_class) + end + + it 'populates fabricated object with the proper attributes' do + expect(subject.name).to eq(image_name) + expect(subject.entrypoint).to eq(entrypoint) + end end context 'when image name is empty' do @@ -41,10 +57,39 @@ describe Gitlab::Ci::Build::Image do let(:service_image_name) { 'postgres' } let(:job) { create(:ci_build, options: { services: [service_image_name] }) } - it 'fabricates an non-empty array of objects' do - is_expected.to be_kind_of(Array) - is_expected.not_to be_empty - expect(subject.first.name).to eq(service_image_name) + context 'when service is defined as string' do + it 'fabricates an non-empty array of objects' do + is_expected.to be_kind_of(Array) + is_expected.not_to be_empty + end + + it 'populates fabricated objects with the proper name attributes' do + expect(subject.first).to be_kind_of(described_class) + expect(subject.first.name).to eq(service_image_name) + end + end + + context 'when service is defined as hash' do + let(:service_entrypoint) { '/bin/sh' } + let(:service_alias) { 'db' } + let(:service_command) { 'sleep 30' } + let(:job) do + create(:ci_build, options: { services: [{ name: service_image_name, entrypoint: service_entrypoint, + alias: service_alias, command: service_command }] }) + end + + it 'fabricates an non-empty array of objects' do + is_expected.to be_kind_of(Array) + is_expected.not_to be_empty + expect(subject.first).to be_kind_of(described_class) + end + + it 'populates fabricated objects with the proper attributes' do + expect(subject.first.name).to eq(service_image_name) + expect(subject.first.entrypoint).to eq(service_entrypoint) + expect(subject.first.alias).to eq(service_alias) + expect(subject.first.command).to eq(service_command) + end end context 'when service image name is empty' do diff --git a/spec/lib/gitlab/ci/config/entry/cache_spec.rb b/spec/lib/gitlab/ci/config/entry/cache_spec.rb index 2ed120f356a..878b1d6b862 100644 --- a/spec/lib/gitlab/ci/config/entry/cache_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/cache_spec.rb @@ -4,7 +4,9 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:entry) { described_class.new(config) } describe 'validations' do - before { entry.compose! } + before do + entry.compose! + end context 'when entry config value is correct' do let(:config) do diff --git a/spec/lib/gitlab/ci/config/entry/environment_spec.rb b/spec/lib/gitlab/ci/config/entry/environment_spec.rb index c330e609337..3c0007f4d57 100644 --- a/spec/lib/gitlab/ci/config/entry/environment_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/environment_spec.rb @@ -3,7 +3,9 @@ require 'spec_helper' describe Gitlab::Ci::Config::Entry::Environment do let(:entry) { described_class.new(config) } - before { entry.compose! } + before do + entry.compose! + end context 'when configuration is a string' do let(:config) { 'production' } diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb index 23270ad5053..293f112b2b0 100644 --- a/spec/lib/gitlab/ci/config/entry/global_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb @@ -33,7 +33,9 @@ describe Gitlab::Ci::Config::Entry::Global do end describe '#compose!' do - before { global.compose! } + before do + global.compose! + end it 'creates nodes hash' do expect(global.descendants).to be_an Array @@ -79,7 +81,9 @@ describe Gitlab::Ci::Config::Entry::Global do end context 'when composed' do - before { global.compose! } + before do + global.compose! + end describe '#errors' do it 'has no errors' do @@ -95,13 +99,13 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#image_value' do it 'returns valid image' do - expect(global.image_value).to eq 'ruby:2.2' + expect(global.image_value).to eq(name: 'ruby:2.2') end end describe '#services_value' do it 'returns array of services' do - expect(global.services_value).to eq ['postgres:9.1', 'mysql:5.5'] + expect(global.services_value).to eq [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }] end end @@ -150,8 +154,8 @@ describe Gitlab::Ci::Config::Entry::Global do script: %w[rspec ls], before_script: %w(ls pwd), commands: "ls\npwd\nrspec\nls", - image: 'ruby:2.2', - services: ['postgres:9.1', 'mysql:5.5'], + image: { name: 'ruby:2.2' }, + services: [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }], stage: 'test', cache: { key: 'k', untracked: true, paths: ['public/'] }, variables: { 'VAR' => 'value' }, @@ -161,8 +165,8 @@ describe Gitlab::Ci::Config::Entry::Global do before_script: [], script: %w[spinach], commands: 'spinach', - image: 'ruby:2.2', - services: ['postgres:9.1', 'mysql:5.5'], + image: { name: 'ruby:2.2' }, + services: [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }], stage: 'test', cache: { key: 'k', untracked: true, paths: ['public/'] }, variables: {}, @@ -175,7 +179,9 @@ describe Gitlab::Ci::Config::Entry::Global do end context 'when most of entires not defined' do - before { global.compose! } + before do + global.compose! + end let(:hash) do { cache: { key: 'a' }, rspec: { script: %w[ls] } } @@ -218,7 +224,9 @@ describe Gitlab::Ci::Config::Entry::Global do # details. # context 'when entires specified but not defined' do - before { global.compose! } + before do + global.compose! + end let(:hash) do { variables: nil, rspec: { script: 'rspec' } } @@ -233,7 +241,9 @@ describe Gitlab::Ci::Config::Entry::Global do end context 'when configuration is not valid' do - before { global.compose! } + before do + global.compose! + end context 'when before script is not an array' do let(:hash) do @@ -297,7 +307,9 @@ describe Gitlab::Ci::Config::Entry::Global do end describe '#[]' do - before { global.compose! } + before do + global.compose! + end let(:hash) do { cache: { key: 'a' }, rspec: { script: 'ls' } } diff --git a/spec/lib/gitlab/ci/config/entry/image_spec.rb b/spec/lib/gitlab/ci/config/entry/image_spec.rb index 3c99cb0a1ee..bca22e39500 100644 --- a/spec/lib/gitlab/ci/config/entry/image_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/image_spec.rb @@ -3,43 +3,104 @@ require 'spec_helper' describe Gitlab::Ci::Config::Entry::Image do let(:entry) { described_class.new(config) } - describe 'validation' do - context 'when entry config value is correct' do - let(:config) { 'ruby:2.2' } + context 'when configuration is a string' do + let(:config) { 'ruby:2.2' } - describe '#value' do - it 'returns image string' do - expect(entry.value).to eq 'ruby:2.2' - end + describe '#value' do + it 'returns image hash' do + expect(entry.value).to eq({ name: 'ruby:2.2' }) end + end + + describe '#errors' do + it 'does not append errors' do + expect(entry.errors).to be_empty + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + + describe '#image' do + it "returns image's name" do + expect(entry.name).to eq 'ruby:2.2' + end + end - describe '#errors' do - it 'does not append errors' do - expect(entry.errors).to be_empty - end + describe '#entrypoint' do + it "returns image's entrypoint" do + expect(entry.entrypoint).to be_nil end + end + end - describe '#valid?' do - it 'is valid' do - expect(entry).to be_valid - end + context 'when configuration is a hash' do + let(:config) { { name: 'ruby:2.2', entrypoint: '/bin/sh' } } + + describe '#value' do + it 'returns image hash' do + expect(entry.value).to eq(config) end end - context 'when entry value is not correct' do - let(:config) { ['ruby:2.2'] } + describe '#errors' do + it 'does not append errors' do + expect(entry.errors).to be_empty + end + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end - describe '#errors' do - it 'saves errors' do - expect(entry.errors) - .to include 'image config should be a string' - end + describe '#image' do + it "returns image's name" do + expect(entry.name).to eq 'ruby:2.2' end + end + + describe '#entrypoint' do + it "returns image's entrypoint" do + expect(entry.entrypoint).to eq '/bin/sh' + end + end + end + + context 'when entry value is not correct' do + let(:config) { ['ruby:2.2'] } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'image config should be a hash or a string' + end + end + + describe '#valid?' do + it 'is not valid' do + expect(entry).not_to be_valid + end + end + end + + context 'when unexpected key is specified' do + let(:config) { { name: 'ruby:2.2', non_existing: 'test' } } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'image config contains unknown keys: non_existing' + end + end - describe '#valid?' do - it 'is not valid' do - expect(entry).not_to be_valid - end + describe '#valid?' do + it 'is not valid' do + expect(entry).not_to be_valid end end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index 9249bb9c172..92cba689f47 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -18,7 +18,9 @@ describe Gitlab::Ci::Config::Entry::Job do end describe 'validations' do - before { entry.compose! } + before do + entry.compose! + end context 'when entry config value is correct' do let(:config) { { script: 'rspec' } } @@ -97,14 +99,16 @@ describe Gitlab::Ci::Config::Entry::Job do let(:deps) { double('deps', '[]' => unspecified) } context 'when job config overrides global config' do - before { entry.compose!(deps) } + before do + entry.compose!(deps) + end let(:config) do { script: 'rspec', image: 'some_image', cache: { key: 'test' } } end it 'overrides global config' do - expect(entry[:image].value).to eq 'some_image' + expect(entry[:image].value).to eq(name: 'some_image') expect(entry[:cache].value).to eq(key: 'test') end end @@ -125,10 +129,14 @@ describe Gitlab::Ci::Config::Entry::Job do end context 'when composed' do - before { entry.compose! } + before do + entry.compose! + end describe '#value' do - before { entry.compose! } + before do + entry.compose! + end context 'when entry is correct' do let(:config) do diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb index 7d104372ac6..c0a2b6517e3 100644 --- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb @@ -4,7 +4,9 @@ describe Gitlab::Ci::Config::Entry::Jobs do let(:entry) { described_class.new(config) } describe 'validations' do - before { entry.compose! } + before do + entry.compose! + end context 'when entry config value is correct' do let(:config) { { rspec: { script: 'rspec' } } } @@ -48,7 +50,9 @@ describe Gitlab::Ci::Config::Entry::Jobs do end context 'when valid job entries composed' do - before { entry.compose! } + before do + entry.compose! + end let(:config) do { rspec: { script: 'rspec' }, diff --git a/spec/lib/gitlab/ci/config/entry/service_spec.rb b/spec/lib/gitlab/ci/config/entry/service_spec.rb new file mode 100644 index 00000000000..7202fe525e4 --- /dev/null +++ b/spec/lib/gitlab/ci/config/entry/service_spec.rb @@ -0,0 +1,119 @@ +require 'spec_helper' + +describe Gitlab::Ci::Config::Entry::Service do + let(:entry) { described_class.new(config) } + + before do + entry.compose! + end + + context 'when configuration is a string' do + let(:config) { 'postgresql:9.5' } + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + + describe '#value' do + it 'returns valid hash' do + expect(entry.value).to include(name: 'postgresql:9.5') + end + end + + describe '#image' do + it "returns service's image name" do + expect(entry.name).to eq 'postgresql:9.5' + end + end + + describe '#alias' do + it "returns service's alias" do + expect(entry.alias).to be_nil + end + end + + describe '#command' do + it "returns service's command" do + expect(entry.command).to be_nil + end + end + end + + context 'when configuration is a hash' do + let(:config) do + { name: 'postgresql:9.5', alias: 'db', command: 'cmd', entrypoint: '/bin/sh' } + end + + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid + end + end + + describe '#value' do + it 'returns valid hash' do + expect(entry.value).to eq config + end + end + + describe '#image' do + it "returns service's image name" do + expect(entry.name).to eq 'postgresql:9.5' + end + end + + describe '#alias' do + it "returns service's alias" do + expect(entry.alias).to eq 'db' + end + end + + describe '#command' do + it "returns service's command" do + expect(entry.command).to eq 'cmd' + end + end + + describe '#entrypoint' do + it "returns service's entrypoint" do + expect(entry.entrypoint).to eq '/bin/sh' + end + end + end + + context 'when entry value is not correct' do + let(:config) { ['postgresql:9.5'] } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'service config should be a hash or a string' + end + end + + describe '#valid?' do + it 'is not valid' do + expect(entry).not_to be_valid + end + end + end + + context 'when unexpected key is specified' do + let(:config) { { name: 'postgresql:9.5', non_existing: 'test' } } + + describe '#errors' do + it 'saves errors' do + expect(entry.errors) + .to include 'service config contains unknown keys: non_existing' + end + end + + describe '#valid?' do + it 'is not valid' do + expect(entry).not_to be_valid + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/entry/services_spec.rb b/spec/lib/gitlab/ci/config/entry/services_spec.rb index 66fad3b6b16..7c4319aee63 100644 --- a/spec/lib/gitlab/ci/config/entry/services_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/services_spec.rb @@ -3,37 +3,32 @@ require 'spec_helper' describe Gitlab::Ci::Config::Entry::Services do let(:entry) { described_class.new(config) } - describe 'validations' do - context 'when entry config value is correct' do - let(:config) { ['postgres:9.1', 'mysql:5.5'] } + before do + entry.compose! + end - describe '#value' do - it 'returns array of services as is' do - expect(entry.value).to eq config - end - end + context 'when configuration is valid' do + let(:config) { ['postgresql:9.5', { name: 'postgresql:9.1', alias: 'postgres_old' }] } - describe '#valid?' do - it 'is valid' do - expect(entry).to be_valid - end + describe '#valid?' do + it 'is valid' do + expect(entry).to be_valid end end - context 'when entry value is not correct' do - let(:config) { 'ls' } - - describe '#errors' do - it 'saves errors' do - expect(entry.errors) - .to include 'services config should be an array of strings' - end + describe '#value' do + it 'returns valid array' do + expect(entry.value).to eq([{ name: 'postgresql:9.5' }, { name: 'postgresql:9.1', alias: 'postgres_old' }]) end + end + end + + context 'when configuration is invalid' do + let(:config) { 'postgresql:9.5' } - describe '#valid?' do - it 'is not valid' do - expect(entry).not_to be_valid - end + describe '#valid?' do + it 'is invalid' do + expect(entry).not_to be_valid end end end diff --git a/spec/lib/gitlab/ci/stage/seed_spec.rb b/spec/lib/gitlab/ci/stage/seed_spec.rb new file mode 100644 index 00000000000..d7e91a5a62c --- /dev/null +++ b/spec/lib/gitlab/ci/stage/seed_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' + +describe Gitlab::Ci::Stage::Seed do + let(:pipeline) { create(:ci_empty_pipeline) } + + let(:builds) do + [{ name: 'rspec' }, { name: 'spinach' }] + end + + subject do + described_class.new(pipeline, 'test', builds) + end + + describe '#stage' do + it 'returns hash attributes of a stage' do + expect(subject.stage).to be_a Hash + expect(subject.stage).to include(:name, :project) + end + end + + describe '#builds' do + it 'returns hash attributes of all builds' do + expect(subject.builds.size).to eq 2 + expect(subject.builds).to all(include(ref: 'master')) + expect(subject.builds).to all(include(tag: false)) + expect(subject.builds).to all(include(project: pipeline.project)) + expect(subject.builds) + .to all(include(trigger_request: pipeline.trigger_requests.first)) + end + end + + describe '#user=' do + let(:user) { build(:user) } + + it 'assignes relevant pipeline attributes' do + subject.user = user + + expect(subject.builds).to all(include(user: user)) + end + end + + describe '#create!' do + it 'creates all stages and builds' do + subject.create! + + expect(pipeline.reload.stages.count).to eq 1 + expect(pipeline.reload.builds.count).to eq 2 + expect(pipeline.builds).to all(satisfy { |job| job.stage_id.present? }) + expect(pipeline.builds).to all(satisfy { |job| job.pipeline.present? }) + expect(pipeline.builds).to all(satisfy { |job| job.project.present? }) + expect(pipeline.stages) + .to all(satisfy { |stage| stage.pipeline.present? }) + expect(pipeline.stages) + .to all(satisfy { |stage| stage.project.present? }) + end + end +end diff --git a/spec/lib/gitlab/ci/status/build/cancelable_spec.rb b/spec/lib/gitlab/ci/status/build/cancelable_spec.rb index 8ad9b7cdf07..114d2490490 100644 --- a/spec/lib/gitlab/ci/status/build/cancelable_spec.rb +++ b/spec/lib/gitlab/ci/status/build/cancelable_spec.rb @@ -47,7 +47,9 @@ describe Gitlab::Ci::Status::Build::Cancelable do describe '#has_action?' do context 'when user is allowed to update build' do - before { build.project.team << [user, :developer] } + before do + build.project.team << [user, :developer] + end it { is_expected.to have_action } end diff --git a/spec/lib/gitlab/ci/status/build/common_spec.rb b/spec/lib/gitlab/ci/status/build/common_spec.rb index 72bd7c4eb93..03d1f46b517 100644 --- a/spec/lib/gitlab/ci/status/build/common_spec.rb +++ b/spec/lib/gitlab/ci/status/build/common_spec.rb @@ -17,13 +17,17 @@ describe Gitlab::Ci::Status::Build::Common do describe '#has_details?' do context 'when user has access to read build' do - before { project.team << [user, :developer] } + before do + project.team << [user, :developer] + end it { is_expected.to have_details } end context 'when user does not have access to read build' do - before { project.update(public_builds: false) } + before do + project.update(public_builds: false) + end it { is_expected.not_to have_details } end diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb index 3f30b2c38f2..c8a97016f20 100644 --- a/spec/lib/gitlab/ci/status/build/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb @@ -6,7 +6,9 @@ describe Gitlab::Ci::Status::Build::Factory do let(:status) { factory.fabricate! } let(:factory) { described_class.new(build, user) } - before { project.team << [user, :developer] } + before do + project.team << [user, :developer] + end context 'when build is successful' do let(:build) { create(:ci_build, :success) } diff --git a/spec/lib/gitlab/ci/status/build/play_spec.rb b/spec/lib/gitlab/ci/status/build/play_spec.rb index 0e15a5f3c6b..32b2e62e4e0 100644 --- a/spec/lib/gitlab/ci/status/build/play_spec.rb +++ b/spec/lib/gitlab/ci/status/build/play_spec.rb @@ -28,7 +28,9 @@ describe Gitlab::Ci::Status::Build::Play do end context 'when user can not push to the branch' do - before { build.project.add_developer(user) } + before do + build.project.add_developer(user) + end it { is_expected.not_to have_action } end diff --git a/spec/lib/gitlab/ci/status/build/retryable_spec.rb b/spec/lib/gitlab/ci/status/build/retryable_spec.rb index 2db0f8d29bd..099d873fc01 100644 --- a/spec/lib/gitlab/ci/status/build/retryable_spec.rb +++ b/spec/lib/gitlab/ci/status/build/retryable_spec.rb @@ -47,7 +47,9 @@ describe Gitlab::Ci::Status::Build::Retryable do describe '#has_action?' do context 'when user is allowed to update build' do - before { build.project.team << [user, :developer] } + before do + build.project.team << [user, :developer] + end it { is_expected.to have_action } end diff --git a/spec/lib/gitlab/ci/status/build/stop_spec.rb b/spec/lib/gitlab/ci/status/build/stop_spec.rb index 8d021c35a69..23902f26b1a 100644 --- a/spec/lib/gitlab/ci/status/build/stop_spec.rb +++ b/spec/lib/gitlab/ci/status/build/stop_spec.rb @@ -19,7 +19,9 @@ describe Gitlab::Ci::Status::Build::Stop do describe '#has_action?' do context 'when user is allowed to update build' do - before { build.project.team << [user, :developer] } + before do + build.project.team << [user, :developer] + end it { is_expected.to have_action } end diff --git a/spec/lib/gitlab/ci/status/external/common_spec.rb b/spec/lib/gitlab/ci/status/external/common_spec.rb index 5a97d98b55f..b38fbee2486 100644 --- a/spec/lib/gitlab/ci/status/external/common_spec.rb +++ b/spec/lib/gitlab/ci/status/external/common_spec.rb @@ -4,9 +4,10 @@ describe Gitlab::Ci::Status::External::Common do let(:user) { create(:user) } let(:project) { external_status.project } let(:external_target_url) { 'http://example.gitlab.com/status' } + let(:external_description) { 'my description' } let(:external_status) do - create(:generic_commit_status, target_url: external_target_url) + create(:generic_commit_status, target_url: external_target_url, description: external_description) end subject do @@ -15,13 +16,21 @@ describe Gitlab::Ci::Status::External::Common do .extend(described_class) end + describe '#label' do + it 'returns description' do + expect(subject.label).to eq external_description + end + end + describe '#has_action?' do it { is_expected.not_to have_action } end describe '#has_details?' do context 'when user has access to read commit status' do - before { project.team << [user, :developer] } + before do + project.team << [user, :developer] + end it { is_expected.to have_details } end diff --git a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb index d665674bf70..f5fd31e8d03 100644 --- a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb @@ -17,7 +17,9 @@ describe Gitlab::Ci::Status::Pipeline::Common do describe '#has_details?' do context 'when user has access to read pipeline' do - before { project.team << [user, :developer] } + before do + project.team << [user, :developer] + end it { is_expected.to have_details } end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 3fdafd867da..30aa463faf8 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -7,7 +7,42 @@ describe Gitlab::Database::MigrationHelpers, lib: true do ) end - before { allow(model).to receive(:puts) } + before do + allow(model).to receive(:puts) + end + + describe '#add_timestamps_with_timezone' do + before do + allow(model).to receive(:transaction_open?).and_return(false) + end + + context 'using PostgreSQL' do + before do + allow(Gitlab::Database).to receive(:postgresql?).and_return(true) + allow(model).to receive(:disable_statement_timeout) + end + + it 'adds "created_at" and "updated_at" fields with the "datetime_with_timezone" data type' do + expect(model).to receive(:add_column).with(:foo, :created_at, :datetime_with_timezone, { null: false }) + expect(model).to receive(:add_column).with(:foo, :updated_at, :datetime_with_timezone, { null: false }) + + model.add_timestamps_with_timezone(:foo) + end + end + + context 'using MySQL' do + before do + allow(Gitlab::Database).to receive(:postgresql?).and_return(false) + end + + it 'adds "created_at" and "updated_at" fields with "datetime_with_timezone" data type' do + expect(model).to receive(:add_column).with(:foo, :created_at, :datetime_with_timezone, { null: false }) + expect(model).to receive(:add_column).with(:foo, :updated_at, :datetime_with_timezone, { null: false }) + + model.add_timestamps_with_timezone(:foo) + end + end + end describe '#add_concurrent_index' do context 'outside a transaction' do diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb index 9b1d66a1b1c..26e5d73d333 100644 --- a/spec/lib/gitlab/database_spec.rb +++ b/spec/lib/gitlab/database_spec.rb @@ -53,14 +53,18 @@ describe Gitlab::Database, lib: true do describe '.nulls_last_order' do context 'when using PostgreSQL' do - before { expect(described_class).to receive(:postgresql?).and_return(true) } + before do + expect(described_class).to receive(:postgresql?).and_return(true) + end it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column ASC NULLS LAST'} it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC NULLS LAST'} end context 'when using MySQL' do - before { expect(described_class).to receive(:postgresql?).and_return(false) } + before do + expect(described_class).to receive(:postgresql?).and_return(false) + end it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column IS NULL, column ASC'} it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC'} @@ -69,14 +73,18 @@ describe Gitlab::Database, lib: true do describe '.nulls_first_order' do context 'when using PostgreSQL' do - before { expect(described_class).to receive(:postgresql?).and_return(true) } + before do + expect(described_class).to receive(:postgresql?).and_return(true) + end it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC NULLS FIRST'} it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column DESC NULLS FIRST'} end context 'when using MySQL' do - before { expect(described_class).to receive(:postgresql?).and_return(false) } + before do + expect(described_class).to receive(:postgresql?).and_return(false) + end it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC'} it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column IS NULL, column DESC'} diff --git a/spec/lib/gitlab/diff/diff_refs_spec.rb b/spec/lib/gitlab/diff/diff_refs_spec.rb new file mode 100644 index 00000000000..a8173558c00 --- /dev/null +++ b/spec/lib/gitlab/diff/diff_refs_spec.rb @@ -0,0 +1,61 @@ +require 'spec_helper' + +describe Gitlab::Diff::DiffRefs, lib: true do + let(:project) { create(:project, :repository) } + + describe '#compare_in' do + context 'with diff refs for the initial commit' do + let(:commit) { project.commit('1a0b36b3cdad1d2ee32457c102a8c0b7056fa863') } + subject { commit.diff_refs } + + it 'returns an appropriate comparison' do + compare = subject.compare_in(project) + + expect(compare.diff_refs).to eq(subject) + end + end + + context 'with diff refs for a commit' do + let(:commit) { project.commit('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') } + subject { commit.diff_refs } + + it 'returns an appropriate comparison' do + compare = subject.compare_in(project) + + expect(compare.diff_refs).to eq(subject) + end + end + + context 'with diff refs for a comparison through the base' do + subject do + described_class.new( + start_sha: '0b4bc9a49b562e85de7cc9e834518ea6828729b9', # feature + base_sha: 'ae73cb07c9eeaf35924a10f713b364d32b2dd34f', + head_sha: 'e63f41fe459e62e1228fcef60d7189127aeba95a' # master + ) + end + + it 'returns an appropriate comparison' do + compare = subject.compare_in(project) + + expect(compare.diff_refs).to eq(subject) + end + end + + context 'with diff refs for a straight comparison' do + subject do + described_class.new( + start_sha: '0b4bc9a49b562e85de7cc9e834518ea6828729b9', # feature + base_sha: '0b4bc9a49b562e85de7cc9e834518ea6828729b9', + head_sha: 'e63f41fe459e62e1228fcef60d7189127aeba95a' # master + ) + end + + it 'returns an appropriate comparison' do + compare = subject.compare_in(project) + + expect(compare.diff_refs).to eq(subject) + end + end + end +end diff --git a/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb b/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb index f2bc15d39d7..d81774c8b8f 100644 --- a/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb +++ b/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb @@ -5,15 +5,7 @@ describe Gitlab::Diff::FileCollection::MergeRequestDiff do let(:diff_files) { described_class.new(merge_request.merge_request_diff, diff_options: nil).diff_files } it 'does not highlight binary files' do - allow_any_instance_of(Gitlab::Diff::File).to receive(:blob).and_return(double("text?" => false)) - - expect_any_instance_of(Gitlab::Diff::File).not_to receive(:highlighted_diff_lines) - - diff_files - end - - it 'does not highlight file if blob is not accessable' do - allow_any_instance_of(Gitlab::Diff::File).to receive(:blob).and_return(nil) + allow_any_instance_of(Gitlab::Diff::File).to receive(:text?).and_return(false) expect_any_instance_of(Gitlab::Diff::File).not_to receive(:highlighted_diff_lines) @@ -21,7 +13,7 @@ describe Gitlab::Diff::FileCollection::MergeRequestDiff do end it 'does not files marked as undiffable in .gitattributes' do - allow_any_instance_of(Repository).to receive(:diffable?).and_return(false) + allow_any_instance_of(Gitlab::Diff::File).to receive(:diffable?).and_return(false) expect_any_instance_of(Gitlab::Diff::File).not_to receive(:highlighted_diff_lines) diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb index 050689b7c9a..f289131cc3a 100644 --- a/spec/lib/gitlab/diff/file_spec.rb +++ b/spec/lib/gitlab/diff/file_spec.rb @@ -6,7 +6,7 @@ describe Gitlab::Diff::File, lib: true do let(:project) { create(:project, :repository) } let(:commit) { project.commit(sample_commit.id) } let(:diff) { commit.raw_diffs.first } - let(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs: commit.diff_refs, repository: project.repository) } + let(:diff_file) { described_class.new(diff, diff_refs: commit.diff_refs, repository: project.repository) } describe '#diff_lines' do let(:diff_lines) { diff_file.diff_lines } @@ -63,11 +63,334 @@ describe Gitlab::Diff::File, lib: true do end end - describe '#blob' do + describe '#new_blob' do it 'returns blob of new commit' do - data = diff_file.blob.data + data = diff_file.new_blob.data expect(data).to include('raise RuntimeError, "System commands must be given as an array of strings"') end end + + describe '#diffable?' do + let(:commit) { project.commit('1a0b36b3cdad1d2ee32457c102a8c0b7056fa863') } + let(:diffs) { commit.diffs } + + before do + info_dir_path = File.join(project.repository.path_to_repo, 'info') + + FileUtils.mkdir(info_dir_path) unless File.exist?(info_dir_path) + File.write(File.join(info_dir_path, 'attributes'), "*.md -diff\n") + end + + it "returns true for files that do not have attributes" do + diff_file = diffs.diff_file_with_new_path('LICENSE') + expect(diff_file.diffable?).to be_truthy + end + + it "returns false for files that have been marked as not being diffable in attributes" do + diff_file = diffs.diff_file_with_new_path('README.md') + expect(diff_file.diffable?).to be_falsey + end + end + + describe '#content_changed?' do + context 'when created' do + let(:commit) { project.commit('33f3729a45c02fc67d00adb1b8bca394b0e761d9') } + let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') } + + it 'returns false' do + expect(diff_file.content_changed?).to be_falsey + end + end + + context 'when deleted' do + let(:commit) { project.commit('d59c60028b053793cecfb4022de34602e1a9218e') } + let(:diff_file) { commit.diffs.diff_file_with_old_path('files/js/commit.js.coffee') } + + it 'returns false' do + expect(diff_file.content_changed?).to be_falsey + end + end + + context 'when renamed' do + let(:commit) { project.commit('6907208d755b60ebeacb2e9dfea74c92c3449a1f') } + let(:diff_file) { commit.diffs.diff_file_with_new_path('files/js/commit.coffee') } + + before do + allow(diff_file.new_blob).to receive(:id).and_return(diff_file.old_blob.id) + end + + it 'returns false' do + expect(diff_file.content_changed?).to be_falsey + end + end + + context 'when content changed' do + context 'when binary' do + let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') } + let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') } + + it 'returns true' do + expect(diff_file.content_changed?).to be_truthy + end + end + + context 'when not binary' do + let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') } + let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') } + + it 'returns true' do + expect(diff_file.content_changed?).to be_truthy + end + end + end + end + + describe '#simple_viewer' do + context 'when the file is not diffable' do + before do + allow(diff_file).to receive(:diffable?).and_return(false) + end + + it 'returns a Not Diffable viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::NotDiffable) + end + end + + context 'when the content changed' do + context 'when the file represented by the diff file is binary' do + before do + allow(diff_file).to receive(:raw_binary?).and_return(true) + end + + it 'returns a No Preview viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::NoPreview) + end + end + + context 'when the diff file old and new blob types are different' do + before do + allow(diff_file).to receive(:different_type?).and_return(true) + end + + it 'returns a No Preview viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::NoPreview) + end + end + + context 'when the file represented by the diff file is text-based' do + it 'returns a text viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::Text) + end + end + end + + context 'when created' do + let(:commit) { project.commit('913c66a37b4a45b9769037c55c2d238bd0942d2e') } + let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') } + + before do + allow(diff_file).to receive(:content_changed?).and_return(nil) + end + + context 'when the file represented by the diff file is binary' do + before do + allow(diff_file).to receive(:raw_binary?).and_return(true) + end + + it 'returns an Added viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::Added) + end + end + + context 'when the diff file old and new blob types are different' do + before do + allow(diff_file).to receive(:different_type?).and_return(true) + end + + it 'returns an Added viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::Added) + end + end + + context 'when the file represented by the diff file is text-based' do + it 'returns a text viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::Text) + end + end + end + + context 'when deleted' do + let(:commit) { project.commit('d59c60028b053793cecfb4022de34602e1a9218e') } + let(:diff_file) { commit.diffs.diff_file_with_old_path('files/js/commit.js.coffee') } + + before do + allow(diff_file).to receive(:content_changed?).and_return(nil) + end + + context 'when the file represented by the diff file is binary' do + before do + allow(diff_file).to receive(:raw_binary?).and_return(true) + end + + it 'returns a Deleted viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::Deleted) + end + end + + context 'when the diff file old and new blob types are different' do + before do + allow(diff_file).to receive(:different_type?).and_return(true) + end + + it 'returns a Deleted viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::Deleted) + end + end + + context 'when the file represented by the diff file is text-based' do + it 'returns a text viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::Text) + end + end + end + + context 'when renamed' do + let(:commit) { project.commit('6907208d755b60ebeacb2e9dfea74c92c3449a1f') } + let(:diff_file) { commit.diffs.diff_file_with_new_path('files/js/commit.coffee') } + + before do + allow(diff_file).to receive(:content_changed?).and_return(nil) + end + + it 'returns a Renamed viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::Renamed) + end + end + + context 'when mode changed' do + before do + allow(diff_file).to receive(:content_changed?).and_return(nil) + allow(diff_file).to receive(:mode_changed?).and_return(true) + end + + it 'returns a Mode Changed viewer' do + expect(diff_file.simple_viewer).to be_a(DiffViewer::ModeChanged) + end + end + end + + describe '#rich_viewer' do + let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') } + let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') } + + context 'when the diff file has a matching viewer' do + context 'when the diff file content did not change' do + before do + allow(diff_file).to receive(:content_changed?).and_return(false) + end + + it 'returns nil' do + expect(diff_file.rich_viewer).to be_nil + end + end + + context 'when the diff file is not diffable' do + before do + allow(diff_file).to receive(:diffable?).and_return(false) + end + + it 'returns nil' do + expect(diff_file.rich_viewer).to be_nil + end + end + + context 'when the diff file old and new blob types are different' do + before do + allow(diff_file).to receive(:different_type?).and_return(true) + end + + it 'returns nil' do + expect(diff_file.rich_viewer).to be_nil + end + end + + context 'when the diff file has an external storage error' do + before do + allow(diff_file).to receive(:external_storage_error?).and_return(true) + end + + it 'returns nil' do + expect(diff_file.rich_viewer).to be_nil + end + end + + context 'when everything is right' do + it 'returns the viewer' do + expect(diff_file.rich_viewer).to be_a(DiffViewer::Image) + end + end + end + + context 'when the diff file does not have a matching viewer' do + let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') } + let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') } + + it 'returns nil' do + expect(diff_file.rich_viewer).to be_nil + end + end + end + + describe '#rendered_as_text?' do + context 'when the simple viewer is text-based' do + let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') } + let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') } + + context 'when ignoring errors' do + context 'when the viewer has render errors' do + before do + diff_file.diff.too_large! + end + + it 'returns true' do + expect(diff_file.rendered_as_text?).to be_truthy + end + end + + context "when the viewer doesn't have render errors" do + it 'returns true' do + expect(diff_file.rendered_as_text?).to be_truthy + end + end + end + + context 'when not ignoring errors' do + context 'when the viewer has render errors' do + before do + diff_file.diff.too_large! + end + + it 'returns false' do + expect(diff_file.rendered_as_text?(ignore_errors: false)).to be_falsey + end + end + + context "when the viewer doesn't have render errors" do + it 'returns true' do + expect(diff_file.rendered_as_text?(ignore_errors: false)).to be_truthy + end + end + end + end + + context 'when the simple viewer is binary' do + let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') } + let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') } + + it 'returns false' do + expect(diff_file.rendered_as_text?).to be_falsey + end + end + end end diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb index 7095104d75c..b3d46e69ccb 100644 --- a/spec/lib/gitlab/diff/position_spec.rb +++ b/spec/lib/gitlab/diff/position_spec.rb @@ -381,6 +381,54 @@ describe Gitlab::Diff::Position, lib: true do end end + describe "position for a file in a straight comparison" do + let(:diff_refs) do + Gitlab::Diff::DiffRefs.new( + start_sha: '0b4bc9a49b562e85de7cc9e834518ea6828729b9', # feature + base_sha: '0b4bc9a49b562e85de7cc9e834518ea6828729b9', + head_sha: 'e63f41fe459e62e1228fcef60d7189127aeba95a' # master + ) + end + + subject do + described_class.new( + old_path: "files/ruby/feature.rb", + new_path: "files/ruby/feature.rb", + old_line: 3, + new_line: nil, + diff_refs: diff_refs + ) + end + + describe "#diff_file" do + it "returns the correct diff file" do + diff_file = subject.diff_file(project.repository) + + expect(diff_file.deleted_file?).to be true + expect(diff_file.old_path).to eq(subject.old_path) + expect(diff_file.diff_refs).to eq(subject.diff_refs) + end + end + + describe "#diff_line" do + it "returns the correct diff line" do + diff_line = subject.diff_line(project.repository) + + expect(diff_line.removed?).to be true + expect(diff_line.old_line).to eq(subject.old_line) + expect(diff_line.text).to eq("- puts 'bar'") + end + end + + describe "#line_code" do + it "returns the correct line code" do + line_code = Gitlab::Diff::LineCode.generate(subject.file_path, 0, subject.old_line) + + expect(subject.line_code(project.repository)).to eq(line_code) + end + end + end + describe "#to_json" do let(:hash) do { diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb index 24df04e985a..4acf4f047f1 100644 --- a/spec/lib/gitlab/etag_caching/middleware_spec.rb +++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb @@ -15,13 +15,13 @@ describe Gitlab::EtagCaching::Middleware do end it 'does not add ETag header' do - _, headers, _ = middleware.call(build_env(path, if_none_match)) + _, headers, _ = middleware.call(build_request(path, if_none_match)) expect(headers['ETag']).to be_nil end it 'passes status code from app' do - status, _, _ = middleware.call(build_env(path, if_none_match)) + status, _, _ = middleware.call(build_request(path, if_none_match)) expect(status).to eq app_status_code end @@ -39,7 +39,7 @@ describe Gitlab::EtagCaching::Middleware do expect_any_instance_of(Gitlab::EtagCaching::Store) .to receive(:touch).and_return('123') - middleware.call(build_env(path, if_none_match)) + middleware.call(build_request(path, if_none_match)) end context 'when If-None-Match header was specified' do @@ -51,7 +51,7 @@ describe Gitlab::EtagCaching::Middleware do expect(Gitlab::Metrics).to receive(:add_event) .with(:etag_caching_key_not_found, endpoint: 'issue_notes') - middleware.call(build_env(path, if_none_match)) + middleware.call(build_request(path, if_none_match)) end end end @@ -65,7 +65,7 @@ describe Gitlab::EtagCaching::Middleware do end it 'returns this value as header' do - _, headers, _ = middleware.call(build_env(path, if_none_match)) + _, headers, _ = middleware.call(build_request(path, if_none_match)) expect(headers['ETag']).to eq 'W/"123"' end @@ -82,17 +82,17 @@ describe Gitlab::EtagCaching::Middleware do it 'does not call app' do expect(app).not_to receive(:call) - middleware.call(build_env(path, if_none_match)) + middleware.call(build_request(path, if_none_match)) end it 'returns status code 304' do - status, _, _ = middleware.call(build_env(path, if_none_match)) + status, _, _ = middleware.call(build_request(path, if_none_match)) expect(status).to eq 304 end it 'returns empty body' do - _, _, body = middleware.call(build_env(path, if_none_match)) + _, _, body = middleware.call(build_request(path, if_none_match)) expect(body).to be_empty end @@ -103,7 +103,7 @@ describe Gitlab::EtagCaching::Middleware do expect(Gitlab::Metrics).to receive(:add_event) .with(:etag_caching_cache_hit, endpoint: 'issue_notes') - middleware.call(build_env(path, if_none_match)) + middleware.call(build_request(path, if_none_match)) end context 'when polling is disabled' do @@ -113,7 +113,7 @@ describe Gitlab::EtagCaching::Middleware do end it 'returns status code 429' do - status, _, _ = middleware.call(build_env(path, if_none_match)) + status, _, _ = middleware.call(build_request(path, if_none_match)) expect(status).to eq 429 end @@ -131,7 +131,7 @@ describe Gitlab::EtagCaching::Middleware do it 'calls app' do expect(app).to receive(:call).and_return([app_status_code, {}, ['body']]) - middleware.call(build_env(path, if_none_match)) + middleware.call(build_request(path, if_none_match)) end it 'tracks "etag_caching_resource_changed" event' do @@ -142,7 +142,7 @@ describe Gitlab::EtagCaching::Middleware do expect(Gitlab::Metrics).to receive(:add_event) .with(:etag_caching_resource_changed, endpoint: 'issue_notes') - middleware.call(build_env(path, if_none_match)) + middleware.call(build_request(path, if_none_match)) end end @@ -160,7 +160,26 @@ describe Gitlab::EtagCaching::Middleware do expect(Gitlab::Metrics).to receive(:add_event) .with(:etag_caching_header_missing, endpoint: 'issue_notes') - middleware.call(build_env(path, if_none_match)) + middleware.call(build_request(path, if_none_match)) + end + end + + context 'when GitLab instance is using a relative URL' do + before do + mock_app_response + end + + it 'uses full path as cache key' do + env = { + 'PATH_INFO' => enabled_path, + 'SCRIPT_NAME' => '/relative-gitlab' + } + + expect_any_instance_of(Gitlab::EtagCaching::Store) + .to receive(:get).with("/relative-gitlab#{enabled_path}") + .and_return(nil) + + middleware.call(env) end end @@ -173,10 +192,7 @@ describe Gitlab::EtagCaching::Middleware do .to receive(:get).and_return(value) end - def build_env(path, if_none_match) - { - 'PATH_INFO' => path, - 'HTTP_IF_NONE_MATCH' => if_none_match - } + def build_request(path, if_none_match) + { 'PATH_INFO' => path, 'HTTP_IF_NONE_MATCH' => if_none_match } end end diff --git a/spec/lib/gitlab/etag_caching/router_spec.rb b/spec/lib/gitlab/etag_caching/router_spec.rb index 269798c7c9e..f69cb502ca6 100644 --- a/spec/lib/gitlab/etag_caching/router_spec.rb +++ b/spec/lib/gitlab/etag_caching/router_spec.rb @@ -2,115 +2,91 @@ require 'spec_helper' describe Gitlab::EtagCaching::Router do it 'matches issue notes endpoint' do - env = build_env( + result = described_class.match( '/my-group/and-subgroup/here-comes-the-project/noteable/issue/1/notes' ) - result = described_class.match(env) - expect(result).to be_present expect(result.name).to eq 'issue_notes' end it 'matches issue title endpoint' do - env = build_env( + result = described_class.match( '/my-group/my-project/issues/123/realtime_changes' ) - result = described_class.match(env) - expect(result).to be_present expect(result.name).to eq 'issue_title' end it 'matches project pipelines endpoint' do - env = build_env( + result = described_class.match( '/my-group/my-project/pipelines.json' ) - result = described_class.match(env) - expect(result).to be_present expect(result.name).to eq 'project_pipelines' end it 'matches commit pipelines endpoint' do - env = build_env( + result = described_class.match( '/my-group/my-project/commit/aa8260d253a53f73f6c26c734c72fdd600f6e6d4/pipelines.json' ) - result = described_class.match(env) - expect(result).to be_present expect(result.name).to eq 'commit_pipelines' end it 'matches new merge request pipelines endpoint' do - env = build_env( + result = described_class.match( '/my-group/my-project/merge_requests/new.json' ) - result = described_class.match(env) - expect(result).to be_present expect(result.name).to eq 'new_merge_request_pipelines' end it 'matches merge request pipelines endpoint' do - env = build_env( + result = described_class.match( '/my-group/my-project/merge_requests/234/pipelines.json' ) - result = described_class.match(env) - expect(result).to be_present expect(result.name).to eq 'merge_request_pipelines' end it 'matches build endpoint' do - env = build_env( + result = described_class.match( '/my-group/my-project/builds/234.json' ) - result = described_class.match(env) - expect(result).to be_present expect(result.name).to eq 'project_build' end it 'does not match blob with confusing name' do - env = build_env( + result = described_class.match( '/my-group/my-project/blob/master/pipelines.json' ) - result = described_class.match(env) - expect(result).to be_blank end it 'matches the environments path' do - env = build_env( + result = described_class.match( '/my-group/my-project/environments.json' ) - result = described_class.match(env) expect(result).to be_present - expect(result.name).to eq 'environments' end it 'matches pipeline#show endpoint' do - env = build_env( + result = described_class.match( '/my-group/my-project/pipelines/2.json' ) - result = described_class.match(env) - expect(result).to be_present expect(result.name).to eq 'project_pipeline' end - - def build_env(path) - { 'PATH_INFO' => path } - end end diff --git a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb index 5d416c9eec3..eaec699ad90 100644 --- a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb +++ b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb @@ -6,7 +6,9 @@ describe Gitlab::Gfm::ReferenceRewriter do let(:new_project) { create(:empty_project, name: 'new-project') } let(:user) { create(:user) } - before { old_project.team << [user, :reporter] } + before do + old_project.team << [user, :reporter] + end describe '#rewrite' do subject do diff --git a/spec/lib/gitlab/git/compare_spec.rb b/spec/lib/gitlab/git/compare_spec.rb index 7c45071ec45..4c9f4a28f32 100644 --- a/spec/lib/gitlab/git/compare_spec.rb +++ b/spec/lib/gitlab/git/compare_spec.rb @@ -2,8 +2,8 @@ require "spec_helper" describe Gitlab::Git::Compare, seed_helper: true do let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } - let(:compare) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, false) } - let(:compare_straight) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, true) } + let(:compare) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, straight: false) } + let(:compare_straight) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, straight: true) } describe '#commits' do subject do diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 26215381cc4..eee4c9eab6d 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -16,7 +16,9 @@ describe Gitlab::Git::Repository, seed_helper: true do describe '#root_ref' do context 'with gitaly disabled' do - before { allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(false) } + before do + allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(false) + end it 'calls #discover_default_branch' do expect(repository).to receive(:discover_default_branch) @@ -25,8 +27,13 @@ describe Gitlab::Git::Repository, seed_helper: true do end context 'with gitaly enabled' do - before { stub_gitaly } - after { Gitlab::GitalyClient.clear_stubs! } + before do + stub_gitaly + end + + after do + Gitlab::GitalyClient.clear_stubs! + end it 'gets the branch name from GitalyClient' do expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name) @@ -120,8 +127,13 @@ describe Gitlab::Git::Repository, seed_helper: true do it { is_expected.not_to include("branch-from-space") } context 'with gitaly enabled' do - before { stub_gitaly } - after { Gitlab::GitalyClient.clear_stubs! } + before do + stub_gitaly + end + + after do + Gitlab::GitalyClient.clear_stubs! + end it 'gets the branch names from GitalyClient' do expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names) @@ -158,8 +170,13 @@ describe Gitlab::Git::Repository, seed_helper: true do it { is_expected.not_to include("v5.0.0") } context 'with gitaly enabled' do - before { stub_gitaly } - after { Gitlab::GitalyClient.clear_stubs! } + before do + stub_gitaly + end + + after do + Gitlab::GitalyClient.clear_stubs! + end it 'gets the tag names from GitalyClient' do expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names) @@ -1235,47 +1252,6 @@ describe Gitlab::Git::Repository, seed_helper: true do end end - describe '#diffable' do - info_dir_path = attributes_path = File.join(SEED_STORAGE_PATH, TEST_REPO_PATH, 'info') - attributes_path = File.join(info_dir_path, 'attributes') - - before(:all) do - FileUtils.mkdir(info_dir_path) unless File.exist?(info_dir_path) - File.write(attributes_path, "*.md -diff\n") - end - - it "should return true for files which are text and do not have attributes" do - blob = Gitlab::Git::Blob.find( - repository, - '33bcff41c232a11727ac6d660bd4b0c2ba86d63d', - 'LICENSE' - ) - expect(repository.diffable?(blob)).to be_truthy - end - - it "should return false for binary files which do not have attributes" do - blob = Gitlab::Git::Blob.find( - repository, - '33bcff41c232a11727ac6d660bd4b0c2ba86d63d', - 'files/images/logo-white.png' - ) - expect(repository.diffable?(blob)).to be_falsey - end - - it "should return false for text files which have been marked as not being diffable in attributes" do - blob = Gitlab::Git::Blob.find( - repository, - '33bcff41c232a11727ac6d660bd4b0c2ba86d63d', - 'README.md' - ) - expect(repository.diffable?(blob)).to be_falsey - end - - after(:all) do - FileUtils.rm_rf(info_dir_path) - end - end - describe '#tag_exists?' do it 'returns true for an existing tag' do tag = repository.tag_names.first @@ -1321,8 +1297,13 @@ describe Gitlab::Git::Repository, seed_helper: true do end context 'with gitaly enabled' do - before { stub_gitaly } - after { Gitlab::GitalyClient.clear_stubs! } + before do + stub_gitaly + end + + after do + Gitlab::GitalyClient.clear_stubs! + end it 'gets the branches from GitalyClient' do expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches). diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index 36d1d777583..3dcc20c48e8 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -60,7 +60,9 @@ describe Gitlab::GitAccess, lib: true do let(:actor) { deploy_key } context 'when the DeployKey has access to the project' do - before { deploy_key.projects << project } + before do + deploy_key.projects << project + end it 'allows pull access' do expect { pull_access_check }.not_to raise_error @@ -84,7 +86,9 @@ describe Gitlab::GitAccess, lib: true do context 'when actor is a User' do context 'when the User can read the project' do - before { project.team << [user, :master] } + before do + project.team << [user, :master] + end it 'allows pull access' do expect { pull_access_check }.not_to raise_error @@ -159,7 +163,9 @@ describe Gitlab::GitAccess, lib: true do end describe '#check_command_disabled!' do - before { project.team << [user, :master] } + before do + project.team << [user, :master] + end context 'over http' do let(:protocol) { 'http' } @@ -196,7 +202,9 @@ describe Gitlab::GitAccess, lib: true do describe '#check_download_access!' do describe 'master permissions' do - before { project.team << [user, :master] } + before do + project.team << [user, :master] + end context 'pull code' do it { expect { pull_access_check }.not_to raise_error } @@ -204,7 +212,9 @@ describe Gitlab::GitAccess, lib: true do end describe 'guest permissions' do - before { project.team << [user, :guest] } + before do + project.team << [user, :guest] + end context 'pull code' do it { expect { pull_access_check }.to raise_unauthorized('You are not allowed to download code from this project.') } @@ -253,7 +263,9 @@ describe Gitlab::GitAccess, lib: true do context 'pull code' do context 'when project is authorized' do - before { key.projects << project } + before do + key.projects << project + end it { expect { pull_access_check }.not_to raise_error } end @@ -292,7 +304,9 @@ describe Gitlab::GitAccess, lib: true do end describe 'reporter user' do - before { project.team << [user, :reporter] } + before do + project.team << [user, :reporter] + end context 'pull code' do it { expect { pull_access_check }.not_to raise_error } @@ -303,7 +317,9 @@ describe Gitlab::GitAccess, lib: true do let(:user) { create(:admin) } context 'when member of the project' do - before { project.team << [user, :reporter] } + before do + project.team << [user, :reporter] + end context 'pull code' do it { expect { pull_access_check }.not_to raise_error } @@ -328,7 +344,9 @@ describe Gitlab::GitAccess, lib: true do end describe '#check_push_access!' do - before { merge_into_protected_branch } + before do + merge_into_protected_branch + end let(:unprotected_branch) { 'unprotected_branch' } let(:changes) do @@ -457,19 +475,25 @@ describe Gitlab::GitAccess, lib: true do [%w(feature exact), ['feat*', 'wildcard']].each do |protected_branch_name, protected_branch_type| context do - before { create(:protected_branch, name: protected_branch_name, project: project) } + before do + create(:protected_branch, name: protected_branch_name, project: project) + end run_permission_checks(permissions_matrix) end context "when developers are allowed to push into the #{protected_branch_type} protected branch" do - before { create(:protected_branch, :developers_can_push, name: protected_branch_name, project: project) } + before do + create(:protected_branch, :developers_can_push, name: protected_branch_name, project: project) + end run_permission_checks(permissions_matrix.deep_merge(developer: { push_protected_branch: true, push_all: true, merge_into_protected_branch: true })) end context "developers are allowed to merge into the #{protected_branch_type} protected branch" do - before { create(:protected_branch, :developers_can_merge, name: protected_branch_name, project: project) } + before do + create(:protected_branch, :developers_can_merge, name: protected_branch_name, project: project) + end context "when a merge request exists for the given source/target branch" do context "when the merge request is in progress" do @@ -496,13 +520,17 @@ describe Gitlab::GitAccess, lib: true do end context "when developers are allowed to push and merge into the #{protected_branch_type} protected branch" do - before { create(:protected_branch, :developers_can_merge, :developers_can_push, name: protected_branch_name, project: project) } + before do + create(:protected_branch, :developers_can_merge, :developers_can_push, name: protected_branch_name, project: project) + end run_permission_checks(permissions_matrix.deep_merge(developer: { push_protected_branch: true, push_all: true, merge_into_protected_branch: true })) end context "when no one is allowed to push to the #{protected_branch_name} protected branch" do - before { create(:protected_branch, :no_one_can_push, name: protected_branch_name, project: project) } + before do + create(:protected_branch, :no_one_can_push, name: protected_branch_name, project: project) + end run_permission_checks(permissions_matrix.deep_merge(developer: { push_protected_branch: false, push_all: false, merge_into_protected_branch: false }, master: { push_protected_branch: false, push_all: false, merge_into_protected_branch: false }, @@ -515,7 +543,9 @@ describe Gitlab::GitAccess, lib: true do let(:authentication_abilities) { build_authentication_abilities } context 'when project is authorized' do - before { project.team << [user, :reporter] } + before do + project.team << [user, :reporter] + end it { expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.') } end @@ -549,7 +579,9 @@ describe Gitlab::GitAccess, lib: true do let(:can_push) { true } context 'when project is authorized' do - before { key.projects << project } + before do + key.projects << project + end it { expect { push_access_check }.not_to raise_error } end @@ -579,7 +611,9 @@ describe Gitlab::GitAccess, lib: true do let(:can_push) { false } context 'when project is authorized' do - before { key.projects << project } + before do + key.projects << project + end it { expect { push_access_check }.to raise_unauthorized('This deploy key does not have write access to this project.') } end diff --git a/spec/lib/gitlab/gitaly_client/notifications_spec.rb b/spec/lib/gitlab/gitaly_client/notifications_spec.rb index b87dacb175b..e5c9e06a15e 100644 --- a/spec/lib/gitlab/gitaly_client/notifications_spec.rb +++ b/spec/lib/gitlab/gitaly_client/notifications_spec.rb @@ -3,12 +3,13 @@ require 'spec_helper' describe Gitlab::GitalyClient::Notifications do describe '#post_receive' do let(:project) { create(:empty_project) } - let(:repo_path) { project.repository.path_to_repo } + let(:storage_name) { project.repository_storage } + let(:relative_path) { project.path_with_namespace + '.git' } subject { described_class.new(project.repository) } it 'sends a post_receive message' do expect_any_instance_of(Gitaly::Notifications::Stub). - to receive(:post_receive).with(gitaly_request_with_repo_path(repo_path)) + to receive(:post_receive).with(gitaly_request_with_path(storage_name, relative_path)) subject.post_receive end diff --git a/spec/lib/gitlab/gitaly_client/ref_spec.rb b/spec/lib/gitlab/gitaly_client/ref_spec.rb index d8cd2dcbd2a..2ea44ef74b0 100644 --- a/spec/lib/gitlab/gitaly_client/ref_spec.rb +++ b/spec/lib/gitlab/gitaly_client/ref_spec.rb @@ -2,7 +2,8 @@ require 'spec_helper' describe Gitlab::GitalyClient::Ref do let(:project) { create(:empty_project) } - let(:repo_path) { project.repository.path_to_repo } + let(:storage_name) { project.repository_storage } + let(:relative_path) { project.path_with_namespace + '.git' } let(:client) { described_class.new(project.repository) } before do @@ -19,7 +20,8 @@ describe Gitlab::GitalyClient::Ref do describe '#branch_names' do it 'sends a find_all_branch_names message' do expect_any_instance_of(Gitaly::Ref::Stub). - to receive(:find_all_branch_names).with(gitaly_request_with_repo_path(repo_path)). + to receive(:find_all_branch_names). + with(gitaly_request_with_path(storage_name, relative_path)). and_return([]) client.branch_names @@ -29,7 +31,8 @@ describe Gitlab::GitalyClient::Ref do describe '#tag_names' do it 'sends a find_all_tag_names message' do expect_any_instance_of(Gitaly::Ref::Stub). - to receive(:find_all_tag_names).with(gitaly_request_with_repo_path(repo_path)). + to receive(:find_all_tag_names). + with(gitaly_request_with_path(storage_name, relative_path)). and_return([]) client.tag_names @@ -39,7 +42,8 @@ describe Gitlab::GitalyClient::Ref do describe '#default_branch_name' do it 'sends a find_default_branch_name message' do expect_any_instance_of(Gitaly::Ref::Stub). - to receive(:find_default_branch_name).with(gitaly_request_with_repo_path(repo_path)). + to receive(:find_default_branch_name). + with(gitaly_request_with_path(storage_name, relative_path)). and_return(double(name: 'foo')) client.default_branch_name @@ -49,7 +53,8 @@ describe Gitlab::GitalyClient::Ref do describe '#local_branches' do it 'sends a find_local_branches message' do expect_any_instance_of(Gitaly::Ref::Stub). - to receive(:find_local_branches).with(gitaly_request_with_repo_path(repo_path)). + to receive(:find_local_branches). + with(gitaly_request_with_path(storage_name, relative_path)). and_return([]) client.local_branches diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb index 95ecba67532..ce7b18b784a 100644 --- a/spec/lib/gitlab/gitaly_client_spec.rb +++ b/spec/lib/gitlab/gitaly_client_spec.rb @@ -5,7 +5,9 @@ require 'spec_helper' describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do describe '.stub' do # Notice that this is referring to gRPC "stubs", not rspec stubs - before { described_class.clear_stubs! } + before do + described_class.clear_stubs! + end context 'when passed a UNIX socket address' do it 'passes the address as-is to GRPC' do @@ -41,7 +43,9 @@ describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do let(:real_feature_name) { "gitaly_#{feature_name}" } context 'when Gitaly is disabled' do - before { allow(described_class).to receive(:enabled?).and_return(false) } + before do + allow(described_class).to receive(:enabled?).and_return(false) + end it 'returns false' do expect(described_class.feature_enabled?(feature_name)).to be(false) @@ -66,7 +70,9 @@ describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do end context "when the feature flag is set to disable" do - before { Feature.get(real_feature_name).disable } + before do + Feature.get(real_feature_name).disable + end it 'returns false' do expect(described_class.feature_enabled?(feature_name, status: feature_status)).to be(false) @@ -74,7 +80,9 @@ describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do end context "when the feature flag is set to enable" do - before { Feature.get(real_feature_name).enable } + before do + Feature.get(real_feature_name).enable + end it 'returns true' do expect(described_class.feature_enabled?(feature_name, status: feature_status)).to be(true) @@ -82,7 +90,9 @@ describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do end context "when the feature flag is set to a percentage of time" do - before { Feature.get(real_feature_name).enable_percentage_of_time(70) } + before do + Feature.get(real_feature_name).enable_percentage_of_time(70) + end it 'bases the result on pseudo-random numbers' do expect(Random).to receive(:rand).and_return(0.3) @@ -104,7 +114,9 @@ describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do end context "when the feature flag is set to disable" do - before { Feature.get(real_feature_name).disable } + before do + Feature.get(real_feature_name).disable + end it 'returns false' do expect(described_class.feature_enabled?(feature_name, status: feature_status)).to be(false) diff --git a/spec/lib/gitlab/health_checks/prometheus_text_format_spec.rb b/spec/lib/gitlab/health_checks/prometheus_text_format_spec.rb new file mode 100644 index 00000000000..ed757ed60d8 --- /dev/null +++ b/spec/lib/gitlab/health_checks/prometheus_text_format_spec.rb @@ -0,0 +1,41 @@ +describe Gitlab::HealthChecks::PrometheusTextFormat do + let(:metric_class) { Gitlab::HealthChecks::Metric } + subject { described_class.new } + + describe '#marshal' do + let(:sample_metrics) do + [metric_class.new('metric1', 1), + metric_class.new('metric2', 2)] + end + + it 'marshal to text with non repeating type definition' do + expected = <<-EXPECTED.strip_heredoc + # TYPE metric1 gauge + metric1 1 + # TYPE metric2 gauge + metric2 2 + EXPECTED + + expect(subject.marshal(sample_metrics)).to eq(expected) + end + + context 'metrics where name repeats' do + let(:sample_metrics) do + [metric_class.new('metric1', 1), + metric_class.new('metric1', 2), + metric_class.new('metric2', 3)] + end + + it 'marshal to text with non repeating type definition' do + expected = <<-EXPECTED.strip_heredoc + # TYPE metric1 gauge + metric1 1 + metric1 2 + # TYPE metric2 gauge + metric2 3 + EXPECTED + expect(subject.marshal(sample_metrics)).to eq(expected) + end + end + end +end diff --git a/spec/lib/gitlab/highlight_spec.rb b/spec/lib/gitlab/highlight_spec.rb index a20cef3b000..fdc5b484ef1 100644 --- a/spec/lib/gitlab/highlight_spec.rb +++ b/spec/lib/gitlab/highlight_spec.rb @@ -7,30 +7,6 @@ describe Gitlab::Highlight, lib: true do let(:repository) { project.repository } let(:commit) { project.commit(sample_commit.id) } - describe '.highlight_lines' do - let(:lines) do - Gitlab::Highlight.highlight_lines(project.repository, commit.id, 'files/ruby/popen.rb') - end - - it 'highlights all the lines properly' do - expect(lines[4]).to eq(%Q{<span id="LC5" class="line" lang="ruby"> <span class="kp">extend</span> <span class="nb">self</span></span>\n}) - expect(lines[21]).to eq(%Q{<span id="LC22" class="line" lang="ruby"> <span class="k">unless</span> <span class="no">File</span><span class="p">.</span><span class="nf">directory?</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></span>\n}) - expect(lines[26]).to eq(%Q{<span id="LC27" class="line" lang="ruby"> <span class="vi">@cmd_status</span> <span class="o">=</span> <span class="mi">0</span></span>\n}) - end - - describe 'with CRLF' do - let(:branch) { 'crlf-diff' } - let(:blob) { repository.blob_at_branch(branch, path) } - let(:lines) do - Gitlab::Highlight.highlight_lines(project.repository, 'crlf-diff', 'files/whitespace') - end - - it 'strips extra LFs' do - expect(lines[0]).to eq("<span id=\"LC1\" class=\"line\" lang=\"plaintext\">test </span>") - end - end - end - describe 'custom highlighting from .gitattributes' do let(:branch) { 'gitattributes' } let(:blob) { repository.blob_at_branch(branch, path) } @@ -39,7 +15,9 @@ describe Gitlab::Highlight, lib: true do Gitlab::Highlight.new(blob.path, blob.data, repository: repository) end - before { project.change_head('gitattributes') } + before do + project.change_head('gitattributes') + end describe 'basic language selection' do let(:path) { 'custom-highlighting/test.gitlab-custom' } @@ -59,6 +37,19 @@ describe Gitlab::Highlight, lib: true do end describe '#highlight' do + describe 'with CRLF' do + let(:branch) { 'crlf-diff' } + let(:path) { 'files/whitespace' } + let(:blob) { repository.blob_at_branch(branch, path) } + let(:lines) do + Gitlab::Highlight.highlight(blob.path, blob.data, repository: repository).lines + end + + it 'strips extra LFs' do + expect(lines[0]).to eq("<span id=\"LC1\" class=\"line\" lang=\"plaintext\">test </span>") + end + end + it 'links dependencies via DependencyLinker' do expect(Gitlab::DependencyLinker).to receive(:link). with('file.name', 'Contents', anything).and_call_original diff --git a/spec/lib/gitlab/i18n_spec.rb b/spec/lib/gitlab/i18n_spec.rb index a3dbeaa3753..0dba4132101 100644 --- a/spec/lib/gitlab/i18n_spec.rb +++ b/spec/lib/gitlab/i18n_spec.rb @@ -4,7 +4,9 @@ describe Gitlab::I18n, lib: true do let(:user) { create(:user, preferred_language: 'es') } describe '.locale=' do - after { described_class.use_default_locale } + after do + described_class.use_default_locale + end it 'sets the locale based on current user preferred language' do described_class.locale = user.preferred_language diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 21296a36729..412eb33b35b 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -91,6 +91,7 @@ merge_request_diff: pipelines: - project - user +- stages - statuses - builds - trigger_requests @@ -104,9 +105,15 @@ pipelines: - artifacts - pipeline_schedule - merge_requests +stages: +- project +- pipeline +- statuses +- builds statuses: - project - pipeline +- stage - user - auto_canceled_by variables: diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index 54ce8051f30..50ff6ecc1e0 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -92,6 +92,7 @@ Milestone: ProjectSnippet: - id - title +- description - content - author_id - project_id @@ -174,6 +175,7 @@ MergeRequestDiff: Ci::Pipeline: - id - project_id +- source - ref - sha - before_sha @@ -191,7 +193,13 @@ Ci::Pipeline: - lock_version - auto_canceled_by_id - pipeline_schedule_id -- source +Ci::Stage: +- id +- name +- project_id +- pipeline_id +- created_at +- updated_at CommitStatus: - id - project_id @@ -213,6 +221,7 @@ CommitStatus: - stage - trigger_request_id - stage_idx +- stage_id - tag - ref - user_id diff --git a/spec/lib/gitlab/kubernetes_spec.rb b/spec/lib/gitlab/kubernetes_spec.rb index 91f9d06b85a..e8c599a95ee 100644 --- a/spec/lib/gitlab/kubernetes_spec.rb +++ b/spec/lib/gitlab/kubernetes_spec.rb @@ -1,6 +1,7 @@ require 'spec_helper' describe Gitlab::Kubernetes do + include KubernetesHelpers include described_class describe '#container_exec_url' do @@ -36,4 +37,13 @@ describe Gitlab::Kubernetes do it { expect(result.query).to match(/\Acontainer=container\+1&/) } end end + + describe '#filter_by_label' do + it 'returns matching labels' do + matching_items = [kube_pod(app: 'foo')] + items = matching_items + [kube_pod] + + expect(filter_by_label(items, app: 'foo')).to eq(matching_items) + end + end end diff --git a/spec/lib/gitlab/ldap/adapter_spec.rb b/spec/lib/gitlab/ldap/adapter_spec.rb index 563c074017a..9454878b057 100644 --- a/spec/lib/gitlab/ldap/adapter_spec.rb +++ b/spec/lib/gitlab/ldap/adapter_spec.rb @@ -74,13 +74,17 @@ describe Gitlab::LDAP::Adapter, lib: true do subject { adapter.dn_matches_filter?(:dn, :filter) } context "when the search result is non-empty" do - before { allow(adapter).to receive(:ldap_search).and_return([:foo]) } + before do + allow(adapter).to receive(:ldap_search).and_return([:foo]) + end it { is_expected.to be_truthy } end context "when the search result is empty" do - before { allow(adapter).to receive(:ldap_search).and_return([]) } + before do + allow(adapter).to receive(:ldap_search).and_return([]) + end it { is_expected.to be_falsey } end @@ -91,13 +95,17 @@ describe Gitlab::LDAP::Adapter, lib: true do context "when the search is successful" do context "and the result is non-empty" do - before { allow(ldap).to receive(:search).and_return([:foo]) } + before do + allow(ldap).to receive(:search).and_return([:foo]) + end it { is_expected.to eq [:foo] } end context "and the result is empty" do - before { allow(ldap).to receive(:search).and_return([]) } + before do + allow(ldap).to receive(:search).and_return([]) + end it { is_expected.to eq [] } end diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb index f4aab429931..f0a1dd22fee 100644 --- a/spec/lib/gitlab/ldap/user_spec.rb +++ b/spec/lib/gitlab/ldap/user_spec.rb @@ -37,7 +37,7 @@ describe Gitlab::LDAP::User, lib: true do end it "does not mark existing ldap user as changed" do - create(:omniauth_user, email: 'john@example.com', extern_uid: 'my-uid', provider: 'ldapmain', ldap_email: true) + create(:omniauth_user, email: 'john@example.com', extern_uid: 'my-uid', provider: 'ldapmain', external_email: true, email_provider: 'ldapmain') expect(ldap_user.changed?).to be_falsey end end @@ -141,8 +141,12 @@ describe Gitlab::LDAP::User, lib: true do expect(ldap_user.gl_user.email).to eq(info[:email]) end - it "has ldap_email set to true" do - expect(ldap_user.gl_user.ldap_email?).to be(true) + it "has external_email set to true" do + expect(ldap_user.gl_user.external_email?).to be(true) + end + + it "has email_provider set to provider" do + expect(ldap_user.gl_user.email_provider).to eql 'ldapmain' end end @@ -155,8 +159,8 @@ describe Gitlab::LDAP::User, lib: true do expect(ldap_user.gl_user.temp_oauth_email?).to be(true) end - it "has ldap_email set to false" do - expect(ldap_user.gl_user.ldap_email?).to be(false) + it "has external_email set to false" do + expect(ldap_user.gl_user.external_email?).to be(false) end end end @@ -169,7 +173,9 @@ describe Gitlab::LDAP::User, lib: true do context 'signup' do context 'dont block on create' do - before { configure_block(false) } + before do + configure_block(false) + end it do ldap_user.save @@ -179,7 +185,9 @@ describe Gitlab::LDAP::User, lib: true do end context 'block on create' do - before { configure_block(true) } + before do + configure_block(true) + end it do ldap_user.save @@ -196,7 +204,9 @@ describe Gitlab::LDAP::User, lib: true do end context 'dont block on create' do - before { configure_block(false) } + before do + configure_block(false) + end it do ldap_user.save @@ -206,7 +216,9 @@ describe Gitlab::LDAP::User, lib: true do end context 'block on create' do - before { configure_block(true) } + before do + configure_block(true) + end it do ldap_user.save diff --git a/spec/lib/gitlab/metrics_spec.rb b/spec/lib/gitlab/metrics_spec.rb index 208a8d028cd..5a87b906609 100644 --- a/spec/lib/gitlab/metrics_spec.rb +++ b/spec/lib/gitlab/metrics_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' describe Gitlab::Metrics do + include StubENV + describe '.settings' do it 'returns a Hash' do expect(described_class.settings).to be_an_instance_of(Hash) @@ -9,7 +11,19 @@ describe Gitlab::Metrics do describe '.enabled?' do it 'returns a boolean' do - expect([true, false].include?(described_class.enabled?)).to eq(true) + expect(described_class.enabled?).to be_in([true, false]) + end + end + + describe '.prometheus_metrics_enabled?' do + it 'returns a boolean' do + expect(described_class.prometheus_metrics_enabled?).to be_in([true, false]) + end + end + + describe '.influx_metrics_enabled?' do + it 'returns a boolean' do + expect(described_class.influx_metrics_enabled?).to be_in([true, false]) end end @@ -177,4 +191,133 @@ describe Gitlab::Metrics do end end end + + shared_examples 'prometheus metrics API' do + describe '#counter' do + subject { described_class.counter(:couter, 'doc') } + + describe '#increment' do + it 'successfully calls #increment without arguments' do + expect { subject.increment }.not_to raise_exception + end + + it 'successfully calls #increment with 1 argument' do + expect { subject.increment({}) }.not_to raise_exception + end + + it 'successfully calls #increment with 2 arguments' do + expect { subject.increment({}, 1) }.not_to raise_exception + end + end + end + + describe '#summary' do + subject { described_class.summary(:summary, 'doc') } + + describe '#observe' do + it 'successfully calls #observe with 2 arguments' do + expect { subject.observe({}, 2) }.not_to raise_exception + end + end + end + + describe '#gauge' do + subject { described_class.gauge(:gauge, 'doc') } + + describe '#set' do + it 'successfully calls #set with 2 arguments' do + expect { subject.set({}, 1) }.not_to raise_exception + end + end + end + + describe '#histogram' do + subject { described_class.histogram(:histogram, 'doc') } + + describe '#observe' do + it 'successfully calls #observe with 2 arguments' do + expect { subject.observe({}, 2) }.not_to raise_exception + end + end + end + end + + context 'prometheus metrics disabled' do + before do + allow(described_class).to receive(:prometheus_metrics_enabled?).and_return(false) + end + + it_behaves_like 'prometheus metrics API' + + describe '#null_metric' do + subject { described_class.provide_metric(:test) } + + it { is_expected.to be_a(Gitlab::Metrics::NullMetric) } + end + + describe '#counter' do + subject { described_class.counter(:counter, 'doc') } + + it { is_expected.to be_a(Gitlab::Metrics::NullMetric) } + end + + describe '#summary' do + subject { described_class.summary(:summary, 'doc') } + + it { is_expected.to be_a(Gitlab::Metrics::NullMetric) } + end + + describe '#gauge' do + subject { described_class.gauge(:gauge, 'doc') } + + it { is_expected.to be_a(Gitlab::Metrics::NullMetric) } + end + + describe '#histogram' do + subject { described_class.histogram(:histogram, 'doc') } + + it { is_expected.to be_a(Gitlab::Metrics::NullMetric) } + end + end + + context 'prometheus metrics enabled' do + let(:metrics_multiproc_dir) { Dir.mktmpdir } + + before do + stub_const('Prometheus::Client::Multiprocdir', metrics_multiproc_dir) + allow(described_class).to receive(:prometheus_metrics_enabled?).and_return(true) + end + + it_behaves_like 'prometheus metrics API' + + describe '#null_metric' do + subject { described_class.provide_metric(:test) } + + it { is_expected.to be_nil } + end + + describe '#counter' do + subject { described_class.counter(:name, 'doc') } + + it { is_expected.not_to be_a(Gitlab::Metrics::NullMetric) } + end + + describe '#summary' do + subject { described_class.summary(:name, 'doc') } + + it { is_expected.not_to be_a(Gitlab::Metrics::NullMetric) } + end + + describe '#gauge' do + subject { described_class.gauge(:name, 'doc') } + + it { is_expected.not_to be_a(Gitlab::Metrics::NullMetric) } + end + + describe '#histogram' do + subject { described_class.histogram(:name, 'doc') } + + it { is_expected.not_to be_a(Gitlab::Metrics::NullMetric) } + end + end end diff --git a/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb b/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb index 168090d5b5c..88107536c9e 100644 --- a/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb +++ b/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb @@ -6,7 +6,9 @@ describe Gitlab::Middleware::RailsQueueDuration do let(:env) { {} } let(:transaction) { double(:transaction) } - before { expect(app).to receive(:call).with(env).and_return('yay') } + before do + expect(app).to receive(:call).with(env).and_return('yay') + end describe '#call' do it 'calls the app when metrics are disabled' do @@ -15,7 +17,9 @@ describe Gitlab::Middleware::RailsQueueDuration do end context 'when metrics are enabled' do - before { allow(Gitlab::Metrics).to receive(:current_transaction).and_return(transaction) } + before do + allow(Gitlab::Metrics).to receive(:current_transaction).and_return(transaction) + end it 'calls the app when metrics are enabled but no timing header is found' do expect(middleware.call(env)).to eq('yay') diff --git a/spec/lib/gitlab/o_auth/auth_hash_spec.rb b/spec/lib/gitlab/o_auth/auth_hash_spec.rb index 8aaeb5779d3..19ab17419fc 100644 --- a/spec/lib/gitlab/o_auth/auth_hash_spec.rb +++ b/spec/lib/gitlab/o_auth/auth_hash_spec.rb @@ -55,7 +55,9 @@ describe Gitlab::OAuth::AuthHash, lib: true do end context 'email not provided' do - before { info_hash.delete(:email) } + before do + info_hash.delete(:email) + end it 'generates a temp email' do expect( auth_hash.email).to start_with('temp-email-for-oauth') @@ -63,7 +65,9 @@ describe Gitlab::OAuth::AuthHash, lib: true do end context 'username not provided' do - before { info_hash.delete(:nickname) } + before do + info_hash.delete(:nickname) + end it 'takes the first part of the email as username' do expect(auth_hash.username).to eql 'onur.kucuk_ABC-123' @@ -71,7 +75,9 @@ describe Gitlab::OAuth::AuthHash, lib: true do end context 'name not provided' do - before { info_hash.delete(:name) } + before do + info_hash.delete(:name) + end it 'concats first and lastname as the name' do expect(auth_hash.name).to eql name_utf8 diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb index 828c953197d..ea29cb9caf1 100644 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ b/spec/lib/gitlab/o_auth/user_spec.rb @@ -28,11 +28,11 @@ describe Gitlab::OAuth::User, lib: true do end end - describe '#save' do - def stub_omniauth_config(messages) - allow(Gitlab.config.omniauth).to receive_messages(messages) - end + def stub_omniauth_config(messages) + allow(Gitlab.config.omniauth).to receive_messages(messages) + end + describe '#save' do def stub_ldap_config(messages) allow(Gitlab::LDAP::Config).to receive_messages(messages) end @@ -112,7 +112,9 @@ describe Gitlab::OAuth::User, lib: true do end context 'with new allow_single_sign_on enabled syntax' do - before { stub_omniauth_config(allow_single_sign_on: ['twitter']) } + before do + stub_omniauth_config(allow_single_sign_on: ['twitter']) + end it "creates a user from Omniauth" do oauth_user.save @@ -125,7 +127,9 @@ describe Gitlab::OAuth::User, lib: true do end context "with old allow_single_sign_on enabled syntax" do - before { stub_omniauth_config(allow_single_sign_on: true) } + before do + stub_omniauth_config(allow_single_sign_on: true) + end it "creates a user from Omniauth" do oauth_user.save @@ -138,14 +142,20 @@ describe Gitlab::OAuth::User, lib: true do end context 'with new allow_single_sign_on disabled syntax' do - before { stub_omniauth_config(allow_single_sign_on: []) } + before do + stub_omniauth_config(allow_single_sign_on: []) + end + it 'throws an error' do expect{ oauth_user.save }.to raise_error StandardError end end context 'with old allow_single_sign_on disabled (Default)' do - before { stub_omniauth_config(allow_single_sign_on: false) } + before do + stub_omniauth_config(allow_single_sign_on: false) + end + it 'throws an error' do expect{ oauth_user.save }.to raise_error StandardError end @@ -153,21 +163,30 @@ describe Gitlab::OAuth::User, lib: true do end context "with auto_link_ldap_user disabled (default)" do - before { stub_omniauth_config(auto_link_ldap_user: false) } + before do + stub_omniauth_config(auto_link_ldap_user: false) + end + include_examples "to verify compliance with allow_single_sign_on" end context "with auto_link_ldap_user enabled" do - before { stub_omniauth_config(auto_link_ldap_user: true) } + before do + stub_omniauth_config(auto_link_ldap_user: true) + end context "and no LDAP provider defined" do - before { stub_ldap_config(providers: []) } + before do + stub_ldap_config(providers: []) + end include_examples "to verify compliance with allow_single_sign_on" end context "and at least one LDAP provider is defined" do - before { stub_ldap_config(providers: %w(ldapmain)) } + before do + stub_ldap_config(providers: %w(ldapmain)) + end context "and a corresponding LDAP person" do before do @@ -238,7 +257,9 @@ describe Gitlab::OAuth::User, lib: true do end context "and no corresponding LDAP person" do - before { allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(nil) } + before do + allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(nil) + end include_examples "to verify compliance with allow_single_sign_on" end @@ -248,11 +269,16 @@ describe Gitlab::OAuth::User, lib: true do describe 'blocking' do let(:provider) { 'twitter' } - before { stub_omniauth_config(allow_single_sign_on: ['twitter']) } + + before do + stub_omniauth_config(allow_single_sign_on: ['twitter']) + end context 'signup with omniauth only' do context 'dont block on create' do - before { stub_omniauth_config(block_auto_created_users: false) } + before do + stub_omniauth_config(block_auto_created_users: false) + end it do oauth_user.save @@ -262,7 +288,9 @@ describe Gitlab::OAuth::User, lib: true do end context 'block on create' do - before { stub_omniauth_config(block_auto_created_users: true) } + before do + stub_omniauth_config(block_auto_created_users: true) + end it do oauth_user.save @@ -284,7 +312,9 @@ describe Gitlab::OAuth::User, lib: true do context "and no account for the LDAP user" do context 'dont block on create (LDAP)' do - before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) } + before do + allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) + end it do oauth_user.save @@ -294,7 +324,9 @@ describe Gitlab::OAuth::User, lib: true do end context 'block on create (LDAP)' do - before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) } + before do + allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) + end it do oauth_user.save @@ -308,7 +340,9 @@ describe Gitlab::OAuth::User, lib: true do let!(:existing_user) { create(:omniauth_user, email: 'john@example.com', extern_uid: 'uid=user1,ou=People,dc=example', provider: 'ldapmain', username: 'john') } context 'dont block on create (LDAP)' do - before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) } + before do + allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) + end it do oauth_user.save @@ -318,7 +352,9 @@ describe Gitlab::OAuth::User, lib: true do end context 'block on create (LDAP)' do - before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) } + before do + allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) + end it do oauth_user.save @@ -336,7 +372,9 @@ describe Gitlab::OAuth::User, lib: true do end context 'dont block on create' do - before { stub_omniauth_config(block_auto_created_users: false) } + before do + stub_omniauth_config(block_auto_created_users: false) + end it do oauth_user.save @@ -346,7 +384,9 @@ describe Gitlab::OAuth::User, lib: true do end context 'block on create' do - before { stub_omniauth_config(block_auto_created_users: true) } + before do + stub_omniauth_config(block_auto_created_users: true) + end it do oauth_user.save @@ -356,7 +396,9 @@ describe Gitlab::OAuth::User, lib: true do end context 'dont block on create (LDAP)' do - before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) } + before do + allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) + end it do oauth_user.save @@ -366,7 +408,9 @@ describe Gitlab::OAuth::User, lib: true do end context 'block on create (LDAP)' do - before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) } + before do + allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) + end it do oauth_user.save @@ -377,4 +421,40 @@ describe Gitlab::OAuth::User, lib: true do end end end + + describe 'updating email' do + let!(:existing_user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'my-provider') } + + before do + stub_omniauth_config(sync_email_from_provider: 'my-provider') + end + + context "when provider sets an email" do + it "updates the user email" do + expect(gl_user.email).to eq(info_hash[:email]) + end + + it "has external_email set to true" do + expect(gl_user.external_email?).to be(true) + end + + it "has email_provider set to provider" do + expect(gl_user.email_provider).to eql 'my-provider' + end + end + + context "when provider doesn't set an email" do + before do + info_hash.delete(:email) + end + + it "does not update the user email" do + expect(gl_user.email).not_to eq(info_hash[:email]) + end + + it "has external_email set to false" do + expect(gl_user.external_email?).to be(false) + end + end + end end diff --git a/spec/lib/gitlab/redis_spec.rb b/spec/lib/gitlab/redis_spec.rb index 8b77c925705..593aa5038ad 100644 --- a/spec/lib/gitlab/redis_spec.rb +++ b/spec/lib/gitlab/redis_spec.rb @@ -108,11 +108,18 @@ describe Gitlab::Redis do end describe '.with' do - before { clear_pool } - after { clear_pool } + before do + clear_pool + end + + after do + clear_pool + end context 'when running not on sidekiq workers' do - before { allow(Sidekiq).to receive(:server?).and_return(false) } + before do + allow(Sidekiq).to receive(:server?).and_return(false) + end it 'instantiates a connection pool with size 5' do expect(ConnectionPool).to receive(:new).with(size: 5).and_call_original diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb index b106d156b75..a4d2367b72a 100644 --- a/spec/lib/gitlab/saml/user_spec.rb +++ b/spec/lib/gitlab/saml/user_spec.rb @@ -31,11 +31,17 @@ describe Gitlab::Saml::User, lib: true do allow(Gitlab::Saml::Config).to receive_messages({ options: { name: 'saml', groups_attribute: 'groups', external_groups: groups, args: {} } }) end - before { stub_basic_saml_config } + before do + stub_basic_saml_config + end describe 'account exists on server' do - before { stub_omniauth_config({ allow_single_sign_on: ['saml'], auto_link_saml_user: true }) } + before do + stub_omniauth_config({ allow_single_sign_on: ['saml'], auto_link_saml_user: true }) + end + let!(:existing_user) { create(:user, email: 'john@mail.com', username: 'john') } + context 'and should bind with SAML' do it 'adds the SAML identity to the existing user' do saml_user.save @@ -57,7 +63,10 @@ describe Gitlab::Saml::User, lib: true do end end - before { stub_saml_group_config(%w(Interns)) } + before do + stub_saml_group_config(%w(Interns)) + end + context 'are defined but the user does not belong there' do it 'does not mark the user as external' do saml_user.save @@ -80,7 +89,9 @@ describe Gitlab::Saml::User, lib: true do describe 'no account exists on server' do shared_examples 'to verify compliance with allow_single_sign_on' do context 'with allow_single_sign_on enabled' do - before { stub_omniauth_config(allow_single_sign_on: ['saml']) } + before do + stub_omniauth_config(allow_single_sign_on: ['saml']) + end it 'creates a user from SAML' do saml_user.save @@ -93,14 +104,20 @@ describe Gitlab::Saml::User, lib: true do end context 'with allow_single_sign_on default (["saml"])' do - before { stub_omniauth_config(allow_single_sign_on: ['saml']) } + before do + stub_omniauth_config(allow_single_sign_on: ['saml']) + end + it 'does not throw an error' do expect{ saml_user.save }.not_to raise_error end end context 'with allow_single_sign_on disabled' do - before { stub_omniauth_config(allow_single_sign_on: false) } + before do + stub_omniauth_config(allow_single_sign_on: false) + end + it 'throws an error' do expect{ saml_user.save }.to raise_error StandardError end @@ -128,15 +145,22 @@ describe Gitlab::Saml::User, lib: true do end context 'with auto_link_ldap_user disabled (default)' do - before { stub_omniauth_config({ auto_link_ldap_user: false, auto_link_saml_user: false, allow_single_sign_on: ['saml'] }) } + before do + stub_omniauth_config({ auto_link_ldap_user: false, auto_link_saml_user: false, allow_single_sign_on: ['saml'] }) + end + include_examples 'to verify compliance with allow_single_sign_on' end context 'with auto_link_ldap_user enabled' do - before { stub_omniauth_config({ auto_link_ldap_user: true, auto_link_saml_user: false }) } + before do + stub_omniauth_config({ auto_link_ldap_user: true, auto_link_saml_user: false }) + end context 'and at least one LDAP provider is defined' do - before { stub_ldap_config(providers: %w(ldapmain)) } + before do + stub_ldap_config(providers: %w(ldapmain)) + end context 'and a corresponding LDAP person' do before do @@ -239,11 +263,15 @@ describe Gitlab::Saml::User, lib: true do end describe 'blocking' do - before { stub_omniauth_config({ allow_single_sign_on: ['saml'], auto_link_saml_user: true }) } + before do + stub_omniauth_config({ allow_single_sign_on: ['saml'], auto_link_saml_user: true }) + end context 'signup with SAML only' do context 'dont block on create' do - before { stub_omniauth_config(block_auto_created_users: false) } + before do + stub_omniauth_config(block_auto_created_users: false) + end it 'does not block the user' do saml_user.save @@ -253,7 +281,9 @@ describe Gitlab::Saml::User, lib: true do end context 'block on create' do - before { stub_omniauth_config(block_auto_created_users: true) } + before do + stub_omniauth_config(block_auto_created_users: true) + end it 'blocks user' do saml_user.save @@ -270,7 +300,9 @@ describe Gitlab::Saml::User, lib: true do end context 'dont block on create' do - before { stub_omniauth_config(block_auto_created_users: false) } + before do + stub_omniauth_config(block_auto_created_users: false) + end it do saml_user.save @@ -280,7 +312,9 @@ describe Gitlab::Saml::User, lib: true do end context 'block on create' do - before { stub_omniauth_config(block_auto_created_users: true) } + before do + stub_omniauth_config(block_auto_created_users: true) + end it do saml_user.save diff --git a/spec/lib/gitlab/serializer/pagination_spec.rb b/spec/lib/gitlab/serializer/pagination_spec.rb index 519eb1b274f..1bc6536439e 100644 --- a/spec/lib/gitlab/serializer/pagination_spec.rb +++ b/spec/lib/gitlab/serializer/pagination_spec.rb @@ -22,7 +22,9 @@ describe Gitlab::Serializer::Pagination do let(:params) { { page: 1, per_page: 2 } } context 'when a multiple resources are present in relation' do - before { create_list(:user, 3) } + before do + create_list(:user, 3) + end it 'correctly paginates the resource' do expect(subject.count).to be 2 diff --git a/spec/lib/gitlab/template/issue_template_spec.rb b/spec/lib/gitlab/template/issue_template_spec.rb index 329d1d74970..bf45c8d16d6 100644 --- a/spec/lib/gitlab/template/issue_template_spec.rb +++ b/spec/lib/gitlab/template/issue_template_spec.rb @@ -52,7 +52,10 @@ describe Gitlab::Template::IssueTemplate do context 'when repo is bare or empty' do let(:empty_project) { create(:empty_project) } - before { empty_project.add_user(user, Gitlab::Access::MASTER) } + + before do + empty_project.add_user(user, Gitlab::Access::MASTER) + end it "returns empty array" do templates = subject.by_category('', empty_project) @@ -77,7 +80,9 @@ describe Gitlab::Template::IssueTemplate do context "when repo is empty" do let(:empty_project) { create(:empty_project) } - before { empty_project.add_user(user, Gitlab::Access::MASTER) } + before do + empty_project.add_user(user, Gitlab::Access::MASTER) + end it "raises file not found" do issue_template = subject.new('.gitlab/issue_templates/not_existent.md', empty_project) diff --git a/spec/lib/gitlab/template/merge_request_template_spec.rb b/spec/lib/gitlab/template/merge_request_template_spec.rb index 2b0056d9bab..8479f92c8df 100644 --- a/spec/lib/gitlab/template/merge_request_template_spec.rb +++ b/spec/lib/gitlab/template/merge_request_template_spec.rb @@ -52,7 +52,10 @@ describe Gitlab::Template::MergeRequestTemplate do context 'when repo is bare or empty' do let(:empty_project) { create(:empty_project) } - before { empty_project.add_user(user, Gitlab::Access::MASTER) } + + before do + empty_project.add_user(user, Gitlab::Access::MASTER) + end it "returns empty array" do templates = subject.by_category('', empty_project) @@ -77,7 +80,9 @@ describe Gitlab::Template::MergeRequestTemplate do context "when repo is empty" do let(:empty_project) { create(:empty_project) } - before { empty_project.add_user(user, Gitlab::Access::MASTER) } + before do + empty_project.add_user(user, Gitlab::Access::MASTER) + end it "raises file not found" do issue_template = subject.new('.gitlab/merge_request_templates/not_existent.md', empty_project) diff --git a/spec/lib/gitlab/uploads_transfer_spec.rb b/spec/lib/gitlab/uploads_transfer_spec.rb new file mode 100644 index 00000000000..109559bb01c --- /dev/null +++ b/spec/lib/gitlab/uploads_transfer_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe Gitlab::UploadsTransfer do + it 'leaves avatar uploads where they are' do + project_with_avatar = create(:empty_project, :with_avatar) + + described_class.new.rename_namespace('project', 'project-renamed') + + expect(File.exist?(project_with_avatar.avatar.path)).to be_truthy + end +end diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb index 3fe8cf43934..e8a37e8d77b 100644 --- a/spec/lib/gitlab/url_builder_spec.rb +++ b/spec/lib/gitlab/url_builder_spec.rb @@ -97,6 +97,17 @@ describe Gitlab::UrlBuilder, lib: true do end end + context 'on a PersonalSnippet' do + it 'returns a proper URL' do + personal_snippet = create(:personal_snippet) + note = build_stubbed(:note_on_personal_snippet, noteable: personal_snippet) + + url = described_class.build(note) + + expect(url).to eq "#{Settings.gitlab['url']}/snippets/#{note.noteable_id}#note_#{note.id}" + end + end + context 'on another object' do it 'returns a proper URL' do project = build_stubbed(:empty_project) diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb index b1999409170..ad19998dff4 100644 --- a/spec/lib/gitlab/workhorse_spec.rb +++ b/spec/lib/gitlab/workhorse_spec.rb @@ -212,7 +212,7 @@ describe Gitlab::Workhorse, lib: true do it 'includes a Repository param' do repo_param = { Repository: { - path: repo_path, + path: '', # deprecated field; grpc automatically creates it anyway storage_name: 'default', relative_path: project.full_path + '.git' } } |