summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2017-05-29 15:49:56 +0000
committerDouwe Maan <douwe@gitlab.com>2017-05-29 15:49:56 +0000
commit26bcef97d64f449b5073ac767c02961763c20b18 (patch)
tree4a0ba9af1b670ee1c2743ff37988799142c33ff5 /spec
parent7dc8961af99d2a30b0a3210f7a4ee43c8779c6d2 (diff)
parent27d5f99e508024b5c2fb8509f83e8e4c6a214865 (diff)
downloadgitlab-ce-26bcef97d64f449b5073ac767c02961763c20b18.tar.gz
Merge branch 'rework-authorizations-performance' into 'master'
Rework project authorizations and nested groups for better performance See merge request !10885
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb8
-rw-r--r--spec/controllers/groups_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb7
-rw-r--r--spec/factories/projects.rb12
-rw-r--r--spec/features/groups/group_name_toggle_spec.rb4
-rw-r--r--spec/features/groups/members/list_spec.rb4
-rw-r--r--spec/features/groups_spec.rb4
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_author_spec.rb2
-rw-r--r--spec/features/projects/group_links_spec.rb2
-rw-r--r--spec/features/projects/members/sorting_spec.rb11
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb3
-rw-r--r--spec/finders/group_members_finder_spec.rb2
-rw-r--r--spec/finders/members_finder_spec.rb2
-rw-r--r--spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb4
-rw-r--r--spec/lib/gitlab/group_hierarchy_spec.rb53
-rw-r--r--spec/lib/gitlab/import_export/members_mapper_spec.rb8
-rw-r--r--spec/lib/gitlab/project_authorizations_spec.rb73
-rw-r--r--spec/lib/gitlab/sql/recursive_cte_spec.rb49
-rw-r--r--spec/migrations/fill_authorized_projects_spec.rb18
-rw-r--r--spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb66
-rw-r--r--spec/models/concerns/routable_spec.rb117
-rw-r--r--spec/models/group_spec.rb2
-rw-r--r--spec/models/members/project_member_spec.rb13
-rw-r--r--spec/models/namespace_spec.rb16
-rw-r--r--spec/models/project_group_link_spec.rb2
-rw-r--r--spec/models/project_team_spec.rb29
-rw-r--r--spec/models/user_spec.rb131
-rw-r--r--spec/policies/group_policy_spec.rb2
-rw-r--r--spec/requests/api/commits_spec.rb1
-rw-r--r--spec/requests/api/groups_spec.rb2
-rw-r--r--spec/requests/api/projects_spec.rb20
-rw-r--r--spec/requests/api/v3/commits_spec.rb1
-rw-r--r--spec/requests/api/v3/groups_spec.rb2
-rw-r--r--spec/requests/api/v3/projects_spec.rb13
-rw-r--r--spec/services/projects/destroy_service_spec.rb2
-rw-r--r--spec/services/users/refresh_authorized_projects_service_spec.rb66
-rw-r--r--spec/spec_helper.rb8
38 files changed, 453 insertions, 310 deletions
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index 412d3643e94..2c9d1ffc9c2 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -22,7 +22,7 @@ describe AutocompleteController do
let(:body) { JSON.parse(response.body) }
it { expect(body).to be_kind_of(Array) }
- it { expect(body.size).to eq 1 }
+ it { expect(body.size).to eq 2 }
it { expect(body.map { |u| u["username"] }).to include(user.username) }
end
@@ -80,8 +80,8 @@ describe AutocompleteController do
end
it { expect(body).to be_kind_of(Array) }
- it { expect(body.size).to eq 2 }
- it { expect(body.map { |u| u['username'] }).to match_array([user.username, non_member.username]) }
+ it { expect(body.size).to eq 3 }
+ it { expect(body.map { |u| u['username'] }).to include(user.username, non_member.username) }
end
end
@@ -122,7 +122,7 @@ describe AutocompleteController do
end
it { expect(body).to be_kind_of(Array) }
- it { expect(body.size).to eq 1 }
+ it { expect(body.size).to eq 2 }
end
describe 'GET #users with project' do
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index 4626f1ebc29..b0b24b1de1b 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -26,7 +26,7 @@ describe GroupsController do
end
end
- describe 'GET #subgroups' do
+ describe 'GET #subgroups', :nested_groups do
let!(:public_subgroup) { create(:group, :public, parent: group) }
let!(:private_subgroup) { create(:group, :private, parent: group) }
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 587a5820c6f..08024a2148b 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::MergeRequestsController do
let(:project) { create(:project) }
- let(:user) { create(:user) }
+ let(:user) { project.owner }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
let(:merge_request_with_conflicts) do
create(:merge_request, source_branch: 'conflict-resolvable', target_branch: 'conflict-start', source_project: project) do |mr|
@@ -12,7 +12,6 @@ describe Projects::MergeRequestsController do
before do
sign_in(user)
- project.team << [user, :master]
end
describe 'GET new' do
@@ -304,6 +303,8 @@ describe Projects::MergeRequestsController do
end
context 'when user cannot access' do
+ let(:user) { create(:user) }
+
before do
project.add_reporter(user)
xhr :post, :merge, base_params
@@ -459,6 +460,8 @@ describe Projects::MergeRequestsController do
end
describe "DELETE destroy" do
+ let(:user) { create(:user) }
+
it "denies access to users unless they're admin or project owner" do
delete :destroy, namespace_id: project.namespace, project_id: project, id: merge_request.iid
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 7a76f5f8afc..e8a9b688319 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -109,6 +109,18 @@ FactoryGirl.define do
merge_requests_access_level: merge_requests_access_level,
repository_access_level: evaluator.repository_access_level
)
+
+ # Normally the class Projects::CreateService is used for creating
+ # projects, and this class takes care of making sure the owner and current
+ # user have access to the project. Our specs don't use said service class,
+ # thus we must manually refresh things here.
+ owner = project.owner
+
+ if owner && owner.is_a?(User) && !project.pending_delete
+ project.members.create!(user: owner, access_level: Gitlab::Access::MASTER)
+ end
+
+ project.group&.refresh_members_authorized_projects
end
end
diff --git a/spec/features/groups/group_name_toggle_spec.rb b/spec/features/groups/group_name_toggle_spec.rb
index 8a1d415c4f1..dfc3c84f29a 100644
--- a/spec/features/groups/group_name_toggle_spec.rb
+++ b/spec/features/groups/group_name_toggle_spec.rb
@@ -22,7 +22,7 @@ feature 'Group name toggle', feature: true, js: true do
expect(page).not_to have_css('.group-name-toggle')
end
- it 'is present if the title is longer than the container' do
+ it 'is present if the title is longer than the container', :nested_groups do
visit group_path(nested_group_3)
title_width = page.evaluate_script("$('.title')[0].offsetWidth")
@@ -35,7 +35,7 @@ feature 'Group name toggle', feature: true, js: true do
expect(title_width).to be > container_width
end
- it 'should show the full group namespace when toggled' do
+ it 'should show the full group namespace when toggled', :nested_groups do
page_height = page.current_window.size[1]
page.current_window.resize_to(SMALL_SCREEN, page_height)
visit group_path(nested_group_3)
diff --git a/spec/features/groups/members/list_spec.rb b/spec/features/groups/members/list_spec.rb
index 543879bd21d..f654fa16a06 100644
--- a/spec/features/groups/members/list_spec.rb
+++ b/spec/features/groups/members/list_spec.rb
@@ -12,7 +12,7 @@ feature 'Groups members list', feature: true do
login_as(user1)
end
- scenario 'show members from current group and parent' do
+ scenario 'show members from current group and parent', :nested_groups do
group.add_developer(user1)
nested_group.add_developer(user2)
@@ -22,7 +22,7 @@ feature 'Groups members list', feature: true do
expect(second_row.text).to include(user2.name)
end
- scenario 'show user once if member of both current group and parent' do
+ scenario 'show user once if member of both current group and parent', :nested_groups do
group.add_developer(user1)
nested_group.add_developer(user1)
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index 3d32c47bf09..24ea7aba0cc 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -83,7 +83,7 @@ feature 'Group', feature: true do
end
end
- describe 'create a nested group', js: true do
+ describe 'create a nested group', :nested_groups, js: true do
let(:group) { create(:group, path: 'foo') }
context 'as admin' do
@@ -196,7 +196,7 @@ feature 'Group', feature: true do
end
end
- describe 'group page with nested groups', js: true do
+ describe 'group page with nested groups', :nested_groups, js: true do
let!(:group) { create(:group) }
let!(:nested_group) { create(:group, parent: group) }
let!(:path) { group_path(group) }
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index 0b573d7cef4..4d38df05928 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -58,7 +58,7 @@ describe 'Dropdown assignee', :feature, :js do
it 'should load all the assignees when opened' do
filtered_search.set('assignee:')
- expect(dropdown_assignee_size).to eq(3)
+ expect(dropdown_assignee_size).to eq(4)
end
it 'shows current user at top of dropdown' do
diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb
index b29177bed06..358b244fb5b 100644
--- a/spec/features/issues/filtered_search/dropdown_author_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb
@@ -65,7 +65,7 @@ describe 'Dropdown author', js: true, feature: true do
it 'should load all the authors when opened' do
send_keys_to_filtered_search('author:')
- expect(dropdown_author_size).to eq(3)
+ expect(dropdown_author_size).to eq(4)
end
it 'shows current user at top of dropdown' do
diff --git a/spec/features/projects/group_links_spec.rb b/spec/features/projects/group_links_spec.rb
index c969acc9140..4e5682c8636 100644
--- a/spec/features/projects/group_links_spec.rb
+++ b/spec/features/projects/group_links_spec.rb
@@ -40,7 +40,7 @@ feature 'Project group links', :feature, :js do
another_group.add_master(master)
end
- it 'does not show ancestors' do
+ it 'does not show ancestors', :nested_groups do
visit namespace_project_settings_members_path(project.namespace, project)
click_link 'Search for a group'
diff --git a/spec/features/projects/members/sorting_spec.rb b/spec/features/projects/members/sorting_spec.rb
index b7ae5f0b925..d428f6fcf22 100644
--- a/spec/features/projects/members/sorting_spec.rb
+++ b/spec/features/projects/members/sorting_spec.rb
@@ -3,10 +3,9 @@ require 'spec_helper'
feature 'Projects > Members > Sorting', feature: true do
let(:master) { create(:user, name: 'John Doe') }
let(:developer) { create(:user, name: 'Mary Jane', last_sign_in_at: 5.days.ago) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:empty_project, namespace: master.namespace, creator: master) }
background do
- create(:project_member, :master, user: master, project: project, created_at: 5.days.ago)
create(:project_member, :developer, user: developer, project: project, created_at: 3.days.ago)
login_as(master)
@@ -39,16 +38,16 @@ feature 'Projects > Members > Sorting', feature: true do
scenario 'sorts by last joined' do
visit_members_list(sort: :last_joined)
- expect(first_member).to include(developer.name)
- expect(second_member).to include(master.name)
+ expect(first_member).to include(master.name)
+ expect(second_member).to include(developer.name)
expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Last joined')
end
scenario 'sorts by oldest joined' do
visit_members_list(sort: :oldest_joined)
- expect(first_member).to include(master.name)
- expect(second_member).to include(developer.name)
+ expect(first_member).to include(developer.name)
+ expect(second_member).to include(master.name)
expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Oldest joined')
end
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 1bf8f710b9f..ec48a4bd726 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -2,11 +2,10 @@ require 'spec_helper'
feature 'Projects > Members > User requests access', feature: true do
let(:user) { create(:user) }
- let(:master) { create(:user) }
let(:project) { create(:project, :public, :access_requestable) }
+ let(:master) { project.owner }
background do
- project.team << [master, :master]
login_as(user)
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/finders/group_members_finder_spec.rb b/spec/finders/group_members_finder_spec.rb
index b762756f9ce..db3fcc23475 100644
--- a/spec/finders/group_members_finder_spec.rb
+++ b/spec/finders/group_members_finder_spec.rb
@@ -18,7 +18,7 @@ describe GroupMembersFinder, '#execute' do
expect(result.to_a).to eq([member3, member2, member1])
end
- it 'returns members for nested group' do
+ it 'returns members for nested group', :nested_groups do
group.add_master(user2)
nested_group.request_access(user4)
member1 = group.add_master(user1)
diff --git a/spec/finders/members_finder_spec.rb b/spec/finders/members_finder_spec.rb
index cf691cf684b..300ba8422e8 100644
--- a/spec/finders/members_finder_spec.rb
+++ b/spec/finders/members_finder_spec.rb
@@ -9,7 +9,7 @@ describe MembersFinder, '#execute' do
let(:user3) { create(:user) }
let(:user4) { create(:user) }
- it 'returns members for project and parent groups' do
+ it 'returns members for project and parent groups', :nested_groups do
nested_group.request_access(user1)
member1 = group.add_master(user2)
member2 = nested_group.add_master(user3)
diff --git a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
index b386852b196..cfb5cba054e 100644
--- a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
+++ b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do
- let(:project) { create(:project) }
+ let!(:project) { create(:project) }
let(:pipeline_status) { described_class.new(project) }
let(:cache_key) { "projects/#{project.id}/pipeline_status" }
@@ -18,7 +18,7 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do
let(:sha) { '424d1b73bc0d3cb726eb7dc4ce17a4d48552f8c6' }
let(:ref) { 'master' }
let(:pipeline_info) { { sha: sha, status: status, ref: ref } }
- let(:project_without_status) { create(:project) }
+ let!(:project_without_status) { create(:project) }
describe '.load_in_batch_for_projects' do
it 'preloads pipeline_status on projects' do
diff --git a/spec/lib/gitlab/group_hierarchy_spec.rb b/spec/lib/gitlab/group_hierarchy_spec.rb
new file mode 100644
index 00000000000..5d0ed1522b3
--- /dev/null
+++ b/spec/lib/gitlab/group_hierarchy_spec.rb
@@ -0,0 +1,53 @@
+require 'spec_helper'
+
+describe Gitlab::GroupHierarchy, :postgresql do
+ let!(:parent) { create(:group) }
+ let!(:child1) { create(:group, parent: parent) }
+ let!(:child2) { create(:group, parent: child1) }
+
+ describe '#base_and_ancestors' do
+ let(:relation) do
+ described_class.new(Group.where(id: child2.id)).base_and_ancestors
+ end
+
+ it 'includes the base rows' do
+ expect(relation).to include(child2)
+ end
+
+ it 'includes all of the ancestors' do
+ expect(relation).to include(parent, child1)
+ end
+ end
+
+ describe '#base_and_descendants' do
+ let(:relation) do
+ described_class.new(Group.where(id: parent.id)).base_and_descendants
+ end
+
+ it 'includes the base rows' do
+ expect(relation).to include(parent)
+ end
+
+ it 'includes all the descendants' do
+ expect(relation).to include(child1, child2)
+ end
+ end
+
+ describe '#all_groups' do
+ let(:relation) do
+ described_class.new(Group.where(id: child1.id)).all_groups
+ end
+
+ it 'includes the base rows' do
+ expect(relation).to include(child1)
+ end
+
+ it 'includes the ancestors' do
+ expect(relation).to include(parent)
+ end
+
+ it 'includes the descendants' do
+ expect(relation).to include(child2)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/members_mapper_spec.rb b/spec/lib/gitlab/import_export/members_mapper_spec.rb
index b9d4e59e770..3e0291c9ae9 100644
--- a/spec/lib/gitlab/import_export/members_mapper_spec.rb
+++ b/spec/lib/gitlab/import_export/members_mapper_spec.rb
@@ -2,9 +2,9 @@ require 'spec_helper'
describe Gitlab::ImportExport::MembersMapper, services: true do
describe 'map members' do
- let(:user) { create(:admin, authorized_projects_populated: true) }
+ let(:user) { create(:admin) }
let(:project) { create(:empty_project, :public, name: 'searchable_project') }
- let(:user2) { create(:user, authorized_projects_populated: true) }
+ let(:user2) { create(:user) }
let(:exported_user_id) { 99 }
let(:exported_members) do
[{
@@ -74,7 +74,7 @@ describe Gitlab::ImportExport::MembersMapper, services: true do
end
context 'user is not an admin' do
- let(:user) { create(:user, authorized_projects_populated: true) }
+ let(:user) { create(:user) }
it 'does not map a project member' do
expect(members_mapper.map[exported_user_id]).to eq(user.id)
@@ -94,7 +94,7 @@ describe Gitlab::ImportExport::MembersMapper, services: true do
end
context 'importer same as group member' do
- let(:user2) { create(:admin, authorized_projects_populated: true) }
+ let(:user2) { create(:admin) }
let(:group) { create(:group) }
let(:project) { create(:empty_project, :public, name: 'searchable_project', namespace: group) }
let(:members_mapper) do
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb
new file mode 100644
index 00000000000..67321f43710
--- /dev/null
+++ b/spec/lib/gitlab/project_authorizations_spec.rb
@@ -0,0 +1,73 @@
+require 'spec_helper'
+
+describe Gitlab::ProjectAuthorizations do
+ let(:group) { create(:group) }
+ let!(:owned_project) { create(:empty_project) }
+ let!(:other_project) { create(:empty_project) }
+ let!(:group_project) { create(:empty_project, namespace: group) }
+
+ let(:user) { owned_project.namespace.owner }
+
+ def map_access_levels(rows)
+ rows.each_with_object({}) do |row, hash|
+ hash[row.project_id] = row.access_level
+ end
+ end
+
+ before do
+ other_project.team << [user, :reporter]
+ group.add_developer(user)
+ end
+
+ let(:authorizations) do
+ klass = if Group.supports_nested_groups?
+ Gitlab::ProjectAuthorizations::WithNestedGroups
+ else
+ Gitlab::ProjectAuthorizations::WithoutNestedGroups
+ end
+
+ klass.new(user).calculate
+ end
+
+ it 'returns the correct number of authorizations' do
+ expect(authorizations.length).to eq(3)
+ end
+
+ it 'includes the correct projects' do
+ expect(authorizations.pluck(:project_id)).
+ to include(owned_project.id, other_project.id, group_project.id)
+ end
+
+ it 'includes the correct access levels' do
+ mapping = map_access_levels(authorizations)
+
+ expect(mapping[owned_project.id]).to eq(Gitlab::Access::MASTER)
+ expect(mapping[other_project.id]).to eq(Gitlab::Access::REPORTER)
+ expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER)
+ end
+
+ if Group.supports_nested_groups?
+ context 'with nested groups' do
+ let!(:nested_group) { create(:group, parent: group) }
+ let!(:nested_project) { create(:empty_project, namespace: nested_group) }
+
+ it 'includes nested groups' do
+ expect(authorizations.pluck(:project_id)).to include(nested_project.id)
+ end
+
+ it 'inherits access levels when the user is not a member of a nested group' do
+ mapping = map_access_levels(authorizations)
+
+ expect(mapping[nested_project.id]).to eq(Gitlab::Access::DEVELOPER)
+ end
+
+ it 'uses the greatest access level when a user is a member of a nested group' do
+ nested_group.add_master(user)
+
+ mapping = map_access_levels(authorizations)
+
+ expect(mapping[nested_project.id]).to eq(Gitlab::Access::MASTER)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/sql/recursive_cte_spec.rb b/spec/lib/gitlab/sql/recursive_cte_spec.rb
new file mode 100644
index 00000000000..25146860615
--- /dev/null
+++ b/spec/lib/gitlab/sql/recursive_cte_spec.rb
@@ -0,0 +1,49 @@
+require 'spec_helper'
+
+describe Gitlab::SQL::RecursiveCTE, :postgresql do
+ let(:cte) { described_class.new(:cte_name) }
+
+ describe '#to_arel' do
+ it 'generates an Arel relation for the CTE body' do
+ rel1 = User.where(id: 1)
+ rel2 = User.where(id: 2)
+
+ cte << rel1
+ cte << rel2
+
+ sql = cte.to_arel.to_sql
+ name = ActiveRecord::Base.connection.quote_table_name(:cte_name)
+
+ sql1, sql2 = ActiveRecord::Base.connection.unprepared_statement do
+ [rel1.except(:order).to_sql, rel2.except(:order).to_sql]
+ end
+
+ expect(sql).to eq("#{name} AS (#{sql1}\nUNION\n#{sql2})")
+ end
+ end
+
+ describe '#alias_to' do
+ it 'returns an alias for the CTE' do
+ table = Arel::Table.new(:kittens)
+
+ source_name = ActiveRecord::Base.connection.quote_table_name(:cte_name)
+ alias_name = ActiveRecord::Base.connection.quote_table_name(:kittens)
+
+ expect(cte.alias_to(table).to_sql).to eq("#{source_name} AS #{alias_name}")
+ end
+ end
+
+ describe '#apply_to' do
+ it 'applies a CTE to an ActiveRecord::Relation' do
+ user = create(:user)
+ cte = described_class.new(:cte_name)
+
+ cte << User.where(id: user.id)
+
+ relation = cte.apply_to(User.all)
+
+ expect(relation.to_sql).to match(/WITH RECURSIVE.+cte_name/)
+ expect(relation.to_a).to eq(User.where(id: user.id).to_a)
+ end
+ end
+end
diff --git a/spec/migrations/fill_authorized_projects_spec.rb b/spec/migrations/fill_authorized_projects_spec.rb
deleted file mode 100644
index 99dc4195818..00000000000
--- a/spec/migrations/fill_authorized_projects_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20170106142508_fill_authorized_projects.rb')
-
-describe FillAuthorizedProjects do
- describe '#up' do
- it 'schedules the jobs in batches' do
- user1 = create(:user)
- user2 = create(:user)
-
- expect(Sidekiq::Client).to receive(:push_bulk).with(
- 'class' => 'AuthorizedProjectsWorker',
- 'args' => [[user1.id], [user2.id]]
- )
-
- described_class.new.up
- end
- end
-end
diff --git a/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb b/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb
new file mode 100644
index 00000000000..175bf1876b2
--- /dev/null
+++ b/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb
@@ -0,0 +1,66 @@
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20170503140202_turn_nested_groups_into_regular_groups_for_mysql.rb')
+
+describe TurnNestedGroupsIntoRegularGroupsForMysql do
+ let!(:parent_group) { create(:group) }
+ let!(:child_group) { create(:group, parent: parent_group) }
+ let!(:project) { create(:project, :empty_repo, namespace: child_group) }
+ let!(:member) { create(:user) }
+ let(:migration) { described_class.new }
+
+ before do
+ parent_group.add_developer(member)
+
+ allow(migration).to receive(:run_migration?).and_return(true)
+ allow(migration).to receive(:verbose).and_return(false)
+ end
+
+ describe '#up' do
+ let(:updated_project) do
+ # path_with_namespace is memoized in an instance variable so we retrieve a
+ # new row here to work around that.
+ Project.find(project.id)
+ end
+
+ before do
+ migration.up
+ end
+
+ it 'unsets the parent_id column' do
+ expect(Namespace.where('parent_id IS NOT NULL').any?).to eq(false)
+ end
+
+ it 'adds members of parent groups as members to the migrated group' do
+ is_member = child_group.members.
+ where(user_id: member, access_level: Gitlab::Access::DEVELOPER).any?
+
+ expect(is_member).to eq(true)
+ end
+
+ it 'update the path of the nested group' do
+ child_group.reload
+
+ expect(child_group.path).to eq("#{parent_group.name}-#{child_group.name}")
+ end
+
+ it 'renames projects of the nested group' do
+ expect(updated_project.path_with_namespace).
+ to eq("#{parent_group.name}-#{child_group.name}/#{updated_project.path}")
+ end
+
+ it 'renames the repository of any projects' do
+ expect(updated_project.repository.path).
+ to end_with("#{parent_group.name}-#{child_group.name}/#{updated_project.path}.git")
+
+ expect(File.directory?(updated_project.repository.path)).to eq(true)
+ end
+
+ it 'creates a redirect route for renamed projects' do
+ exists = RedirectRoute.
+ where(source_type: 'Project', source_id: project.id).
+ any?
+
+ expect(exists).to eq(true)
+ end
+ end
+end
diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb
index 49a4132f763..0e10d91836d 100644
--- a/spec/models/concerns/routable_spec.rb
+++ b/spec/models/concerns/routable_spec.rb
@@ -115,123 +115,6 @@ describe Group, 'Routable' do
end
end
- describe '.member_descendants' do
- let!(:user) { create(:user) }
- let!(:nested_group) { create(:group, parent: group) }
-
- before { group.add_owner(user) }
- subject { described_class.member_descendants(user.id) }
-
- it { is_expected.to eq([nested_group]) }
- end
-
- describe '.member_self_and_descendants' do
- let!(:user) { create(:user) }
- let!(:nested_group) { create(:group, parent: group) }
-
- before { group.add_owner(user) }
- subject { described_class.member_self_and_descendants(user.id) }
-
- it { is_expected.to match_array [group, nested_group] }
- end
-
- describe '.member_hierarchy' do
- # foo/bar would also match foo/barbaz instead of just foo/bar and foo/bar/baz
- let!(:user) { create(:user) }
-
- # group
- # _______ (foo) _______
- # | |
- # | |
- # nested_group_1 nested_group_2
- # (bar) (barbaz)
- # | |
- # | |
- # nested_group_1_1 nested_group_2_1
- # (baz) (baz)
- #
- let!(:nested_group_1) { create :group, parent: group, name: 'bar' }
- let!(:nested_group_1_1) { create :group, parent: nested_group_1, name: 'baz' }
- let!(:nested_group_2) { create :group, parent: group, name: 'barbaz' }
- let!(:nested_group_2_1) { create :group, parent: nested_group_2, name: 'baz' }
-
- context 'user is not a member of any group' do
- subject { described_class.member_hierarchy(user.id) }
-
- it 'returns an empty array' do
- is_expected.to eq []
- end
- end
-
- context 'user is member of all groups' do
- before do
- group.add_owner(user)
- nested_group_1.add_owner(user)
- nested_group_1_1.add_owner(user)
- nested_group_2.add_owner(user)
- nested_group_2_1.add_owner(user)
- end
- subject { described_class.member_hierarchy(user.id) }
-
- it 'returns all groups' do
- is_expected.to match_array [
- group,
- nested_group_1, nested_group_1_1,
- nested_group_2, nested_group_2_1
- ]
- end
- end
-
- context 'user is member of the top group' do
- before { group.add_owner(user) }
- subject { described_class.member_hierarchy(user.id) }
-
- it 'returns all groups' do
- is_expected.to match_array [
- group,
- nested_group_1, nested_group_1_1,
- nested_group_2, nested_group_2_1
- ]
- end
- end
-
- context 'user is member of the first child (internal node), branch 1' do
- before { nested_group_1.add_owner(user) }
- subject { described_class.member_hierarchy(user.id) }
-
- it 'returns the groups in the hierarchy' do
- is_expected.to match_array [
- group,
- nested_group_1, nested_group_1_1
- ]
- end
- end
-
- context 'user is member of the first child (internal node), branch 2' do
- before { nested_group_2.add_owner(user) }
- subject { described_class.member_hierarchy(user.id) }
-
- it 'returns the groups in the hierarchy' do
- is_expected.to match_array [
- group,
- nested_group_2, nested_group_2_1
- ]
- end
- end
-
- context 'user is member of the last child (leaf node)' do
- before { nested_group_1_1.add_owner(user) }
- subject { described_class.member_hierarchy(user.id) }
-
- it 'returns the groups in the hierarchy' do
- is_expected.to match_array [
- group,
- nested_group_1, nested_group_1_1
- ]
- end
- end
- end
-
describe '#full_path' do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 6ca1eb0374d..316bf153660 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -340,7 +340,7 @@ describe Group, models: true do
it { expect(subject.parent).to be_kind_of(Group) }
end
- describe '#members_with_parents' do
+ describe '#members_with_parents', :nested_groups do
let!(:group) { create(:group, :nested) }
let!(:master) { group.parent.add_user(create(:user), GroupMember::MASTER) }
let!(:developer) { group.add_user(create(:user), GroupMember::DEVELOPER) }
diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb
index 87ea2e70680..cf9c701e8c5 100644
--- a/spec/models/members/project_member_spec.rb
+++ b/spec/models/members/project_member_spec.rb
@@ -22,16 +22,15 @@ describe ProjectMember, models: true do
end
describe '.add_user' do
- context 'when called with the project owner' do
- it 'adds the user as a member' do
- project = create(:empty_project)
+ it 'adds the user as a member' do
+ user = create(:user)
+ project = create(:empty_project)
- expect(project.users).not_to include(project.owner)
+ expect(project.users).not_to include(user)
- described_class.add_user(project, project.owner, :master, current_user: project.owner)
+ described_class.add_user(project, user, :master, current_user: project.owner)
- expect(project.users.reload).to include(project.owner)
- end
+ expect(project.users.reload).to include(user)
end
end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index ff5e7c350aa..0e74f1ab1bd 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -287,21 +287,21 @@ describe Namespace, models: true do
end
end
- describe '#ancestors' do
+ describe '#ancestors', :nested_groups do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:deep_nested_group) { create(:group, parent: nested_group) }
let(:very_deep_nested_group) { create(:group, parent: deep_nested_group) }
it 'returns the correct ancestors' do
- expect(very_deep_nested_group.ancestors).to eq([group, nested_group, deep_nested_group])
- expect(deep_nested_group.ancestors).to eq([group, nested_group])
- expect(nested_group.ancestors).to eq([group])
+ expect(very_deep_nested_group.ancestors).to include(group, nested_group, deep_nested_group)
+ expect(deep_nested_group.ancestors).to include(group, nested_group)
+ expect(nested_group.ancestors).to include(group)
expect(group.ancestors).to eq([])
end
end
- describe '#descendants' do
+ describe '#descendants', :nested_groups do
let!(:group) { create(:group, path: 'git_lab') }
let!(:nested_group) { create(:group, parent: group) }
let!(:deep_nested_group) { create(:group, parent: nested_group) }
@@ -311,9 +311,9 @@ describe Namespace, models: true do
it 'returns the correct descendants' do
expect(very_deep_nested_group.descendants.to_a).to eq([])
- expect(deep_nested_group.descendants.to_a).to eq([very_deep_nested_group])
- expect(nested_group.descendants.to_a).to eq([deep_nested_group, very_deep_nested_group])
- expect(group.descendants.to_a).to eq([nested_group, deep_nested_group, very_deep_nested_group])
+ expect(deep_nested_group.descendants.to_a).to include(very_deep_nested_group)
+ expect(nested_group.descendants.to_a).to include(deep_nested_group, very_deep_nested_group)
+ expect(group.descendants.to_a).to include(nested_group, deep_nested_group, very_deep_nested_group)
end
end
diff --git a/spec/models/project_group_link_spec.rb b/spec/models/project_group_link_spec.rb
index 9b711bfc007..4161b9158b1 100644
--- a/spec/models/project_group_link_spec.rb
+++ b/spec/models/project_group_link_spec.rb
@@ -23,7 +23,7 @@ describe ProjectGroupLink do
expect(project_group_link).not_to be_valid
end
- it "doesn't allow a project to be shared with an ancestor of the group it is in" do
+ it "doesn't allow a project to be shared with an ancestor of the group it is in", :nested_groups do
project_group_link.group = parent_group
expect(project_group_link).not_to be_valid
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index 942eeab251d..fb2d5f60009 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -81,7 +81,7 @@ describe ProjectTeam, models: true do
user = create(:user)
project.add_guest(user)
- expect(project.team.members).to contain_exactly(user)
+ expect(project.team.members).to contain_exactly(user, project.owner)
end
it 'returns project members of a specified level' do
@@ -100,7 +100,8 @@ describe ProjectTeam, models: true do
group_access: Gitlab::Access::GUEST
)
- expect(project.team.members).to contain_exactly(group_member.user)
+ expect(project.team.members).
+ to contain_exactly(group_member.user, project.owner)
end
it 'returns invited members of a group of a specified level' do
@@ -137,7 +138,10 @@ describe ProjectTeam, models: true do
describe '#find_member' do
context 'personal project' do
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) do
+ create(:empty_project, :public, :access_requestable)
+ end
+
let(:requester) { create(:user) }
before do
@@ -200,7 +204,9 @@ describe ProjectTeam, models: true do
let(:requester) { create(:user) }
context 'personal project' do
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) do
+ create(:empty_project, :public, :access_requestable)
+ end
context 'when project is not shared with group' do
before do
@@ -244,7 +250,9 @@ describe ProjectTeam, models: true do
context 'group project' do
let(:group) { create(:group, :access_requestable) }
- let!(:project) { create(:empty_project, group: group) }
+ let!(:project) do
+ create(:empty_project, group: group)
+ end
before do
group.add_master(master)
@@ -265,8 +273,15 @@ describe ProjectTeam, models: true do
let(:group) { create(:group) }
let(:developer) { create(:user) }
let(:master) { create(:user) }
- let(:personal_project) { create(:empty_project, namespace: developer.namespace) }
- let(:group_project) { create(:empty_project, namespace: group) }
+
+ let(:personal_project) do
+ create(:empty_project, namespace: developer.namespace)
+ end
+
+ let(:group_project) do
+ create(:empty_project, namespace: group)
+ end
+
let(:members_project) { create(:empty_project) }
let(:shared_project) { create(:empty_project) }
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index aabdac4bb75..9edf34b05ad 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -627,16 +627,6 @@ describe User, models: true do
it { expect(User.without_projects).to include user_without_project2 }
end
- describe '.not_in_project' do
- before do
- User.delete_all
- @user = create :user
- @project = create(:empty_project)
- end
-
- it { expect(User.not_in_project(@project)).to include(@user, @project.owner) }
- end
-
describe 'user creation' do
describe 'normal user' do
let(:user) { create(:user, name: 'John Smith') }
@@ -1561,48 +1551,103 @@ describe User, models: true do
end
end
- describe '#nested_groups' do
+ describe '#all_expanded_groups' do
+ # foo/bar would also match foo/barbaz instead of just foo/bar and foo/bar/baz
let!(:user) { create(:user) }
- let!(:group) { create(:group) }
- let!(:nested_group) { create(:group, parent: group) }
- before do
- group.add_owner(user)
+ # group
+ # _______ (foo) _______
+ # | |
+ # | |
+ # nested_group_1 nested_group_2
+ # (bar) (barbaz)
+ # | |
+ # | |
+ # nested_group_1_1 nested_group_2_1
+ # (baz) (baz)
+ #
+ let!(:group) { create :group }
+ let!(:nested_group_1) { create :group, parent: group, name: 'bar' }
+ let!(:nested_group_1_1) { create :group, parent: nested_group_1, name: 'baz' }
+ let!(:nested_group_2) { create :group, parent: group, name: 'barbaz' }
+ let!(:nested_group_2_1) { create :group, parent: nested_group_2, name: 'baz' }
- # Add more data to ensure method does not include wrong groups
- create(:group).add_owner(create(:user))
+ subject { user.all_expanded_groups }
+
+ context 'user is not a member of any group' do
+ it 'returns an empty array' do
+ is_expected.to eq([])
+ end
end
- it { expect(user.nested_groups).to eq([nested_group]) }
- end
+ context 'user is member of all groups' do
+ before do
+ group.add_owner(user)
+ nested_group_1.add_owner(user)
+ nested_group_1_1.add_owner(user)
+ nested_group_2.add_owner(user)
+ nested_group_2_1.add_owner(user)
+ end
- describe '#all_expanded_groups' do
- let!(:user) { create(:user) }
- let!(:group) { create(:group) }
- let!(:nested_group_1) { create(:group, parent: group) }
- let!(:nested_group_2) { create(:group, parent: group) }
+ it 'returns all groups' do
+ is_expected.to match_array [
+ group,
+ nested_group_1, nested_group_1_1,
+ nested_group_2, nested_group_2_1
+ ]
+ end
+ end
- before { nested_group_1.add_owner(user) }
+ context 'user is member of the top group' do
+ before { group.add_owner(user) }
- it { expect(user.all_expanded_groups).to match_array [group, nested_group_1] }
- end
+ if Group.supports_nested_groups?
+ it 'returns all groups' do
+ is_expected.to match_array [
+ group,
+ nested_group_1, nested_group_1_1,
+ nested_group_2, nested_group_2_1
+ ]
+ end
+ else
+ it 'returns the top-level groups' do
+ is_expected.to match_array [group]
+ end
+ end
+ end
- describe '#nested_groups_projects' do
- let!(:user) { create(:user) }
- let!(:group) { create(:group) }
- let!(:nested_group) { create(:group, parent: group) }
- let!(:project) { create(:empty_project, namespace: group) }
- let!(:nested_project) { create(:empty_project, namespace: nested_group) }
+ context 'user is member of the first child (internal node), branch 1', :nested_groups do
+ before { nested_group_1.add_owner(user) }
- before do
- group.add_owner(user)
+ it 'returns the groups in the hierarchy' do
+ is_expected.to match_array [
+ group,
+ nested_group_1, nested_group_1_1
+ ]
+ end
+ end
+
+ context 'user is member of the first child (internal node), branch 2', :nested_groups do
+ before { nested_group_2.add_owner(user) }
- # Add more data to ensure method does not include wrong projects
- other_project = create(:empty_project, namespace: create(:group, :nested))
- other_project.add_developer(create(:user))
+ it 'returns the groups in the hierarchy' do
+ is_expected.to match_array [
+ group,
+ nested_group_2, nested_group_2_1
+ ]
+ end
end
- it { expect(user.nested_groups_projects).to eq([nested_project]) }
+ context 'user is member of the last child (leaf node)', :nested_groups do
+ before { nested_group_1_1.add_owner(user) }
+
+ it 'returns the groups in the hierarchy' do
+ is_expected.to match_array [
+ group,
+ nested_group_1, nested_group_1_1
+ ]
+ end
+ end
end
describe '#refresh_authorized_projects', redis: true do
@@ -1622,10 +1667,6 @@ describe User, models: true do
expect(user.project_authorizations.count).to eq(2)
end
- it 'sets the authorized_projects_populated column' do
- expect(user.authorized_projects_populated).to eq(true)
- end
-
it 'stores the correct access levels' do
expect(user.project_authorizations.where(access_level: Gitlab::Access::GUEST).exists?).to eq(true)
expect(user.project_authorizations.where(access_level: Gitlab::Access::REPORTER).exists?).to eq(true)
@@ -1735,7 +1776,7 @@ describe User, models: true do
end
end
- context 'with 2FA requirement on nested parent group' do
+ context 'with 2FA requirement on nested parent group', :nested_groups do
let!(:group1) { create :group, require_two_factor_authentication: true }
let!(:group1a) { create :group, require_two_factor_authentication: false, parent: group1 }
@@ -1750,7 +1791,7 @@ describe User, models: true do
end
end
- context 'with 2FA requirement on nested child group' do
+ context 'with 2FA requirement on nested child group', :nested_groups do
let!(:group1) { create :group, require_two_factor_authentication: false }
let!(:group1a) { create :group, require_two_factor_authentication: true, parent: group1 }
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 2077c14ff7a..4c37a553227 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -107,7 +107,7 @@ describe GroupPolicy, models: true do
end
end
- describe 'private nested group inherit permissions' do
+ describe 'private nested group inherit permissions', :nested_groups do
let(:nested_group) { create(:group, :private, parent: group) }
subject { described_class.abilities(current_user, nested_group).to_set }
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 0b0e4c2b112..b84361d3abd 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -5,7 +5,6 @@ describe API::Commits do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let!(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
- let!(:master) { create(:project_member, :master, user: user, project: project) }
let!(:guest) { create(:project_member, :guest, user: user2, project: project) }
let!(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') }
let!(:another_note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'another comment on a commit') }
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 90b36374ded..bb53796cbd7 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -429,7 +429,7 @@ describe API::Groups do
expect(json_response["request_access_enabled"]).to eq(group[:request_access_enabled])
end
- it "creates a nested group" do
+ it "creates a nested group", :nested_groups do
parent = create(:group)
parent.add_owner(user3)
group = attributes_for(:group, { parent_id: parent.id })
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index d5c3b5b34ad..f95a287a184 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -11,8 +11,7 @@ describe API::Projects do
let(:project) { create(:empty_project, creator_id: user.id, namespace: user.namespace) }
let(:project2) { create(:empty_project, path: 'project2', creator_id: user.id, namespace: user.namespace) }
let(:snippet) { create(:project_snippet, :public, author: user, project: project, title: 'example') }
- let(:project_member) { create(:project_member, :master, user: user, project: project) }
- let(:project_member2) { create(:project_member, :developer, user: user3, project: project) }
+ let(:project_member) { create(:project_member, :developer, user: user3, project: project) }
let(:user4) { create(:user) }
let(:project3) do
create(:project,
@@ -27,7 +26,7 @@ describe API::Projects do
builds_enabled: false,
snippets_enabled: false)
end
- let(:project_member3) do
+ let(:project_member2) do
create(:project_member,
user: user4,
project: project3,
@@ -210,7 +209,7 @@ describe API::Projects do
let(:public_project) { create(:empty_project, :public) }
before do
- project_member2
+ project_member
user3.update_attributes(starred_projects: [project, project2, project3, public_project])
end
@@ -784,19 +783,18 @@ describe API::Projects do
describe 'GET /projects/:id/users' do
shared_examples_for 'project users response' do
it 'returns the project users' do
- member = create(:user)
- create(:project_member, :developer, user: member, project: project)
-
get api("/projects/#{project.id}/users", current_user)
+ user = project.namespace.owner
+
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
first_user = json_response.first
- expect(first_user['username']).to eq(member.username)
- expect(first_user['name']).to eq(member.name)
+ expect(first_user['username']).to eq(user.username)
+ expect(first_user['name']).to eq(user.name)
expect(first_user.keys).to contain_exactly(*%w[name username id state avatar_url web_url])
end
end
@@ -1091,8 +1089,8 @@ describe API::Projects do
before { user4 }
before { project3 }
before { project4 }
- before { project_member3 }
before { project_member2 }
+ before { project_member }
it 'returns 400 when nothing sent' do
project_param = {}
@@ -1573,7 +1571,7 @@ describe API::Projects do
context 'when authenticated as developer' do
before do
- project_member2
+ project_member
end
it 'returns forbidden error' do
diff --git a/spec/requests/api/v3/commits_spec.rb b/spec/requests/api/v3/commits_spec.rb
index c2e8c3ae6f7..386f60065ad 100644
--- a/spec/requests/api/v3/commits_spec.rb
+++ b/spec/requests/api/v3/commits_spec.rb
@@ -5,7 +5,6 @@ describe API::V3::Commits do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let!(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
- let!(:master) { create(:project_member, :master, user: user, project: project) }
let!(:guest) { create(:project_member, :guest, user: user2, project: project) }
let!(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') }
let!(:another_note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'another comment on a commit') }
diff --git a/spec/requests/api/v3/groups_spec.rb b/spec/requests/api/v3/groups_spec.rb
index bc261b5e07c..98e8c954909 100644
--- a/spec/requests/api/v3/groups_spec.rb
+++ b/spec/requests/api/v3/groups_spec.rb
@@ -421,7 +421,7 @@ describe API::V3::Groups do
expect(json_response["request_access_enabled"]).to eq(group[:request_access_enabled])
end
- it "creates a nested group" do
+ it "creates a nested group", :nested_groups do
parent = create(:group)
parent.add_owner(user3)
group = attributes_for(:group, { parent_id: parent.id })
diff --git a/spec/requests/api/v3/projects_spec.rb b/spec/requests/api/v3/projects_spec.rb
index dc7c3d125b1..bc591b2eb37 100644
--- a/spec/requests/api/v3/projects_spec.rb
+++ b/spec/requests/api/v3/projects_spec.rb
@@ -10,8 +10,7 @@ describe API::V3::Projects do
let(:project) { create(:empty_project, creator_id: user.id, namespace: user.namespace) }
let(:project2) { create(:empty_project, path: 'project2', creator_id: user.id, namespace: user.namespace) }
let(:snippet) { create(:project_snippet, :public, author: user, project: project, title: 'example') }
- let(:project_member) { create(:project_member, :master, user: user, project: project) }
- let(:project_member2) { create(:project_member, :developer, user: user3, project: project) }
+ let(:project_member) { create(:project_member, :developer, user: user3, project: project) }
let(:user4) { create(:user) }
let(:project3) do
create(:project,
@@ -25,7 +24,7 @@ describe API::V3::Projects do
issues_enabled: false, wiki_enabled: false,
snippets_enabled: false)
end
- let(:project_member3) do
+ let(:project_member2) do
create(:project_member,
user: user4,
project: project3,
@@ -286,7 +285,7 @@ describe API::V3::Projects do
let(:public_project) { create(:empty_project, :public) }
before do
- project_member2
+ project_member
user3.update_attributes(starred_projects: [project, project2, project3, public_project])
end
@@ -622,7 +621,6 @@ describe API::V3::Projects do
context 'when authenticated' do
before do
project
- project_member
end
it 'returns a project by id' do
@@ -814,8 +812,7 @@ describe API::V3::Projects do
describe 'GET /projects/:id/users' do
shared_examples_for 'project users response' do
it 'returns the project users' do
- member = create(:user)
- create(:project_member, :developer, user: member, project: project)
+ member = project.owner
get v3_api("/projects/#{project.id}/users", current_user)
@@ -1163,8 +1160,8 @@ describe API::V3::Projects do
before { user4 }
before { project3 }
before { project4 }
- before { project_member3 }
before { project_member2 }
+ before { project_member }
context 'when unauthenticated' do
it 'returns authentication error' do
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index 4b8589b2736..0d6dd28e332 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -70,7 +70,7 @@ describe Projects::DestroyService, services: true do
end
end
- expect(project.team.members.count).to eq 1
+ expect(project.team.members.count).to eq 2
end
end
diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb
index b19374ef1a2..8c40d25e00c 100644
--- a/spec/services/users/refresh_authorized_projects_service_spec.rb
+++ b/spec/services/users/refresh_authorized_projects_service_spec.rb
@@ -1,15 +1,13 @@
require 'spec_helper'
describe Users::RefreshAuthorizedProjectsService do
- let(:project) { create(:empty_project) }
+ # We're using let! here so that any expectations for the service class are not
+ # triggered twice.
+ let!(:project) { create(:empty_project) }
+
let(:user) { project.namespace.owner }
let(:service) { described_class.new(user) }
- def create_authorization(project, user, access_level = Gitlab::Access::MASTER)
- ProjectAuthorization.
- create!(project: project, user: user, access_level: access_level)
- end
-
describe '#execute', :redis do
it 'refreshes the authorizations using a lease' do
expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).
@@ -31,7 +29,8 @@ describe Users::RefreshAuthorizedProjectsService do
it 'updates the authorized projects of the user' do
project2 = create(:empty_project)
- to_remove = create_authorization(project2, user)
+ to_remove = user.project_authorizations.
+ create!(project: project2, access_level: Gitlab::Access::MASTER)
expect(service).to receive(:update_authorizations).
with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]])
@@ -40,7 +39,10 @@ describe Users::RefreshAuthorizedProjectsService do
end
it 'sets the access level of a project to the highest available level' do
- to_remove = create_authorization(project, user, Gitlab::Access::DEVELOPER)
+ user.project_authorizations.delete_all
+
+ to_remove = user.project_authorizations.
+ create!(project: project, access_level: Gitlab::Access::DEVELOPER)
expect(service).to receive(:update_authorizations).
with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]])
@@ -61,34 +63,10 @@ describe Users::RefreshAuthorizedProjectsService do
service.update_authorizations([], [])
end
-
- context 'when the authorized projects column is not set' do
- before do
- user.update!(authorized_projects_populated: nil)
- end
-
- it 'populates the authorized projects column' do
- service.update_authorizations([], [])
-
- expect(user.authorized_projects_populated).to eq true
- end
- end
-
- context 'when the authorized projects column is set' do
- before do
- user.update!(authorized_projects_populated: true)
- end
-
- it 'does nothing' do
- expect(user).not_to receive(:set_authorized_projects_column)
-
- service.update_authorizations([], [])
- end
- end
end
it 'removes authorizations that should be removed' do
- authorization = create_authorization(project, user)
+ authorization = user.project_authorizations.find_by(project_id: project.id)
service.update_authorizations([authorization.project_id])
@@ -96,6 +74,8 @@ describe Users::RefreshAuthorizedProjectsService do
end
it 'inserts authorizations that should be added' do
+ user.project_authorizations.delete_all
+
service.update_authorizations([], [[user.id, project.id, Gitlab::Access::MASTER]])
authorizations = user.project_authorizations
@@ -105,16 +85,6 @@ describe Users::RefreshAuthorizedProjectsService do
expect(authorizations[0].project_id).to eq(project.id)
expect(authorizations[0].access_level).to eq(Gitlab::Access::MASTER)
end
-
- it 'populates the authorized projects column' do
- # make sure we start with a nil value no matter what the default in the
- # factory may be.
- user.update!(authorized_projects_populated: nil)
-
- service.update_authorizations([], [[user.id, project.id, Gitlab::Access::MASTER]])
-
- expect(user.authorized_projects_populated).to eq(true)
- end
end
describe '#fresh_access_levels_per_project' do
@@ -163,7 +133,7 @@ describe Users::RefreshAuthorizedProjectsService do
end
end
- context 'projects of subgroups of groups the user is a member of' do
+ context 'projects of subgroups of groups the user is a member of', :nested_groups do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let!(:other_project) { create(:empty_project, group: nested_group) }
@@ -191,7 +161,7 @@ describe Users::RefreshAuthorizedProjectsService do
end
end
- context 'projects shared with subgroups of groups the user is a member of' do
+ context 'projects shared with subgroups of groups the user is a member of', :nested_groups do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
let(:other_project) { create(:empty_project) }
@@ -208,8 +178,6 @@ describe Users::RefreshAuthorizedProjectsService do
end
describe '#current_authorizations_per_project' do
- before { create_authorization(project, user) }
-
let(:hash) { service.current_authorizations_per_project }
it 'returns a Hash' do
@@ -233,13 +201,13 @@ describe Users::RefreshAuthorizedProjectsService do
describe '#current_authorizations' do
context 'without authorizations' do
it 'returns an empty list' do
+ user.project_authorizations.delete_all
+
expect(service.current_authorizations.empty?).to eq(true)
end
end
context 'with an authorization' do
- before { create_authorization(project, user) }
-
let(:row) { service.current_authorizations.take }
it 'returns the currently authorized projects' do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 51571ddebe9..4c2eba8fa46 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -92,6 +92,14 @@ RSpec.configure do |config|
Gitlab::Redis.with(&:flushall)
Sidekiq.redis(&:flushall)
end
+
+ config.around(:each, :nested_groups) do |example|
+ example.run if Group.supports_nested_groups?
+ end
+
+ config.around(:each, :postgresql) do |example|
+ example.run if Gitlab::Database.postgresql?
+ end
end
FactoryGirl::SyntaxRunner.class_eval do