更新
更旧
require 'spec_helper'
RSpec.describe NamespacesHelper, feature_category: :groups_and_projects do
let!(:admin) { create(:admin) }
let!(:admin_project_creation_level) { nil }
let!(:admin_group) do
create(:group, :private, project_creation_level: admin_project_creation_level)
let!(:user) { create(:user) }
let!(:user_project_creation_level) { nil }
let!(:user_group) do
create(:group, :private, project_creation_level: user_project_creation_level)
create(:group, :private, parent: admin_group, project_creation_level: nil)
create(
:group,
:private,
parent: admin_group,
project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS
)
create(
:group,
:private,
parent: admin_group,
project_creation_level: ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS
)
let!(:project1) { build(:project, namespace: subgroup1) }
let!(:project2) do
user.create_namespace!(path: user.username, name: user.name) unless user.namespace
build(:project, namespace: user.namespace)
end
let_it_be(:attribute) { :math_rendering_limits_enabled }
before do
admin_group.add_owner(admin)
user_group.add_owner(user)
end
describe '#check_group_lock' do
context 'when the method exists on namespace_settings' do
it 'calls the method on namespace_settings' do
expect(subgroup1.namespace_settings).to receive(attribute).and_return(true)
expect(helper.check_group_lock(subgroup1, attribute)).to be true
end
end
context 'when the method does not exist on namespace_settings' do
it 'returns false' do
expect(helper.check_group_lock(subgroup1, :non_existent_method)).to be false
end
end
end
describe '#check_project_lock' do
let(:project) { build(:project, group: subgroup1) }
it 'returns true when the method exists and returns true' do
allow(project.project_setting).to receive(attribute).and_return(true)
expect(helper.check_project_lock(project, attribute)).to be true
end
it 'returns false when the method does not exist' do
expect(helper.check_project_lock(project, :non_existent_method)).to be false
end
end
describe '#cascading_namespace_settings_tooltip_data' do
it 'returns tooltip data with testid' do
allow(helper).to receive(:cascading_namespace_settings_tooltip_raw_data).and_return({ key: 'value' })
result = helper.cascading_namespace_settings_tooltip_data(attribute, subgroup1, -> {})
expect(result[:tooltip_data]).to eq('{"key":"value"}')
expect(result[:testid]).to eq('cascading-settings-lock-icon')
end
end
describe '#cascading_namespace_settings_tooltip_raw_data' do
helper.cascading_namespace_settings_tooltip_data(
attribute,
subgroup1,
->(locked_ancestor) { edit_group_path(locked_ancestor, anchor: 'js-permissions-settings') }
)
end
context 'when locked by an application setting' do
before do
allow(subgroup1.namespace_settings).to receive("#{attribute}_locked_by_application_setting?").and_return(true)
allow(subgroup1.namespace_settings).to receive("#{attribute}_locked_by_ancestor?").and_return(false)
end
it 'returns expected hash' do
expect(subject).to match({
locked_by_application_setting: true,
locked_by_ancestor: false
}.to_json,
testid: 'cascading-settings-lock-icon'
})
end
end
context 'when locked by an ancestor namespace' do
before do
allow(subgroup1.namespace_settings).to receive("#{attribute}_locked_by_application_setting?").and_return(false)
allow(subgroup1.namespace_settings).to receive("#{attribute}_locked_by_ancestor?").and_return(true)
allow(subgroup1.namespace_settings).to receive("#{attribute}_locked_ancestor").and_return(admin_group.namespace_settings)
end
it 'returns expected hash' do
expect(subject).to match({
locked_by_application_setting: false,
locked_by_ancestor: true,
ancestor_namespace: {
full_name: admin_group.full_name,
path: edit_group_path(admin_group, anchor: 'js-permissions-settings')
}
}.to_json,
testid: 'cascading-settings-lock-icon'
})
end
end
end
describe '#project_cascading_namespace_settings_tooltip_data' do
using RSpec::Parameterized::TableSyntax
let(:settings_path_helper) { ->(locked_ancestor) { edit_group_path(locked_ancestor) } }
subject do
helper.project_cascading_namespace_settings_tooltip_data(attribute, project, settings_path_helper)
end
shared_examples 'returns correct data' do
context 'when attribute is nil' do
let(:attribute) { nil }
it { is_expected.to be nil }
context 'when project is nil' do
let(:project) { nil }
context 'when settings_path_helper is nil' do
let(:settings_path_helper) { nil }
it { is_expected.to be nil }
end
where(:locked_by_ancestor, :locked_by_application_setting, :locked_by_project, :expected_result) do
false | false | false | { locked_by_application_setting: false, locked_by_ancestor: false }
false | true | false | { locked_by_application_setting: true, locked_by_ancestor: false }
true | false | false | { locked_by_application_setting: false, locked_by_ancestor: true, ancestor_namespace: { full_name: String, path: String } }
false | false | true | { locked_by_application_setting: false, locked_by_ancestor: true, ancestor_namespace: { full_name: String, path: String } }
end
with_them do
allow(helper).to receive(:check_project_lock)
.with(project, "#{attribute}_locked_by_application_setting?")
.and_return(locked_by_application_setting)
allow(helper).to receive(:check_project_lock)
.with(project, "#{attribute}_locked_by_ancestor?")
.and_return(locked_by_ancestor)
allow(helper).to receive(:check_project_lock)
.with(project, "#{attribute}_locked?")
.and_return(locked_by_project)
end
it 'returns the expected result' do
is_expected.to include(expected_result)
if expected_result[:ancestor_namespace]
expect(subject[:ancestor_namespace][:full_name]).to eq(project.parent.name)
expect(subject[:ancestor_namespace][:path]).to eq(Gitlab::UrlBuilder.build(project.parent, only_path: true))
end
context 'when data is already locked by ancestor' do
before do
allow(helper).to receive(:check_group_lock)
.with(project.namespace, "#{attribute}_locked_by_ancestor?")
.and_return(true)
allow(helper).to receive(:check_group_lock)
.with(project.namespace, "#{attribute}_locked_by_application_setting?")
.and_return(false)
end
it 'returns early without modifying data' do
expect(helper).not_to receive(:check_project_lock)
is_expected.to eq({ locked_by_ancestor: true, locked_by_application_setting: false })
end
context 'when project parent is a group' do
let(:project) { project1 }
it_behaves_like 'returns correct data'
end
context 'when project parent is a user namespace' do
let(:project) { project2 }
it_behaves_like 'returns correct data'
describe '#cascading_namespace_setting_locked?' do
context 'when `group` argument is `nil`' do
it 'returns `false`' do
expect(helper.cascading_namespace_setting_locked?(attribute, nil)).to eq(false)
end
end
context 'when `*_locked?` method does not exist' do
it 'returns `false`' do
expect(helper.cascading_namespace_setting_locked?(:attribute_that_does_not_exist, admin_group)).to eq(false)
end
end
context 'when `*_locked?` method does exist' do
before do
allow(admin_group.namespace_settings).to receive(:"#{attribute}_locked?").and_return(true)
end
it 'calls corresponding `*_locked?` method' do
helper.cascading_namespace_setting_locked?(attribute, admin_group, include_self: true)
expect(admin_group.namespace_settings).to have_received(:"#{attribute}_locked?").with(include_self: true)
describe '#pipeline_usage_app_data', unless: Gitlab.ee?, feature_category: :consumables_cost_management do
it 'returns a hash with necessary data for the frontend' do
expect(helper.pipeline_usage_app_data(user_group)).to eql({
namespace_actual_plan_name: user_group.actual_plan_name,
namespace_path: user_group.full_path,
namespace_id: user_group.id,
user_namespace: user_group.user_namespace?.to_s,
page_size: Kaminari.config.default_per_page
})
end
end