diff options
author | Lin Jen-Shin <godfat@godfat.org> | 2017-11-06 21:44:57 +0800 |
---|---|---|
committer | Lin Jen-Shin <godfat@godfat.org> | 2017-11-06 21:44:57 +0800 |
commit | fc6aad0b4442c58fde1ac924cb2dd73823273537 (patch) | |
tree | 3f4a46a5b649cf623ab5e8e42eaa2e06cb2b20cf /spec/controllers/groups | |
parent | 239332eed3fa870fd41be83864882c0f389840d8 (diff) | |
parent | cfc932cad10b1d6c494222e9d91aa75583b56145 (diff) | |
download | gitlab-ce-fc6aad0b4442c58fde1ac924cb2dd73823273537.tar.gz |
Merge remote-tracking branch 'upstream/master' into no-ivar-in-modules
* upstream/master: (1723 commits)
Resolve "Editor icons"
Refactor issuable destroy action
Ignore routes matching legacy_*_redirect in route specs
Gitlab::Git::RevList and LfsChanges use lazy popen
Gitlab::Git::Popen can lazily hand output to a block
Merge branch 'master-i18n' into 'master'
Remove unique validation from external_url in Environment
Expose `duration` in Job API entity
Add TimeCop freeze for DST and Regular time
Harcode project visibility
update a changelog
Put a condition to old migration that adds fast_forward column to MRs
Expose project visibility as CI variable
fix flaky tests by removing unneeded clicks and focus actions
fix flaky test in gfm_autocomplete_spec.rb
Use Gitlab::Git operations for repository mirroring
Encapsulate git operations for mirroring in Gitlab::Git
Create a Wiki Repository's raw_repository properly
Add `Gitlab::Git::Repository#fetch` command
Fix Gitlab::Metrics::System#real_time and #monotonic_time doc
...
Diffstat (limited to 'spec/controllers/groups')
6 files changed, 305 insertions, 19 deletions
diff --git a/spec/controllers/groups/children_controller_spec.rb b/spec/controllers/groups/children_controller_spec.rb new file mode 100644 index 00000000000..4262d474e59 --- /dev/null +++ b/spec/controllers/groups/children_controller_spec.rb @@ -0,0 +1,286 @@ +require 'spec_helper' + +describe Groups::ChildrenController do + let(:group) { create(:group, :public) } + let(:user) { create(:user) } + let!(:group_member) { create(:group_member, group: group, user: user) } + + describe 'GET #index' do + context 'for projects' do + let!(:public_project) { create(:project, :public, namespace: group) } + let!(:private_project) { create(:project, :private, namespace: group) } + + context 'as a user' do + before do + sign_in(user) + end + + it 'shows all children' do + get :index, group_id: group.to_param, format: :json + + expect(assigns(:children)).to contain_exactly(public_project, private_project) + end + + context 'being member of private subgroup' do + it 'shows public and private children the user is member of' do + group_member.destroy! + private_project.add_guest(user) + + get :index, group_id: group.to_param, format: :json + + expect(assigns(:children)).to contain_exactly(public_project, private_project) + end + end + end + + context 'as a guest' do + it 'shows the public children' do + get :index, group_id: group.to_param, format: :json + + expect(assigns(:children)).to contain_exactly(public_project) + end + end + end + + context 'for subgroups', :nested_groups do + let!(:public_subgroup) { create(:group, :public, parent: group) } + let!(:private_subgroup) { create(:group, :private, parent: group) } + let!(:public_project) { create(:project, :public, namespace: group) } + let!(:private_project) { create(:project, :private, namespace: group) } + + context 'as a user' do + before do + sign_in(user) + end + + it 'shows all children' do + get :index, group_id: group.to_param, format: :json + + expect(assigns(:children)).to contain_exactly(public_subgroup, private_subgroup, public_project, private_project) + end + + context 'being member of private subgroup' do + it 'shows public and private children the user is member of' do + group_member.destroy! + private_subgroup.add_guest(user) + private_project.add_guest(user) + + get :index, group_id: group.to_param, format: :json + + expect(assigns(:children)).to contain_exactly(public_subgroup, private_subgroup, public_project, private_project) + end + end + end + + context 'as a guest' do + it 'shows the public children' do + get :index, group_id: group.to_param, format: :json + + expect(assigns(:children)).to contain_exactly(public_subgroup, public_project) + end + end + + context 'filtering children' do + it 'expands the tree for matching projects' do + project = create(:project, :public, namespace: public_subgroup, name: 'filterme') + + get :index, group_id: group.to_param, filter: 'filter', format: :json + + group_json = json_response.first + project_json = group_json['children'].first + + expect(group_json['id']).to eq(public_subgroup.id) + expect(project_json['id']).to eq(project.id) + end + + it 'expands the tree for matching subgroups' do + matched_group = create(:group, :public, parent: public_subgroup, name: 'filterme') + + get :index, group_id: group.to_param, filter: 'filter', format: :json + + group_json = json_response.first + matched_group_json = group_json['children'].first + + expect(group_json['id']).to eq(public_subgroup.id) + expect(matched_group_json['id']).to eq(matched_group.id) + end + + it 'merges the trees correctly' do + shared_subgroup = create(:group, :public, parent: group, path: 'hardware') + matched_project_1 = create(:project, :public, namespace: shared_subgroup, name: 'mobile-soc') + + l2_subgroup = create(:group, :public, parent: shared_subgroup, path: 'broadcom') + l3_subgroup = create(:group, :public, parent: l2_subgroup, path: 'wifi-group') + matched_project_2 = create(:project, :public, namespace: l3_subgroup, name: 'mobile') + + get :index, group_id: group.to_param, filter: 'mobile', format: :json + + shared_group_json = json_response.first + expect(shared_group_json['id']).to eq(shared_subgroup.id) + + matched_project_1_json = shared_group_json['children'].detect { |child| child['type'] == 'project' } + expect(matched_project_1_json['id']).to eq(matched_project_1.id) + + l2_subgroup_json = shared_group_json['children'].detect { |child| child['type'] == 'group' } + expect(l2_subgroup_json['id']).to eq(l2_subgroup.id) + + l3_subgroup_json = l2_subgroup_json['children'].first + expect(l3_subgroup_json['id']).to eq(l3_subgroup.id) + + matched_project_2_json = l3_subgroup_json['children'].first + expect(matched_project_2_json['id']).to eq(matched_project_2.id) + end + + it 'expands the tree upto a specified parent' do + subgroup = create(:group, :public, parent: group) + l2_subgroup = create(:group, :public, parent: subgroup) + create(:project, :public, namespace: l2_subgroup, name: 'test') + + get :index, group_id: subgroup.to_param, filter: 'test', format: :json + + expect(response).to have_http_status(200) + end + + it 'returns an array with one element when only one result is matched' do + create(:project, :public, namespace: group, name: 'match') + + get :index, group_id: group.to_param, filter: 'match', format: :json + + expect(json_response).to be_kind_of(Array) + expect(json_response.size).to eq(1) + end + + it 'returns an empty array when there are no search results' do + subgroup = create(:group, :public, parent: group) + l2_subgroup = create(:group, :public, parent: subgroup) + create(:project, :public, namespace: l2_subgroup, name: 'no-match') + + get :index, group_id: subgroup.to_param, filter: 'test', format: :json + + expect(json_response).to eq([]) + end + + it 'includes pagination headers' do + 2.times { |i| create(:group, :public, parent: public_subgroup, name: "filterme#{i}") } + + get :index, group_id: group.to_param, filter: 'filter', per_page: 1, format: :json + + expect(response).to include_pagination_headers + end + end + + context 'queries per rendered element', :request_store do + # We need to make sure the following counts are preloaded + # otherwise they will cause an extra query + # 1. Count of visible projects in the element + # 2. Count of visible subgroups in the element + # 3. Count of members of a group + let(:expected_queries_per_group) { 0 } + let(:expected_queries_per_project) { 0 } + + def get_list + get :index, group_id: group.to_param, format: :json + end + + it 'queries the expected amount for a group row' do + control = ActiveRecord::QueryRecorder.new { get_list } + + _new_group = create(:group, :public, parent: group) + + expect { get_list }.not_to exceed_query_limit(control).with_threshold(expected_queries_per_group) + end + + it 'queries the expected amount for a project row' do + control = ActiveRecord::QueryRecorder.new { get_list } + _new_project = create(:project, :public, namespace: group) + + expect { get_list }.not_to exceed_query_limit(control).with_threshold(expected_queries_per_project) + end + + context 'when rendering hierarchies' do + # When loading hierarchies we load the all the ancestors for matched projects + # in 1 separate query + let(:extra_queries_for_hierarchies) { 1 } + + def get_filtered_list + get :index, group_id: group.to_param, filter: 'filter', format: :json + end + + it 'queries the expected amount when nested rows are increased for a group' do + matched_group = create(:group, :public, parent: group, name: 'filterme') + + control = ActiveRecord::QueryRecorder.new { get_filtered_list } + + matched_group.update!(parent: public_subgroup) + + expect { get_filtered_list }.not_to exceed_query_limit(control).with_threshold(extra_queries_for_hierarchies) + end + + it 'queries the expected amount when a new group match is added' do + create(:group, :public, parent: public_subgroup, name: 'filterme') + + control = ActiveRecord::QueryRecorder.new { get_filtered_list } + + create(:group, :public, parent: public_subgroup, name: 'filterme2') + create(:group, :public, parent: public_subgroup, name: 'filterme3') + + expect { get_filtered_list }.not_to exceed_query_limit(control).with_threshold(extra_queries_for_hierarchies) + end + + it 'queries the expected amount when nested rows are increased for a project' do + matched_project = create(:project, :public, namespace: group, name: 'filterme') + + control = ActiveRecord::QueryRecorder.new { get_filtered_list } + + matched_project.update!(namespace: public_subgroup) + + expect { get_filtered_list }.not_to exceed_query_limit(control).with_threshold(extra_queries_for_hierarchies) + end + end + end + end + + context 'pagination' do + let(:per_page) { 3 } + + before do + allow(Kaminari.config).to receive(:default_per_page).and_return(per_page) + end + + context 'with only projects' do + let!(:other_project) { create(:project, :public, namespace: group) } + let!(:first_page_projects) { create_list(:project, per_page, :public, namespace: group ) } + + it 'has projects on the first page' do + get :index, group_id: group.to_param, sort: 'id_desc', format: :json + + expect(assigns(:children)).to contain_exactly(*first_page_projects) + end + + it 'has projects on the second page' do + get :index, group_id: group.to_param, sort: 'id_desc', page: 2, format: :json + + expect(assigns(:children)).to contain_exactly(other_project) + end + end + + context 'with subgroups and projects', :nested_groups do + let!(:first_page_subgroups) { create_list(:group, per_page, :public, parent: group) } + let!(:other_subgroup) { create(:group, :public, parent: group) } + let!(:next_page_projects) { create_list(:project, per_page, :public, namespace: group) } + + it 'contains all subgroups' do + get :index, group_id: group.to_param, sort: 'id_asc', format: :json + + expect(assigns(:children)).to contain_exactly(*first_page_subgroups) + end + + it 'contains the project and group on the second page' do + get :index, group_id: group.to_param, sort: 'id_asc', page: 2, format: :json + + expect(assigns(:children)).to contain_exactly(other_subgroup, *next_page_projects.take(per_page - 1)) + end + end + end + end +end diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb index cce53f6697c..9c6d584f59b 100644 --- a/spec/controllers/groups/group_members_controller_spec.rb +++ b/spec/controllers/groups/group_members_controller_spec.rb @@ -8,7 +8,7 @@ describe Groups::GroupMembersController do it 'renders index with 200 status code' do get :index, group_id: group - expect(response).to have_http_status(200) + expect(response).to have_gitlab_http_status(200) expect(response).to render_template(:index) end end @@ -30,7 +30,7 @@ describe Groups::GroupMembersController do user_ids: group_user.id, access_level: Gitlab::Access::GUEST - expect(response).to have_http_status(403) + expect(response).to have_gitlab_http_status(403) expect(group.users).not_to include group_user end end @@ -73,7 +73,7 @@ describe Groups::GroupMembersController do it 'returns 403' do delete :destroy, group_id: group, id: 42 - expect(response).to have_http_status(403) + expect(response).to have_gitlab_http_status(403) end end @@ -86,7 +86,7 @@ describe Groups::GroupMembersController do it 'returns 403' do delete :destroy, group_id: group, id: member - expect(response).to have_http_status(403) + expect(response).to have_gitlab_http_status(403) expect(group.members).to include member end end @@ -123,7 +123,7 @@ describe Groups::GroupMembersController do it 'returns 404' do delete :leave, group_id: group - expect(response).to have_http_status(404) + expect(response).to have_gitlab_http_status(404) end end @@ -144,7 +144,7 @@ describe Groups::GroupMembersController do it 'supports json request' do delete :leave, group_id: group, format: :json - expect(response).to have_http_status(200) + expect(response).to have_gitlab_http_status(200) expect(json_response['notice']).to eq "You left the \"#{group.name}\" group." end end @@ -157,7 +157,7 @@ describe Groups::GroupMembersController do it 'cannot removes himself from the group' do delete :leave, group_id: group - expect(response).to have_http_status(403) + expect(response).to have_gitlab_http_status(403) end end @@ -204,7 +204,7 @@ describe Groups::GroupMembersController do it 'returns 403' do post :approve_access_request, group_id: group, id: 42 - expect(response).to have_http_status(403) + expect(response).to have_gitlab_http_status(403) end end @@ -217,7 +217,7 @@ describe Groups::GroupMembersController do it 'returns 403' do post :approve_access_request, group_id: group, id: member - expect(response).to have_http_status(403) + expect(response).to have_gitlab_http_status(403) expect(group.members).not_to include member end end diff --git a/spec/controllers/groups/labels_controller_spec.rb b/spec/controllers/groups/labels_controller_spec.rb index 899d8ebd12b..da54aa9054c 100644 --- a/spec/controllers/groups/labels_controller_spec.rb +++ b/spec/controllers/groups/labels_controller_spec.rb @@ -16,7 +16,7 @@ describe Groups::LabelsController do post :toggle_subscription, group_id: group.to_param, id: label.to_param - expect(response).to have_http_status(200) + expect(response).to have_gitlab_http_status(200) end end end diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb index fbbc67f3ae0..c1aba46be04 100644 --- a/spec/controllers/groups/milestones_controller_spec.rb +++ b/spec/controllers/groups/milestones_controller_spec.rb @@ -35,7 +35,7 @@ describe Groups::MilestonesController do it 'shows group milestones page' do get :index, group_id: group.to_param - expect(response).to have_http_status(200) + expect(response).to have_gitlab_http_status(200) end context 'as JSON' do @@ -51,7 +51,7 @@ describe Groups::MilestonesController do expect(milestones.count).to eq(2) expect(milestones.first["title"]).to eq("group milestone") expect(milestones.second["title"]).to eq("legacy") - expect(response).to have_http_status(200) + expect(response).to have_gitlab_http_status(200) expect(response.content_type).to eq 'application/json' end end @@ -153,7 +153,7 @@ describe Groups::MilestonesController do it 'does not redirect' do get :index, group_id: group.to_param - expect(response).not_to have_http_status(301) + expect(response).not_to have_gitlab_http_status(301) end end @@ -172,7 +172,7 @@ describe Groups::MilestonesController do it 'does not redirect' do get :show, group_id: group.to_param, id: title - expect(response).not_to have_http_status(301) + expect(response).not_to have_gitlab_http_status(301) end end @@ -242,7 +242,7 @@ describe Groups::MilestonesController do group_id: group.to_param, milestone: { title: title } - expect(response).not_to have_http_status(404) + expect(response).not_to have_gitlab_http_status(404) end it 'does not redirect to the correct casing' do @@ -250,7 +250,7 @@ describe Groups::MilestonesController do group_id: group.to_param, milestone: { title: title } - expect(response).not_to have_http_status(301) + expect(response).not_to have_gitlab_http_status(301) end end @@ -262,7 +262,7 @@ describe Groups::MilestonesController do group_id: redirect_route.path, milestone: { title: title } - expect(response).to have_http_status(404) + expect(response).to have_gitlab_http_status(404) end end end diff --git a/spec/controllers/groups/settings/ci_cd_controller_spec.rb b/spec/controllers/groups/settings/ci_cd_controller_spec.rb index 2e0efb57c74..e9f0924caba 100644 --- a/spec/controllers/groups/settings/ci_cd_controller_spec.rb +++ b/spec/controllers/groups/settings/ci_cd_controller_spec.rb @@ -13,7 +13,7 @@ describe Groups::Settings::CiCdController do it 'renders show with 200 status code' do get :show, group_id: group - expect(response).to have_http_status(200) + expect(response).to have_gitlab_http_status(200) expect(response).to render_template(:show) end end diff --git a/spec/controllers/groups/variables_controller_spec.rb b/spec/controllers/groups/variables_controller_spec.rb index 02f2fa46047..8ea98cd9e8f 100644 --- a/spec/controllers/groups/variables_controller_spec.rb +++ b/spec/controllers/groups/variables_controller_spec.rb @@ -48,7 +48,7 @@ describe Groups::VariablesController do post :update, group_id: group, id: variable.id, variable: { key: '?', value: variable.value } - expect(response).to have_http_status(200) + expect(response).to have_gitlab_http_status(200) expect(response).to render_template :show end end |