diff options
Diffstat (limited to 'spec/controllers/projects')
9 files changed, 257 insertions, 57 deletions
diff --git a/spec/controllers/projects/badges_controller_spec.rb b/spec/controllers/projects/badges_controller_spec.rb index 5ec8d8d41d7..4ae29ba7f54 100644 --- a/spec/controllers/projects/badges_controller_spec.rb +++ b/spec/controllers/projects/badges_controller_spec.rb @@ -7,51 +7,115 @@ describe Projects::BadgesController do let!(:pipeline) { create(:ci_empty_pipeline) } let(:user) { create(:user) } - before do - project.add_maintainer(user) - sign_in(user) - end + shared_examples 'a badge resource' do |badge_type| + context 'when pipelines are public' do + before do + project.update!(public_builds: true) + end + + context 'when project is public' do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + end + + it "returns the #{badge_type} badge to unauthenticated users" do + get_badge(badge_type) + + expect(response).to have_gitlab_http_status(:ok) + end + end + + context 'when project is restricted' do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + project.add_guest(user) + sign_in(user) + end + + it "returns the #{badge_type} badge to guest users" do + get_badge(badge_type) + + expect(response).to have_gitlab_http_status(:ok) + end + end + end - it 'requests the pipeline badge successfully' do - get_badge(:pipeline) + context 'format' do + before do + project.add_maintainer(user) + sign_in(user) + end - expect(response).to have_gitlab_http_status(:ok) - end + it 'renders the `flat` badge layout by default' do + get_badge(badge_type) - it 'requests the coverage badge successfully' do - get_badge(:coverage) + expect(response).to render_template('projects/badges/badge') + end - expect(response).to have_gitlab_http_status(:ok) - end + context 'when style param is set to `flat`' do + it 'renders the `flat` badge layout' do + get_badge(badge_type, 'flat') - it 'renders the `flat` badge layout by default' do - get_badge(:coverage) + expect(response).to render_template('projects/badges/badge') + end + end - expect(response).to render_template('projects/badges/badge') - end + context 'when style param is set to an invalid type' do + it 'renders the `flat` (default) badge layout' do + get_badge(badge_type, 'xxx') + + expect(response).to render_template('projects/badges/badge') + end + end - context 'when style param is set to `flat`' do - it 'renders the `flat` badge layout' do - get_badge(:coverage, 'flat') + context 'when style param is set to `flat-square`' do + it 'renders the `flat-square` badge layout' do + get_badge(badge_type, 'flat-square') - expect(response).to render_template('projects/badges/badge') + expect(response).to render_template('projects/badges/badge_flat-square') + end + end end - end - context 'when style param is set to an invalid type' do - it 'renders the `flat` (default) badge layout' do - get_badge(:coverage, 'xxx') + context 'when pipelines are not public' do + before do + project.update!(public_builds: false) + end - expect(response).to render_template('projects/badges/badge') + context 'when project is public' do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + end + + it 'returns 404 to unauthenticated users' do + get_badge(badge_type) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when project is restricted to the user' do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) + project.add_guest(user) + sign_in(user) + end + + it 'defaults to project permissions' do + get_badge(:coverage) + + expect(response).to have_gitlab_http_status(:not_found) + end + end end end - context 'when style param is set to `flat-square`' do - it 'renders the `flat-square` badge layout' do - get_badge(:coverage, 'flat-square') + describe '#pipeline' do + it_behaves_like 'a badge resource', :pipeline + end - expect(response).to render_template('projects/badges/badge_flat-square') - end + describe '#coverage' do + it_behaves_like 'a badge resource', :coverage end def get_badge(badge, style = nil) diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index ebbbebf1bc0..8872e8d38e7 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -551,7 +551,7 @@ describe Projects::EnvironmentsController do end context 'when the specified dashboard is the default dashboard' do - let(:dashboard_path) { Gitlab::Metrics::Dashboard::SystemDashboardService::SYSTEM_DASHBOARD_PATH } + let(:dashboard_path) { ::Metrics::Dashboard::SystemDashboardService::SYSTEM_DASHBOARD_PATH } it_behaves_like 'the default dashboard' end diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb index 844c61f1ace..d11ef24ef96 100644 --- a/spec/controllers/projects/error_tracking_controller_spec.rb +++ b/spec/controllers/projects/error_tracking_controller_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'rails_helper' +require 'spec_helper' describe Projects::ErrorTrackingController do set(:project) { create(:project) } diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 32d14dce936..fab47aa4701 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -251,15 +251,13 @@ describe Projects::IssuesController do end end - describe 'Redirect after sign in' do + # This spec runs as a request-style spec in order to invoke the + # Rails router. A controller-style spec matches the wrong route, and + # session['user_return_to'] becomes incorrect. + describe 'Redirect after sign in', type: :request do context 'with an AJAX request' do it 'does not store the visited URL' do - get :show, params: { - format: :json, - namespace_id: project.namespace, - project_id: project, - id: issue.iid - }, xhr: true + get project_issue_path(project, issue), xhr: true expect(session['user_return_to']).to be_blank end @@ -267,14 +265,9 @@ describe Projects::IssuesController do context 'without an AJAX request' do it 'stores the visited URL' do - get :show, - params: { - namespace_id: project.namespace.to_param, - project_id: project, - id: issue.iid - } + get project_issue_path(project, issue) - expect(session['user_return_to']).to eq("/#{project.namespace.to_param}/#{project.to_param}/issues/#{issue.iid}") + expect(session['user_return_to']).to eq(project_issue_path(project, issue)) end end end @@ -1260,6 +1253,28 @@ describe Projects::IssuesController do sign_in(user) end + context do + it_behaves_like 'discussions provider' do + let!(:author) { create(:user) } + let!(:project) { create(:project) } + + let!(:issue) { create(:issue, project: project, author: user) } + + let!(:note_on_issue1) { create(:discussion_note_on_issue, noteable: issue, project: issue.project, author: create(:user)) } + let!(:note_on_issue2) { create(:discussion_note_on_issue, noteable: issue, project: issue.project, author: create(:user)) } + + let(:requested_iid) { issue.iid } + let(:expected_discussion_count) { 3 } + let(:expected_discussion_ids) do + [ + issue.notes.first.discussion_id, + note_on_issue1.discussion_id, + note_on_issue2.discussion_id + ] + end + end + end + it 'returns discussion json' do get :discussions, params: { namespace_id: project.namespace, project_id: project, id: issue.iid } diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb index e428aa3c7b7..f076a5e769f 100644 --- a/spec/controllers/projects/jobs_controller_spec.rb +++ b/spec/controllers/projects/jobs_controller_spec.rb @@ -546,7 +546,7 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do expect(response).to have_gitlab_http_status(:ok) expect(json_response['id']).to eq job.id expect(json_response['status']).to eq job.status - expect(json_response['html']).to eq('<span class="">BUILD TRACE</span>') + expect(json_response['html']).to eq('<span>BUILD TRACE</span>') end end @@ -676,6 +676,8 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do end describe 'POST play' do + let(:variable_attributes) { [] } + before do project.add_developer(user) @@ -698,6 +700,14 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do it 'transits to pending' do expect(job.reload).to be_pending end + + context 'when job variables are specified' do + let(:variable_attributes) { [{ key: 'first', secret_value: 'first' }] } + + it 'assigns the job variables' do + expect(job.reload.job_variables.map(&:key)).to contain_exactly('first') + end + end end context 'when job is not playable' do @@ -712,7 +722,8 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do post :play, params: { namespace_id: project.namespace, project_id: project, - id: job.id + id: job.id, + job_variables_attributes: variable_attributes } end end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index f11880122b1..b1dc6a65dd4 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -621,10 +621,100 @@ describe Projects::MergeRequestsController do format: :json end - it 'responds with serialized pipelines' do - expect(json_response['pipelines']).not_to be_empty - expect(json_response['count']['all']).to eq 1 - expect(response).to include_pagination_headers + context 'with "enabled" builds on a public project' do + let(:project) { create(:project, :repository, :public) } + + context 'for a project owner' do + it 'responds with serialized pipelines' do + expect(json_response['pipelines']).to be_present + expect(json_response['count']['all']).to eq(1) + expect(response).to include_pagination_headers + end + end + + context 'for an unassociated user' do + let(:user) { create :user } + + it 'responds with no pipelines' do + expect(json_response['pipelines']).to be_present + expect(json_response['count']['all']).to eq(1) + expect(response).to include_pagination_headers + end + end + end + + context 'with private builds on a public project' do + let(:project) { create(:project, :repository, :public, :builds_private) } + + context 'for a project owner' do + it 'responds with serialized pipelines' do + expect(json_response['pipelines']).to be_present + expect(json_response['count']['all']).to eq(1) + expect(response).to include_pagination_headers + end + end + + context 'for an unassociated user' do + let(:user) { create :user } + + it 'responds with no pipelines' do + expect(json_response['pipelines']).to be_empty + expect(json_response['count']['all']).to eq(0) + expect(response).to include_pagination_headers + end + end + + context 'from a project fork' do + let(:fork_user) { create :user } + let(:forked_project) { fork_project(project, fork_user, repository: true) } # Forked project carries over :builds_private + let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: forked_project) } + + context 'with private builds' do + context 'for the target project member' do + it 'does not respond with serialized pipelines' do + expect(json_response['pipelines']).to be_empty + expect(json_response['count']['all']).to eq(0) + expect(response).to include_pagination_headers + end + end + + context 'for the source project member' do + let(:user) { fork_user } + + it 'responds with serialized pipelines' do + expect(json_response['pipelines']).to be_present + expect(json_response['count']['all']).to eq(1) + expect(response).to include_pagination_headers + end + end + end + + context 'with public builds' do + let(:forked_project) do + fork_project(project, fork_user, repository: true).tap do |new_project| + new_project.project_feature.update(builds_access_level: ProjectFeature::ENABLED) + end + end + + context 'for the target project member' do + it 'does not respond with serialized pipelines' do + expect(json_response['pipelines']).to be_present + expect(json_response['count']['all']).to eq(1) + expect(response).to include_pagination_headers + end + end + + context 'for the source project member' do + let(:user) { fork_user } + + it 'responds with serialized pipelines' do + expect(json_response['pipelines']).to be_present + expect(json_response['count']['all']).to eq(1) + expect(response).to include_pagination_headers + end + end + end + end end end @@ -885,10 +975,9 @@ describe Projects::MergeRequestsController do environment2 = create(:environment, project: forked) create(:deployment, :succeed, environment: environment2, sha: sha, ref: 'master', deployable: build) - # TODO address the last 11 queries + # TODO address the last 5 queries # See https://gitlab.com/gitlab-org/gitlab-ce/issues/63952 (5 queries) - # And https://gitlab.com/gitlab-org/gitlab-ce/issues/64105 (6 queries) - leeway = 11 + leeway = 5 expect { get_ci_environments_status }.not_to exceed_all_query_limit(control_count + leeway) end end @@ -1121,6 +1210,22 @@ describe Projects::MergeRequestsController do end end end + + context do + it_behaves_like 'discussions provider' do + let!(:author) { create(:user) } + let!(:project) { create(:project) } + + let!(:merge_request) { create(:merge_request, source_project: project) } + + let!(:mr_note1) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) } + let!(:mr_note2) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) } + + let(:requested_iid) { merge_request.iid } + let(:expected_discussion_count) { 2 } + let(:expected_discussion_ids) { [mr_note1.discussion_id, mr_note2.discussion_id] } + end + end end describe 'GET edit' do diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb index 767cee7d54a..9b2025b836c 100644 --- a/spec/controllers/projects/milestones_controller_spec.rb +++ b/spec/controllers/projects/milestones_controller_spec.rb @@ -115,7 +115,7 @@ describe Projects::MilestonesController do end end - context 'with nested groups', :nested_groups do + context 'with nested groups' do let!(:subgroup) { create(:group, :public, parent: group) } let!(:subgroup_milestone) { create(:milestone, group: subgroup) } diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb index 98aea9056dc..9ab565dc2e8 100644 --- a/spec/controllers/projects/notes_controller_spec.rb +++ b/spec/controllers/projects/notes_controller_spec.rb @@ -43,7 +43,7 @@ describe Projects::NotesController do request.headers['X-Last-Fetched-At'] = last_fetched_at expect(NotesFinder).to receive(:new) - .with(anything, anything, hash_including(last_fetched_at: last_fetched_at)) + .with(anything, hash_including(last_fetched_at: last_fetched_at)) .and_call_original get :index, params: request_params diff --git a/spec/controllers/projects/uploads_controller_spec.rb b/spec/controllers/projects/uploads_controller_spec.rb index 776c1270977..661ed9840b1 100644 --- a/spec/controllers/projects/uploads_controller_spec.rb +++ b/spec/controllers/projects/uploads_controller_spec.rb @@ -10,6 +10,11 @@ describe Projects::UploadsController do { namespace_id: model.namespace.to_param, project_id: model } end + let(:other_model) { create(:project, :public) } + let(:other_params) do + { namespace_id: other_model.namespace.to_param, project_id: other_model } + end + it_behaves_like 'handle uploads' context 'when the URL the old style, without /-/system' do |