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