Commit 892dea67 authored by Felipe Artur's avatar Felipe Artur
Browse files

Project tools visibility level

parent d24571d75b56
require 'spec_helper'
include WaitForAjax
describe 'Edit Project Settings', feature: true do
let(:member) { create(:user) }
let!(:project) { create(:project, :public, path: 'gitlab', name: 'sample') }
let(:non_member) { create(:user) }
describe 'project features visibility selectors', js: true do
before do
project.team << [member, :master]
login_as(member)
end
tools = { builds: "pipelines", issues: "issues", wiki: "wiki", snippets: "snippets", merge_requests: "merge_requests" }
tools.each do |tool_name, shortcut_name|
describe "feature #{tool_name}" do
it 'toggles visibility' do
visit edit_namespace_project_path(project.namespace, project)
select 'Disabled', from: "project_project_feature_attributes_#{tool_name}_access_level"
click_button 'Save changes'
wait_for_ajax
expect(page).not_to have_selector(".shortcuts-#{shortcut_name}")
select 'Everyone with access', from: "project_project_feature_attributes_#{tool_name}_access_level"
click_button 'Save changes'
wait_for_ajax
expect(page).to have_selector(".shortcuts-#{shortcut_name}")
select 'Only team members', from: "project_project_feature_attributes_#{tool_name}_access_level"
click_button 'Save changes'
wait_for_ajax
expect(page).to have_selector(".shortcuts-#{shortcut_name}")
sleep 0.1
end
end
end
end
describe 'project features visibility pages' do
before do
@tools =
{
builds: namespace_project_pipelines_path(project.namespace, project),
issues: namespace_project_issues_path(project.namespace, project),
wiki: namespace_project_wiki_path(project.namespace, project, :home),
snippets: namespace_project_snippets_path(project.namespace, project),
merge_requests: namespace_project_merge_requests_path(project.namespace, project),
}
end
context 'normal user' do
it 'renders 200 if tool is enabled' do
@tools.each do |method_name, url|
project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::ENABLED)
visit url
expect(page.status_code).to eq(200)
end
end
it 'renders 404 if feature is disabled' do
@tools.each do |method_name, url|
project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::DISABLED)
visit url
expect(page.status_code).to eq(404)
end
end
it 'renders 404 if feature is enabled only for team members' do
project.team.truncate
@tools.each do |method_name, url|
project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::PRIVATE)
visit url
expect(page.status_code).to eq(404)
end
end
it 'renders 200 if users is member of group' do
group = create(:group)
project.group = group
project.save
group.add_owner(member)
@tools.each do |method_name, url|
project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::PRIVATE)
visit url
expect(page.status_code).to eq(200)
end
end
end
context 'admin user' do
before do
non_member.update_attribute(:admin, true)
login_as(non_member)
end
it 'renders 404 if feature is disabled' do
@tools.each do |method_name, url|
project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::DISABLED)
visit url
expect(page.status_code).to eq(404)
end
end
it 'renders 200 if feature is enabled only for team members' do
project.team.truncate
@tools.each do |method_name, url|
project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::PRIVATE)
visit url
expect(page.status_code).to eq(200)
end
end
end
end
end
......@@ -7,7 +7,8 @@
it 'recognizes CI' do
token = '123'
project = create(:empty_project)
project.update_attributes(runners_token: token, builds_enabled: true)
project.update_attributes(runners_token: token)
ip = 'ip'
expect(gl_auth).to receive(:rate_limit!).with(ip, success: true, login: 'gitlab-ci-token')
......
......@@ -3,7 +3,7 @@
describe Gitlab::GithubImport::Importer, lib: true do
describe '#execute' do
context 'when an error occurs' do
let(:project) { create(:project, import_url: 'https://github.com/octocat/Hello-World.git', wiki_enabled: false) }
let(:project) { create(:project, import_url: 'https://github.com/octocat/Hello-World.git', wiki_access_level: ProjectFeature::DISABLED) }
let(:octocat) { double(id: 123456, login: 'octocat') }
let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
......
{
"description": "Nisi et repellendus ut enim quo accusamus vel magnam.",
"issues_enabled": true,
"merge_requests_enabled": true,
"wiki_enabled": true,
"snippets_enabled": false,
"visibility_level": 10,
"archived": false,
"issues": [
......@@ -7307,4 +7303,4 @@
"protected_branches": [
]
}
\ No newline at end of file
}
......@@ -5,7 +5,7 @@
let(:user) { create(:user) }
let(:namespace) { create(:namespace, owner: user) }
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: "", project_path: 'path') }
let(:project) { create(:empty_project, name: 'project', path: 'project') }
let!(:project) { create(:empty_project, name: 'project', path: 'project', builds_access_level: ProjectFeature::DISABLED, issues_access_level: ProjectFeature::DISABLED) }
let(:project_tree_restorer) { described_class.new(user: user, shared: shared, project: project) }
let(:restored_project_json) { project_tree_restorer.restore }
......@@ -18,6 +18,17 @@
expect(restored_project_json).to be true
end
it 'restore correct project features' do
restored_project_json
project = Project.find_by_path('project')
expect(project.project_feature.issues_access_level).to eq(ProjectFeature::DISABLED)
expect(project.project_feature.builds_access_level).to eq(ProjectFeature::DISABLED)
expect(project.project_feature.snippets_access_level).to eq(ProjectFeature::ENABLED)
expect(project.project_feature.wiki_access_level).to eq(ProjectFeature::ENABLED)
expect(project.project_feature.merge_requests_access_level).to eq(ProjectFeature::ENABLED)
end
it 'creates a valid pipeline note' do
restored_project_json
......
......@@ -111,6 +111,14 @@
expect(saved_project_json['issues'].first['label_links'].first['label']).not_to be_empty
end
it 'has project feature' do
project_feature = saved_project_json['project_feature']
expect(project_feature).not_to be_empty
expect(project_feature["issues_access_level"]).to eq(ProjectFeature::DISABLED)
expect(project_feature["wiki_access_level"]).to eq(ProjectFeature::ENABLED)
expect(project_feature["builds_access_level"]).to eq(ProjectFeature::PRIVATE)
end
it 'does not complain about non UTF-8 characters in MR diffs' do
ActiveRecord::Base.connection.execute("UPDATE merge_request_diffs SET st_diffs = '---\n- :diff: !binary |-\n LS0tIC9kZXYvbnVsbAorKysgYi9pbWFnZXMvbnVjb3IucGRmCkBAIC0wLDAg\n KzEsMTY3OSBAQAorJVBERi0xLjUNJeLjz9MNCisxIDAgb2JqDTw8L01ldGFk\n YXR'")
......@@ -154,6 +162,10 @@ def setup_project
create(:event, target: milestone, project: project, action: Event::CREATED, author: user)
project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED)
project.project_feature.update_attribute(:wiki_access_level, ProjectFeature::ENABLED)
project.project_feature.update_attribute(:builds_access_level, ProjectFeature::PRIVATE)
project
end
......
......@@ -32,6 +32,12 @@
expect(described_class.new(shared: shared).project_tree).to match(include: [:issues])
end
it 'generates the correct hash for a single project feature relation' do
setup_yaml(project_tree: [:project_feature])
expect(described_class.new(shared: shared).project_tree).to match(include: [:project_feature])
end
it 'generates the correct hash for a multiple project relation' do
setup_yaml(project_tree: [:issues, :snippets])
......
......@@ -220,13 +220,13 @@
end
describe '.project_disabled_features_rules' do
let(:project) { build(:project) }
let(:project) { create(:project, wiki_access_level: ProjectFeature::DISABLED) }
subject { described_class.allowed(project.owner, project) }
context 'wiki named abilities' do
it 'disables wiki abilities if the project has no wiki' do
expect(project).to receive(:has_wiki?).and_return(false)
expect(project).to receive(:has_external_wiki?).and_return(false)
expect(subject).not_to include(:read_wiki, :create_wiki, :update_wiki, :admin_wiki)
end
end
......
require 'spec_helper'
describe ProjectFeaturesCompatibility do
let(:project) { create(:project) }
let(:features) { %w(issues wiki builds merge_requests snippets) }
# We had issues_enabled, snippets_enabled, builds_enabled, merge_requests_enabled and issues_enabled fields on projects table
# All those fields got moved to a new table called project_feature and are now integers instead of booleans
# This spec tests if the described concern makes sure parameters received by the API are correctly parsed to the new table
# So we can keep it compatible
it "converts fields from 'true' to ProjectFeature::ENABLED" do
features.each do |feature|
project.update_attribute("#{feature}_enabled".to_sym, "true")
expect(project.project_feature.public_send("#{feature}_access_level")).to eq(ProjectFeature::ENABLED)
end
end
it "converts fields from 'false' to ProjectFeature::DISABLED" do
features.each do |feature|
project.update_attribute("#{feature}_enabled".to_sym, "false")
expect(project.project_feature.public_send("#{feature}_access_level")).to eq(ProjectFeature::DISABLED)
end
end
end
require 'spec_helper'
describe ProjectFeature do
let(:project) { create(:project) }
let(:user) { create(:user) }
describe '#feature_available?' do
let(:features) { %w(issues wiki builds merge_requests snippets) }
context 'when features are disabled' do
it "returns false" do
features.each do |feature|
project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::DISABLED)
expect(project.feature_available?(:issues, user)).to eq(false)
end
end
end
context 'when features are enabled only for team members' do
it "returns false when user is not a team member" do
features.each do |feature|
project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::PRIVATE)
expect(project.feature_available?(:issues, user)).to eq(false)
end
end
it "returns true when user is a team member" do
project.team << [user, :developer]
features.each do |feature|
project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::PRIVATE)
expect(project.feature_available?(:issues, user)).to eq(true)
end
end
it "returns true when user is a member of project group" do
group = create(:group)
project = create(:project, namespace: group)
group.add_developer(user)
features.each do |feature|
project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::PRIVATE)
expect(project.feature_available?(:issues, user)).to eq(true)
end
end
it "returns true if user is an admin" do
user.update_attribute(:admin, true)
features.each do |feature|
project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::PRIVATE)
expect(project.feature_available?(:issues, user)).to eq(true)
end
end
end
context 'when feature is enabled for everyone' do
it "returns true" do
features.each do |feature|
project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::ENABLED)
expect(project.feature_available?(:issues, user)).to eq(true)
end
end
end
end
describe '#*_enabled?' do
let(:features) { %w(wiki builds merge_requests) }
it "returns false when feature is disabled" do
features.each do |feature|
project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::DISABLED)
expect(project.public_send("#{feature}_enabled?")).to eq(false)
end
end
it "returns true when feature is enabled only for team members" do
features.each do |feature|
project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::PRIVATE)
expect(project.public_send("#{feature}_enabled?")).to eq(true)
end
end
it "returns true when feature is enabled for everyone" do
features.each do |feature|
project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::ENABLED)
expect(project.public_send("#{feature}_enabled?")).to eq(true)
end
end
end
end
......@@ -508,7 +508,7 @@
describe '#has_wiki?' do
let(:no_wiki_project) { build(:project, wiki_enabled: false, has_external_wiki: false) }
let(:wiki_enabled_project) { build(:project, wiki_enabled: true) }
let(:wiki_enabled_project) { build(:project) }
let(:external_wiki_project) { build(:project, has_external_wiki: true) }
it 'returns true if project is wiki enabled or has external wiki' do
......@@ -734,8 +734,6 @@ def create_pipeline
describe '#builds_enabled' do
let(:project) { create :project }
before { project.builds_enabled = true }
subject { project.builds_enabled }
it { expect(project.builds_enabled?).to be_truthy }
......
......@@ -1006,8 +1006,7 @@
end
it 'does not include projects for which issues are disabled' do
project = create(:project)
project.update_attributes(issues_enabled: false)
project = create(:project, issues_access_level: ProjectFeature::DISABLED)
expect(user.projects_where_can_admin_issues.to_a).to be_empty
expect(user.can?(:admin_issue, project)).to eq(false)
......
......@@ -73,7 +73,7 @@
end
it 'does not include open_issues_count' do
project.update_attributes( { issues_enabled: false } )
project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED)
get api('/projects', user)
expect(response.status).to eq 200
......@@ -231,8 +231,15 @@
post api('/projects', user), project
project.each_pair do |k, v|
next if %i{ issues_enabled merge_requests_enabled wiki_enabled }.include?(k)
expect(json_response[k.to_s]).to eq(v)
end
# Check feature permissions attributes
project = Project.find_by_path(project[:path])
expect(project.project_feature.issues_access_level).to eq(ProjectFeature::DISABLED)
expect(project.project_feature.merge_requests_access_level).to eq(ProjectFeature::DISABLED)
expect(project.project_feature.wiki_access_level).to eq(ProjectFeature::DISABLED)
end
it 'sets a project as public' do
......
......@@ -289,7 +289,8 @@ def attempt_login(include_password)
let(:project) { FactoryGirl.create :empty_project }
before do
project.update_attributes(runners_token: token, builds_enabled: true)
project.update_attributes(runners_token: token)
project.project_feature.update_attributes(builds_access_level: ProjectFeature::ENABLED)
end
it "downloads get status 200" do
......
......@@ -22,19 +22,20 @@
context 'when using authorized request' do
context 'using CI token' do
let(:project) { create(:empty_project, runners_token: 'token', builds_enabled: builds_enabled) }
let(:project) { create(:empty_project, runners_token: 'token') }
let(:headers) { { authorization: credentials('gitlab-ci-token', project.runners_token) } }
subject! { get '/jwt/auth', parameters, headers }
context 'project with enabled CI' do
let(:builds_enabled) { true }
subject! { get '/jwt/auth', parameters, headers }
it { expect(service_class).to have_received(:new).with(project, nil, parameters) }
end
context 'project with disabled CI' do
let(:builds_enabled) { false }
before do
project.project_feature.update_attribute(:builds_access_level, ProjectFeature::DISABLED)
end
subject! { get '/jwt/auth', parameters, headers }
it { expect(response).to have_http_status(403) }
end
......
......@@ -151,6 +151,25 @@ module Ci
it { expect(build.runner).to eq(specific_runner) }
end
end
context 'disallow when builds are disabled' do
before do
project.update(shared_runners_enabled: true)
project.project_feature.update_attribute(:builds_access_level, ProjectFeature::DISABLED)
end
context 'and uses shared runner' do
let(:build) { service.execute(shared_runner) }
it { expect(build).to be_nil }
end
context 'and uses specific runner' do
let(:build) { service.execute(specific_runner) }
it { expect(build).to be_nil }
end
end
end
end
end
......@@ -50,7 +50,7 @@
let(:changes) { new_branch_changes }
before do
project.merge_requests_enabled = false
project.project_feature.update_attribute(:merge_requests_access_level, ProjectFeature::DISABLED)
end
it_behaves_like 'no_merge_request_url'
......
......@@ -69,7 +69,7 @@
context 'wiki_enabled false does not create wiki repository directory' do
before do
@opts.merge!(wiki_enabled: false)
@opts.merge!( { project_feature_attributes: { wiki_access_level: ProjectFeature::DISABLED } })
@project = create_project(@user, @opts)
@path = ProjectWiki.new(@project, @user).send(:path_to_repo)
end
......@@ -85,7 +85,7 @@
context 'global builds_enabled false does not enable CI by default' do
before do
@opts.merge!(builds_enabled: false)
project.project_feature.update_attribute(:builds_access_level, ProjectFeature::DISABLED)
end
it { is_expected.to be_falsey }
......@@ -93,7 +93,7 @@
context 'global builds_enabled true does enable CI by default' do
before do
@opts.merge!(builds_enabled: true)
project.project_feature.update_attribute(:builds_access_level, ProjectFeature::ENABLED)
end
it { is_expected.to be_truthy }
......
......@@ -5,7 +5,7 @@
subject { described_class.new }
it 'passes when the project has no push events' do
project = create(:project_empty_repo, wiki_enabled: false)
project = create(:project_empty_repo, wiki_access_level: ProjectFeature::DISABLED)
project.events.destroy_all
break_repo(project)
......@@ -25,7 +25,7 @@
end
it 'fails if the wiki repository is broken' do
project = create(:project_empty_repo, wiki_enabled: true)
project = create(:project_empty_repo, wiki_access_level: ProjectFeature::ENABLED)
project.create_wiki
# Test sanity: everything should be fine before the wiki repo is broken
......@@ -39,7 +39,7 @@
end
it 'skips wikis when disabled' do
project = create(:project_empty_repo, wiki_enabled: false)
project = create(:project_empty_repo, wiki_access_level: ProjectFeature::DISABLED)
# Make sure the test would fail if the wiki repo was checked
break_wiki(project)
......@@ -49,7 +49,7 @@
end
it 'creates missing wikis' do
project = create(:project_empty_repo, wiki_enabled: true)
project = create(:project_empty_repo, wiki_access_level: ProjectFeature::ENABLED)
FileUtils.rm_rf(wiki_path(project))
subject.perform(project.id)
......
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