diff --git a/lib/gitlab/import_export/group/import_export.yml b/lib/gitlab/import_export/group/import_export.yml index e30414265bea985fe19226041ae30682226caf1d..c2a1a1f8575191f09e5244be77133f4cd4665975 100644 --- a/lib/gitlab/import_export/group/import_export.yml +++ b/lib/gitlab/import_export/group/import_export.yml @@ -56,7 +56,6 @@ excluded_attributes: - :runners_token - :runners_token_encrypted - :saml_discovery_token - - :visibility_level - :trial_ends_on - :shared_runners_minute_limit - :extra_shared_runners_minutes_limit diff --git a/lib/gitlab/import_export/group/tree_restorer.rb b/lib/gitlab/import_export/group/tree_restorer.rb index 19d707aaca5632cbb116fb31719aba53d780af06..0b92942eb8ad938569e2552af4b3c47ab9c811fe 100644 --- a/lib/gitlab/import_export/group/tree_restorer.rb +++ b/lib/gitlab/import_export/group/tree_restorer.rb @@ -65,6 +65,15 @@ def process_root(group_id) # with existing groups name and/or path. group_attributes.delete_attributes('name', 'path') + if @top_level_group.has_parent? + group_attributes.attributes['visibility_level'] = sub_group_visibility_level( + group_attributes.attributes['visibility_level'], + @top_level_group.parent + ) + elsif Gitlab::VisibilityLevel.restricted_level?(group_attributes.attributes['visibility_level']) + group_attributes.delete_attribute('visibility_level') + end + restore_group(@top_level_group, group_attributes) end @@ -86,6 +95,7 @@ def create_group(group_attributes) parent_id = group_attributes.delete_attribute('parent_id') name = group_attributes.delete_attribute('name') path = group_attributes.delete_attribute('path') + visibility_level = group_attributes.delete_attribute('visibility_level') parent_group = @groups_mapping.fetch(parent_id) { raise(ArgumentError, 'Parent group not found') } @@ -94,7 +104,7 @@ def create_group(group_attributes) name: name, path: path, parent_id: parent_group.id, - visibility_level: sub_group_visibility_level(group_attributes.attributes, parent_group) + visibility_level: sub_group_visibility_level(visibility_level, parent_group) ).execute group.validate! @@ -124,16 +134,23 @@ def relation_reader end end - def sub_group_visibility_level(group_hash, parent_group) - original_visibility_level = group_hash['visibility_level'] || Gitlab::VisibilityLevel::PRIVATE + def sub_group_visibility_level(visibility_level, parent_group) + parent_visibility_level = parent_group.visibility_level - if parent_group && parent_group.visibility_level < original_visibility_level - Gitlab::VisibilityLevel.closest_allowed_level(parent_group.visibility_level) + original_visibility_level = visibility_level || + closest_allowed_level(parent_visibility_level) + + if parent_visibility_level < original_visibility_level + closest_allowed_level(parent_visibility_level) else - original_visibility_level + closest_allowed_level(original_visibility_level) end end + def closest_allowed_level(visibility_level) + Gitlab::VisibilityLevel.closest_allowed_level(visibility_level) + end + def reader strong_memoize(:reader) do Gitlab::ImportExport::Reader.new( diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1689.json b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1689.json new file mode 100644 index 0000000000000000000000000000000000000000..4c0a29599b91e0c7bfd7f7d3d7be0d659699f950 --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1689.json @@ -0,0 +1,48 @@ +{ + "depth": 1, + "tree_path": [ + 1689 + ], + "tree_cycle": false, + "id": 1689, + "name": "public-group-3", + "path": "public-group-3", + "description": "", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 20, + "request_access_enabled": true, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": null, + "shared_runners_minutes_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": 2, + "file_template_project_id": null, + "custom_project_templates_group_id": null, + "auto_devops_enabled": null, + "last_ci_minutes_notification_at": null, + "last_ci_minutes_usage_notification_level": null, + "subgroup_creation_level": 1, + "emails_disabled": null, + "max_artifacts_size": null, + "mentions_disabled": null, + "default_branch_protection": 2, + "unlock_membership_to_ldap": null, + "max_personal_access_token_lifetime": null, + "push_rule_id": null, + "shared_runners_enabled": true, + "allow_descendants_override_disabled_shared_runners": false, + "traversal_ids": [ + 1689 + ], + "organization_id": 1 +} diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1690.json b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1690.json new file mode 100644 index 0000000000000000000000000000000000000000..f01c79b06d8e080e8572b6efe2b5f6f30b1b823e --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1690.json @@ -0,0 +1,50 @@ +{ + "depth": 2, + "tree_path": [ + 1689, + 1690 + ], + "tree_cycle": false, + "id": 1690, + "name": "private-subgroup", + "path": "private-subgroup", + "description": "", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 0, + "request_access_enabled": true, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": 1689, + "shared_runners_minutes_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": 2, + "file_template_project_id": null, + "custom_project_templates_group_id": null, + "auto_devops_enabled": null, + "last_ci_minutes_notification_at": null, + "last_ci_minutes_usage_notification_level": null, + "subgroup_creation_level": 1, + "emails_disabled": null, + "max_artifacts_size": null, + "mentions_disabled": null, + "default_branch_protection": 2, + "unlock_membership_to_ldap": null, + "max_personal_access_token_lifetime": null, + "push_rule_id": null, + "shared_runners_enabled": true, + "allow_descendants_override_disabled_shared_runners": false, + "traversal_ids": [ + 1689, + 1690 + ], + "organization_id": 1 +} diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1691.json b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1691.json new file mode 100644 index 0000000000000000000000000000000000000000..f9c08b420c0df99b79cedbe432a835de8e7dfaf1 --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1691.json @@ -0,0 +1,50 @@ +{ + "depth": 2, + "tree_path": [ + 1689, + 1691 + ], + "tree_cycle": false, + "id": 1691, + "name": "internal-subgroup", + "path": "internal-subgroup", + "description": "", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 10, + "request_access_enabled": true, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": 1689, + "shared_runners_minutes_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": 2, + "file_template_project_id": null, + "custom_project_templates_group_id": null, + "auto_devops_enabled": null, + "last_ci_minutes_notification_at": null, + "last_ci_minutes_usage_notification_level": null, + "subgroup_creation_level": 1, + "emails_disabled": null, + "max_artifacts_size": null, + "mentions_disabled": null, + "default_branch_protection": 2, + "unlock_membership_to_ldap": null, + "max_personal_access_token_lifetime": null, + "push_rule_id": null, + "shared_runners_enabled": true, + "allow_descendants_override_disabled_shared_runners": false, + "traversal_ids": [ + 1689, + 1691 + ], + "organization_id": 1 +} diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1692.json b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1692.json new file mode 100644 index 0000000000000000000000000000000000000000..381230e86a8cbddad3895ca6759e2c92790cf999 --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/1692.json @@ -0,0 +1,50 @@ +{ + "depth": 2, + "tree_path": [ + 1689, + 1692 + ], + "tree_cycle": false, + "id": 1692, + "name": "public-subgroup", + "path": "public-subgroup", + "description": "", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 20, + "request_access_enabled": true, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": 1689, + "shared_runners_minutes_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": 2, + "file_template_project_id": null, + "custom_project_templates_group_id": null, + "auto_devops_enabled": null, + "last_ci_minutes_notification_at": null, + "last_ci_minutes_usage_notification_level": null, + "subgroup_creation_level": 1, + "emails_disabled": null, + "max_artifacts_size": null, + "mentions_disabled": null, + "default_branch_protection": 2, + "unlock_membership_to_ldap": null, + "max_personal_access_token_lifetime": null, + "push_rule_id": null, + "shared_runners_enabled": true, + "allow_descendants_override_disabled_shared_runners": false, + "traversal_ids": [ + 1689, + 1692 + ], + "organization_id": 1 +} diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2106.json b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2106.json new file mode 100644 index 0000000000000000000000000000000000000000..1707e341129f6ec95605c165e16581c2a26fefc2 --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2106.json @@ -0,0 +1,52 @@ +{ + "depth": 3, + "tree_path": [ + 1689, + 1691, + 2106 + ], + "tree_cycle": false, + "id": 2106, + "name": "internal-sub-subgroup", + "path": "internal-sub-subgroup", + "description": "", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 10, + "request_access_enabled": true, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": 1691, + "shared_runners_minutes_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": 2, + "file_template_project_id": null, + "custom_project_templates_group_id": null, + "auto_devops_enabled": null, + "last_ci_minutes_notification_at": null, + "last_ci_minutes_usage_notification_level": null, + "subgroup_creation_level": 1, + "emails_disabled": null, + "max_artifacts_size": null, + "mentions_disabled": null, + "default_branch_protection": 2, + "unlock_membership_to_ldap": null, + "max_personal_access_token_lifetime": null, + "push_rule_id": null, + "shared_runners_enabled": true, + "allow_descendants_override_disabled_shared_runners": false, + "traversal_ids": [ + 1689, + 1691, + 2106 + ], + "organization_id": 1 +} diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2107.json b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2107.json new file mode 100644 index 0000000000000000000000000000000000000000..cac1c82682134fec2ddceb97cfcdad298643993a --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2107.json @@ -0,0 +1,52 @@ +{ + "depth": 3, + "tree_path": [ + 1689, + 1692, + 2107 + ], + "tree_cycle": false, + "id": 2107, + "name": "internal-sub-subgroup", + "path": "internal-sub-subgroup", + "description": "", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 10, + "request_access_enabled": true, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": 1692, + "shared_runners_minutes_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": 2, + "file_template_project_id": null, + "custom_project_templates_group_id": null, + "auto_devops_enabled": null, + "last_ci_minutes_notification_at": null, + "last_ci_minutes_usage_notification_level": null, + "subgroup_creation_level": 1, + "emails_disabled": null, + "max_artifacts_size": null, + "mentions_disabled": null, + "default_branch_protection": 2, + "unlock_membership_to_ldap": null, + "max_personal_access_token_lifetime": null, + "push_rule_id": null, + "shared_runners_enabled": true, + "allow_descendants_override_disabled_shared_runners": false, + "traversal_ids": [ + 1689, + 1692, + 2107 + ], + "organization_id": 1 +} diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2108.json b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2108.json new file mode 100644 index 0000000000000000000000000000000000000000..d464b41e9086ab60a2d5fdab794515be17e0353b --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2108.json @@ -0,0 +1,52 @@ +{ + "depth": 3, + "tree_path": [ + 1689, + 1692, + 2108 + ], + "tree_cycle": false, + "id": 2108, + "name": "public-sub-subgroup", + "path": "public-sub-subgroup", + "description": "", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 20, + "request_access_enabled": true, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": 1692, + "shared_runners_minutes_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": 2, + "file_template_project_id": null, + "custom_project_templates_group_id": null, + "auto_devops_enabled": null, + "last_ci_minutes_notification_at": null, + "last_ci_minutes_usage_notification_level": null, + "subgroup_creation_level": 1, + "emails_disabled": null, + "max_artifacts_size": null, + "mentions_disabled": null, + "default_branch_protection": 2, + "unlock_membership_to_ldap": null, + "max_personal_access_token_lifetime": null, + "push_rule_id": null, + "shared_runners_enabled": true, + "allow_descendants_override_disabled_shared_runners": false, + "traversal_ids": [ + 1689, + 1692, + 2108 + ], + "organization_id": 1 +} diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2109.json b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2109.json new file mode 100644 index 0000000000000000000000000000000000000000..7f3adf364d75187e867ef99b313be380e692f147 --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2109.json @@ -0,0 +1,52 @@ +{ + "depth": 3, + "tree_path": [ + 1689, + 1692, + 2109 + ], + "tree_cycle": false, + "id": 2109, + "name": "private-sub-subgroup", + "path": "private-sub-subgroup", + "description": "", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 0, + "request_access_enabled": true, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": 1692, + "shared_runners_minutes_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": 2, + "file_template_project_id": null, + "custom_project_templates_group_id": null, + "auto_devops_enabled": null, + "last_ci_minutes_notification_at": null, + "last_ci_minutes_usage_notification_level": null, + "subgroup_creation_level": 1, + "emails_disabled": null, + "max_artifacts_size": null, + "mentions_disabled": null, + "default_branch_protection": 2, + "unlock_membership_to_ldap": null, + "max_personal_access_token_lifetime": null, + "push_rule_id": null, + "shared_runners_enabled": true, + "allow_descendants_override_disabled_shared_runners": false, + "traversal_ids": [ + 1689, + 1692, + 2109 + ], + "organization_id": 1 +} diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2110.json b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2110.json new file mode 100644 index 0000000000000000000000000000000000000000..744b8d36b16e4fb9c7c317d3e2e8c0e178cfe9e0 --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/2110.json @@ -0,0 +1,52 @@ +{ + "depth": 3, + "tree_path": [ + 1689, + 1690, + 2110 + ], + "tree_cycle": false, + "id": 2110, + "name": "private-sub-subgroup", + "path": "private-sub-subgroup", + "description": "", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 0, + "request_access_enabled": true, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": 1690, + "shared_runners_minutes_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": 2, + "file_template_project_id": null, + "custom_project_templates_group_id": null, + "auto_devops_enabled": null, + "last_ci_minutes_notification_at": null, + "last_ci_minutes_usage_notification_level": null, + "subgroup_creation_level": 1, + "emails_disabled": null, + "max_artifacts_size": null, + "mentions_disabled": null, + "default_branch_protection": 2, + "unlock_membership_to_ldap": null, + "max_personal_access_token_lifetime": null, + "push_rule_id": null, + "shared_runners_enabled": true, + "allow_descendants_override_disabled_shared_runners": false, + "traversal_ids": [ + 1689, + 1690, + 2110 + ], + "organization_id": 1 +} diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/_all.ndjson b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/_all.ndjson new file mode 100644 index 0000000000000000000000000000000000000000..6c0425eabf474d6f5928234675315a46e1673bbd --- /dev/null +++ b/spec/fixtures/lib/gitlab/import_export/group_exports/visibility_levels/nested_subgroups/tree/groups/_all.ndjson @@ -0,0 +1,9 @@ +1689 +1690 +1691 +1692 +2110 +2106 +2107 +2108 +2109 diff --git a/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb index a6afd0a36ec4ae16c7ab30353da9f245f2da25f3..9766d5d6d594c4b19f445c193b8c87635be58290 100644 --- a/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb @@ -177,30 +177,146 @@ end context 'group visibility levels' do - let(:user) { create(:user) } - let(:shared) { Gitlab::ImportExport::Shared.new(group) } - let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) } + context 'when the @top_level_group is the destination_group' do + let(:user) { create(:user) } + let(:shared) { Gitlab::ImportExport::Shared.new(group) } + let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) } + + shared_examples 'with visibility level' do |visibility_level, expected_visibilities| + context "when visibility level is #{visibility_level}" do + let(:group) { create(:group, visibility_level) } + let(:filepath) { "group_exports/visibility_levels/#{visibility_level}" } + + before do + setup_import_export_config(filepath) + group_tree_restorer.restore + end - before do - setup_import_export_config(filepath) + it "imports all subgroups as #{visibility_level}" do + expect(group.children.map(&:visibility_level)).to match_array(expected_visibilities) + end + end + end - group_tree_restorer.restore + include_examples 'with visibility level', :public, [20, 10, 0] + include_examples 'with visibility level', :private, [0, 0, 0] + include_examples 'with visibility level', :internal, [10, 10, 0] end - shared_examples 'with visibility level' do |visibility_level, expected_visibilities| - context "when visibility level is #{visibility_level}" do - let(:group) { create(:group, visibility_level) } - let(:filepath) { "group_exports/visibility_levels/#{visibility_level}" } + context 'when the destination_group is the @top_level_group.parent' do + let(:user) { create(:user) } + let(:shared) { Gitlab::ImportExport::Shared.new(group) } + let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) } + + shared_examples 'with visibility level' do |visibility_level, expected_visibilities, group_visibility| + context "when source level is #{visibility_level}" do + let(:parent) { create(:group, visibility_level) } + let(:group) { create(:group, visibility_level, parent: parent) } + let(:filepath) { "group_exports/visibility_levels/#{visibility_level}" } + + before do + setup_import_export_config(filepath) + parent.add_maintainer(user) + group_tree_restorer.restore + end - it "imports all subgroups as #{visibility_level}" do - expect(group.children.map(&:visibility_level)).to match_array(expected_visibilities) + it "imports all subgroups as #{visibility_level}" do + expect(group.visibility_level).to eq(group_visibility) + expect(group.children.map(&:visibility_level)).to match_array(expected_visibilities) + end end end + + include_examples 'with visibility level', :public, [20, 10, 0], 20 + include_examples 'with visibility level', :private, [0, 0, 0], 0 + include_examples 'with visibility level', :internal, [10, 10, 0], 10 + end + + context 'when the visibility level is restricted' do + let(:user) { create(:user) } + let(:shared) { Gitlab::ImportExport::Shared.new(group) } + let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) } + let(:group) { create(:group, :internal) } + let(:filepath) { "group_exports/visibility_levels/internal" } + + before do + setup_import_export_config(filepath) + Gitlab::CurrentSettings.restricted_visibility_levels = [10] + group_tree_restorer.restore + end + + after do + Gitlab::CurrentSettings.restricted_visibility_levels = [] + end + + it 'updates the visibility_level' do + expect(group.children.map(&:visibility_level)).to match_array([0, 0, 0]) + end end + end + + context 'when there are nested subgroups' do + let(:filepath) { "group_exports/visibility_levels/nested_subgroups" } - include_examples 'with visibility level', :public, [20, 10, 0] - include_examples 'with visibility level', :private, [0, 0, 0] - include_examples 'with visibility level', :internal, [10, 10, 0] + context "when destination level is :public" do + let(:user) { create(:user) } + let(:shared) { Gitlab::ImportExport::Shared.new(group) } + let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) } + let(:parent) { create(:group, :public) } + let(:group) { create(:group, :public, parent: parent) } + + before do + setup_import_export_config(filepath) + parent.add_maintainer(user) + group_tree_restorer.restore + end + + it "imports all subgroups with original visibility_level" do + expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC) + expect(group.descendants.map(&:visibility_level)) + .to match_array([0, 0, 0, 10, 10, 10, 20, 20]) + end + end + + context "when destination level is :internal" do + let(:user) { create(:user) } + let(:shared) { Gitlab::ImportExport::Shared.new(group) } + let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) } + let(:parent) { create(:group, :internal) } + let(:group) { create(:group, :internal, parent: parent) } + + before do + setup_import_export_config(filepath) + parent.add_maintainer(user) + group_tree_restorer.restore + end + + it "imports non-public subgroups with original level and public subgroups as internal" do + expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::INTERNAL) + expect(group.descendants.map(&:visibility_level)) + .to match_array([0, 0, 0, 10, 10, 10, 10, 10]) + end + end + + context "when destination level is :private" do + let(:user) { create(:user) } + let(:shared) { Gitlab::ImportExport::Shared.new(group) } + let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) } + let(:parent) { create(:group, :private) } + let(:group) { create(:group, :private, parent: parent) } + + before do + setup_import_export_config(filepath) + parent.add_maintainer(user) + group_tree_restorer.restore + end + + it "imports all subgroups as private" do + expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + expect(group.descendants.map(&:visibility_level)) + .to match_array([0, 0, 0, 0, 0, 0, 0, 0]) + end + end end end diff --git a/spec/requests/import/gitlab_groups_controller_spec.rb b/spec/requests/import/gitlab_groups_controller_spec.rb index 1766c48cca1d9603bdba6a1cd8334bf36c2d25a6..734a4cefc5cfa2c2360d5cd30b468313805e0497 100644 --- a/spec/requests/import/gitlab_groups_controller_spec.rb +++ b/spec/requests/import/gitlab_groups_controller_spec.rb @@ -69,7 +69,7 @@ def upload_archive(file, headers = {}, params = {}) expect(GroupImportWorker).to have_received(:perform_async).with(user.id, group.id) expect(group.description).to eq 'A voluptate non sequi temporibus quam at.' - expect(group.visibility_level).to eq Gitlab::VisibilityLevel::PRIVATE + expect(group.visibility_level).to eq Gitlab::VisibilityLevel::PUBLIC end end