Hide restricted and disallowed visibility radios

Show a message if many levels are restricted and a
different message if all levels are restricted.
This commit is contained in:
Luke Bennett 2019-06-28 22:38:26 +01:00 committed by Douglas Barbosa Alexandre
parent 96277bb9d6
commit 9b40fc7416
No known key found for this signature in database
GPG key ID: 4DC4A918C347CAC9
6 changed files with 365 additions and 311 deletions

View file

@ -65,20 +65,6 @@ module VisibilityLevelHelper
end
end
def restricted_visibility_level_description(level)
level_name = Gitlab::VisibilityLevel.level_name(level)
_("%{level_name} visibility has been restricted by the administrator.") % { level_name: level_name.capitalize }
end
def disallowed_visibility_level_description(level, form_model)
case form_model
when Project
disallowed_project_visibility_level_description(level, form_model)
when Group
disallowed_group_visibility_level_description(level, form_model)
end
end
# Note: these messages closely mirror the form validation strings found in the project
# model and any changes or additons to these may also need to be made there.
def disallowed_project_visibility_level_description(level, project)
@ -181,6 +167,14 @@ module VisibilityLevelHelper
[requested_level, max_allowed_visibility_level(form_model)].min
end
def multiple_visibility_levels_restricted?
restricted_visibility_levels.many? # rubocop: disable CodeReuse/ActiveRecord
end
def all_visibility_levels_restricted?
Gitlab::VisibilityLevel.values == restricted_visibility_levels
end
private
def max_allowed_visibility_level(form_model)

View file

@ -1,17 +1,19 @@
- Gitlab::VisibilityLevel.values.each do |level|
- disallowed = disallowed_visibility_level?(form_model, level)
- restricted = restricted_visibility_levels.include?(level)
- disabled = disallowed || restricted
.form-check{ class: [('disabled' if disabled), ('restricted' if restricted)] }
= form.radio_button model_method, level, checked: (selected_level == level), disabled: disabled, class: 'form-check-input', data: { track_label: "blank_project", track_event: "activate_form_input", track_property: "#{model_method}", track_value: "#{level}" }
- next if disallowed || restricted
.form-check
= form.radio_button model_method, level, checked: (selected_level == level), class: 'form-check-input', data: { track_label: "blank_project", track_event: "activate_form_input", track_property: "#{model_method}", track_value: "#{level}" }
= form.label "#{model_method}_#{level}", class: 'form-check-label' do
= visibility_level_icon(level)
.option-title
= visibility_level_label(level)
.option-description
= visibility_level_description(level, form_model)
.option-disabled-reason
- if restricted
= restricted_visibility_level_description(level)
- elsif disallowed
= disallowed_visibility_level_description(level, form_model)
.text-muted
- if all_visibility_levels_restricted?
= _('Visibility settings have been disabled by the administrator.')
- elsif multiple_visibility_levels_restricted?
= _('Other visibility settings have been disabled by the administrator.')

View file

@ -0,0 +1,5 @@
---
title: Hide restricted and disallowed visibility radios
merge_request: 30590
author:
type: fixed

View file

@ -171,9 +171,6 @@ msgstr ""
msgid "%{level_name} is not allowed since the fork source project has lower visibility."
msgstr ""
msgid "%{level_name} visibility has been restricted by the administrator."
msgstr ""
msgid "%{link_start}Read more%{link_end} about role permissions"
msgstr ""
@ -7228,6 +7225,9 @@ msgstr ""
msgid "Other Labels"
msgstr ""
msgid "Other visibility settings have been disabled by the administrator."
msgstr ""
msgid "Outbound requests"
msgstr ""
@ -11974,6 +11974,9 @@ msgstr ""
msgid "Visibility level:"
msgstr ""
msgid "Visibility settings have been disabled by the administrator."
msgstr ""
msgid "Visibility, project features, permissions"
msgstr ""

View file

