2019-07-07 11:18:12 +05:30
# frozen_string_literal: true
2015-04-26 12:48:37 +05:30
require 'spec_helper'
2020-07-28 23:09:34 +05:30
RSpec . describe GroupsHelper do
2017-09-10 17:25:29 +05:30
include ApplicationHelper
2022-08-27 11:52:29 +05:30
include AvatarsHelper
2017-09-10 17:25:29 +05:30
2021-04-29 21:17:54 +05:30
describe '#group_icon_url' do
2018-03-17 18:26:18 +05:30
it 'returns an url for the avatar' do
2021-04-29 21:17:54 +05:30
group = create ( :group , :with_avatar )
2018-11-08 19:23:39 +05:30
2021-04-29 21:17:54 +05:30
expect ( group_icon_url ( group . path ) . to_s ) . to match ( group . avatar . url )
2015-04-26 12:48:37 +05:30
end
2016-09-13 17:45:13 +05:30
it 'gives default avatar_icon when no avatar is present' do
2021-04-29 21:17:54 +05:30
group = build_stubbed ( :group )
2018-03-17 18:26:18 +05:30
expect ( group_icon_url ( group . path ) ) . to match_asset_path ( 'group_avatar.png' )
2015-04-26 12:48:37 +05:30
end
end
2016-09-29 09:46:39 +05:30
2021-04-29 21:17:54 +05:30
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-29 09:46:39 +05:30
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-04-29 21:17:54 +05:30
let_it_be_with_reload ( :another_project ) { create ( :project , namespace_id : group . id ) }
2016-09-29 09:46:39 +05:30
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-09-10 17:25:29 +05:30
2021-04-29 21:17:54 +05:30
describe '#group_title' do
2021-01-29 00:20:46 +05:30
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-09-10 17:25:29 +05:30
2021-06-08 01:23:25 +05:30
context 'traversal queries' do
shared_examples 'correct ancestor order' do
it 'outputs the groups in the correct order' do
expect ( subject )
2021-12-11 22:18:48 +05:30
. to match ( %r{ <li><a.*> #{ deep_nested_group . name } .*</li>.*<a.*> #{ very_deep_nested_group . name } </a> }m )
2021-06-08 01:23:25 +05:30
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
2018-03-17 18:26:18 +05:30
end
2021-01-29 00:20:46 +05:30
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-04-29 21:17:54 +05:30
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
2018-03-17 18:26:18 +05:30
end
2022-08-27 11:52:29 +05:30
describe '#group_title_link' do
let_it_be ( :group ) { create ( :group , :with_avatar ) }
let ( :raw_link ) { group_title_link ( group , show_avatar : true ) }
let ( :document ) { Nokogiri :: HTML . parse ( raw_link ) }
describe 'link' do
subject ( :link ) { document . css ( '.group-path' ) . first }
it 'uses the group name as innerText' do
expect ( link . inner_text ) . to eq ( group . name )
end
it 'links to the group path' do
expect ( link . attr ( 'href' ) ) . to eq ( group_path ( group ) )
end
end
describe 'icon' do
subject ( :icon ) { document . css ( '.avatar-tile' ) . first }
it 'specifies the group name as the alt text' do
expect ( icon . attr ( 'alt' ) ) . to eq ( group . name )
end
it 'uses the group\'s avatar_url' do
expect ( icon . attr ( 'src' ) ) . to eq ( group . avatar_url )
end
end
end
2019-10-12 21:52:04 +05:30
describe '#share_with_group_lock_help_text' do
2021-06-08 01:23:25 +05:30
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-11-18 22:05:49 +05:30
default_help : " Applied to all subgroups unless overridden by a group owner. " ,
2021-06-08 01:23:25 +05:30
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
2018-03-17 18:26:18 +05:30
2021-06-08 01:23:25 +05:30
let ( :possible_linked_ancestors ) do
{
root_group : root_group ,
subgroup : subgroup
}
end
let ( :users ) do
{
root_owner : root_owner ,
sub_owner : sub_owner ,
sub_sub_owner : sub_sub_owner
}
end
subject { helper . share_with_group_lock_help_text ( sub_subgroup ) }
before_all do
root_group . add_owner ( root_owner )
subgroup . add_owner ( sub_owner )
sub_subgroup . add_owner ( sub_sub_owner )
end
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
2018-03-17 18:26:18 +05:30
end
end
2021-06-08 01:23:25 +05:30
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 )
end
include_examples 'correct ancestor order'
2018-03-17 18:26:18 +05:30
end
2017-09-10 17:25:29 +05:30
end
end
2018-03-27 19:54:05 +05:30
2021-04-29 21:17:54 +05:30
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-07-07 11:18:12 +05:30
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-10-12 21:52:04 +05:30
describe '#can_disable_group_emails?' do
2021-04-29 21:17:54 +05:30
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-10-12 21:52:04 +05:30
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-05-24 23:13:21 +05:30
describe '#can_update_default_branch_protection?' do
2021-04-29 21:17:54 +05:30
let_it_be ( :current_user ) { create ( :user ) }
let_it_be ( :group ) { create ( :group ) }
2020-05-24 23:13:21 +05:30
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-11-24 15:15:51 +05:30
2022-08-13 15:12:31 +05:30
describe '#show_thanks_for_purchase_alert?' do
2022-11-25 23:54:43 +05:30
subject { helper . show_thanks_for_purchase_alert? ( quantity ) }
2021-01-29 00:20:46 +05:30
2022-11-25 23:54:43 +05:30
context 'with quantity present' do
let ( :quantity ) { 1 }
2021-01-29 00:20:46 +05:30
2022-11-25 23:54:43 +05:30
it 'returns true' do
is_expected . to be_truthy
end
2021-01-29 00:20:46 +05:30
end
2022-11-25 23:54:43 +05:30
context 'with quantity not present' do
let ( :quantity ) { nil }
it 'returns false' do
is_expected . to be_falsey
end
2021-01-29 00:20:46 +05:30
end
2022-11-25 23:54:43 +05:30
context 'with quantity empty' do
let ( :quantity ) { '' }
2021-01-29 00:20:46 +05:30
2022-11-25 23:54:43 +05:30
it 'returns false' do
is_expected . to be_falsey
end
2021-01-29 00:20:46 +05:30
end
end
2021-04-29 21:17:54 +05:30
describe '#render_setting_to_allow_project_access_token_creation?' do
2021-03-11 19:13:27 +05:30
let_it_be ( :current_user ) { create ( :user ) }
2021-04-29 21:17:54 +05:30
let_it_be ( :parent ) { create ( :group ) }
let_it_be ( :group ) { create ( :group , parent : parent ) }
2021-03-11 19:13:27 +05:30
before do
allow ( helper ) . to receive ( :current_user ) { current_user }
2021-04-29 21:17:54 +05:30
parent . add_owner ( current_user )
group . add_owner ( current_user )
2021-03-11 19:13:27 +05:30
end
2021-04-29 21:17:54 +05:30
it 'returns true if group is root' do
expect ( helper . render_setting_to_allow_project_access_token_creation? ( parent ) ) . to be_truthy
2021-03-11 19:13:27 +05:30
end
2021-04-29 21:17:54 +05:30
it 'returns false if group is subgroup' do
expect ( helper . render_setting_to_allow_project_access_token_creation? ( group ) ) . to be_falsy
2021-03-11 19:13:27 +05:30
end
end
2021-10-27 15:23:28 +05:30
describe '#can_admin_group_member?' do
let_it_be ( :user ) { create ( :user ) }
let_it_be ( :group ) { create ( :group ) }
2021-03-11 19:13:27 +05:30
2021-10-27 15:23:28 +05:30
before do
allow ( helper ) . to receive ( :current_user ) { user }
2021-03-11 19:13:27 +05:30
end
2021-10-27 15:23:28 +05:30
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
2021-03-11 19:13:27 +05:30
2021-10-27 15:23:28 +05:30
it 'returns false when current_user can not admin members' do
expect ( helper . can_admin_group_member? ( group ) ) . to be ( false )
2021-03-11 19:13:27 +05:30
end
end
2021-11-11 11:23:49 +05:30
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-07-23 23:45:48 +05:30
2022-08-27 11:52:29 +05:30
describe '#subgroup_creation_data' do
let_it_be ( :name ) { 'parent group' }
let_it_be ( :group ) { build ( :group , name : name ) }
2022-07-23 23:45:48 +05:30
let_it_be ( :subgroup ) { build ( :group , parent : group ) }
2022-08-27 11:52:29 +05:30
context 'when group has a parent' do
it 'returns expected hash' do
expect ( subgroup_creation_data ( subgroup ) ) . to eq ( {
import_existing_group_path : '/groups/new#import-group-pane' ,
parent_group_name : name
} )
end
end
context 'when group does not have a parent' do
it 'returns expected hash' do
expect ( subgroup_creation_data ( group ) ) . to eq ( {
import_existing_group_path : '/groups/new#import-group-pane' ,
parent_group_name : nil
} )
end
end
end
describe '#group_name_and_path_app_data' do
2022-07-23 23:45:48 +05:30
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
2022-08-27 11:52:29 +05:30
expect ( group_name_and_path_app_data ) . to match ( {
base_path : 'https://gitlab.com/' ,
mattermost_enabled : 'true'
} )
2022-07-23 23:45:48 +05:30
end
end
end
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' ,
2022-08-27 11:52:29 +05:30
new_subgroup_path : including ( " groups/new?parent_id= #{ group . id } # create-group-pane " ) ,
2022-07-23 23:45:48 +05:30
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-10-11 01:57:18 +05:30
describe '#group_overview_tabs_app_data' do
let_it_be ( :group ) { create ( :group ) }
let_it_be ( :user ) { create ( :user ) }
2022-11-25 23:54:43 +05:30
let_it_be ( :initial_sort ) { 'created_asc' }
2022-10-11 01:57:18 +05:30
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 }
2022-11-25 23:54:43 +05:30
allow ( helper ) . to receive ( :project_list_sort_by ) . and_return ( initial_sort )
2022-10-11 01:57:18 +05:30
end
it 'returns expected hash' do
expect ( helper . group_overview_tabs_app_data ( group ) ) . to match (
{
subgroups_and_projects_endpoint : including ( " /groups/ #{ group . path } /-/children.json " ) ,
shared_projects_endpoint : including ( " /groups/ #{ group . path } /-/shared_projects.json " ) ,
archived_projects_endpoint : including ( " /groups/ #{ group . path } /-/children.json?archived=only " ) ,
2022-11-25 23:54:43 +05:30
current_group_visibility : group . visibility ,
initial_sort : initial_sort
2022-10-11 01:57:18 +05:30
} . merge ( helper . group_overview_tabs_app_data ( group ) )
)
end
end
2022-07-23 23:45:48 +05:30
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-04-26 12:48:37 +05:30
end