Commit 28fa95fe authored by Erick Bajao's avatar Erick Bajao

Fix closest_setting to properly support boolean types

Clean up specs and fix logic about handling boolean type
settings.

Move out responsibility of fetching closest namespace setting
to the namespace model.
parent af61265d
......@@ -316,6 +316,12 @@ class Namespace < ApplicationRecord
Pages::VirtualDomain.new(all_projects_with_pages, trim_prefix: full_path)
end
def closest_setting(name)
self_and_ancestors(hierarchy_order: :asc)
.find { |n| !n.read_attribute(name).nil? }
.try(name)
end
private
def all_projects_with_pages
......
......@@ -2251,16 +2251,16 @@ class Project < ApplicationRecord
end
def closest_setting(name)
read_attribute(name) || closest_namespace_setting(name) || app_settings_for(name)
setting = read_attribute(name)
setting = closest_namespace_setting(name) if setting.nil?
setting = app_settings_for(name) if setting.nil?
setting
end
private
def closest_namespace_setting(name)
namespace
.self_and_ancestors(hierarchy_order: :asc)
.find { |n| !n.read_attribute(name).nil? }
.try(name)
namespace.closest_setting(name)
end
def app_settings_for(name)
......
......@@ -954,4 +954,52 @@ describe Namespace do
expect(group.has_parent?).to be_falsy
end
end
describe '#closest_setting' do
using RSpec::Parameterized::TableSyntax
shared_examples_for 'fetching closest setting' do
let!(:root_namespace) { create(:namespace) }
let!(:namespace) { create(:namespace, parent: root_namespace) }
let(:setting) { namespace.closest_setting(setting_name) }
before do
root_namespace.update_attribute(setting_name, root_setting)
namespace.update_attribute(setting_name, child_setting)
end
it 'returns closest non-nil value' do
expect(setting).to eq(result)
end
end
context 'when setting is of non-boolean type' do
where(:root_setting, :child_setting, :result) do
100 | 200 | 200
100 | nil | 100
nil | nil | nil
end
with_them do
let(:setting_name) { :max_artifacts_size }
it_behaves_like 'fetching closest setting'
end
end
context 'when setting is of boolean type' do
where(:root_setting, :child_setting, :result) do
true | false | false
true | nil | true
nil | nil | nil
end
with_them do
let(:setting_name) { :lfs_enabled }
it_behaves_like 'fetching closest setting'
end
end
end
end
......@@ -5122,55 +5122,48 @@ describe Project do
end
describe '#closest_setting' do
let(:root_namespace) { create(:namespace) }
let(:namespace) { create(:namespace, parent: root_namespace) }
let(:project) { create(:project, namespace: namespace) }
let(:setting) { project.closest_setting(:max_artifacts_size) }
using RSpec::Parameterized::TableSyntax
before do
stub_application_setting(max_artifacts_size: 100)
root_namespace.update!(max_artifacts_size: 200)
namespace.update!(max_artifacts_size: 300)
project.update!(max_artifacts_size: 400)
end
shared_examples_for 'fetching closest setting' do
let!(:namespace) { create(:namespace) }
let!(:project) { create(:project, namespace: namespace) }
context 'when project has non-nil value for setting' do
it 'returns project level setting' do
expect(setting).to eq(400)
end
end
let(:setting_name) { :some_setting }
let(:setting) { project.closest_setting(setting_name) }
context 'when project has nil value for setting' do
before do
project.update!(max_artifacts_size: nil)
allow(project).to receive(:read_attribute).with(setting_name).and_return(project_setting)
allow(namespace).to receive(:closest_setting).with(setting_name).and_return(group_setting)
allow(Gitlab::CurrentSettings).to receive(setting_name).and_return(global_setting)
end
context 'and namespace has non-nil value for setting' do
it 'returns namespace level setting' do
expect(setting).to eq(300)
it 'returns closest non-nil value' do
expect(setting).to eq(result)
end
end
context 'and namespace has nil value for setting' do
before do
namespace.update!(max_artifacts_size: nil)
context 'when setting is of non-boolean type' do
where(:global_setting, :group_setting, :project_setting, :result) do
100 | 200 | 300 | 300
100 | 200 | nil | 200
100 | nil | nil | 100
nil | nil | nil | nil
end
context 'and root namespace has non-nil value for setting' do
it 'returns root namespace level setting' do
expect(setting).to eq(200)
with_them do
it_behaves_like 'fetching closest setting'
end
end
context 'and root namespace has nil value for setting' do
before do
root_namespace.update!(max_artifacts_size: nil)
context 'when setting is of boolean type' do
where(:global_setting, :group_setting, :project_setting, :result) do
true | true | false | false
true | false | nil | false
true | nil | nil | true
end
it 'returns application level setting' do
expect(setting).to eq(100)
end
end
with_them do
it_behaves_like 'fetching closest setting'
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment