2019-03-30 03:23:56 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2015-01-08 12:53:35 -05:00
|
|
|
require 'spec_helper'
|
|
|
|
|
2017-07-10 10:24:02 -04:00
|
|
|
describe ApplicationSetting do
|
2017-07-25 13:09:00 -04:00
|
|
|
let(:setting) { described_class.create_from_defaults }
|
2015-05-02 09:53:32 -04:00
|
|
|
|
2018-05-04 13:23:50 -04:00
|
|
|
it { include(CacheableAttributes) }
|
|
|
|
it { expect(described_class.current_without_cache).to eq(described_class.last) }
|
|
|
|
|
2015-11-05 10:22:37 -05:00
|
|
|
it { expect(setting).to be_valid }
|
2017-04-24 15:12:05 -04:00
|
|
|
it { expect(setting.uuid).to be_present }
|
2017-08-24 07:01:33 -04:00
|
|
|
it { expect(setting).to have_db_column(:auto_devops_enabled) }
|
2015-05-02 09:53:32 -04:00
|
|
|
|
2015-12-01 18:45:36 -05:00
|
|
|
describe 'validations' do
|
|
|
|
let(:http) { 'http://example.com' }
|
|
|
|
let(:https) { 'https://example.com' }
|
|
|
|
let(:ftp) { 'ftp://example.com' }
|
|
|
|
|
|
|
|
it { is_expected.to allow_value(nil).for(:home_page_url) }
|
|
|
|
it { is_expected.to allow_value(http).for(:home_page_url) }
|
|
|
|
it { is_expected.to allow_value(https).for(:home_page_url) }
|
|
|
|
it { is_expected.not_to allow_value(ftp).for(:home_page_url) }
|
|
|
|
|
|
|
|
it { is_expected.to allow_value(nil).for(:after_sign_out_path) }
|
|
|
|
it { is_expected.to allow_value(http).for(:after_sign_out_path) }
|
|
|
|
it { is_expected.to allow_value(https).for(:after_sign_out_path) }
|
|
|
|
it { is_expected.not_to allow_value(ftp).for(:after_sign_out_path) }
|
2016-02-05 04:12:36 -05:00
|
|
|
|
2018-11-07 06:00:21 -05:00
|
|
|
it { is_expected.to allow_value("dev.gitlab.com").for(:commit_email_hostname) }
|
|
|
|
it { is_expected.not_to allow_value("@dev.gitlab").for(:commit_email_hostname) }
|
|
|
|
|
2017-02-14 11:19:36 -05:00
|
|
|
describe 'default_artifacts_expire_in' do
|
2017-02-16 10:40:13 -05:00
|
|
|
it 'sets an error if it cannot parse' do
|
2017-02-14 11:19:36 -05:00
|
|
|
setting.update(default_artifacts_expire_in: 'a')
|
|
|
|
|
2017-02-16 10:40:13 -05:00
|
|
|
expect_invalid
|
2017-02-14 11:19:36 -05:00
|
|
|
end
|
|
|
|
|
2017-02-16 10:40:13 -05:00
|
|
|
it 'sets an error if it is blank' do
|
|
|
|
setting.update(default_artifacts_expire_in: ' ')
|
2017-02-15 02:31:25 -05:00
|
|
|
|
2017-02-16 10:40:13 -05:00
|
|
|
expect_invalid
|
2017-02-15 02:31:25 -05:00
|
|
|
end
|
|
|
|
|
2017-02-14 11:19:36 -05:00
|
|
|
it 'sets the value if it is valid' do
|
|
|
|
setting.update(default_artifacts_expire_in: '30 days')
|
|
|
|
|
|
|
|
expect(setting).to be_valid
|
|
|
|
expect(setting.default_artifacts_expire_in).to eq('30 days')
|
|
|
|
end
|
|
|
|
|
2017-02-16 10:40:13 -05:00
|
|
|
it 'sets the value if it is 0' do
|
|
|
|
setting.update(default_artifacts_expire_in: '0')
|
2017-02-14 11:19:36 -05:00
|
|
|
|
|
|
|
expect(setting).to be_valid
|
2017-02-16 10:40:13 -05:00
|
|
|
expect(setting.default_artifacts_expire_in).to eq('0')
|
|
|
|
end
|
|
|
|
|
|
|
|
def expect_invalid
|
|
|
|
expect(setting).to be_invalid
|
|
|
|
expect(setting.errors.messages)
|
2017-02-21 05:46:52 -05:00
|
|
|
.to have_key(:default_artifacts_expire_in)
|
2017-02-14 11:19:36 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-05 04:12:36 -05:00
|
|
|
it { is_expected.to validate_presence_of(:max_attachment_size) }
|
|
|
|
|
|
|
|
it do
|
|
|
|
is_expected.to validate_numericality_of(:max_attachment_size)
|
|
|
|
.only_integer
|
|
|
|
.is_greater_than(0)
|
|
|
|
end
|
2016-02-09 09:51:06 -05:00
|
|
|
|
2019-01-31 06:28:31 -05:00
|
|
|
it do
|
|
|
|
is_expected.to validate_numericality_of(:local_markdown_version)
|
|
|
|
.only_integer
|
|
|
|
.is_greater_than_or_equal_to(0)
|
|
|
|
.is_less_than(65536)
|
|
|
|
end
|
|
|
|
|
2017-08-25 09:08:48 -04:00
|
|
|
context 'key restrictions' do
|
|
|
|
it 'supports all key types' do
|
|
|
|
expect(described_class::SUPPORTED_KEY_TYPES).to contain_exactly(:rsa, :dsa, :ecdsa, :ed25519)
|
|
|
|
end
|
2017-08-21 06:30:03 -04:00
|
|
|
|
2017-08-30 16:20:00 -04:00
|
|
|
it 'does not allow all key types to be disabled' do
|
|
|
|
described_class::SUPPORTED_KEY_TYPES.each do |type|
|
|
|
|
setting["#{type}_key_restriction"] = described_class::FORBIDDEN_KEY_VALUE
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(setting).not_to be_valid
|
|
|
|
expect(setting.errors.messages).to have_key(:allowed_key_types)
|
|
|
|
end
|
|
|
|
|
2017-08-25 09:08:48 -04:00
|
|
|
where(:type) do
|
|
|
|
described_class::SUPPORTED_KEY_TYPES
|
|
|
|
end
|
2017-08-21 06:30:03 -04:00
|
|
|
|
2017-08-25 09:08:48 -04:00
|
|
|
with_them do
|
|
|
|
let(:field) { :"#{type}_key_restriction" }
|
2017-08-21 06:30:03 -04:00
|
|
|
|
2017-08-25 09:08:48 -04:00
|
|
|
it { is_expected.to validate_presence_of(field) }
|
2017-08-28 16:58:36 -04:00
|
|
|
it { is_expected.to allow_value(*KeyRestrictionValidator.supported_key_restrictions(type)).for(field) }
|
2017-08-25 09:08:48 -04:00
|
|
|
it { is_expected.not_to allow_value(128).for(field) }
|
|
|
|
end
|
2017-08-21 06:30:03 -04:00
|
|
|
end
|
|
|
|
|
2016-02-09 09:51:06 -05:00
|
|
|
it_behaves_like 'an object with email-formated attributes', :admin_notification_email do
|
|
|
|
subject { setting }
|
|
|
|
end
|
2016-06-29 23:35:00 -04:00
|
|
|
|
2016-11-03 10:12:20 -04:00
|
|
|
# Upgraded databases will have this sort of content
|
|
|
|
context 'repository_storages is a String, not an Array' do
|
2017-06-14 14:18:56 -04:00
|
|
|
before do
|
2018-06-04 04:38:18 -04:00
|
|
|
described_class.where(id: setting.id).update_all(repository_storages: 'default')
|
2017-06-14 14:18:56 -04:00
|
|
|
end
|
2016-11-03 10:12:20 -04:00
|
|
|
|
|
|
|
it { expect(setting.repository_storages).to eq(['default']) }
|
|
|
|
end
|
|
|
|
|
2018-01-22 13:29:15 -05:00
|
|
|
context 'auto_devops_domain setting' do
|
|
|
|
context 'when auto_devops_enabled? is true' do
|
|
|
|
before do
|
|
|
|
setting.update(auto_devops_enabled: true)
|
|
|
|
end
|
|
|
|
|
2018-01-22 14:37:02 -05:00
|
|
|
it 'can be blank' do
|
|
|
|
setting.update(auto_devops_domain: '')
|
|
|
|
|
|
|
|
expect(setting).to be_valid
|
|
|
|
end
|
|
|
|
|
2018-01-22 13:29:15 -05:00
|
|
|
context 'with a valid value' do
|
|
|
|
before do
|
|
|
|
setting.update(auto_devops_domain: 'domain.com')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is valid' do
|
|
|
|
expect(setting).to be_valid
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with an invalid value' do
|
|
|
|
before do
|
|
|
|
setting.update(auto_devops_domain: 'definitelynotahostname')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is invalid' do
|
|
|
|
expect(setting).to be_invalid
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-11-03 10:12:20 -04:00
|
|
|
context 'repository storages' do
|
2016-06-29 23:35:00 -04:00
|
|
|
before do
|
2016-11-03 10:12:20 -04:00
|
|
|
storages = {
|
|
|
|
'custom1' => 'tmp/tests/custom_repositories_1',
|
|
|
|
'custom2' => 'tmp/tests/custom_repositories_2',
|
2017-05-03 07:22:03 -04:00
|
|
|
'custom3' => 'tmp/tests/custom_repositories_3'
|
2016-11-03 10:12:20 -04:00
|
|
|
|
|
|
|
}
|
2016-06-29 23:35:00 -04:00
|
|
|
allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
|
|
|
|
end
|
|
|
|
|
2016-11-03 10:12:20 -04:00
|
|
|
describe 'inclusion' do
|
|
|
|
it { is_expected.to allow_value('custom1').for(:repository_storages) }
|
2017-02-22 12:46:57 -05:00
|
|
|
it { is_expected.to allow_value(%w(custom2 custom3)).for(:repository_storages) }
|
2016-11-03 10:12:20 -04:00
|
|
|
it { is_expected.not_to allow_value('alternative').for(:repository_storages) }
|
2017-02-22 12:46:57 -05:00
|
|
|
it { is_expected.not_to allow_value(%w(alternative custom1)).for(:repository_storages) }
|
2016-11-03 10:12:20 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
describe 'presence' do
|
|
|
|
it { is_expected.not_to allow_value([]).for(:repository_storages) }
|
|
|
|
it { is_expected.not_to allow_value("").for(:repository_storages) }
|
|
|
|
it { is_expected.not_to allow_value(nil).for(:repository_storages) }
|
|
|
|
end
|
2016-06-29 23:35:00 -04:00
|
|
|
end
|
2016-10-27 08:59:52 -04:00
|
|
|
|
|
|
|
context 'housekeeping settings' do
|
|
|
|
it { is_expected.not_to allow_value(0).for(:housekeeping_incremental_repack_period) }
|
|
|
|
|
2017-08-21 05:51:45 -04:00
|
|
|
it 'wants the full repack period to be at least the incremental repack period' do
|
2016-10-27 08:59:52 -04:00
|
|
|
subject.housekeeping_incremental_repack_period = 2
|
|
|
|
subject.housekeeping_full_repack_period = 1
|
|
|
|
|
|
|
|
expect(subject).not_to be_valid
|
|
|
|
end
|
|
|
|
|
2017-08-21 05:51:45 -04:00
|
|
|
it 'wants the gc period to be at least the full repack period' do
|
|
|
|
subject.housekeeping_full_repack_period = 100
|
|
|
|
subject.housekeeping_gc_period = 90
|
2016-10-27 08:59:52 -04:00
|
|
|
|
|
|
|
expect(subject).not_to be_valid
|
|
|
|
end
|
2017-08-21 05:51:45 -04:00
|
|
|
|
|
|
|
it 'allows the same period for incremental repack and full repack, effectively skipping incremental repack' do
|
|
|
|
subject.housekeeping_incremental_repack_period = 2
|
|
|
|
subject.housekeeping_full_repack_period = 2
|
|
|
|
|
|
|
|
expect(subject).to be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'allows the same period for full repack and gc, effectively skipping full repack' do
|
|
|
|
subject.housekeeping_full_repack_period = 100
|
|
|
|
subject.housekeeping_gc_period = 100
|
|
|
|
|
|
|
|
expect(subject).to be_valid
|
|
|
|
end
|
2017-07-10 08:29:16 -04:00
|
|
|
end
|
2017-11-29 04:12:12 -05:00
|
|
|
|
|
|
|
context 'gitaly timeouts' do
|
|
|
|
[:gitaly_timeout_default, :gitaly_timeout_medium, :gitaly_timeout_fast].each do |timeout_name|
|
|
|
|
it do
|
|
|
|
is_expected.to validate_presence_of(timeout_name)
|
|
|
|
is_expected.to validate_numericality_of(timeout_name).only_integer
|
|
|
|
.is_greater_than_or_equal_to(0)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
[:gitaly_timeout_medium, :gitaly_timeout_fast].each do |timeout_name|
|
|
|
|
it "validates that #{timeout_name} is lower than timeout_default" do
|
|
|
|
subject[:gitaly_timeout_default] = 50
|
|
|
|
subject[timeout_name] = 100
|
|
|
|
|
|
|
|
expect(subject).to be_invalid
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'accepts all timeouts equal' do
|
|
|
|
subject.gitaly_timeout_default = 0
|
|
|
|
subject.gitaly_timeout_medium = 0
|
|
|
|
subject.gitaly_timeout_fast = 0
|
|
|
|
|
|
|
|
expect(subject).to be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'accepts timeouts in descending order' do
|
|
|
|
subject.gitaly_timeout_default = 50
|
|
|
|
subject.gitaly_timeout_medium = 30
|
|
|
|
subject.gitaly_timeout_fast = 20
|
|
|
|
|
|
|
|
expect(subject).to be_valid
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'rejects timeouts in ascending order' do
|
|
|
|
subject.gitaly_timeout_default = 20
|
|
|
|
subject.gitaly_timeout_medium = 30
|
|
|
|
subject.gitaly_timeout_fast = 50
|
|
|
|
|
|
|
|
expect(subject).to be_invalid
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'rejects medium timeout larger than default' do
|
|
|
|
subject.gitaly_timeout_default = 30
|
|
|
|
subject.gitaly_timeout_medium = 50
|
|
|
|
subject.gitaly_timeout_fast = 20
|
|
|
|
|
|
|
|
expect(subject).to be_invalid
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'rejects medium timeout smaller than fast' do
|
|
|
|
subject.gitaly_timeout_default = 30
|
|
|
|
subject.gitaly_timeout_medium = 15
|
|
|
|
subject.gitaly_timeout_fast = 20
|
|
|
|
|
|
|
|
expect(subject).to be_invalid
|
|
|
|
end
|
|
|
|
end
|
2018-04-24 12:28:04 -04:00
|
|
|
|
|
|
|
describe 'enforcing terms' do
|
|
|
|
it 'requires the terms to present when enforcing users to accept' do
|
|
|
|
subject.enforce_terms = true
|
|
|
|
|
|
|
|
expect(subject).to be_invalid
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is valid when terms are created' do
|
|
|
|
create(:term)
|
|
|
|
subject.enforce_terms = true
|
|
|
|
|
|
|
|
expect(subject).to be_valid
|
|
|
|
end
|
|
|
|
end
|
2017-07-10 08:29:16 -04:00
|
|
|
end
|
|
|
|
|
2017-10-05 15:56:23 -04:00
|
|
|
context 'restrict creating duplicates' do
|
|
|
|
before do
|
|
|
|
described_class.create_from_defaults
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'raises an record creation violation if already created' do
|
|
|
|
expect { described_class.create_from_defaults }.to raise_error(ActiveRecord::RecordNotUnique)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-09-12 08:55:29 -04:00
|
|
|
describe 'setting Sentry DSNs' do
|
|
|
|
context 'server DSN' do
|
|
|
|
it 'strips leading and trailing whitespace' do
|
|
|
|
subject.update(sentry_dsn: ' http://test ')
|
|
|
|
|
|
|
|
expect(subject.sentry_dsn).to eq('http://test')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'handles nil values' do
|
|
|
|
subject.update(sentry_dsn: nil)
|
|
|
|
|
|
|
|
expect(subject.sentry_dsn).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'client-side DSN' do
|
|
|
|
it 'strips leading and trailing whitespace' do
|
|
|
|
subject.update(clientside_sentry_dsn: ' http://test ')
|
|
|
|
|
|
|
|
expect(subject.clientside_sentry_dsn).to eq('http://test')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'handles nil values' do
|
|
|
|
subject.update(clientside_sentry_dsn: nil)
|
|
|
|
|
|
|
|
expect(subject.clientside_sentry_dsn).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-06-25 04:28:19 -04:00
|
|
|
describe '#disabled_oauth_sign_in_sources=' do
|
|
|
|
before do
|
|
|
|
allow(Devise).to receive(:omniauth_providers).and_return([:github])
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'removes unknown sources (as strings) from the array' do
|
|
|
|
subject.disabled_oauth_sign_in_sources = %w[github test]
|
|
|
|
|
|
|
|
expect(subject).to be_valid
|
|
|
|
expect(subject.disabled_oauth_sign_in_sources).to eq ['github']
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'removes unknown sources (as symbols) from the array' do
|
|
|
|
subject.disabled_oauth_sign_in_sources = %i[github test]
|
|
|
|
|
|
|
|
expect(subject).to be_valid
|
|
|
|
expect(subject.disabled_oauth_sign_in_sources).to eq ['github']
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'ignores nil' do
|
|
|
|
subject.disabled_oauth_sign_in_sources = nil
|
|
|
|
|
|
|
|
expect(subject).to be_valid
|
|
|
|
expect(subject.disabled_oauth_sign_in_sources).to be_empty
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-07-06 12:57:02 -04:00
|
|
|
describe 'performance bar settings' do
|
|
|
|
describe 'performance_bar_allowed_group' do
|
|
|
|
context 'with no performance_bar_allowed_group_id saved' do
|
|
|
|
it 'returns nil' do
|
|
|
|
expect(setting.performance_bar_allowed_group).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with a performance_bar_allowed_group_id saved' do
|
|
|
|
let(:group) { create(:group) }
|
|
|
|
|
|
|
|
before do
|
2018-05-25 12:44:15 -04:00
|
|
|
setting.update!(performance_bar_allowed_group_id: group.id)
|
2017-07-06 12:57:02 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns the group' do
|
2018-05-25 12:44:15 -04:00
|
|
|
expect(setting.reload.performance_bar_allowed_group).to eq(group)
|
2017-07-06 12:57:02 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-07-06 20:34:51 -04:00
|
|
|
describe 'performance_bar_enabled' do
|
|
|
|
context 'with the Performance Bar is enabled' do
|
|
|
|
let(:group) { create(:group) }
|
2017-07-06 12:57:02 -04:00
|
|
|
|
|
|
|
before do
|
2018-05-25 12:44:15 -04:00
|
|
|
setting.update!(performance_bar_allowed_group_id: group.id)
|
2017-07-06 12:57:02 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns true' do
|
2018-05-25 12:44:15 -04:00
|
|
|
expect(setting.reload.performance_bar_enabled).to be_truthy
|
2017-07-06 12:57:02 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-09-24 11:30:49 -04:00
|
|
|
context 'diff limit settings' do
|
|
|
|
describe '#diff_max_patch_bytes' do
|
|
|
|
context 'validations' do
|
|
|
|
it { is_expected.to validate_presence_of(:diff_max_patch_bytes) }
|
|
|
|
|
|
|
|
it do
|
|
|
|
is_expected.to validate_numericality_of(:diff_max_patch_bytes)
|
|
|
|
.only_integer
|
|
|
|
.is_greater_than_or_equal_to(Gitlab::Git::Diff::DEFAULT_MAX_PATCH_BYTES)
|
|
|
|
.is_less_than_or_equal_to(Gitlab::Git::Diff::MAX_PATCH_BYTES_UPPER_BOUND)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-10-23 06:58:41 -04:00
|
|
|
|
2019-03-14 10:15:44 -04:00
|
|
|
it_behaves_like 'application settings examples'
|
2015-01-08 12:53:35 -05:00
|
|
|
end
|