summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Artur <felipefac@gmail.com>2016-08-01 19:31:21 -0300
committerFelipe Artur <felipefac@gmail.com>2016-08-31 20:53:24 -0300
commitb9c604d84009be1d76ca21679696cccfe42e157b (patch)
tree5a86f37b68a71a4e68a5a58a4ec3a08c540bde7d
parente71cd7a300017cf85e16de3b1c68fdb25c3a4b4d (diff)
downloadgitlab-ce-issue_19734.tar.gz
Project tools visibility levelissue_19734
-rw-r--r--CHANGELOG1
-rw-r--r--app/controllers/jwt_controller.rb2
-rw-r--r--app/controllers/projects/application_controller.rb2
-rw-r--r--app/controllers/projects/discussions_controller.rb2
-rw-r--r--app/controllers/projects/issues_controller.rb2
-rw-r--r--app/controllers/projects/labels_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb2
-rw-r--r--app/controllers/projects/milestones_controller.rb2
-rw-r--r--app/controllers/projects/snippets_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb18
-rw-r--r--app/helpers/application_helper.rb2
-rw-r--r--app/helpers/compare_helper.rb2
-rw-r--r--app/helpers/projects_helper.rb19
-rw-r--r--app/models/concerns/project_features_compatibility.rb37
-rw-r--r--app/models/project.rb27
-rw-r--r--app/models/project_feature.rb63
-rw-r--r--app/models/user.rb2
-rw-r--r--app/policies/project_policy.rb12
-rw-r--r--app/services/ci/register_build_service.rb8
-rw-r--r--app/services/merge_requests/get_urls_service.rb2
-rw-r--r--app/services/projects/create_service.rb4
-rw-r--r--app/services/projects/fork_service.rb4
-rw-r--r--app/views/layouts/nav/_project_settings.html.haml2
-rw-r--r--app/views/projects/edit.html.haml98
-rw-r--r--app/views/projects/graphs/_head.html.haml2
-rw-r--r--db/migrate/20160831214002_create_project_features.rb16
-rw-r--r--db/migrate/20160831214543_migrate_project_features.rb44
-rw-r--r--db/migrate/20160831223750_remove_features_enabled_from_projects.rb29
-rw-r--r--db/schema.rb20
-rw-r--r--doc/user/permissions.md9
-rw-r--r--features/steps/project/project.rb2
-rw-r--r--features/steps/shared/project.rb6
-rw-r--r--lib/api/entities.rb12
-rw-r--r--lib/api/groups.rb2
-rw-r--r--lib/api/projects.rb2
-rw-r--r--lib/gitlab/github_import/importer.rb2
-rw-r--r--lib/gitlab/github_import/project_creator.rb12
-rw-r--r--lib/gitlab/import_export/import_export.yml7
-rw-r--r--spec/controllers/projects/snippets_controller_spec.rb2
-rw-r--r--spec/factories/projects.rb21
-rw-r--r--spec/features/projects/features_visibility_spec.rb117
-rw-r--r--spec/features/projects/import_export/test_project_export.tar.gzbin687442 -> 676870 bytes
-rw-r--r--spec/lib/gitlab/auth_spec.rb3
-rw-r--r--spec/lib/gitlab/github_import/importer_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/project.json6
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb13
-rw-r--r--spec/lib/gitlab/import_export/project_tree_saver_spec.rb12
-rw-r--r--spec/lib/gitlab/import_export/reader_spec.rb6
-rw-r--r--spec/models/ability_spec.rb4
-rw-r--r--spec/models/concerns/project_features_compatibility_spec.rb25
-rw-r--r--spec/models/project_feature_spec.rb91
-rw-r--r--spec/models/project_spec.rb4
-rw-r--r--spec/models/user_spec.rb3
-rw-r--r--spec/requests/api/projects_spec.rb9
-rw-r--r--spec/requests/git_http_spec.rb3
-rw-r--r--spec/requests/jwt_controller_spec.rb13
-rw-r--r--spec/services/ci/register_build_service_spec.rb19
-rw-r--r--spec/services/merge_requests/get_urls_service_spec.rb2
-rw-r--r--spec/services/projects/create_service_spec.rb6
-rw-r--r--spec/workers/repository_check/single_repository_worker_spec.rb8
60 files changed, 708 insertions, 143 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 13ec1bb885f..a2b6766f98b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -34,6 +34,7 @@ v 8.12.0 (unreleased)
- Added project specific enable/disable setting for LFS !5997
- Don't expose a user's token in the `/api/v3/user` API (!6047)
- Remove redundant js-timeago-pending from user activity log (ClemMakesApps)
+ - Ability to manage project issues, snippets, wiki, merge requests and builds access level
- Added tests for diff notes
- Add a button to download latest successful artifacts for branches and tags !5142
- Remove redundant pipeline tooltips (ClemMakesApps)
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb
index 014b9b43ff2..66ebdcc37a7 100644
--- a/app/controllers/jwt_controller.rb
+++ b/app/controllers/jwt_controller.rb
@@ -37,7 +37,7 @@ class JwtController < ApplicationController
def authenticate_project(login, password)
if login == 'gitlab-ci-token'
- Project.find_by(builds_enabled: true, runners_token: password)
+ Project.with_builds_enabled.find_by(runners_token: password)
end
end
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index 91315a07deb..b2ff36f6538 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -88,6 +88,6 @@ class Projects::ApplicationController < ApplicationController
end
def builds_enabled
- return render_404 unless @project.builds_enabled?
+ return render_404 unless @project.feature_available?(:builds, current_user)
end
end
diff --git a/app/controllers/projects/discussions_controller.rb b/app/controllers/projects/discussions_controller.rb
index b2e8733ccb7..d174e1145a7 100644
--- a/app/controllers/projects/discussions_controller.rb
+++ b/app/controllers/projects/discussions_controller.rb
@@ -38,6 +38,6 @@ class Projects::DiscussionsController < Projects::ApplicationController
end
def module_enabled
- render_404 unless @project.merge_requests_enabled
+ render_404 unless @project.feature_available?(:merge_requests, current_user)
end
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 7c03dcd2e64..72d2d361878 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -201,7 +201,7 @@ class Projects::IssuesController < Projects::ApplicationController
end
def module_enabled
- return render_404 unless @project.issues_enabled && @project.default_issues_tracker?
+ return render_404 unless @project.feature_available?(:issues, current_user) && @project.default_issues_tracker?
end
def redirect_to_external_issue_tracker
diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb
index 0ca675623e5..28fa4a5b141 100644
--- a/app/controllers/projects/labels_controller.rb
+++ b/app/controllers/projects/labels_controller.rb
@@ -99,7 +99,7 @@ class Projects::LabelsController < Projects::ApplicationController
protected
def module_enabled
- unless @project.issues_enabled || @project.merge_requests_enabled
+ unless @project.feature_available?(:issues, current_user) || @project.feature_available?(:merge_requests, current_user)
return render_404
end
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 4f5f3b6aa09..4f9ca0097a1 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -413,7 +413,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def module_enabled
- return render_404 unless @project.merge_requests_enabled
+ return render_404 unless @project.feature_available?(:merge_requests, current_user)
end
def validates_merge_request
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index da2892bfb3f..ff63f22cb5b 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -106,7 +106,7 @@ class Projects::MilestonesController < Projects::ApplicationController
end
def module_enabled
- unless @project.issues_enabled || @project.merge_requests_enabled
+ unless @project.feature_available?(:issues, current_user) || @project.feature_available?(:merge_requests, current_user)
return render_404
end
end
diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb
index 6d0a7ee1031..17ceefec3b8 100644
--- a/app/controllers/projects/snippets_controller.rb
+++ b/app/controllers/projects/snippets_controller.rb
@@ -94,7 +94,7 @@ class Projects::SnippetsController < Projects::ApplicationController
end
def module_enabled
- return render_404 unless @project.snippets_enabled
+ return render_404 unless @project.feature_available?(:snippets, current_user)
end
def snippet_params
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 84d6b106cd7..eaa38fa6c98 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -303,13 +303,23 @@ class ProjectsController < Projects::ApplicationController
end
def project_params
+ project_feature_attributes =
+ {
+ project_feature_attributes:
+ [
+ :issues_access_level, :builds_access_level,
+ :wiki_access_level, :merge_requests_access_level, :snippets_access_level
+ ]
+ }
+
params.require(:project).permit(
:name, :path, :description, :issues_tracker, :tag_list, :runners_token,
- :issues_enabled, :merge_requests_enabled, :snippets_enabled, :container_registry_enabled,
+ :container_registry_enabled,
:issues_tracker_id, :default_branch,
- :wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar,
- :builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
- :public_builds, :only_allow_merge_if_build_succeeds, :request_access_enabled, :lfs_enabled
+ :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar,
+ :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
+ :public_builds, :only_allow_merge_if_build_succeeds, :request_access_enabled,
+ :lfs_enabled, project_feature_attributes
)
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index f3733b01721..5f3765cad0d 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -110,7 +110,7 @@ module ApplicationHelper
project = event.project
# Skip if project repo is empty or MR disabled
- return false unless project && !project.empty_repo? && project.merge_requests_enabled
+ return false unless project && !project.empty_repo? && project.feature_available?(:merge_requests, current_user)
# Skip if user already created appropriate MR
return false if project.merge_requests.where(source_branch: event.branch_name).opened.any?
diff --git a/app/helpers/compare_helper.rb b/app/helpers/compare_helper.rb
index f1dc906cab4..aa54ee07bdc 100644
--- a/app/helpers/compare_helper.rb
+++ b/app/helpers/compare_helper.rb
@@ -3,7 +3,7 @@ module CompareHelper
from.present? &&
to.present? &&
from != to &&
- project.merge_requests_enabled &&
+ project.feature_available?(:merge_requests, current_user) &&
project.repository.branch_names.include?(from) &&
project.repository.branch_names.include?(to)
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index f07077bd133..79a1eba9714 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -412,4 +412,23 @@ module ProjectsHelper
message.strip.gsub(project.repository_storage_path.chomp('/'), "[REPOS PATH]")
end
+
+ def project_feature_options
+ {
+ 'Disabled' => ProjectFeature::DISABLED,
+ 'Only team members' => ProjectFeature::PRIVATE,
+ 'Everyone with access' => ProjectFeature::ENABLED
+ }
+ end
+
+ def project_feature_access_select(field)
+ # Don't show option "everyone with access" if project is private
+ options = project_feature_options
+ level = @project.project_feature.public_send(field)
+
+ options.delete('Everyone with access') if @project.private? && level != ProjectFeature::ENABLED
+
+ options = options_for_select(options, selected: @project.project_feature.public_send(field) || ProjectFeature::ENABLED)
+ content_tag(:select, options, name: "project[project_feature_attributes][#{field.to_s}]", id: "project_project_feature_attributes_#{field.to_s}", class: "pull-right form-control").html_safe
+ end
end
diff --git a/app/models/concerns/project_features_compatibility.rb b/app/models/concerns/project_features_compatibility.rb
new file mode 100644
index 00000000000..9216122923e
--- /dev/null
+++ b/app/models/concerns/project_features_compatibility.rb
@@ -0,0 +1,37 @@
+# Makes api V3 compatible with old project features permissions methods
+#
+# After migrating issues_enabled merge_requests_enabled builds_enabled snippets_enabled and wiki_enabled
+# fields to a new table "project_features", support for the old fields is still needed in the API.
+
+module ProjectFeaturesCompatibility
+ extend ActiveSupport::Concern
+
+ def wiki_enabled=(value)
+ write_feature_attribute(:wiki_access_level, value)
+ end
+
+ def builds_enabled=(value)
+ write_feature_attribute(:builds_access_level, value)
+ end
+
+ def merge_requests_enabled=(value)
+ write_feature_attribute(:merge_requests_access_level, value)
+ end
+
+ def issues_enabled=(value)
+ write_feature_attribute(:issues_access_level, value)
+ end
+
+ def snippets_enabled=(value)
+ write_feature_attribute(:snippets_access_level, value)
+ end
+
+ private
+
+ def write_feature_attribute(field, value)
+ build_project_feature unless project_feature
+
+ access_level = value == "true" ? ProjectFeature::ENABLED : ProjectFeature::DISABLED
+ project_feature.update_attribute(field, access_level)
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index e5027af4a0e..a6de2c48071 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -11,24 +11,23 @@ class Project < ActiveRecord::Base
include AfterCommitQueue
include CaseSensitivity
include TokenAuthenticatable
+ include ProjectFeaturesCompatibility
extend Gitlab::ConfigHelper
UNKNOWN_IMPORT_URL = 'http://unknown.git'
+ delegate :feature_available?, :builds_enabled?, :wiki_enabled?, :merge_requests_enabled?, to: :project_feature, allow_nil: true
+
default_value_for :archived, false
default_value_for :visibility_level, gitlab_config_features.visibility_level
- default_value_for :issues_enabled, gitlab_config_features.issues
- default_value_for :merge_requests_enabled, gitlab_config_features.merge_requests
- default_value_for :builds_enabled, gitlab_config_features.builds
- default_value_for :wiki_enabled, gitlab_config_features.wiki
- default_value_for :snippets_enabled, gitlab_config_features.snippets
default_value_for :container_registry_enabled, gitlab_config_features.container_registry
default_value_for(:repository_storage) { current_application_settings.repository_storage }
default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled }
after_create :ensure_dir_exist
after_save :ensure_dir_exist, if: :namespace_id_changed?
+ after_initialize :setup_project_feature
# set last_activity_at to the same as created_at
after_create :set_last_activity_at
@@ -62,10 +61,10 @@ class Project < ActiveRecord::Base
belongs_to :group, -> { where(type: Group) }, foreign_key: 'namespace_id'
belongs_to :namespace
- has_one :board, dependent: :destroy
-
has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id'
+ has_one :board, dependent: :destroy
+
# Project services
has_many :services
has_one :campfire_service, dependent: :destroy
@@ -130,6 +129,7 @@ class Project < ActiveRecord::Base
has_many :notification_settings, dependent: :destroy, as: :source
has_one :import_data, dependent: :destroy, class_name: "ProjectImportData"
+ has_one :project_feature, dependent: :destroy
has_many :commit_statuses, dependent: :destroy, class_name: 'CommitStatus', foreign_key: :gl_project_id
has_many :pipelines, dependent: :destroy, class_name: 'Ci::Pipeline', foreign_key: :gl_project_id
@@ -142,6 +142,7 @@ class Project < ActiveRecord::Base
has_many :deployments, dependent: :destroy
accepts_nested_attributes_for :variables, allow_destroy: true
+ accepts_nested_attributes_for :project_feature
delegate :name, to: :owner, allow_nil: true, prefix: true
delegate :members, to: :team, prefix: true
@@ -159,8 +160,6 @@ class Project < ActiveRecord::Base
length: { within: 0..255 },
format: { with: Gitlab::Regex.project_path_regex,
message: Gitlab::Regex.project_path_regex_message }
- validates :issues_enabled, :merge_requests_enabled,
- :wiki_enabled, inclusion: { in: [true, false] }
validates :namespace, presence: true
validates_uniqueness_of :name, scope: :namespace_id
validates_uniqueness_of :path, scope: :namespace_id
@@ -196,6 +195,9 @@ class Project < ActiveRecord::Base
scope :for_milestones, ->(ids) { joins(:milestones).where('milestones.id' => ids).distinct }
scope :with_push, -> { joins(:events).where('events.action = ?', Event::PUSHED) }
+ scope :with_builds_enabled, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id').where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0') }
+ scope :with_issues_enabled, -> { joins('LEFT JOIN project_features ON projects.id = project_features.project_id').where('project_features.issues_access_level IS NULL or project_features.issues_access_level > 0') }
+
scope :active, -> { joins(:issues, :notes, :merge_requests).order('issues.created_at, notes.created_at, merge_requests.created_at DESC') }
scope :abandoned, -> { where('projects.last_activity_at < ?', 6.months.ago) }
@@ -1121,7 +1123,7 @@ class Project < ActiveRecord::Base
end
def enable_ci
- self.builds_enabled = true
+ project_feature.update_attribute(:builds_access_level, ProjectFeature::ENABLED)
end
def any_runners?(&block)
@@ -1288,6 +1290,11 @@ class Project < ActiveRecord::Base
private
+ # Prevents the creation of project_feature record for every project
+ def setup_project_feature
+ build_project_feature unless project_feature
+ end
+
def default_branch_protected?
current_application_settings.default_branch_protection == Gitlab::Access::PROTECTION_FULL ||
current_application_settings.default_branch_protection == Gitlab::Access::PROTECTION_DEV_CAN_MERGE
diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb
new file mode 100644
index 00000000000..9c602c582bd
--- /dev/null
+++ b/app/models/project_feature.rb
@@ -0,0 +1,63 @@
+class ProjectFeature < ActiveRecord::Base
+ # == Project features permissions
+ #
+ # Grants access level to project tools
+ #
+ # Tools can be enabled only for users, everyone or disabled
+ # Access control is made only for non private projects
+ #
+ # levels:
+ #
+ # Disabled: not enabled for anyone
+ # Private: enabled only for team members
+ # Enabled: enabled for everyone able to access the project
+ #
+
+ # Permision levels
+ DISABLED = 0
+ PRIVATE = 10
+ ENABLED = 20
+
+ FEATURES = %i(issues merge_requests wiki snippets builds)
+
+ belongs_to :project
+
+ def feature_available?(feature, user)
+ raise ArgumentError, 'invalid project feature' unless FEATURES.include?(feature)
+
+ get_permission(user, public_send("#{feature}_access_level"))
+ end
+
+ def builds_enabled?
+ return true unless builds_access_level
+
+ builds_access_level > DISABLED
+ end
+
+ def wiki_enabled?
+ return true unless wiki_access_level
+
+ wiki_access_level > DISABLED
+ end
+
+ def merge_requests_enabled?
+ return true unless merge_requests_access_level
+
+ merge_requests_access_level > DISABLED
+ end
+
+ private
+
+ def get_permission(user, level)
+ case level
+ when DISABLED
+ false
+ when PRIVATE
+ user && (project.team.member?(user) || user.admin?)
+ when ENABLED
+ true
+ else
+ true
+ end
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 8f5958333d7..6996740eebd 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -433,7 +433,7 @@ class User < ActiveRecord::Base
#
# This logic is duplicated from `Ability#project_abilities` into a SQL form.
def projects_where_can_admin_issues
- authorized_projects(Gitlab::Access::REPORTER).non_archived.where.not(issues_enabled: false)
+ authorized_projects(Gitlab::Access::REPORTER).non_archived.with_issues_enabled
end
def is_admin?
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 15a9f2f0dca..acf36d422d1 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -145,28 +145,28 @@ class ProjectPolicy < BasePolicy
end
def disabled_features!
- unless project.issues_enabled
+ unless project.feature_available?(:issues, user)
cannot!(*named_abilities(:issue))
end
- unless project.merge_requests_enabled
+ unless project.feature_available?(:merge_requests, user)
cannot!(*named_abilities(:merge_request))
end
- unless project.issues_enabled || project.merge_requests_enabled
+ unless project.feature_available?(:issues, user) || project.feature_available?(:merge_requests, user)
cannot!(*named_abilities(:label))
cannot!(*named_abilities(:milestone))
end
- unless project.snippets_enabled
+ unless project.feature_available?(:snippets, user)
cannot!(*named_abilities(:project_snippet))
end
- unless project.has_wiki?
+ unless project.feature_available?(:wiki, user) || project.has_external_wiki?
cannot!(*named_abilities(:wiki))
end
- unless project.builds_enabled
+ unless project.feature_available?(:builds, user)
cannot!(*named_abilities(:build))
cannot!(*named_abilities(:pipeline))
cannot!(*named_abilities(:environment))
diff --git a/app/services/ci/register_build_service.rb b/app/services/ci/register_build_service.rb
index 9a187f5d694..6973191b203 100644
--- a/app/services/ci/register_build_service.rb
+++ b/app/services/ci/register_build_service.rb
@@ -8,16 +8,18 @@ module Ci
builds =
if current_runner.shared?
builds.
- # don't run projects which have not enabled shared runners
- joins(:project).where(projects: { builds_enabled: true, shared_runners_enabled: true }).
+ # don't run projects which have not enabled shared runners and builds
+ joins(:project).where(projects: { shared_runners_enabled: true }).
+ joins('LEFT JOIN project_features ON ci_builds.gl_project_id = project_features.project_id').
# this returns builds that are ordered by number of running builds
# we prefer projects that don't use shared runners at all
joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.gl_project_id=project_builds.gl_project_id").
+ where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0').
order('COALESCE(project_builds.running_builds, 0) ASC', 'ci_builds.id ASC')
else
# do run projects which are only assigned to this runner (FIFO)
- builds.where(project: current_runner.projects.where(builds_enabled: true)).order('created_at ASC')
+ builds.where(project: current_runner.projects.with_builds_enabled).order('created_at ASC')
end
build = builds.find do |build|
diff --git a/app/services/merge_requests/get_urls_service.rb b/app/services/merge_requests/get_urls_service.rb
index 08c1f72d65a..1262ecbc29a 100644
--- a/app/services/merge_requests/get_urls_service.rb
+++ b/app/services/merge_requests/get_urls_service.rb
@@ -31,7 +31,7 @@ module MergeRequests
def get_branches(changes)
return [] if project.empty_repo?
- return [] unless project.merge_requests_enabled
+ return [] unless project.merge_requests_enabled?
changes_list = Gitlab::ChangesList.new(changes)
changes_list.map do |change|
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index 55956be2844..be749ba4a1c 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -7,7 +7,6 @@ module Projects
def execute
forked_from_project_id = params.delete(:forked_from_project_id)
import_data = params.delete(:import_data)
-
@project = Project.new(params)
# Make sure that the user is allowed to use the specified visibility level
@@ -81,8 +80,7 @@ module Projects
log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"")
unless @project.gitlab_project_import?
- @project.create_wiki if @project.wiki_enabled?
-
+ @project.create_wiki if @project.feature_available?(:wiki, current_user)
@project.build_missing_services
@project.create_labels
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index de6dc38cc8e..a2de4dccece 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -8,7 +8,6 @@ module Projects
name: @project.name,
path: @project.path,
shared_runners_enabled: @project.shared_runners_enabled,
- builds_enabled: @project.builds_enabled,
namespace_id: @params[:namespace].try(:id) || current_user.namespace.id
}
@@ -17,6 +16,9 @@ module Projects
end
new_project = CreateService.new(current_user, new_params).execute
+ builds_access_level = @project.project_feature.builds_access_level
+ new_project.project_feature.update_attributes(builds_access_level: builds_access_level)
+
new_project
end
diff --git a/app/views/layouts/nav/_project_settings.html.haml b/app/views/layouts/nav/_project_settings.html.haml
index 52a5bdc1a1b..613b8b7d301 100644
--- a/app/views/layouts/nav/_project_settings.html.haml
+++ b/app/views/layouts/nav/_project_settings.html.haml
@@ -26,7 +26,7 @@
%span
Protected Branches
- - if @project.builds_enabled?
+ - if @project.feature_available?(:builds, current_user)
= nav_link(controller: :runners) do
= link_to namespace_project_runners_path(@project.namespace, @project), title: 'Runners' do
%span
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 836c6d7b83f..f6d751a343e 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -44,52 +44,56 @@
%hr
%fieldset.features.append-bottom-0
%h5.prepend-top-0
- Features
- .form-group
- .checkbox
- = f.label :issues_enabled do
- = f.check_box :issues_enabled
- %strong Issues
- %br
- %span.descr Lightweight issue tracking system for this project
- .form-group
- .checkbox
- = f.label :merge_requests_enabled do
- = f.check_box :merge_requests_enabled
- %strong Merge Requests
- %br
- %span.descr Submit changes to be merged upstream
- .form-group
- .checkbox
- = f.label :builds_enabled do
- = f.check_box :builds_enabled
- %strong Builds
- %br
- %span.descr Test and deploy your changes before merge
- .form-group
- .checkbox
- = f.label :wiki_enabled do
- = f.check_box :wiki_enabled
- %strong Wiki
- %br
- %span.descr Pages for project documentation
- .form-group
- .checkbox
- = f.label :snippets_enabled do
- = f.check_box :snippets_enabled
- %strong Snippets
- %br
- %span.descr Share code pastes with others out of git repository
- - if Gitlab.config.lfs.enabled && current_user.admin?
- .form-group
- .checkbox
- = f.label :lfs_enabled do
- = f.check_box :lfs_enabled, checked: @project.lfs_enabled?
- %strong LFS
- %br
- %span.descr
- Git Large File Storage
- = link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
+ Feature Visibility
+
+ = f.fields_for :project_feature do |feature_fields|
+ .form_group.prepend-top-20
+ .row
+ .col-md-9
+ = feature_fields.label :issues_access_level, "Issues", class: 'label-light'
+ %span.help-block Lightweight issue tracking system for this project
+ .col-md-3
+ = project_feature_access_select(:issues_access_level)
+
+ .row
+ .col-md-9
+ = feature_fields.label :merge_requests_access_level, "Merge requests", class: 'label-light'
+ %span.help-block Submit changes to be merged upstream
+ .col-md-3
+ = project_feature_access_select(:merge_requests_access_level)
+
+ .row
+ .col-md-9
+ = feature_fields.label :builds_access_level, "Builds", class: 'label-light'
+ %span.help-block Submit Test and deploy your changes before merge
+ .col-md-3
+ = project_feature_access_select(:builds_access_level)
+
+ .row
+ .col-md-9
+ = feature_fields.label :wiki_access_level, "Wiki", class: 'label-light'
+ %span.help-block Pages for project documentation
+ .col-md-3
+ = project_feature_access_select(:wiki_access_level)
+
+ .row
+ .col-md-9
+ = feature_fields.label :snippets_access_level, "Snippets", class: 'label-light'
+ %span.help-block Share code pastes with others out of Git repository
+ .col-md-3
+ = project_feature_access_select(:snippets_access_level)
+
+ - if Gitlab.config.lfs.enabled && current_user.admin?
+ .form-group
+ .checkbox
+ = f.label :lfs_enabled do
+ = f.check_box :lfs_enabled, checked: @project.lfs_enabled?
+ %strong LFS
+ %br
+ %span.descr
+ Git Large File Storage
+ = link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
+
- if Gitlab.config.registry.enabled
.form-group
.checkbox
@@ -98,7 +102,7 @@
%strong Container Registry
%br
%span.descr Enable Container Registry for this repository
- %hr
+
= render 'merge_request_settings', f: f
%hr
%fieldset.features.append-bottom-default
diff --git a/app/views/projects/graphs/_head.html.haml b/app/views/projects/graphs/_head.html.haml
index a231d684559..082e2cb4d8c 100644
--- a/app/views/projects/graphs/_head.html.haml
+++ b/app/views/projects/graphs/_head.html.haml
@@ -12,7 +12,7 @@
= link_to 'Commits', commits_namespace_project_graph_path
= nav_link(action: :languages) do
= link_to 'Languages', languages_namespace_project_graph_path
- - if @project.builds_enabled?
+ - if @project.feature_available?(:builds, current_user)
= nav_link(action: :ci) do
= link_to ci_namespace_project_graph_path do
Continuous Integration
diff --git a/db/migrate/20160831214002_create_project_features.rb b/db/migrate/20160831214002_create_project_features.rb
new file mode 100644
index 00000000000..2d76a015a08
--- /dev/null
+++ b/db/migrate/20160831214002_create_project_features.rb
@@ -0,0 +1,16 @@
+class CreateProjectFeatures < ActiveRecord::Migration
+ DOWNTIME = false
+
+ def change
+ create_table :project_features do |t|
+ t.belongs_to :project, index: true
+ t.integer :merge_requests_access_level
+ t.integer :issues_access_level
+ t.integer :wiki_access_level
+ t.integer :snippets_access_level
+ t.integer :builds_access_level
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20160831214543_migrate_project_features.rb b/db/migrate/20160831214543_migrate_project_features.rb
new file mode 100644
index 00000000000..93f9821bc76
--- /dev/null
+++ b/db/migrate/20160831214543_migrate_project_features.rb
@@ -0,0 +1,44 @@
+class MigrateProjectFeatures < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = true
+ DOWNTIME_REASON =
+ <<-EOT
+ Migrating issues_enabled, merge_requests_enabled, wiki_enabled, builds_enabled, snippets_enabled fields from projects to
+ a new table called project_features.
+ EOT
+
+ def up
+ sql =
+ %Q{
+ INSERT INTO project_features(project_id, issues_access_level, merge_requests_access_level, wiki_access_level,
+ builds_access_level, snippets_access_level, created_at, updated_at)
+ SELECT
+ id AS project_id,
+ CASE WHEN issues_enabled IS true THEN 20 ELSE 0 END AS issues_access_level,
+ CASE WHEN merge_requests_enabled IS true THEN 20 ELSE 0 END AS merge_requests_access_level,
+ CASE WHEN wiki_enabled IS true THEN 20 ELSE 0 END AS wiki_access_level,
+ CASE WHEN builds_enabled IS true THEN 20 ELSE 0 END AS builds_access_level,
+ CASE WHEN snippets_enabled IS true THEN 20 ELSE 0 END AS snippets_access_level,
+ created_at,
+ updated_at
+ FROM projects
+ }
+
+ execute(sql)
+ end
+
+ def down
+ sql = %Q{
+ UPDATE projects
+ SET
+ issues_enabled = COALESCE((SELECT CASE WHEN issues_access_level = 20 THEN true ELSE false END AS issues_enabled FROM project_features WHERE project_features.project_id = projects.id), true),
+ merge_requests_enabled = COALESCE((SELECT CASE WHEN merge_requests_access_level = 20 THEN true ELSE false END AS merge_requests_enabled FROM project_features WHERE project_features.project_id = projects.id),true),
+ wiki_enabled = COALESCE((SELECT CASE WHEN wiki_access_level = 20 THEN true ELSE false END AS wiki_enabled FROM project_features WHERE project_features.project_id = projects.id), true),
+ builds_enabled = COALESCE((SELECT CASE WHEN builds_access_level = 20 THEN true ELSE false END AS builds_enabled FROM project_features WHERE project_features.project_id = projects.id), true),
+ snippets_enabled = COALESCE((SELECT CASE WHEN snippets_access_level = 20 THEN true ELSE false END AS snippets_enabled FROM project_features WHERE project_features.project_id = projects.id),true)
+ }
+
+ execute(sql)
+ end
+end
diff --git a/db/migrate/20160831223750_remove_features_enabled_from_projects.rb b/db/migrate/20160831223750_remove_features_enabled_from_projects.rb
new file mode 100644
index 00000000000..a2c207b49ea
--- /dev/null
+++ b/db/migrate/20160831223750_remove_features_enabled_from_projects.rb
@@ -0,0 +1,29 @@
+# See http://doc.gitlab.com/ce/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class RemoveFeaturesEnabledFromProjects < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+ disable_ddl_transaction!
+
+ # Set this constant to true if this migration requires downtime.
+ DOWNTIME = true
+ DOWNTIME_REASON = "Removing fields from database requires downtine."
+
+ def up
+ remove_column :projects, :issues_enabled
+ remove_column :projects, :merge_requests_enabled
+ remove_column :projects, :builds_enabled
+ remove_column :projects, :wiki_enabled
+ remove_column :projects, :snippets_enabled
+ end
+
+ # Ugly SQL but the only way i found to make it work on both Postgres and Mysql
+ # It will be slow but it is ok since it is a revert method
+ def down
+ add_column_with_default(:projects, :issues_enabled, :boolean, default: true, allow_null: false)
+ add_column_with_default(:projects, :merge_requests_enabled, :boolean, default: true, allow_null: false)
+ add_column_with_default(:projects, :builds_enabled, :boolean, default: true, allow_null: false)
+ add_column_with_default(:projects, :wiki_enabled, :boolean, default: true, allow_null: false)
+ add_column_with_default(:projects, :snippets_enabled, :boolean, default: true, allow_null: false)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 963d528d170..af6e74a4e25 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20160830232601) do
+ActiveRecord::Schema.define(version: 20160831223750) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -766,6 +766,19 @@ ActiveRecord::Schema.define(version: 20160830232601) do
add_index "personal_access_tokens", ["token"], name: "index_personal_access_tokens_on_token", unique: true, using: :btree
add_index "personal_access_tokens", ["user_id"], name: "index_personal_access_tokens_on_user_id", using: :btree
+ create_table "project_features", force: :cascade do |t|
+ t.integer "project_id"
+ t.integer "merge_requests_access_level"
+ t.integer "issues_access_level"
+ t.integer "wiki_access_level"
+ t.integer "snippets_access_level"
+ t.integer "builds_access_level"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "project_features", ["project_id"], name: "index_project_features_on_project_id", using: :btree
+
create_table "project_group_links", force: :cascade do |t|
t.integer "project_id", null: false
t.integer "group_id", null: false
@@ -790,11 +803,7 @@ ActiveRecord::Schema.define(version: 20160830232601) do
t.datetime "created_at"
t.datetime "updated_at"
t.integer "creator_id"
- t.boolean "issues_enabled", default: true, null: false
- t.boolean "merge_requests_enabled", default: true, null: false
- t.boolean "wiki_enabled", default: true, null: false
t.integer "namespace_id"
- t.boolean "snippets_enabled", default: true, null: false
t.datetime "last_activity_at"
t.string "import_url"
t.integer "visibility_level", default: 0, null: false
@@ -808,7 +817,6 @@ ActiveRecord::Schema.define(version: 20160830232601) do
t.integer "commit_count", default: 0
t.text "import_error"
t.integer "ci_id"
- t.boolean "builds_enabled", default: true, null: false
t.boolean "shared_runners_enabled", default: true, null: false
t.string "runners_token"
t.string "build_coverage_regex"
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index 66542861781..1498cb361c8 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -104,6 +104,15 @@ will find the option to flag the user as external.
By default new users are not set as external users. This behavior can be changed
by an administrator under **Admin > Application Settings**.
+## Project features
+
+Project features like wiki and issues can be hidden from users depending on
+which visibility level you select on project settings.
+
+- Disabled: disabled for everyone
+- Only team members: only team members will see even if your project is public or internal
+- Everyone with access: everyone can see depending on your project visibility level
+
## GitLab CI
GitLab CI permissions rely on the role the user has in GitLab. There are four
diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb
index 76fefee9254..975c879149e 100644
--- a/features/steps/project/project.rb
+++ b/features/steps/project/project.rb
@@ -5,7 +5,7 @@ class Spinach::Features::Project < Spinach::FeatureSteps
step 'change project settings' do
fill_in 'project_name_edit', with: 'NewName'
- uncheck 'project_issues_enabled'
+ select 'Disabled', from: 'project_project_feature_attributes_issues_access_level'
end
step 'I save project' do
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index 0b4920883b8..afbd8ef1233 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -15,7 +15,7 @@ module SharedProject
# Create a specific project called "Shop"
step 'I own project "Shop"' do
@project = Project.find_by(name: "Shop")
- @project ||= create(:project, name: "Shop", namespace: @user.namespace, snippets_enabled: true)
+ @project ||= create(:project, name: "Shop", namespace: @user.namespace)
@project.team << [@user, :master]
end
@@ -41,6 +41,8 @@ module SharedProject
step 'I own project "Forum"' do
@project = Project.find_by(name: "Forum")
@project ||= create(:project, name: "Forum", namespace: @user.namespace, path: 'forum_project')
+ @project.build_project_feature
+ @project.project_feature.save
@project.team << [@user, :master]
end
@@ -95,7 +97,7 @@ module SharedProject
step 'I should see project settings' do
expect(current_path).to eq edit_namespace_project_path(@project.namespace, @project)
expect(page).to have_content("Project name")
- expect(page).to have_content("Features")
+ expect(page).to have_content("Feature Visibility")
end
def current_project
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index fe7468dd681..e7fe437ee0d 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -76,7 +76,15 @@ module API
expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group }
expose :name, :name_with_namespace
expose :path, :path_with_namespace
- expose :issues_enabled, :merge_requests_enabled, :wiki_enabled, :builds_enabled, :snippets_enabled, :container_registry_enabled
+ expose :container_registry_enabled
+
+ # Expose old field names with the new permissions methods to keep API compatible
+ expose(:issues_enabled) { |project, options| project.feature_available?(:issues, options[:user]) }
+ expose(:merge_requests_enabled) { |project, options| project.feature_available?(:merge_requests, options[:user]) }
+ expose(:wiki_enabled) { |project, options| project.feature_available?(:wiki, options[:user]) }
+ expose(:builds_enabled) { |project, options| project.feature_available?(:builds, options[:user]) }
+ expose(:snippets_enabled) { |project, options| project.feature_available?(:snippets, options[:user]) }
+
expose :created_at, :last_activity_at
expose :shared_runners_enabled, :lfs_enabled
expose :creator_id
@@ -84,7 +92,7 @@ module API
expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? }
expose :avatar_url
expose :star_count, :forks_count
- expose :open_issues_count, if: lambda { |project, options| project.issues_enabled? && project.default_issues_tracker? }
+ expose :open_issues_count, if: lambda { |project, options| project.feature_available?(:issues, options[:user]) && project.default_issues_tracker? }
expose :runners_token, if: lambda { |_project, options| options[:user_can_admin_project] }
expose :public_builds
expose :shared_with_groups do |project, options|
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index f981ec0dbfe..d2df77238d5 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -97,7 +97,7 @@ module API
group = find_group(params[:id])
projects = GroupProjectsFinder.new(group).execute(current_user)
projects = paginate projects
- present projects, with: Entities::Project
+ present projects, with: Entities::Project, user: current_user
end
# Transfer a project to the Group namespace
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index f8979a1cc29..a1fd598414a 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -51,7 +51,7 @@ module API
@projects = current_user.viewable_starred_projects
@projects = filter_projects(@projects)
@projects = paginate @projects
- present @projects, with: Entities::Project
+ present @projects, with: Entities::Project, user: current_user
end
# Get all projects for admin user
diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb
index 1b2a5eb8f52..4fdc2f46be0 100644
--- a/lib/gitlab/github_import/importer.rb
+++ b/lib/gitlab/github_import/importer.rb
@@ -168,7 +168,7 @@ module Gitlab
unless project.wiki_enabled?
wiki = WikiFormatter.new(project)
gitlab_shell.import_repository(project.repository_storage_path, wiki.path_with_namespace, wiki.import_url)
- project.update_attribute(:wiki_enabled, true)
+ project.project.update_attribute(:wiki_access_level, ProjectFeature::ENABLED)
end
rescue Gitlab::Shell::Error => e
# GitHub error message when the wiki repo has not been created,
diff --git a/lib/gitlab/github_import/project_creator.rb b/lib/gitlab/github_import/project_creator.rb
index f4221003db5..0ad30c1e5b2 100644
--- a/lib/gitlab/github_import/project_creator.rb
+++ b/lib/gitlab/github_import/project_creator.rb
@@ -11,7 +11,7 @@ module Gitlab
end
def execute
- ::Projects::CreateService.new(
+ project = ::Projects::CreateService.new(
current_user,
name: repo.name,
path: repo.name,
@@ -20,9 +20,15 @@ module Gitlab
visibility_level: repo.private ? Gitlab::VisibilityLevel::PRIVATE : Gitlab::VisibilityLevel::PUBLIC,
import_type: "github",
import_source: repo.full_name,
- import_url: repo.clone_url.sub("https://", "https://#{@session_data[:github_access_token]}@"),
- wiki_enabled: !repo.has_wiki? # If repo has wiki we'll import it later
+ import_url: repo.clone_url.sub("https://", "https://#{@session_data[:github_access_token]}@")
).execute
+
+ # If repo has wiki we'll import it later
+ if repo.has_wiki? && project
+ project.project_feature.update_attribute(:wiki_access_level, ProjectFeature::DISABLED)
+ end
+
+ project
end
end
end
diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml
index 1da51043611..c2e8a1ca5dd 100644
--- a/lib/gitlab/import_export/import_export.yml
+++ b/lib/gitlab/import_export/import_export.yml
@@ -39,15 +39,12 @@ project_tree:
- :labels
- milestones:
- :events
+ - :project_feature
# Only include the following attributes for the models specified.
included_attributes:
project:
- :description
- - :issues_enabled
- - :merge_requests_enabled
- - :wiki_enabled
- - :snippets_enabled
- :visibility_level
- :archived
user:
@@ -72,4 +69,4 @@ methods:
statuses:
- :type
merge_request_diff:
- - :utf8_st_diffs \ No newline at end of file
+ - :utf8_st_diffs
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb
index b8a28f43707..72a3ebf2ebd 100644
--- a/spec/controllers/projects/snippets_controller_spec.rb
+++ b/spec/controllers/projects/snippets_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::SnippetsController do
- let(:project) { create(:project_empty_repo, :public, snippets_enabled: true) }
+ let(:project) { create(:project_empty_repo, :public) }
let(:user) { create(:user) }
let(:user2) { create(:user) }
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index f82d68a1816..fb84ba07d25 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -8,7 +8,6 @@ FactoryGirl.define do
path { name.downcase.gsub(/\s/, '_') }
namespace
creator
- snippets_enabled true
trait :public do
visibility_level Gitlab::VisibilityLevel::PUBLIC
@@ -27,6 +26,26 @@ FactoryGirl.define do
project.create_repository
end
end
+
+ # Nest Project Feature attributes
+ transient do
+ wiki_access_level ProjectFeature::ENABLED
+ builds_access_level ProjectFeature::ENABLED
+ snippets_access_level ProjectFeature::ENABLED
+ issues_access_level ProjectFeature::ENABLED
+ merge_requests_access_level ProjectFeature::ENABLED
+ end
+
+ after(:create) do |project, evaluator|
+ project.project_feature.
+ update_attributes(
+ wiki_access_level: evaluator.wiki_access_level,
+ builds_access_level: evaluator.builds_access_level,
+ snippets_access_level: evaluator.snippets_access_level,
+ issues_access_level: evaluator.issues_access_level,
+ merge_requests_access_level: evaluator.merge_requests_access_level,
+ )
+ end
end
# Project with empty repository
diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb
new file mode 100644
index 00000000000..349316d8b0d
--- /dev/null
+++ b/spec/features/projects/features_visibility_spec.rb
@@ -0,0 +1,117 @@
+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)
+ @tools = { builds: "pipelines", issues: "issues", wiki: "wiki", snippets: "snippets", merge_requests: "merge_requests" }
+ end
+
+ it 'toggles features visibility' do
+ @tools.each do |tool_name, shortcut_name|
+ 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}")
+ 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
diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz
index 7bb0d26b21c..e14b2705704 100644
--- a/spec/features/projects/import_export/test_project_export.tar.gz
+++ b/spec/features/projects/import_export/test_project_export.tar.gz
Binary files differ
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index b0772cad312..7c23e02d05a 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -7,7 +7,8 @@ describe Gitlab::Auth, lib: true do
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')
diff --git a/spec/lib/gitlab/github_import/importer_spec.rb b/spec/lib/gitlab/github_import/importer_spec.rb
index b7c3bc4e1a7..3fb8de81545 100644
--- a/spec/lib/gitlab/github_import/importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
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') }
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index cbbf98dca94..5114f9c55e1 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -1,9 +1,5 @@
{
"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
+}
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index 4d857945fde..a07ef279e68 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -5,7 +5,7 @@ describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do
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 @@ describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do
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
diff --git a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
index 3a86a4ce07c..d891c2d0cc6 100644
--- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
@@ -111,6 +111,14 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
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 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
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
diff --git a/spec/lib/gitlab/import_export/reader_spec.rb b/spec/lib/gitlab/import_export/reader_spec.rb
index b6dec41d218..3ceb1e7e803 100644
--- a/spec/lib/gitlab/import_export/reader_spec.rb
+++ b/spec/lib/gitlab/import_export/reader_spec.rb
@@ -32,6 +32,12 @@ describe Gitlab::ImportExport::Reader, lib: true do
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])
diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb
index b05510342bc..1bdf005c823 100644
--- a/spec/models/ability_spec.rb
+++ b/spec/models/ability_spec.rb
@@ -220,13 +220,13 @@ describe Ability, lib: true do
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
diff --git a/spec/models/concerns/project_features_compatibility_spec.rb b/spec/models/concerns/project_features_compatibility_spec.rb
new file mode 100644
index 00000000000..5363aea4d22
--- /dev/null
+++ b/spec/models/concerns/project_features_compatibility_spec.rb
@@ -0,0 +1,25 @@
+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
diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb
new file mode 100644
index 00000000000..8d554a01be5
--- /dev/null
+++ b/spec/models/project_feature_spec.rb
@@ -0,0 +1,91 @@
+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
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index dd309ea1b68..4a41fafb84d 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -508,7 +508,7 @@ describe Project, models: true do
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 @@ describe Project, models: true do
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 }
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 8eb0c5033c9..a1770d96f83 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1006,8 +1006,7 @@ describe User, models: true do
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)
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 63f2467be63..28aa56e8644 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -73,7 +73,7 @@ describe API::API, api: true do
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 @@ describe API::API, api: true do
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
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index afaf4b7cefb..9ca3b021aa2 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -289,7 +289,8 @@ describe 'Git HTTP requests', lib: true do
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
diff --git a/spec/requests/jwt_controller_spec.rb b/spec/requests/jwt_controller_spec.rb
index c6172b9cc7d..fc42b534dca 100644
--- a/spec/requests/jwt_controller_spec.rb
+++ b/spec/requests/jwt_controller_spec.rb
@@ -22,19 +22,20 @@ describe JwtController do
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
diff --git a/spec/services/ci/register_build_service_spec.rb b/spec/services/ci/register_build_service_spec.rb
index 026d0ca6534..1e21a32a062 100644
--- a/spec/services/ci/register_build_service_spec.rb
+++ b/spec/services/ci/register_build_service_spec.rb
@@ -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
diff --git a/spec/services/merge_requests/get_urls_service_spec.rb b/spec/services/merge_requests/get_urls_service_spec.rb
index 8a4b76367e3..3a71776e81f 100644
--- a/spec/services/merge_requests/get_urls_service_spec.rb
+++ b/spec/services/merge_requests/get_urls_service_spec.rb
@@ -50,7 +50,7 @@ describe MergeRequests::GetUrlsService do
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'
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index bbced59ff02..3ea1273abc3 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -69,7 +69,7 @@ describe Projects::CreateService, services: true do
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 @@ describe Projects::CreateService, services: true do
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 @@ describe Projects::CreateService, services: true do
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 }
diff --git a/spec/workers/repository_check/single_repository_worker_spec.rb b/spec/workers/repository_check/single_repository_worker_spec.rb
index 05e07789dac..59cfb2c8e3a 100644
--- a/spec/workers/repository_check/single_repository_worker_spec.rb
+++ b/spec/workers/repository_check/single_repository_worker_spec.rb
@@ -5,7 +5,7 @@ describe RepositoryCheck::SingleRepositoryWorker do
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 @@ describe RepositoryCheck::SingleRepositoryWorker do
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 @@ describe RepositoryCheck::SingleRepositoryWorker do
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 @@ describe RepositoryCheck::SingleRepositoryWorker do
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)