@ -3,300 +3,330 @@ require 'spec_helper'
describe 'New project' do
include Select2Helper
let(:user) { create(:admin) }
context 'as a user' do
let(:user) { create(:user) }
before do
sign_in(user)
end
it 'shows "New project" page', :js do
visit new_project_path
expect(page).to have_content('Project name')
expect(page).to have_content('Project URL')
expect(page).to have_content('Project slug')
find('#import-project-tab').click
expect(page).to have_link('GitHub')
expect(page).to have_link('Bitbucket')
expect(page).to have_link('GitLab.com')
expect(page).to have_link('Google Code')
expect(page).to have_button('Repo by URL')
expect(page).to have_link('GitLab export')
end
describe 'manifest import option' do
before do
sign_in(user)
end
it 'shows a message if multiple levels are restricted' do
Gitlab::CurrentSettings.update!(
restricted_visibility_levels: [Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL]
)
visit new_project_path
find('#import-project-tab').click
expect(page).to have_content 'Other visibility settings have been disabled by the administrator.'
end
context 'when using postgres', :postgresql do
it { expect(page).to have_link('Manifest file') }
end
it 'shows a message if all levels are restricted' do
Gitlab::CurrentSettings.update!(
restricted_visibility_levels: Gitlab::VisibilityLevel.values
)
context 'when using mysql', :mysql do
it { expect(page).not_to have_link('Manifest file') }
visit new_project_path
expect(page).to have_content 'Visibility settings have been disabled by the administrator.'
end
end
context 'Visibility level selector', :js do
Gitlab::VisibilityLevel.options.each do |key, level|
it "sets selector to #{key}" do
stub_application_setting(default_project_visibility: level)
context 'as an admin' do
let(:user) { create(:admin) }
visit new_project_path
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{level}")).to be_checked
end
end
it "saves visibility level #{level} on validation error" do
visit new_project_path
choose(s_(key))
click_button('Create project')
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{level}")).to be_checked
end
end
end
context 'when group visibility is private but default is internal' do
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end
it 'has private selected' do
group = create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE)
visit new_project_path(namespace_id: group.id)
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
context 'when group visibility is public but user requests private' do
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end
it 'has private selected' do
group = create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
end
context 'Readme selector' do
it 'shows the initialize with Readme checkbox on "Blank project" tab' do
visit new_project_path
expect(page).to have_css('input#project_initialize_with_readme')
expect(page).to have_content('Initialize repository with a README')
end
it 'does not show the initialize with Readme checkbox on "Create from template" tab' do
visit new_project_path
find('#create-from-template-pane').click
first('.choose-template').click
page.within '.project-fields-form' do
expect(page).not_to have_css('input#project_initialize_with_readme')
expect(page).not_to have_content('Initialize repository with a README')
end
end
it 'does not show the initialize with Readme checkbox on "Import project" tab' do
visit new_project_path
find('#import-project-tab').click
first('.js-import-git-toggle-button').click
page.within '.toggle-import-form' do
expect(page).not_to have_css('input#project_initialize_with_readme')
expect(page).not_to have_content('Initialize repository with a README')
end
end
end
context 'Namespace selector' do
context 'with user namespace' do
before do
visit new_project_path
end
it 'selects the user namespace' do
page.within('#blank-project-pane') do
namespace = find('#project_namespace_id')
expect(namespace.text).to eq user.username
end
end
end
context 'with group namespace' do
let(:group) { create(:group, :private) }
before do
group.add_owner(user)
visit new_project_path(namespace_id: group.id)
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
namespace = find('#project_namespace_id option[selected]')
expect(namespace.text).to eq group.name
end
end
end
context 'with subgroup namespace' do
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
before do
group.add_maintainer(user)
visit new_project_path(namespace_id: subgroup.id)
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
namespace = find('#project_namespace_id option[selected]')
expect(namespace.text).to eq subgroup.full_path
end
end
end
context 'when changing namespaces dynamically', :js do
let(:public_group) { create(:group, :public) }
let(:internal_group) { create(:group, :internal) }
let(:private_group) { create(:group, :private) }
before do
public_group.add_owner(user)
internal_group.add_owner(user)
private_group.add_owner(user)
visit new_project_path(namespace_id: public_group.id)
end
it 'enables the correct visibility options' do
select2(user.namespace_id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
select2(public_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
select2(internal_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
select2(private_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
end
end
end
context 'Import project options', :js do
before do
visit new_project_path
find('#import-project-tab').click
sign_in(user)
end
context 'from git repository url, "Repo by URL"' do
it 'shows "New project" page', :js do
visit new_project_path
expect(page).to have_content('Project name')
expect(page).to have_content('Project URL')
expect(page).to have_content('Project slug')
find('#import-project-tab').click
expect(page).to have_link('GitHub')
expect(page).to have_link('Bitbucket')
expect(page).to have_link('GitLab.com')
expect(page).to have_link('Google Code')
expect(page).to have_button('Repo by URL')
expect(page).to have_link('GitLab export')
end
describe 'manifest import option' do
before do
visit new_project_path
find('#import-project-tab').click
end
context 'when using postgres', :postgresql do
it { expect(page).to have_link('Manifest file') }
end
context 'when using mysql', :mysql do
it { expect(page).not_to have_link('Manifest file') }
end
end
context 'Visibility level selector', :js do
Gitlab::VisibilityLevel.options.each do |key, level|
it "sets selector to #{key}" do
stub_application_setting(default_project_visibility: level)
visit new_project_path
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{level}")).to be_checked
end
end
it "saves visibility level #{level} on validation error" do
visit new_project_path
choose(s_(key))
click_button('Create project')
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{level}")).to be_checked
end
end
end
context 'when group visibility is private but default is internal' do
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end
it 'has private selected' do
group = create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE)
visit new_project_path(namespace_id: group.id)
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
context 'when group visibility is public but user requests private' do
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end
it 'has private selected' do
group = create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
end
context 'Readme selector' do
it 'shows the initialize with Readme checkbox on "Blank project" tab' do
visit new_project_path
expect(page).to have_css('input#project_initialize_with_readme')
expect(page).to have_content('Initialize repository with a README')
end
it 'does not show the initialize with Readme checkbox on "Create from template" tab' do
visit new_project_path
find('#create-from-template-pane').click
first('.choose-template').click
page.within '.project-fields-form' do
expect(page).not_to have_css('input#project_initialize_with_readme')
expect(page).not_to have_content('Initialize repository with a README')
end
end
it 'does not show the initialize with Readme checkbox on "Import project" tab' do
visit new_project_path
find('#import-project-tab').click
first('.js-import-git-toggle-button').click
end
it 'does not autocomplete sensitive git repo URL' do
autocomplete = find('#project_import_url')['autocomplete']
expect(autocomplete).to eq('off')
end
it 'shows import instructions' do
git_import_instructions = first('.js-toggle-content')
expect(git_import_instructions).to be_visible
expect(git_import_instructions).to have_content 'Git repository URL'
end
it 'keeps "Import project" tab open after form validation error' do
collision_project = create(:project, name: 'test-name-collision', namespace: user.namespace)
fill_in 'project_import_url', with: collision_project.http_url_to_repo
fill_in 'project_name', with: collision_project.name
click_on 'Create project'
expect(page).to have_css('#import-project-pane.active')
expect(page).not_to have_css('.toggle-import-form.hide')
page.within '.toggle-import-form' do
expect(page).not_to have_css('input#project_initialize_with_readme')
expect(page).not_to have_content('Initialize repository with a README')
end
end
end
context 'from GitHub' do
before do
first('.js-import-github').click
context 'Namespace selector' do
context 'with user namespace' do
before do
visit new_project_path
end
it 'selects the user namespace' do
page.within('#blank-project-pane') do
namespace = find('#project_namespace_id')
expect(namespace.text).to eq user.username
end
end
end
it 'shows import instructions' do
expect(page).to have_content('Import repositories from GitHub')
expect(current_path).to eq new_import_github_path
context 'with group namespace' do
let(:group) { create(:group, :private) }
before do
group.add_owner(user)
visit new_project_path(namespace_id: group.id)
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
namespace = find('#project_namespace_id option[selected]')
expect(namespace.text).to eq group.name
end
end
end
context 'with subgroup namespace' do
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
before do
group.add_maintainer(user)
visit new_project_path(namespace_id: subgroup.id)
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
namespace = find('#project_namespace_id option[selected]')
expect(namespace.text).to eq subgroup.full_path
end
end
end
context 'when changing namespaces dynamically', :js do
let(:public_group) { create(:group, :public) }
let(:internal_group) { create(:group, :internal) }
let(:private_group) { create(:group, :private) }
before do
public_group.add_owner(user)
internal_group.add_owner(user)
private_group.add_owner(user)
visit new_project_path(namespace_id: public_group.id)
end
it 'enables the correct visibility options' do
select2(user.namespace_id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
select2(public_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
select2(internal_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
select2(private_group.id, from: '#project_namespace_id')
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).to be_disabled
expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
end
end
end
context 'from Google Code' do
context 'Import project options', :js do
before do
first('.import_google_code').click
visit new_project_path
find('#import-project-tab').click
end
it 'shows import instructions' do
expect(page).to have_content('Import projects from Google Code')
expect(current_path).to eq new_import_google_code_path
context 'from git repository url, "Repo by URL"' do
before do
first('.js-import-git-toggle-button').click
end
it 'does not autocomplete sensitive git repo URL' do
autocomplete = find('#project_import_url')['autocomplete']
expect(autocomplete).to eq('off')
end
it 'shows import instructions' do
git_import_instructions = first('.js-toggle-content')
expect(git_import_instructions).to be_visible
expect(git_import_instructions).to have_content 'Git repository URL'
end
it 'keeps "Import project" tab open after form validation error' do
collision_project = create(:project, name: 'test-name-collision', namespace: user.namespace)
fill_in 'project_import_url', with: collision_project.http_url_to_repo
fill_in 'project_name', with: collision_project.name
click_on 'Create project'
expect(page).to have_css('#import-project-pane.active')
expect(page).not_to have_css('.toggle-import-form.hide')
end
end
context 'from GitHub' do
before do
first('.js-import-github').click
end
it 'shows import instructions' do
expect(page).to have_content('Import repositories from GitHub')
expect(current_path).to eq new_import_github_path
end
end
context 'from Google Code' do
before do
first('.import_google_code').click
end
it 'shows import instructions' do
expect(page).to have_content('Import projects from Google Code')
expect(current_path).to eq new_import_google_code_path
end
end
context 'from manifest file', :postgresql do
before do
first('.import_manifest').click
end
it 'shows import instructions' do
expect(page).to have_content('Manifest file import')
expect(current_path).to eq new_import_manifest_path
end
end
end
context 'from manifest file', :postgresql do
before do
first('.import_manifest').click
end
context 'Namespace selector' do
context 'with group with DEVELOPER_MAINTAINER_PROJECT_ACCESS project_creation_level' do
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
it 'shows import instructions' do
expect(page).to have_content('Manifest file import')
expect(current_path).to eq new_import_manifest_path
end
end
end
before do
group.add_developer(user)
visit new_project_path(namespace_id: group.id)
end
context 'Namespace selector' do
context 'with group with DEVELOPER_MAINTAINER_PROJECT_ACCESS project_creation_level' do
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
it 'selects the group namespace' do
page.within('#blank-project-pane') do
namespace = find('#project_namespace_id option[selected]')
before do
group.add_developer(user)
visit new_project_path(namespace_id: group.id)
end
it 'selects the group namespace' do
page.within('#blank-project-pane') do
namespace = find('#project_namespace_id option[selected]')
expect(namespace.text).to eq group.full_path
expect(namespace.text).to eq group.full_path
end
end
end
end

View file

@ -137,32 +137,6 @@ describe VisibilityLevelHelper do
end
end
describe "disallowed_visibility_level_description" do
let(:group) { create(:group, :internal) }
let!(:subgroup) { create(:group, :internal, parent: group) }
let!(:project) { create(:project, :internal, group: group) }
describe "project" do
it "provides correct description for disabled levels" do
expect(disallowed_visibility_level?(project, Gitlab::VisibilityLevel::PUBLIC)).to be_truthy
expect(strip_tags disallowed_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC, project))
.to include "the visibility of #{project.group.name} is internal"
end
end
describe "group" do
it "provides correct description for disabled levels" do
expect(disallowed_visibility_level?(group, Gitlab::VisibilityLevel::PRIVATE)).to be_truthy
expect(disallowed_visibility_level_description(Gitlab::VisibilityLevel::PRIVATE, group))
.to include "it contains projects with higher visibility", "it contains sub-groups with higher visibility"
expect(disallowed_visibility_level?(subgroup, Gitlab::VisibilityLevel::PUBLIC)).to be_truthy
expect(strip_tags disallowed_visibility_level_description(Gitlab::VisibilityLevel::PUBLIC, subgroup))
.to include "the visibility of #{group.name} is internal"
end
end
end
describe "selected_visibility_level" do
let(:group) { create(:group, :public) }
let!(:project) { create(:project, :internal, group: group) }
@ -207,4 +181,50 @@ describe VisibilityLevelHelper do
end
end
end
describe 'multiple_visibility_levels_restricted?' do
using RSpec::Parameterized::TableSyntax
let(:user) { create(:user) }
subject { helper.multiple_visibility_levels_restricted? }
where(:restricted_visibility_levels, :expected) do
[Gitlab::VisibilityLevel::PUBLIC] | false
[Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::INTERNAL] | true
[Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PRIVATE] | true
end
with_them do
before do
allow(helper).to receive(:current_user) { user }
allow(Gitlab::CurrentSettings.current_application_settings).to receive(:restricted_visibility_levels) { restricted_visibility_levels }
end
it { is_expected.to eq(expected) }
end
end
describe 'all_visibility_levels_restricted?' do
using RSpec::Parameterized::TableSyntax
let(:user) { create(:user) }
subject { helper.all_visibility_levels_restricted? }
where(:restricted_visibility_levels, :expected) do
[Gitlab::VisibilityLevel::PUBLIC] | false
[Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::INTERNAL] | false
Gitlab::VisibilityLevel.values | true
end
with_them do
before do
allow(helper).to receive(:current_user) { user }
allow(Gitlab::CurrentSettings.current_application_settings).to receive(:restricted_visibility_levels) { restricted_visibility_levels }
end
it { is_expected.to eq(expected) }
end
end
end