-
+
:gitlab_environment do |_t, args|
+ require 'sidekiq/testing'
+
+ GroupSeeder.new(
+ subgroups_depth: args.subgroups_depth,
+ username: args.username
+ ).seed
+ end
+ end
+end
+
+class GroupSeeder
+ PROJECT_URL = 'https://gitlab.com/gitlab-org/gitlab-test.git'
+
+ attr_reader :all_group_ids
+
+ def initialize(subgroups_depth:, username:)
+ @subgroups_depth = subgroups_depth.to_i
+ @user = User.find_by_username(username)
+ @group_names = Set.new
+ @resource_count = 2
+ @all_groups = {}
+ @all_group_ids = []
+ end
+
+ def seed
+ create_groups
+
+ puts 'Done!'
+ end
+
+ def create_groups
+ create_root_group
+ create_sub_groups
+ create_users_and_members
+ create_epics if Gitlab.ee?
+ create_labels
+ create_milestones
+
+ Sidekiq::Testing.inline! do
+ create_projects
+ end
+ end
+
+ def create_users_and_members
+ all_group_ids.each do |group_id|
+ @resource_count.times do |_|
+ user = create_user
+ create_member(user.id, group_id)
+ end
+ end
+ end
+
+ def create_root_group
+ root_group = ::Groups::CreateService.new(@user, group_params).execute
+
+ track_group_id(1, root_group.id)
+ end
+
+ def create_sub_groups
+ (2..@subgroups_depth).each do |level|
+ parent_level = level - 1
+ current_level = level
+ parent_groups = @all_groups[parent_level]
+
+ parent_groups.each do |parent_id|
+ @resource_count.times do |_|
+ sub_group = ::Groups::CreateService.new(@user, group_params(parent_id: parent_id)).execute
+
+ track_group_id(current_level, sub_group.id)
+ end
+ end
+ end
+ end
+
+ def track_group_id(depth_level, group_id)
+ @all_groups[depth_level] ||= []
+ @all_groups[depth_level] << group_id
+ @all_group_ids << group_id
+ end
+
+ def group_params(parent_id: nil)
+ name = unique_name
+
+ {
+ name: name,
+ path: name,
+ parent_id: parent_id
+ }
+ end
+
+ def unique_name
+ name = ffaker_name
+ name = ffaker_name until @group_names.add?(name)
+ name
+ end
+
+ def ffaker_name
+ FFaker::Lorem.characters(5)
+ end
+
+ def create_user
+ User.create!(
+ username: FFaker::Internet.user_name,
+ name: FFaker::Name.name,
+ email: FFaker::Internet.email,
+ confirmed_at: DateTime.now,
+ password: Devise.friendly_token
+ )
+ end
+
+ def create_member(user_id, group_id)
+ roles = Gitlab::Access.values
+
+ GroupMember.create(user_id: user_id, access_level: roles.sample, source_id: group_id)
+ end
+
+ def create_epics
+ all_group_ids.each do |group_id|
+ @resource_count.times do |_|
+ group = Group.find(group_id)
+
+ epic_params = {
+ title: FFaker::Lorem.sentence(6),
+ description: FFaker::Lorem.paragraphs(3).join("\n\n"),
+ author: group.users.sample,
+ group: group
+ }
+
+ Epic.create!(epic_params)
+ end
+ end
+ end
+
+ def create_labels
+ all_group_ids.each do |group_id|
+ @resource_count.times do |_|
+ group = Group.find(group_id)
+ label_title = FFaker::Product.brand
+
+ Labels::CreateService.new(title: label_title, color: "##{Digest::MD5.hexdigest(label_title)[0..5]}").execute(group: group)
+ end
+ end
+ end
+
+ def create_milestones
+ all_group_ids.each do |group_id|
+ @resource_count.times do |i|
+ group = Group.find(group_id)
+
+ milestone_params = {
+ title: "v#{i}.0",
+ description: FFaker::Lorem.sentence,
+ state: [:active, :closed].sample
+ }
+
+ Milestones::CreateService.new(group, group.members.sample, milestone_params).execute
+ end
+ end
+ end
+
+ def create_projects
+ all_group_ids.each do |group_id|
+ group = Group.find(group_id)
+
+ @resource_count.times do |i|
+ _, project_path = PROJECT_URL.split('/')[-2..-1]
+
+ project_path.gsub!('.git', '')
+
+ params = {
+ import_url: PROJECT_URL,
+ namespace_id: group.id,
+ name: project_path.titleize + FFaker::Lorem.characters(10),
+ description: FFaker::Lorem.sentence,
+ visibility_level: 0,
+ skip_disk_validation: true
+ }
+
+ project = nil
+
+ Sidekiq::Worker.skipping_transaction_check do
+ project = ::Projects::CreateService.new(@user, params).execute
+ project.send(:_run_after_commit_queue)
+ project.import_state.send(:_run_after_commit_queue)
+ project.repository.expire_all_method_caches
+ end
+
+ create_project_issues(project)
+ assign_issues_to_epics_and_milestones(project)
+ end
+ end
+ end
+
+ def create_project_issues(project)
+ seeder = Quality::Seeders::Issues.new(project: project)
+ seeder.seed(backfill_weeks: 2, average_issues_per_week: 2)
+ end
+
+ def assign_issues_to_epics_and_milestones(project)
+ group_ids = project.group.self_and_ancestors.map(&:id)
+
+ project.issues.each do |issue|
+ issue_params = {
+ milestone: Milestone.where(group: group_ids).sample
+ }
+
+ issue_params[:epic] = Epic.where(group: group_ids).sample if Gitlab.ee?
+
+ issue.update(issue_params)
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 81442d3fc7d..adc979efd1d 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -6035,6 +6035,9 @@ msgstr ""
msgid "Default project deletion protection"
msgstr ""
+msgid "Default projects limit"
+msgstr ""
+
msgid "Default: Directly import the Google Code email address or username"
msgstr ""
@@ -10470,6 +10473,9 @@ msgstr ""
msgid "Is blocked by"
msgstr ""
+msgid "Is this GitLab trial for your company?"
+msgstr ""
+
msgid "Is using license seat:"
msgstr ""
@@ -11628,6 +11634,9 @@ msgstr ""
msgid "Maximum delay (Minutes)"
msgstr ""
+msgid "Maximum duration of a session."
+msgstr ""
+
msgid "Maximum job timeout"
msgstr ""
@@ -11646,12 +11655,24 @@ msgstr ""
msgid "Maximum number of mirrors that can be synchronizing at the same time."
msgstr ""
+msgid "Maximum number of projects."
+msgstr ""
+
msgid "Maximum page reached"
msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum size limit for a single commit."
+msgstr ""
+
+msgid "Maximum size limit for each repository."
+msgstr ""
+
+msgid "Maximum size of individual attachments in comments."
+msgstr ""
+
msgid "Maximum time between updates that a mirror can have when scheduled to synchronize."
msgstr ""
@@ -17024,9 +17045,6 @@ msgstr ""
msgid "Session duration (minutes)"
msgstr ""
-msgid "Session expiration, projects limit and attachment size."
-msgstr ""
-
msgid "Set %{epic_ref} as the parent epic."
msgstr ""
@@ -17066,6 +17084,9 @@ msgstr ""
msgid "Set parent epic to an epic"
msgstr ""
+msgid "Set projects and maximum size limits, session duration, user options, and check feature availability for namespace plan."
+msgstr ""
+
msgid "Set requirements for a user to sign-in. Enable mandatory two-factor authentication."
msgstr ""
diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
index 3f3711f9eb8..d3a0c9b790b 100644
--- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
@@ -83,17 +83,17 @@ describe 'User updates wiki page' do
end
it 'updates the commit message as the title is changed', :js do
+ fill_in(:wiki_title, with: '& < > \ \ { } &')
+
+ expect(page).to have_field('wiki[message]', with: 'Update & < > \ \ { } &')
+ end
+
+ it 'correctly escapes the commit message entities', :js do
fill_in(:wiki_title, with: 'Wiki title')
expect(page).to have_field('wiki[message]', with: 'Update Wiki title')
end
- it 'does not allow XSS', :js do
- fill_in(:wiki_title, with: '