2019-03-28 10:24:08 +00:00
# frozen_string_literal: true
2015-03-12 21:51:41 +00:00
require 'spec_helper'
2020-06-24 09:08:32 +00:00
RSpec . describe GroupsHelper do
2017-06-20 21:35:55 +00:00
include ApplicationHelper
2021-03-25 18:09:07 +00:00
describe '#group_icon_url' do
2017-10-02 11:35:01 +00:00
it 'returns an url for the avatar' do
2021-03-25 18:09:07 +00:00
group = create ( :group , :with_avatar )
2018-06-06 21:26:00 +00:00
2021-03-25 18:09:07 +00:00
expect ( group_icon_url ( group . path ) . to_s ) . to match ( group . avatar . url )
2015-03-12 21:51:41 +00:00
end
2016-07-25 18:16:19 +00:00
it 'gives default avatar_icon when no avatar is present' do
2021-03-25 18:09:07 +00:00
group = build_stubbed ( :group )
2017-10-02 11:35:01 +00:00
expect ( group_icon_url ( group . path ) ) . to match_asset_path ( 'group_avatar.png' )
2015-03-12 21:51:41 +00:00
end
end
2016-09-06 16:48:00 +00:00
2021-03-25 18:09:07 +00:00
describe '#group_lfs_status' do
let_it_be_with_reload ( :group ) { create ( :group ) }
let_it_be_with_reload ( :project ) { create ( :project , namespace_id : group . id ) }
2016-09-06 16:48:00 +00:00
before do
allow ( Gitlab . config . lfs ) . to receive ( :enabled ) . and_return ( true )
end
context 'only one project in group' do
before do
group . update_attribute ( :lfs_enabled , true )
end
it 'returns all projects as enabled' do
expect ( group_lfs_status ( group ) ) . to include ( 'Enabled for all projects' )
end
it 'returns all projects as disabled' do
project . update_attribute ( :lfs_enabled , false )
expect ( group_lfs_status ( group ) ) . to include ( 'Enabled for 0 out of 1 project' )
end
end
context 'more than one project in group' do
2021-03-25 18:09:07 +00:00
let_it_be_with_reload ( :another_project ) { create ( :project , namespace_id : group . id ) }
2016-09-06 16:48:00 +00:00
context 'LFS enabled in group' do
before do
group . update_attribute ( :lfs_enabled , true )
end
it 'returns both projects as enabled' do
expect ( group_lfs_status ( group ) ) . to include ( 'Enabled for all projects' )
end
it 'returns only one as enabled' do
project . update_attribute ( :lfs_enabled , false )
expect ( group_lfs_status ( group ) ) . to include ( 'Enabled for 1 out of 2 projects' )
end
end
context 'LFS disabled in group' do
before do
group . update_attribute ( :lfs_enabled , false )
end
it 'returns both projects as disabled' do
expect ( group_lfs_status ( group ) ) . to include ( 'Disabled for all projects' )
end
it 'returns only one as disabled' do
project . update_attribute ( :lfs_enabled , true )
expect ( group_lfs_status ( group ) ) . to include ( 'Disabled for 1 out of 2 projects' )
end
end
end
end
2017-06-20 21:35:55 +00:00
2021-03-25 18:09:07 +00:00
describe '#group_title' do
2020-11-12 00:09:44 +00:00
let_it_be ( :group ) { create ( :group ) }
let_it_be ( :nested_group ) { create ( :group , parent : group ) }
let_it_be ( :deep_nested_group ) { create ( :group , parent : nested_group ) }
let_it_be ( :very_deep_nested_group ) { create ( :group , parent : deep_nested_group ) }
subject { helper . group_title ( very_deep_nested_group ) }
2017-06-20 21:35:55 +00:00
2021-05-06 09:18:56 +00:00
context 'traversal queries' do
shared_examples 'correct ancestor order' do
it 'outputs the groups in the correct order' do
expect ( subject )
2021-11-02 12:12:25 +00:00
. to match ( %r{ <li><a.*> #{ deep_nested_group . name } .*</li>.*<a.*> #{ very_deep_nested_group . name } </a> }m )
2021-05-06 09:18:56 +00:00
end
end
context 'recursive' do
before do
stub_feature_flags ( use_traversal_ids : false )
end
include_examples 'correct ancestor order'
end
context 'linear' do
before do
stub_feature_flags ( use_traversal_ids : true )
very_deep_nested_group . reload # make sure traversal_ids are reloaded
end
include_examples 'correct ancestor order'
end
2017-06-20 21:35:55 +00:00
end
2020-11-12 00:09:44 +00:00
it 'enqueues the elements in the breadcrumb schema list' do
expect ( helper ) . to receive ( :push_to_schema_breadcrumb ) . with ( group . name , group_path ( group ) )
expect ( helper ) . to receive ( :push_to_schema_breadcrumb ) . with ( nested_group . name , group_path ( nested_group ) )
expect ( helper ) . to receive ( :push_to_schema_breadcrumb ) . with ( deep_nested_group . name , group_path ( deep_nested_group ) )
expect ( helper ) . to receive ( :push_to_schema_breadcrumb ) . with ( very_deep_nested_group . name , group_path ( very_deep_nested_group ) )
subject
end
2021-03-29 21:09:08 +00:00
it 'avoids N+1 queries' do
control_count = ActiveRecord :: QueryRecorder . new do
helper . group_title ( nested_group )
end
expect do
helper . group_title ( very_deep_nested_group )
end . not_to exceed_query_limit ( control_count )
end
2017-06-20 21:35:55 +00:00
end
2017-09-06 00:02:11 +00:00
2019-07-24 09:20:54 +00:00
describe '#share_with_group_lock_help_text' do
2021-05-06 09:18:56 +00:00
context 'traversal queries' do
let_it_be_with_reload ( :root_group ) { create ( :group ) }
let_it_be_with_reload ( :subgroup ) { create ( :group , parent : root_group ) }
let_it_be_with_reload ( :sub_subgroup ) { create ( :group , parent : subgroup ) }
let_it_be ( :root_owner ) { create ( :user ) }
let_it_be ( :sub_owner ) { create ( :user ) }
let_it_be ( :sub_sub_owner ) { create ( :user ) }
let ( :possible_help_texts ) do
{
2021-09-30 21:11:33 +00:00
default_help : " Applied to all subgroups unless overridden by a group owner. " ,
2021-05-06 09:18:56 +00:00
ancestor_locked_but_you_can_override : %r{ This setting is applied on <a .+>.+</a> \ . You can override the setting or .+ } ,
ancestor_locked_so_ask_the_owner : / This setting is applied on .+ \ . To share projects in this group with another group, ask the owner to override the setting or remove the share with group lock from .+ / ,
ancestor_locked_and_has_been_overridden : / This setting is applied on .+ and has been overridden on this subgroup /
}
end
2020-08-11 03:11:00 +00:00
2021-05-06 09:18:56 +00:00
let ( :possible_linked_ancestors ) do
{
root_group : root_group ,
subgroup : subgroup
}
end
2020-08-11 03:11:00 +00:00
2021-05-06 09:18:56 +00:00
let ( :users ) do
{
root_owner : root_owner ,
sub_owner : sub_owner ,
sub_sub_owner : sub_sub_owner
}
end
2019-12-17 18:07:48 +00:00
2021-05-06 09:18:56 +00:00
subject { helper . share_with_group_lock_help_text ( sub_subgroup ) }
2017-09-06 00:02:11 +00:00
2021-05-06 09:18:56 +00:00
before_all do
root_group . add_owner ( root_owner )
subgroup . add_owner ( sub_owner )
sub_subgroup . add_owner ( sub_sub_owner )
end
2021-03-25 18:09:07 +00:00
2021-05-06 09:18:56 +00:00
shared_examples 'correct ancestor order' do
# rubocop:disable Layout/SpaceBeforeComma
where ( :root_share_with_group_locked , :subgroup_share_with_group_locked , :sub_subgroup_share_with_group_locked , :current_user , :help_text , :linked_ancestor ) do
[
[ false , false , false , :root_owner , :default_help , nil ] ,
[ false , false , false , :sub_owner , :default_help , nil ] ,
[ false , false , false , :sub_sub_owner , :default_help , nil ] ,
[ false , false , true , :root_owner , :default_help , nil ] ,
[ false , false , true , :sub_owner , :default_help , nil ] ,
[ false , false , true , :sub_sub_owner , :default_help , nil ] ,
[ false , true , false , :root_owner , :ancestor_locked_and_has_been_overridden , :subgroup ] ,
[ false , true , false , :sub_owner , :ancestor_locked_and_has_been_overridden , :subgroup ] ,
[ false , true , false , :sub_sub_owner , :ancestor_locked_and_has_been_overridden , :subgroup ] ,
[ false , true , true , :root_owner , :ancestor_locked_but_you_can_override , :subgroup ] ,
[ false , true , true , :sub_owner , :ancestor_locked_but_you_can_override , :subgroup ] ,
[ false , true , true , :sub_sub_owner , :ancestor_locked_so_ask_the_owner , :subgroup ] ,
[ true , false , false , :root_owner , :default_help , nil ] ,
[ true , false , false , :sub_owner , :default_help , nil ] ,
[ true , false , false , :sub_sub_owner , :default_help , nil ] ,
[ true , false , true , :root_owner , :default_help , nil ] ,
[ true , false , true , :sub_owner , :default_help , nil ] ,
[ true , false , true , :sub_sub_owner , :default_help , nil ] ,
[ true , true , false , :root_owner , :ancestor_locked_and_has_been_overridden , :root_group ] ,
[ true , true , false , :sub_owner , :ancestor_locked_and_has_been_overridden , :root_group ] ,
[ true , true , false , :sub_sub_owner , :ancestor_locked_and_has_been_overridden , :root_group ] ,
[ true , true , true , :root_owner , :ancestor_locked_but_you_can_override , :root_group ] ,
[ true , true , true , :sub_owner , :ancestor_locked_so_ask_the_owner , :root_group ] ,
[ true , true , true , :sub_sub_owner , :ancestor_locked_so_ask_the_owner , :root_group ]
]
end
# rubocop:enable Layout/SpaceBeforeComma
with_them do
before do
root_group . update_column ( :share_with_group_lock , true ) if root_share_with_group_locked
subgroup . update_column ( :share_with_group_lock , true ) if subgroup_share_with_group_locked
sub_subgroup . update_column ( :share_with_group_lock , true ) if sub_subgroup_share_with_group_locked
allow ( helper ) . to receive ( :current_user ) . and_return ( users [ current_user ] )
allow ( helper ) . to receive ( :can? )
. with ( users [ current_user ] , :change_share_with_group_lock , subgroup )
. and_return ( Ability . allowed? ( users [ current_user ] , :change_share_with_group_lock , subgroup ) )
ancestor = possible_linked_ancestors [ linked_ancestor ]
if ancestor
allow ( helper ) . to receive ( :can? )
. with ( users [ current_user ] , :read_group , ancestor )
. and_return ( Ability . allowed? ( users [ current_user ] , :read_group , ancestor ) )
allow ( helper ) . to receive ( :can? )
. with ( users [ current_user ] , :admin_group , ancestor )
. and_return ( Ability . allowed? ( users [ current_user ] , :admin_group , ancestor ) )
end
end
it 'has the correct help text with correct ancestor links' do
expect ( subject ) . to match ( possible_help_texts [ help_text ] )
expect ( subject ) . to match ( possible_linked_ancestors [ linked_ancestor ] . name ) unless help_text == :default_help
end
end
end
2017-09-06 00:02:11 +00:00
2021-05-06 09:18:56 +00:00
context 'recursive' do
before do
stub_feature_flags ( use_traversal_ids : false )
2017-09-06 06:49:57 +00:00
end
2021-05-06 09:18:56 +00:00
include_examples 'correct ancestor order'
2017-09-06 00:02:11 +00:00
end
2021-05-06 09:18:56 +00:00
context 'linear' do
before do
stub_feature_flags ( use_traversal_ids : true )
end
include_examples 'correct ancestor order'
2017-09-06 00:02:11 +00:00
end
end
end
2017-12-11 14:21:06 +00:00
2021-03-25 18:09:07 +00:00
describe '#parent_group_options' do
let_it_be ( :current_user ) { create ( :user ) }
let_it_be ( :group ) { create ( :group , name : 'group' ) }
let_it_be ( :group2 ) { create ( :group , name : 'group2' ) }
2019-04-02 06:49:11 +00:00
before do
group . add_owner ( current_user )
group2 . add_owner ( current_user )
end
it 'includes explicitly owned groups except self' do
expect ( parent_group_options ( group2 ) ) . to eq ( [ { id : group . id , text : group . human_name } ] . to_json )
end
it 'excludes parent group' do
subgroup = create ( :group , parent : group2 )
expect ( parent_group_options ( subgroup ) ) . to eq ( [ { id : group . id , text : group . human_name } ] . to_json )
end
it 'includes subgroups with inherited ownership' do
subgroup = create ( :group , parent : group )
expect ( parent_group_options ( group2 ) ) . to eq ( [ { id : group . id , text : group . human_name } , { id : subgroup . id , text : subgroup . human_name } ] . to_json )
end
it 'excludes own subgroups' do
create ( :group , parent : group2 )
expect ( parent_group_options ( group2 ) ) . to eq ( [ { id : group . id , text : group . human_name } ] . to_json )
end
end
2019-08-17 05:56:48 +00:00
describe '#can_disable_group_emails?' do
2021-03-25 18:09:07 +00:00
let_it_be ( :current_user ) { create ( :user ) }
let_it_be ( :group ) { create ( :group , name : 'group' ) }
let_it_be ( :subgroup ) { create ( :group , name : 'subgroup' , parent : group ) }
2019-08-17 05:56:48 +00:00
before do
allow ( helper ) . to receive ( :current_user ) { current_user }
end
it 'returns true for the group owner' do
allow ( helper ) . to receive ( :can? ) . with ( current_user , :set_emails_disabled , group ) { true }
expect ( helper . can_disable_group_emails? ( group ) ) . to be_truthy
end
it 'returns false for anyone else' do
allow ( helper ) . to receive ( :can? ) . with ( current_user , :set_emails_disabled , group ) { false }
expect ( helper . can_disable_group_emails? ( group ) ) . to be_falsey
end
context 'when subgroups' do
before do
allow ( helper ) . to receive ( :can? ) . with ( current_user , :set_emails_disabled , subgroup ) { true }
end
it 'returns false if parent group is disabling emails' do
allow ( group ) . to receive ( :emails_disabled? ) . and_return ( true )
expect ( helper . can_disable_group_emails? ( subgroup ) ) . to be_falsey
end
it 'returns true if parent group is not disabling emails' do
allow ( group ) . to receive ( :emails_disabled? ) . and_return ( false )
expect ( helper . can_disable_group_emails? ( subgroup ) ) . to be_truthy
end
end
end
2020-04-24 09:09:44 +00:00
describe '#can_update_default_branch_protection?' do
2021-03-25 18:09:07 +00:00
let_it_be ( :current_user ) { create ( :user ) }
let_it_be ( :group ) { create ( :group ) }
2020-04-24 09:09:44 +00:00
subject { helper . can_update_default_branch_protection? ( group ) }
before do
allow ( helper ) . to receive ( :current_user ) { current_user }
end
context 'for users who can update default branch protection of the group' do
before do
allow ( helper ) . to receive ( :can? ) . with ( current_user , :update_default_branch_protection , group ) { true }
end
it { is_expected . to be_truthy }
end
context 'for users who cannot update default branch protection of the group' do
before do
allow ( helper ) . to receive ( :can? ) . with ( current_user , :update_default_branch_protection , group ) { false }
end
it { is_expected . to be_falsey }
end
end
2020-09-04 03:08:22 +00:00
2020-10-28 15:08:49 +00:00
describe '#show_thanks_for_purchase_banner?' do
subject { helper . show_thanks_for_purchase_banner? }
it 'returns true with purchased_quantity present in params' do
allow ( controller ) . to receive ( :params ) { { purchased_quantity : '1' } }
is_expected . to be_truthy
end
it 'returns false with purchased_quantity not present in params' do
is_expected . to be_falsey
end
it 'returns false with purchased_quantity is empty in params' do
allow ( controller ) . to receive ( :params ) { { purchased_quantity : '' } }
is_expected . to be_falsey
end
end
2021-04-06 03:09:02 +00:00
describe '#render_setting_to_allow_project_access_token_creation?' do
let_it_be ( :current_user ) { create ( :user ) }
let_it_be ( :parent ) { create ( :group ) }
let_it_be ( :group ) { create ( :group , parent : parent ) }
before do
allow ( helper ) . to receive ( :current_user ) { current_user }
parent . add_owner ( current_user )
group . add_owner ( current_user )
end
it 'returns true if group is root' do
expect ( helper . render_setting_to_allow_project_access_token_creation? ( parent ) ) . to be_truthy
end
it 'returns false if group is subgroup' do
expect ( helper . render_setting_to_allow_project_access_token_creation? ( group ) ) . to be_falsy
end
end
2021-08-19 00:11:16 +00:00
describe '#can_admin_group_member?' do
let_it_be ( :user ) { create ( :user ) }
let_it_be ( :group ) { create ( :group ) }
before do
allow ( helper ) . to receive ( :current_user ) { user }
end
it 'returns true when current_user can admin members' do
group . add_owner ( user )
expect ( helper . can_admin_group_member? ( group ) ) . to be ( true )
end
it 'returns false when current_user can not admin members' do
expect ( helper . can_admin_group_member? ( group ) ) . to be ( false )
end
end
2021-08-26 12:10:28 +00:00
describe '#localized_jobs_to_be_done_choices' do
it 'has a translation for all `jobs_to_be_done` values' do
expect ( localized_jobs_to_be_done_choices . keys ) . to match_array ( NamespaceSetting . jobs_to_be_dones . keys )
end
end
2022-06-08 21:08:52 +00:00
describe '#group_name_and_path_app_data' do
let_it_be ( :group ) { build ( :group , name : 'My awesome group' , path : 'my-awesome-group' ) }
let_it_be ( :subgroup ) { build ( :group , parent : group ) }
let_it_be ( :root_url ) { 'https://gitlab.com/' }
before do
allow ( Gitlab . config . mattermost ) . to receive ( :enabled ) . and_return ( true )
allow ( helper ) . to receive ( :root_url ) { root_url }
end
context 'when group has a parent' do
it 'returns expected hash' do
expect ( group_name_and_path_app_data ( subgroup ) ) . to match (
{ base_path : 'https://gitlab.com/my-awesome-group' , mattermost_enabled : 'true' }
)
end
end
context 'when group does not have a parent' do
it 'returns expected hash' do
expect ( group_name_and_path_app_data ( group ) ) . to match (
{ base_path : root_url , mattermost_enabled : 'true' }
)
end
end
end
2022-06-10 03:08:14 +00:00
describe '#subgroups_and_projects_list_app_data' do
let_it_be ( :group ) { create ( :group ) }
let_it_be ( :user ) { create ( :user ) }
before do
allow ( helper ) . to receive ( :current_user ) . and_return ( user )
allow ( helper ) . to receive ( :can? ) . with ( user , :create_subgroup , group ) { true }
allow ( helper ) . to receive ( :can? ) . with ( user , :create_projects , group ) { true }
end
it 'returns expected hash' do
expect ( helper . subgroups_and_projects_list_app_data ( group ) ) . to match ( {
show_schema_markup : 'true' ,
new_subgroup_path : including ( " groups/new?parent_id= #{ group . id } " ) ,
new_project_path : including ( " /projects/new?namespace_id= #{ group . id } " ) ,
new_subgroup_illustration : including ( 'illustrations/subgroup-create-new-sm' ) ,
new_project_illustration : including ( 'illustrations/project-create-new-sm' ) ,
empty_subgroup_illustration : including ( 'illustrations/empty-state/empty-subgroup-md' ) ,
render_empty_state : 'true' ,
can_create_subgroups : 'true' ,
can_create_projects : 'true'
} )
end
end
2022-06-16 15:09:00 +00:00
describe " # enabled_git_access_protocol_options_for_group " do
subject { helper . enabled_git_access_protocol_options_for_group }
before do
expect ( :: Gitlab :: CurrentSettings ) . to receive ( :enabled_git_access_protocol ) . and_return ( instance_setting )
end
context " instance setting is nil " do
let ( :instance_setting ) { nil }
it { is_expected . to contain_exactly ( [ _ ( " Both SSH and HTTP(S) " ) , " all " ] , [ _ ( " Only SSH " ) , " ssh " ] , [ _ ( " Only HTTP(S) " ) , " http " ] ) }
end
context " instance setting is blank " do
let ( :instance_setting ) { nil }
it { is_expected . to contain_exactly ( [ _ ( " Both SSH and HTTP(S) " ) , " all " ] , [ _ ( " Only SSH " ) , " ssh " ] , [ _ ( " Only HTTP(S) " ) , " http " ] ) }
end
context " instance setting is ssh " do
let ( :instance_setting ) { " ssh " }
it { is_expected . to contain_exactly ( [ _ ( " Only SSH " ) , " ssh " ] ) }
end
context " instance setting is http " do
let ( :instance_setting ) { " http " }
it { is_expected . to contain_exactly ( [ _ ( " Only HTTP(S) " ) , " http " ] ) }
end
end
2015-03-12 21:51:41 +00:00
end